diff --git a/api4/image.go b/api4/image.go index c1087f5e2b..9022724b2a 100644 --- a/api4/image.go +++ b/api4/image.go @@ -20,12 +20,27 @@ func getImage(c *Context, w http.ResponseWriter, r *http.Request) { if err != nil { c.Err = model.NewAppError("getImage", "api.image.get.app_error", nil, err.Error(), http.StatusBadRequest) return + } else if parsedURL.Opaque != "" { + c.Err = model.NewAppError("getImage", "api.image.get.app_error", nil, "", http.StatusBadRequest) + return + } + siteURL, err := url.Parse(*c.App.Config().ServiceSettings.SiteURL) + if err != nil { + c.Err = model.NewAppError("getImage", "model.config.is_valid.site_url.app_error", nil, err.Error(), http.StatusInternalServerError) + return + } + + if parsedURL.Scheme == "" { + parsedURL.Scheme = siteURL.Scheme + } + if parsedURL.Host == "" { + parsedURL.Host = siteURL.Host } // in case image proxy is enabled and we are fetching a remote image (NOT static or served by plugins), pass request to proxy - if *c.App.Config().ImageProxySettings.Enable && parsedURL.IsAbs() { - c.App.ImageProxy().GetImage(w, r, actualURL) + if *c.App.Config().ImageProxySettings.Enable && parsedURL.Host != siteURL.Host { + c.App.ImageProxy().GetImage(w, r, parsedURL.String()) } else { - http.Redirect(w, r, actualURL, http.StatusFound) + http.Redirect(w, r, parsedURL.String(), http.StatusFound) } } diff --git a/api4/image_test.go b/api4/image_test.go index 562a4bd4f9..92bfa2d130 100644 --- a/api4/image_test.go +++ b/api4/image_test.go @@ -8,6 +8,7 @@ import ( "net/http" "net/http/httptest" "net/url" + "strings" "testing" "github.com/stretchr/testify/assert" @@ -100,5 +101,26 @@ func TestGetImage(t *testing.T) { resp, err = th.Client.HttpClient.Do(r) require.NoError(t, err) assert.Equal(t, http.StatusFound, resp.StatusCode) + + // protocol relative URLs should be handled by proxy + th.App.UpdateConfig(func(cfg *model.Config) { + cfg.ServiceSettings.SiteURL = model.NewString("http://foo.com") + }) + r, err = http.NewRequest("GET", th.Client.ApiUrl+"/image?url="+strings.TrimPrefix(imageServer.URL, "http:")+"/image.png", nil) + require.NoError(t, err) + r.Header.Set(model.HEADER_AUTH, th.Client.AuthType+" "+th.Client.AuthToken) + + resp, err = th.Client.HttpClient.Do(r) + require.NoError(t, err) + assert.Equal(t, http.StatusOK, resp.StatusCode) + + // opaque URLs are not supported, should return an error + r, err = http.NewRequest("GET", th.Client.ApiUrl+"/image?url=mailto:test@example.com", nil) + require.NoError(t, err) + r.Header.Set(model.HEADER_AUTH, th.Client.AuthType+" "+th.Client.AuthToken) + + resp, err = th.Client.HttpClient.Do(r) + require.NoError(t, err) + assert.Equal(t, http.StatusBadRequest, resp.StatusCode) }) }