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  }