github.com/cjdelisle/matterfoss@v5.11.1+incompatible/services/imageproxy/atmos_camo.go (about) 1 // Copyright (c) 2017-present Mattermost, Inc. All Rights Reserved. 2 // See License.txt for license information. 3 4 package imageproxy 5 6 import ( 7 "crypto/hmac" 8 "crypto/sha1" 9 "encoding/hex" 10 "io" 11 "net/http" 12 "strings" 13 ) 14 15 type AtmosCamoBackend struct { 16 proxy *ImageProxy 17 } 18 19 func makeAtmosCamoBackend(proxy *ImageProxy) *AtmosCamoBackend { 20 return &AtmosCamoBackend{ 21 proxy: proxy, 22 } 23 } 24 25 func (backend *AtmosCamoBackend) GetImage(w http.ResponseWriter, r *http.Request, imageURL string) { 26 http.Redirect(w, r, backend.GetProxiedImageURL(imageURL), http.StatusFound) 27 } 28 29 func (backend *AtmosCamoBackend) GetImageDirect(imageURL string) (io.ReadCloser, string, error) { 30 req, err := http.NewRequest("GET", backend.GetProxiedImageURL(imageURL), nil) 31 if err != nil { 32 return nil, "", Error{err} 33 } 34 35 client := backend.proxy.HTTPService.MakeClient(false) 36 37 resp, err := client.Do(req) 38 if err != nil { 39 return nil, "", Error{err} 40 } 41 42 // Note that we don't do any additional validation of the received data since we expect the image proxy to do that 43 return resp.Body, resp.Header.Get("Content-Type"), nil 44 } 45 46 func (backend *AtmosCamoBackend) GetProxiedImageURL(imageURL string) string { 47 cfg := *backend.proxy.ConfigService.Config() 48 siteURL := *cfg.ServiceSettings.SiteURL 49 proxyURL := *cfg.ImageProxySettings.RemoteImageProxyURL 50 options := *cfg.ImageProxySettings.RemoteImageProxyOptions 51 52 return getAtmosCamoImageURL(imageURL, siteURL, proxyURL, options) 53 } 54 55 func getAtmosCamoImageURL(imageURL, siteURL, proxyURL, options string) string { 56 // Don't proxy blank images, relative URLs, absolute URLs on this server, or URLs that are already going through the proxy 57 if imageURL == "" || imageURL[0] == '/' || (siteURL != "" && strings.HasPrefix(imageURL, siteURL)) || strings.HasPrefix(imageURL, proxyURL) { 58 return imageURL 59 } 60 61 mac := hmac.New(sha1.New, []byte(options)) 62 mac.Write([]byte(imageURL)) 63 digest := hex.EncodeToString(mac.Sum(nil)) 64 65 return proxyURL + "/" + digest + "/" + hex.EncodeToString([]byte(imageURL)) 66 } 67 68 func (backend *AtmosCamoBackend) GetUnproxiedImageURL(proxiedURL string) string { 69 proxyURL := *backend.proxy.ConfigService.Config().ImageProxySettings.RemoteImageProxyURL + "/" 70 71 if !strings.HasPrefix(proxiedURL, proxyURL) { 72 return proxiedURL 73 } 74 75 path := proxiedURL[len(proxyURL):] 76 77 slash := strings.IndexByte(path, '/') 78 if slash == -1 { 79 return proxiedURL 80 } 81 82 decoded, err := hex.DecodeString(path[slash+1:]) 83 if err != nil { 84 return proxiedURL 85 } 86 87 return string(decoded) 88 }