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