github.com/vnforks/kid@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 }