diff --git a/backend/app/rest/api/rest_private_test.go b/backend/app/rest/api/rest_private_test.go index d3dae176..252e3c36 100644 --- a/backend/app/rest/api/rest_private_test.go +++ b/backend/app/rest/api/rest_private_test.go @@ -870,25 +870,25 @@ func TestRest_SavePictureCtrl(t *testing.T) { body, err := ioutil.ReadAll(resp.Body) require.NoError(t, err) assert.Equal(t, 1462, len(body)) - assert.Equal(t, "image/*", resp.Header.Get("Content-Type")) + assert.Equal(t, "image/png", resp.Header.Get("Content-Type")) id = savePic("picture.gif") resp, err = http.Get(fmt.Sprintf("%s/api/v1/picture/%s", ts.URL, id)) require.NoError(t, err) assert.Equal(t, 200, resp.StatusCode) - assert.Equal(t, "image/*", resp.Header.Get("Content-Type")) + assert.Equal(t, "image/png", resp.Header.Get("Content-Type")) id = savePic("picture.jpg") resp, err = http.Get(fmt.Sprintf("%s/api/v1/picture/%s", ts.URL, id)) require.NoError(t, err) assert.Equal(t, 200, resp.StatusCode) - assert.Equal(t, "image/*", resp.Header.Get("Content-Type")) + assert.Equal(t, "image/png", resp.Header.Get("Content-Type")) id = savePic("picture.blah") resp, err = http.Get(fmt.Sprintf("%s/api/v1/picture/%s", ts.URL, id)) require.NoError(t, err) assert.Equal(t, 200, resp.StatusCode) - assert.Equal(t, "image/*", resp.Header.Get("Content-Type")) + assert.Equal(t, "image/png", resp.Header.Get("Content-Type")) resp, err = http.Get(fmt.Sprintf("%s/api/v1/picture/blah/pic.blah", ts.URL)) require.NoError(t, err) diff --git a/backend/app/rest/api/rest_public.go b/backend/app/rest/api/rest_public.go index e53f6b9a..654c4765 100644 --- a/backend/app/rest/api/rest_public.go +++ b/backend/app/rest/api/rest_public.go @@ -422,20 +422,6 @@ func (s *public) listCtrl(w http.ResponseWriter, r *http.Request) { // GET /picture/{user}/{id} - get picture func (s *public) loadPictureCtrl(w http.ResponseWriter, r *http.Request) { - - imgContentType := func(img string) string { - img = strings.ToLower(img) - switch { - case strings.HasSuffix(img, ".png"): - return "image/png" - case strings.HasSuffix(img, ".jpg") || strings.HasSuffix(img, ".jpeg"): - return "image/jpeg" - case strings.HasSuffix(img, ".gif"): - return "image/gif" - } - return "image/*" - } - id := chi.URLParam(r, "user") + "/" + chi.URLParam(r, "id") img, err := s.imageService.Load(id) if err != nil { @@ -453,7 +439,7 @@ func (s *public) loadPictureCtrl(w http.ResponseWriter, r *http.Request) { } } - w.Header().Set("Content-Type", imgContentType(id)) + w.Header().Set("Content-Type", s.imageService.ImgContentType(img)) w.Header().Set("Content-Length", strconv.Itoa(len(img))) w.WriteHeader(http.StatusOK) if _, err = io.Copy(w, bytes.NewReader(img)); err != nil { diff --git a/backend/app/rest/proxy/image.go b/backend/app/rest/proxy/image.go index 3a5f7484..8f85b915 100644 --- a/backend/app/rest/proxy/image.go +++ b/backend/app/rest/proxy/image.go @@ -131,7 +131,7 @@ func (p Image) Handler(w http.ResponseWriter, r *http.Request) { } } - w.Header().Add("Content-Type", "image/*") + w.Header().Add("Content-Type", p.ImageService.ImgContentType(img)) _, err = io.Copy(w, bytes.NewReader(img)) if err != nil { log.Printf("[WARN] can't copy image stream, %s", err) diff --git a/backend/app/rest/proxy/image_test.go b/backend/app/rest/proxy/image_test.go index 9702c8e5..919d3461 100644 --- a/backend/app/rest/proxy/image_test.go +++ b/backend/app/rest/proxy/image_test.go @@ -109,7 +109,7 @@ func TestImage_Routes(t *testing.T) { require.NoError(t, err) assert.Equal(t, 200, resp.StatusCode) assert.Equal(t, "1462", resp.Header["Content-Length"][0]) - assert.Equal(t, "image/*", resp.Header["Content-Type"][0]) + assert.Equal(t, "image/png", resp.Header["Content-Type"][0]) encodedImgURL = base64.URLEncoding.EncodeToString([]byte(httpSrv.URL + "/image/no-such-image.png")) resp, err = http.Get(ts.URL + "/?src=" + encodedImgURL) @@ -147,10 +147,10 @@ func TestImage_RoutesCachingImage(t *testing.T) { require.Nil(t, err) assert.Equal(t, 200, resp.StatusCode) assert.Equal(t, "1462", resp.Header["Content-Length"][0]) - assert.Equal(t, "image/*", resp.Header["Content-Type"][0]) + assert.Equal(t, "image/png", resp.Header["Content-Type"][0]) imageStore.AssertCalled(t, "Load", mock.Anything) - imageStore.AssertCalled(t, "SaveWithID", "cached_images/4b84b15bff6ee5796152495a230e45e3d7e947d9-"+sha1Str(imgURL), mock.Anything) + imageStore.AssertCalled(t, "SaveWithID", "cached_images/4b84b15bff6ee5796152495a230e45e3d7e947d9-"+sha1Str(imgURL), gopherPNGBytes()) imageStore.AssertCalled(t, "Commit", mock.Anything) } @@ -178,7 +178,8 @@ func TestImage_RoutesUsingCachedImage(t *testing.T) { require.Nil(t, err) assert.Equal(t, 200, resp.StatusCode) assert.Equal(t, "256", resp.Header["Content-Length"][0]) - assert.Equal(t, "image/*", resp.Header["Content-Type"][0]) + assert.Equal(t, "text/plain; charset=utf-8", resp.Header["Content-Type"][0], + "if you save text you receive text/plain in response, that's only fair option you got") imageStore.AssertCalled(t, "Load", mock.Anything) } diff --git a/backend/app/store/image/image.go b/backend/app/store/image/image.go index a2937304..aa78e655 100644 --- a/backend/app/store/image/image.go +++ b/backend/app/store/image/image.go @@ -201,6 +201,15 @@ func (s *Service) SaveWithID(id string, r io.Reader) (string, error) { return s.store.SaveWithID(id, img) } +func (s *Service) ImgContentType(img []byte) string { + contentType := http.DetectContentType(img) + if contentType == "application/octet-stream" { + // replace generic fallback with one which make sense in our scenario + return "image/*" + } + return contentType +} + // prepareImage calls readAndValidateImage and resize on provided image. func (s *Service) prepareImage(r io.Reader) ([]byte, error) { data, err := readAndValidateImage(r, s.MaxSize)