github.com/masterhung0112/hk_server/v5@v5.0.0-20220302090640-ec71aef15e1c/services/imageproxy/atmos_camo_test.go (about) 1 // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. 2 // See LICENSE.txt for license information. 3 4 package imageproxy 5 6 import ( 7 "io/ioutil" 8 "net/http" 9 "net/http/httptest" 10 "net/url" 11 "testing" 12 13 "github.com/stretchr/testify/assert" 14 "github.com/stretchr/testify/require" 15 16 "github.com/masterhung0112/hk_server/v5/model" 17 "github.com/masterhung0112/hk_server/v5/services/httpservice" 18 "github.com/masterhung0112/hk_server/v5/utils/testutils" 19 ) 20 21 func makeTestAtmosCamoProxy() *ImageProxy { 22 configService := &testutils.StaticConfigService{ 23 Cfg: &model.Config{ 24 ServiceSettings: model.ServiceSettings{ 25 SiteURL: model.NewString("https://mattermost.example.com"), 26 AllowedUntrustedInternalConnections: model.NewString("127.0.0.1"), 27 }, 28 ImageProxySettings: model.ImageProxySettings{ 29 Enable: model.NewBool(true), 30 ImageProxyType: model.NewString(model.IMAGE_PROXY_TYPE_ATMOS_CAMO), 31 RemoteImageProxyURL: model.NewString("http://images.example.com"), 32 RemoteImageProxyOptions: model.NewString("7e5f3fab20b94782b43cdb022a66985ef28ba355df2c5d5da3c9a05e4b697bac"), 33 }, 34 }, 35 } 36 37 return MakeImageProxy(configService, httpservice.MakeHTTPService(configService), nil) 38 } 39 40 func TestAtmosCamoBackend_GetImage(t *testing.T) { 41 imageURL := "http://www.mattermost.org/wp-content/uploads/2016/03/logoHorizontalWhite.png" 42 proxiedURL := "http://images.example.com/62183a1cf0a4927c3b56d249366c2745e34ffe63/687474703a2f2f7777772e6d61747465726d6f73742e6f72672f77702d636f6e74656e742f75706c6f6164732f323031362f30332f6c6f676f486f72697a6f6e74616c57686974652e706e67" 43 44 proxy := makeTestAtmosCamoProxy() 45 46 recorder := httptest.NewRecorder() 47 request, _ := http.NewRequest(http.MethodGet, "", nil) 48 proxy.GetImage(recorder, request, imageURL) 49 resp := recorder.Result() 50 51 assert.Equal(t, http.StatusFound, resp.StatusCode) 52 assert.Equal(t, proxiedURL, resp.Header.Get("Location")) 53 } 54 55 func TestAtmosCamoBackend_GetImageDirect(t *testing.T) { 56 handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 57 w.Header().Set("Cache-Control", "max-age=2592000, private") 58 w.Header().Set("Content-Type", "image/png") 59 w.Header().Set("Content-Length", "10") 60 61 w.WriteHeader(http.StatusOK) 62 w.Write([]byte("1111111111")) 63 }) 64 65 mock := httptest.NewServer(handler) 66 defer mock.Close() 67 68 proxy := makeTestAtmosCamoProxy() 69 parsedURL, err := url.Parse(*proxy.ConfigService.Config().ServiceSettings.SiteURL) 70 require.NoError(t, err) 71 72 remoteURL, err := url.Parse(mock.URL) 73 require.NoError(t, err) 74 75 backend := &AtmosCamoBackend{ 76 proxy: proxy, 77 siteURL: parsedURL, 78 remoteURL: remoteURL, 79 } 80 81 body, contentType, err := backend.GetImageDirect("https://example.com/image.png") 82 83 assert.NoError(t, err) 84 assert.Equal(t, "image/png", contentType) 85 86 require.NotNil(t, body) 87 respBody, _ := ioutil.ReadAll(body) 88 assert.Equal(t, []byte("1111111111"), respBody) 89 } 90 91 func TestGetAtmosCamoImageURL(t *testing.T) { 92 imageURL := "http://www.mattermost.org/wp-content/uploads/2016/03/logoHorizontal.png" 93 proxiedURL := "http://images.example.com/5b6f6661516bc837b89b54566eb619d14a5c3eca/687474703a2f2f7777772e6d61747465726d6f73742e6f72672f77702d636f6e74656e742f75706c6f6164732f323031362f30332f6c6f676f486f72697a6f6e74616c2e706e67" 94 95 defaultSiteURL := "https://mattermost.example.com" 96 proxyURL := "http://images.example.com" 97 98 for _, test := range []struct { 99 Name string 100 Input string 101 SiteURL string 102 Expected string 103 }{ 104 { 105 Name: "should proxy image", 106 Input: imageURL, 107 SiteURL: defaultSiteURL, 108 Expected: proxiedURL, 109 }, 110 { 111 Name: "should proxy image when no site URL is set", 112 Input: imageURL, 113 SiteURL: "", 114 Expected: proxiedURL, 115 }, 116 { 117 Name: "should proxy image when a site URL with a subpath is set", 118 Input: imageURL, 119 SiteURL: proxyURL + "/subpath", 120 Expected: proxiedURL, 121 }, 122 { 123 Name: "should not proxy a relative image", 124 Input: "/static/logo.png", 125 SiteURL: defaultSiteURL, 126 Expected: "https://mattermost.example.com/static/logo.png", 127 }, 128 { 129 Name: "should bypass opaque URLs", 130 Input: "http:xyz123?query", 131 SiteURL: defaultSiteURL, 132 Expected: defaultSiteURL, 133 }, 134 { 135 Name: "should not proxy an image on the HungKnow server ", 136 Input: "https://mattermost.example.com/static/logo.png", 137 SiteURL: defaultSiteURL, 138 Expected: "https://mattermost.example.com/static/logo.png", 139 }, 140 { 141 Name: "should not proxy an image on the HungKnow server when a subpath is set", 142 Input: "https://mattermost.example.com/static/logo.png", 143 SiteURL: defaultSiteURL + "/static", 144 Expected: "https://mattermost.example.com/static/logo.png", 145 }, 146 { 147 Name: "should not proxy an image that has already been proxied", 148 Input: proxiedURL, 149 SiteURL: defaultSiteURL, 150 Expected: proxiedURL, 151 }, 152 { 153 Name: "should not bypass protocol relative URLs", 154 Input: "//www.mattermost.org/wp-content/uploads/2016/03/logoHorizontal.png", 155 SiteURL: "http://mattermost.example.com", 156 Expected: proxiedURL, 157 }, 158 { 159 Name: "should not bypass if the host prefix is same", 160 Input: "http://www.mattermost.org.example.com/wp-content/uploads/2016/03/logoHorizontal.png", 161 SiteURL: defaultSiteURL, 162 Expected: "http://images.example.com/99dcf38b8e6110d6e3ebcfb7a2db9ce875bc5c03/687474703a2f2f7777772e6d61747465726d6f73742e6f72672e6578616d706c652e636f6d2f77702d636f6e74656e742f75706c6f6164732f323031362f30332f6c6f676f486f72697a6f6e74616c2e706e67", 163 }, 164 { 165 Name: "should not bypass for user auth URLs", 166 Input: "http://www.mattermost.org@example.com/wp-content/uploads/2016/03/logoHorizontal.png", 167 SiteURL: defaultSiteURL, 168 Expected: "http://images.example.com/19deedea7c0b75369f8d2162ee4e7ab36e26ca50/687474703a2f2f7777772e6d61747465726d6f73742e6f7267406578616d706c652e636f6d2f77702d636f6e74656e742f75706c6f6164732f323031362f30332f6c6f676f486f72697a6f6e74616c2e706e67", 169 }, 170 } { 171 t.Run(test.Name, func(t *testing.T) { 172 parsedURL, err := url.Parse(test.SiteURL) 173 require.NoError(t, err) 174 175 remoteURL, err := url.Parse(proxyURL) 176 require.NoError(t, err) 177 178 backend := &AtmosCamoBackend{ 179 proxy: makeTestAtmosCamoProxy(), 180 siteURL: parsedURL, 181 remoteURL: remoteURL, 182 } 183 184 assert.Equal(t, test.Expected, backend.getAtmosCamoImageURL(test.Input)) 185 }) 186 } 187 188 }