github.com/masterhung0112/hk_server/v5@v5.0.0-20220302090640-ec71aef15e1c/services/httpservice/httpservice.go (about)

     1  // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
     2  // See LICENSE.txt for license information.
     3  
     4  package httpservice
     5  
     6  import (
     7  	"net"
     8  	"net/http"
     9  	"strings"
    10  	"time"
    11  	"unicode"
    12  
    13  	"github.com/masterhung0112/hk_server/v5/services/configservice"
    14  )
    15  
    16  // HTTPService wraps the functionality for making http requests to provide some improvements to the default client
    17  // behaviour.
    18  type HTTPService interface {
    19  	// MakeClient returns an http client constructed with a RoundTripper as returned by MakeTransport.
    20  	MakeClient(trustURLs bool) *http.Client
    21  
    22  	// MakeTransport returns a RoundTripper that is suitable for making requests to external resources. The default
    23  	// implementation provides:
    24  	// - A shorter timeout for dial and TLS handshake (defined as constant "ConnectTimeout")
    25  	// - A timeout for end-to-end requests
    26  	// - A Mattermost-specific user agent header
    27  	// - Additional security for untrusted and insecure connections
    28  	MakeTransport(trustURLs bool) *MattermostTransport
    29  }
    30  
    31  type HTTPServiceImpl struct {
    32  	configService configservice.ConfigService
    33  
    34  	RequestTimeout time.Duration
    35  }
    36  
    37  func splitFields(c rune) bool {
    38  	return unicode.IsSpace(c) || c == ','
    39  }
    40  
    41  func MakeHTTPService(configService configservice.ConfigService) HTTPService {
    42  	return &HTTPServiceImpl{
    43  		configService,
    44  		RequestTimeout,
    45  	}
    46  }
    47  
    48  func (h *HTTPServiceImpl) MakeClient(trustURLs bool) *http.Client {
    49  	return &http.Client{
    50  		Transport: h.MakeTransport(trustURLs),
    51  		Timeout:   h.RequestTimeout,
    52  	}
    53  }
    54  
    55  func (h *HTTPServiceImpl) MakeTransport(trustURLs bool) *MattermostTransport {
    56  	insecure := h.configService.Config().ServiceSettings.EnableInsecureOutgoingConnections != nil && *h.configService.Config().ServiceSettings.EnableInsecureOutgoingConnections
    57  
    58  	if trustURLs {
    59  		return NewTransport(insecure, nil, nil)
    60  	}
    61  
    62  	allowHost := func(host string) bool {
    63  		if h.configService.Config().ServiceSettings.AllowedUntrustedInternalConnections == nil {
    64  			return false
    65  		}
    66  		for _, allowed := range strings.FieldsFunc(*h.configService.Config().ServiceSettings.AllowedUntrustedInternalConnections, splitFields) {
    67  			if host == allowed {
    68  				return true
    69  			}
    70  		}
    71  		return false
    72  	}
    73  
    74  	allowIP := func(ip net.IP) bool {
    75  		reservedIP := IsReservedIP(ip)
    76  		ownIP, err := IsOwnIP(ip)
    77  
    78  		// If there is an error getting the self-assigned IPs, default to the secure option
    79  		if err != nil {
    80  			return false
    81  		}
    82  
    83  		// If it's not a reserved IP and it's not self-assigned IP, accept the IP
    84  		if !reservedIP && !ownIP {
    85  			return true
    86  		}
    87  
    88  		if h.configService.Config().ServiceSettings.AllowedUntrustedInternalConnections == nil {
    89  			return false
    90  		}
    91  
    92  		// In the case it's the self-assigned IP, enforce that it needs to be explicitly added to the AllowedUntrustedInternalConnections
    93  		for _, allowed := range strings.FieldsFunc(*h.configService.Config().ServiceSettings.AllowedUntrustedInternalConnections, splitFields) {
    94  			if _, ipRange, err := net.ParseCIDR(allowed); err == nil && ipRange.Contains(ip) {
    95  				return true
    96  			}
    97  		}
    98  		return false
    99  	}
   100  
   101  	return NewTransport(insecure, allowHost, allowIP)
   102  }