MM-13838 Bypass the HTTP client when getting image dimensions from the image proxy (#10208)

* MM-13838 Bypass the HTTP client when getting image dimensions from the proxy

* Add additional log messages to debug failing test

* Fix unit test to work on Jenkins
Этот коммит содержится в:
Harrison Healey
2019-02-04 12:43:30 -05:00
коммит произвёл GitHub
родитель 85c60f1402
Коммит dbf54b3599
8 изменённых файлов: 304 добавлений и 11 удалений

Просмотреть файл

@@ -346,18 +346,34 @@ func (a *App) getLinkMetadata(requestURL string, timestamp int64, isNewPost bool
return nil, nil, err
}
request.Header.Add("Accept", "text/html, image/*")
var body io.ReadCloser
var contentType string
client := a.HTTPService.MakeClient(false)
client.Timeout = time.Duration(*a.Config().ExperimentalSettings.LinkMetadataTimeoutMilliseconds) * time.Millisecond
if (request.URL.Scheme+"://"+request.URL.Host) == a.GetSiteURL() && request.URL.Path == "/api/v4/image" {
// /api/v4/image requires authentication, so bypass the API by hitting the proxy directly
body, contentType, err = a.ImageProxy.GetImageDirect(a.ImageProxy.GetUnproxiedImageURL(request.URL.String()))
} else {
request.Header.Add("Accept", "text/html, image/*")
res, err := client.Do(request)
client := a.HTTPService.MakeClient(false)
client.Timeout = time.Duration(*a.Config().ExperimentalSettings.LinkMetadataTimeoutMilliseconds) * time.Millisecond
var res *http.Response
res, err = client.Do(request)
if res != nil {
body = res.Body
contentType = res.Header.Get("Content-Type")
}
}
if body != nil {
defer body.Close()
}
if err == nil {
defer res.Body.Close()
// Parse the data
og, image, err = a.parseLinkMetadata(requestURL, res.Body, res.Header.Get("Content-Type"))
og, image, err = a.parseLinkMetadata(requestURL, body, contentType)
}
// Write back to cache and database, even if there was an error and the results are nil

Просмотреть файл

@@ -19,6 +19,8 @@ import (
"github.com/dyatlov/go-opengraph/opengraph"
"github.com/mattermost/mattermost-server/model"
"github.com/mattermost/mattermost-server/services/httpservice"
"github.com/mattermost/mattermost-server/services/imageproxy"
"github.com/mattermost/mattermost-server/utils/testutils"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
@@ -1064,8 +1066,6 @@ func TestGetLinkMetadata(t *testing.T) {
return th
}
th := Setup().InitBasic()
defer th.TearDown()
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
params := r.URL.Query()
@@ -1510,6 +1510,11 @@ func TestGetLinkMetadata(t *testing.T) {
defer th.TearDown()
// Fake the SiteURL to have the relative URL resolve to the external server
oldSiteURL := *th.App.Config().ServiceSettings.SiteURL
defer th.App.UpdateConfig(func(cfg *model.Config) {
*cfg.ServiceSettings.SiteURL = oldSiteURL
})
th.App.UpdateConfig(func(cfg *model.Config) {
*cfg.ServiceSettings.SiteURL = server.URL
})
@@ -1522,6 +1527,45 @@ func TestGetLinkMetadata(t *testing.T) {
assert.NotNil(t, img)
assert.Nil(t, err)
})
t.Run("should error on local addresses other than the image proxy", func(t *testing.T) {
th := setup()
defer th.TearDown()
// Disable AllowedUntrustedInternalConnections since it's turned on for the previous tests
oldAllowUntrusted := *th.App.Config().ServiceSettings.AllowedUntrustedInternalConnections
oldSiteURL := *th.App.Config().ServiceSettings.SiteURL
defer th.App.UpdateConfig(func(cfg *model.Config) {
*cfg.ServiceSettings.AllowedUntrustedInternalConnections = oldAllowUntrusted
*cfg.ServiceSettings.SiteURL = oldSiteURL
})
th.App.UpdateConfig(func(cfg *model.Config) {
*cfg.ServiceSettings.AllowedUntrustedInternalConnections = ""
*cfg.ServiceSettings.SiteURL = "http://mattermost.example.com"
*cfg.ImageProxySettings.Enable = true
*cfg.ImageProxySettings.ImageProxyType = "local"
})
requestURL := server.URL + "/image?height=200&width=300&name=" + t.Name()
timestamp := int64(1547510400000)
og, img, err := th.App.getLinkMetadata(requestURL, timestamp, false)
assert.Nil(t, og)
assert.Nil(t, img)
assert.NotNil(t, err)
assert.IsType(t, &url.Error{}, err)
assert.Equal(t, httpservice.AddressForbidden, err.(*url.Error).Err)
requestURL = th.App.GetSiteURL() + "/api/v4/image?url=" + url.QueryEscape(requestURL)
// Note that this request still fails while testing because the request made by the image proxy is blocked
og, img, err = th.App.getLinkMetadata(requestURL, timestamp, false)
assert.Nil(t, og)
assert.Nil(t, img)
assert.NotNil(t, err)
assert.IsType(t, imageproxy.Error{}, err)
})
}
func TestResolveMetadataURL(t *testing.T) {