From fdf1164aee36d60b34ca82c07fe02b68e972f53a Mon Sep 17 00:00:00 2001 From: Torsten Juergeleit Date: Wed, 31 May 2017 16:34:05 +0200 Subject: PLT-5705 Created a single source of http.Client creation logic with internet proxy support, reasonable timeouts and optional insecure connections (#6503) --- app/command.go | 8 +------- app/notification.go | 8 +------- app/oauth.go | 14 +++----------- app/post.go | 44 ++++++-------------------------------------- app/webhook.go | 13 ++----------- app/webrtc.go | 7 +------ app/webtrc.go | 7 +------ 7 files changed, 15 insertions(+), 86 deletions(-) (limited to 'app') diff --git a/app/command.go b/app/command.go index 2af934710..bfb97ae0c 100644 --- a/app/command.go +++ b/app/command.go @@ -4,7 +4,6 @@ package app import ( - "crypto/tls" "fmt" "io/ioutil" "net/http" @@ -204,18 +203,13 @@ func ExecuteCommand(args *model.CommandArgs) (*model.CommandResponse, *model.App method = "GET" } - tr := &http.Transport{ - TLSClientConfig: &tls.Config{InsecureSkipVerify: *utils.Cfg.ServiceSettings.EnableInsecureOutgoingConnections}, - } - client := &http.Client{Transport: tr} - req, _ := http.NewRequest(method, cmd.URL, strings.NewReader(p.Encode())) req.Header.Set("Accept", "application/json") if cmd.Method == model.COMMAND_METHOD_POST { req.Header.Set("Content-Type", "application/x-www-form-urlencoded") } - if resp, err := client.Do(req); err != nil { + if resp, err := utils.HttpClient().Do(req); err != nil { return nil, model.NewAppError("command", "api.command.execute_command.failed.app_error", map[string]interface{}{"Trigger": trigger}, err.Error(), http.StatusInternalServerError) } else { if resp.StatusCode == http.StatusOK { diff --git a/app/notification.go b/app/notification.go index 49576d1f0..90a87ea35 100644 --- a/app/notification.go +++ b/app/notification.go @@ -4,7 +4,6 @@ package app import ( - "crypto/tls" "fmt" "html" "html/template" @@ -557,14 +556,9 @@ func ClearPushNotification(userId string, channelId string) *model.AppError { func sendToPushProxy(msg model.PushNotification, session *model.Session) { msg.ServerId = utils.CfgDiagnosticId - tr := &http.Transport{ - TLSClientConfig: &tls.Config{InsecureSkipVerify: *utils.Cfg.ServiceSettings.EnableInsecureOutgoingConnections}, - DisableKeepAlives: true, - } - httpClient := &http.Client{Transport: tr} request, _ := http.NewRequest("POST", *utils.Cfg.EmailSettings.PushNotificationServer+model.API_URL_SUFFIX_V1+"/send_push", strings.NewReader(msg.ToJson())) - if resp, err := httpClient.Do(request); err != nil { + if resp, err := utils.HttpClient().Do(request); err != nil { l4g.Error("Device push reported as error for UserId=%v SessionId=%v message=%v", session.UserId, session.Id, err.Error()) } else { pushResponse := model.PushResponseFromJson(resp.Body) diff --git a/app/oauth.go b/app/oauth.go index deeb10f17..a2edae8be 100644 --- a/app/oauth.go +++ b/app/oauth.go @@ -5,7 +5,6 @@ package app import ( "bytes" - "crypto/tls" b64 "encoding/base64" "fmt" "io" @@ -576,10 +575,6 @@ func AuthorizeOAuthUser(service, code, state, redirectUri string) (io.ReadCloser p.Set("grant_type", model.ACCESS_TOKEN_GRANT_TYPE) p.Set("redirect_uri", redirectUri) - tr := &http.Transport{ - TLSClientConfig: &tls.Config{InsecureSkipVerify: *utils.Cfg.ServiceSettings.EnableInsecureOutgoingConnections}, - } - client := &http.Client{Transport: tr} req, _ := http.NewRequest("POST", sso.TokenEndpoint, strings.NewReader(p.Encode())) req.Header.Set("Content-Type", "application/x-www-form-urlencoded") @@ -587,14 +582,11 @@ func AuthorizeOAuthUser(service, code, state, redirectUri string) (io.ReadCloser var ar *model.AccessResponse var respBody []byte - if resp, err := client.Do(req); err != nil { + if resp, err := utils.HttpClient().Do(req); err != nil { return nil, "", nil, model.NewLocAppError("AuthorizeOAuthUser", "api.user.authorize_oauth_user.token_failed.app_error", nil, err.Error()) } else { ar = model.AccessResponseFromJson(resp.Body) - defer func() { - ioutil.ReadAll(resp.Body) - resp.Body.Close() - }() + defer CloseBody(resp) if ar == nil { return nil, "", nil, model.NewLocAppError("AuthorizeOAuthUser", "api.user.authorize_oauth_user.bad_response.app_error", nil, "") } @@ -616,7 +608,7 @@ func AuthorizeOAuthUser(service, code, state, redirectUri string) (io.ReadCloser req.Header.Set("Accept", "application/json") req.Header.Set("Authorization", "Bearer "+ar.AccessToken) - if resp, err := client.Do(req); err != nil { + if resp, err := utils.HttpClient().Do(req); err != nil { return nil, "", nil, model.NewLocAppError("AuthorizeOAuthUser", "api.user.authorize_oauth_user.service.app_error", map[string]interface{}{"Service": service}, err.Error()) } else { diff --git a/app/post.go b/app/post.go index 341287cf4..baea6179f 100644 --- a/app/post.go +++ b/app/post.go @@ -4,12 +4,8 @@ package app import ( - "net" "net/http" - "net/url" - "os" "regexp" - "time" l4g "github.com/alecthomas/log4go" "github.com/dyatlov/go-opengraph/opengraph" @@ -19,35 +15,7 @@ import ( "github.com/mattermost/platform/utils" ) -var ( - httpClient *http.Client - - httpTimeout = time.Duration(5 * time.Second) - linkWithTextRegex = regexp.MustCompile(`<([^<\|]+)\|([^>]+)>`) -) - -func dialTimeout(network, addr string) (net.Conn, error) { - return net.DialTimeout(network, addr, httpTimeout) -} - -func init() { - p, ok := os.LookupEnv("HTTP_PROXY") - if ok { - if u, err := url.Parse(p); err == nil { - httpClient = &http.Client{ - Transport: &http.Transport{ - Proxy: http.ProxyURL(u), - Dial: dialTimeout, - }, - } - return - } - } - - httpClient = &http.Client{ - Timeout: httpTimeout, - } -} +var linkWithTextRegex = regexp.MustCompile(`<([^<\|]+)\|([^>]+)>`) func CreatePostAsUser(post *model.Post) (*model.Post, *model.AppError) { // Check that channel has not been deleted @@ -126,7 +94,7 @@ func CreatePost(post *model.Post, teamId string, triggerWebhooks bool) (*model.P } esInterface := einterfaces.GetElasticSearchInterface() - if (esInterface != nil && *utils.Cfg.ElasticSearchSettings.EnableIndexing) { + if esInterface != nil && *utils.Cfg.ElasticSearchSettings.EnableIndexing { go esInterface.IndexPost(rpost, teamId) } @@ -314,7 +282,7 @@ func UpdatePost(post *model.Post, safeUpdate bool) (*model.Post, *model.AppError rpost := result.Data.(*model.Post) esInterface := einterfaces.GetElasticSearchInterface() - if (esInterface != nil && *utils.Cfg.ElasticSearchSettings.EnableIndexing) { + if esInterface != nil && *utils.Cfg.ElasticSearchSettings.EnableIndexing { go func() { if rchannel := <-Srv.Store.Channel().GetForPost(rpost.Id); rchannel.Err != nil { l4g.Error("Couldn't get channel %v for post %v for ElasticSearch indexing.", rpost.ChannelId, rpost.Id) @@ -501,7 +469,7 @@ func DeletePost(postId string) (*model.Post, *model.AppError) { go DeleteFlaggedPosts(post.Id) esInterface := einterfaces.GetElasticSearchInterface() - if (esInterface != nil && *utils.Cfg.ElasticSearchSettings.EnableIndexing) { + if esInterface != nil && *utils.Cfg.ElasticSearchSettings.EnableIndexing { go esInterface.DeletePost(post.Id) } @@ -532,7 +500,7 @@ func SearchPostsInTeam(terms string, userId string, teamId string, isOrSearch bo paramsList := model.ParseSearchParams(terms) esInterface := einterfaces.GetElasticSearchInterface() - if (esInterface != nil && *utils.Cfg.ElasticSearchSettings.EnableSearching && utils.IsLicensed && *utils.License.Features.ElasticSearch) { + if esInterface != nil && *utils.Cfg.ElasticSearchSettings.EnableSearching && utils.IsLicensed && *utils.License.Features.ElasticSearch { finalParamsList := []*model.SearchParams{} for _, params := range paramsList { @@ -643,7 +611,7 @@ func GetFileInfosForPost(postId string, readFromMaster bool) ([]*model.FileInfo, func GetOpenGraphMetadata(url string) *opengraph.OpenGraph { og := opengraph.NewOpenGraph() - res, err := httpClient.Get(url) + res, err := utils.HttpClient().Get(url) if err != nil { l4g.Error("GetOpenGraphMetadata request failed for url=%v with err=%v", url, err.Error()) return og diff --git a/app/webhook.go b/app/webhook.go index e095c1b80..1ec96a32e 100644 --- a/app/webhook.go +++ b/app/webhook.go @@ -4,9 +4,7 @@ package app import ( - "crypto/tls" "io" - "io/ioutil" "net/http" "regexp" "strings" @@ -87,23 +85,16 @@ func handleWebhookEvents(post *model.Post, team *model.Team, channel *model.Chan body = strings.NewReader(payload.ToFormValues()) contentType = "application/x-www-form-urlencoded" } - tr := &http.Transport{ - TLSClientConfig: &tls.Config{InsecureSkipVerify: *utils.Cfg.ServiceSettings.EnableInsecureOutgoingConnections}, - } - client := &http.Client{Transport: tr} for _, url := range hook.CallbackURLs { go func(url string) { req, _ := http.NewRequest("POST", url, body) req.Header.Set("Content-Type", contentType) req.Header.Set("Accept", "application/json") - if resp, err := client.Do(req); err != nil { + if resp, err := utils.HttpClient().Do(req); err != nil { l4g.Error(utils.T("api.post.handle_webhook_events_and_forget.event_post.error"), err.Error()) } else { - defer func() { - ioutil.ReadAll(resp.Body) - resp.Body.Close() - }() + defer CloseBody(resp) respProps := model.MapFromJson(resp.Body) if text, ok := respProps["text"]; ok { diff --git a/app/webrtc.go b/app/webrtc.go index 6692fff60..4d44234a8 100644 --- a/app/webrtc.go +++ b/app/webrtc.go @@ -6,7 +6,6 @@ package app import ( "crypto/hmac" "crypto/sha1" - "crypto/tls" "encoding/base64" "net/http" "strconv" @@ -60,11 +59,7 @@ func GetWebrtcToken(sessionId string) (string, *model.AppError) { rq, _ := http.NewRequest("POST", *utils.Cfg.WebrtcSettings.GatewayAdminUrl, strings.NewReader(model.MapToJson(data))) rq.Header.Set("Content-Type", "application/json") - tr := &http.Transport{ - TLSClientConfig: &tls.Config{InsecureSkipVerify: *utils.Cfg.ServiceSettings.EnableInsecureOutgoingConnections}, - } - httpClient := &http.Client{Transport: tr} - if rp, err := httpClient.Do(rq); err != nil { + if rp, err := utils.HttpClient().Do(rq); err != nil { return "", model.NewAppError("WebRTC.Token", "model.client.connecting.app_error", nil, err.Error(), http.StatusInternalServerError) } else if rp.StatusCode >= 300 { defer CloseBody(rp) diff --git a/app/webtrc.go b/app/webtrc.go index a2ead21ab..76e173651 100644 --- a/app/webtrc.go +++ b/app/webtrc.go @@ -4,7 +4,6 @@ package app import ( - "crypto/tls" "encoding/base64" "net/http" "strings" @@ -25,9 +24,5 @@ func RevokeWebrtcToken(sessionId string) { rq.Header.Set("Content-Type", "application/json") // we do not care about the response - tr := &http.Transport{ - TLSClientConfig: &tls.Config{InsecureSkipVerify: *utils.Cfg.ServiceSettings.EnableInsecureOutgoingConnections}, - } - httpClient := &http.Client{Transport: tr} - httpClient.Do(rq) + utils.HttpClient().Do(rq) } -- cgit v1.2.3-1-g7c22