mirror of
https://github.com/mattermost/mattermost.git
synced 2025-02-25 18:55:24 -06:00
Switching redirect_location route to use httpservice client and adding caching. (#10118)
This commit is contained in:
committed by
GitHub
parent
b890f8d007
commit
ce2c7110d3
@@ -14,8 +14,13 @@ import (
|
||||
"github.com/mattermost/mattermost-server/mlog"
|
||||
"github.com/mattermost/mattermost-server/model"
|
||||
"github.com/mattermost/mattermost-server/services/filesstore"
|
||||
"github.com/mattermost/mattermost-server/utils"
|
||||
)
|
||||
|
||||
const REDIRECT_LOCATION_CACHE_SIZE = 10000
|
||||
|
||||
var redirectLocationDataCache = utils.NewLru(REDIRECT_LOCATION_CACHE_SIZE)
|
||||
|
||||
func (api *API) InitSystem() {
|
||||
api.BaseRoutes.System.Handle("/ping", api.ApiHandler(getSystemPing)).Methods("GET")
|
||||
|
||||
@@ -471,32 +476,42 @@ func testS3(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
func getRedirectLocation(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
m := make(map[string]string)
|
||||
m["location"] = ""
|
||||
|
||||
cfg := c.App.GetConfig()
|
||||
if !*cfg.ServiceSettings.EnableLinkPreviews {
|
||||
w.Write([]byte(model.MapToJson(m)))
|
||||
return
|
||||
}
|
||||
|
||||
url := r.URL.Query().Get("url")
|
||||
if len(url) == 0 {
|
||||
c.SetInvalidParam("url")
|
||||
return
|
||||
}
|
||||
|
||||
client := &http.Client{
|
||||
CheckRedirect: func(req *http.Request, via []*http.Request) error {
|
||||
return http.ErrUseLastResponse
|
||||
},
|
||||
}
|
||||
|
||||
res, err := client.Head(url)
|
||||
if err != nil {
|
||||
// Always return a success status and a JSON string to limit the amount of information returned to a
|
||||
// hacker attempting to use Mattermost to probe a private network.
|
||||
if location, ok := openGraphDataCache.Get(url); ok {
|
||||
m["location"] = location.(string)
|
||||
w.Write([]byte(model.MapToJson(m)))
|
||||
return
|
||||
}
|
||||
|
||||
m["location"] = res.Header.Get("Location")
|
||||
client := c.App.HTTPService.MakeClient(false)
|
||||
client.CheckRedirect = func(req *http.Request, via []*http.Request) error {
|
||||
return http.ErrUseLastResponse
|
||||
}
|
||||
|
||||
res, err := client.Head(url)
|
||||
if err != nil {
|
||||
// Cache failures to prevent retries.
|
||||
redirectLocationDataCache.AddWithExpiresInSecs(url, "", 3600) // Expires after 1 hour
|
||||
// Always return a success status and a JSON string to limit information returned to client.
|
||||
w.Write([]byte(model.MapToJson(m)))
|
||||
return
|
||||
}
|
||||
|
||||
location := res.Header.Get("Location")
|
||||
redirectLocationDataCache.AddWithExpiresInSecs(url, location, 3600) // Expires after 1 hour
|
||||
m["location"] = location
|
||||
|
||||
w.Write([]byte(model.MapToJson(m)))
|
||||
return
|
||||
|
||||
@@ -751,6 +751,7 @@ func TestRedirectLocation(t *testing.T) {
|
||||
}()
|
||||
|
||||
*th.App.Config().ServiceSettings.EnableLinkPreviews = true
|
||||
*th.App.Config().ServiceSettings.AllowedUntrustedInternalConnections = "127.0.0.1"
|
||||
|
||||
_, resp := th.SystemAdminClient.GetRedirectLocation("https://mattermost.com/", "")
|
||||
CheckNoError(t, resp)
|
||||
@@ -760,9 +761,7 @@ func TestRedirectLocation(t *testing.T) {
|
||||
|
||||
actual, resp := th.SystemAdminClient.GetRedirectLocation(mockBitlyLink, "")
|
||||
CheckNoError(t, resp)
|
||||
if actual != expected {
|
||||
t.Errorf("Expected %v but got %v.", expected, actual)
|
||||
}
|
||||
assert.Equal(t, expected, actual)
|
||||
|
||||
*th.App.Config().ServiceSettings.EnableLinkPreviews = false
|
||||
actual, resp = th.SystemAdminClient.GetRedirectLocation("https://mattermost.com/", "")
|
||||
|
||||
Reference in New Issue
Block a user