From 38941f58cf72e8e8811377570fdab1426cc6947b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Guillot?= Date: Tue, 21 Nov 2017 23:09:01 -0800 Subject: [PATCH] Improve image proxy --- server/core/response.go | 5 +++++ server/ui/controller/proxy.go | 25 ++++++++++++++++--------- 2 files changed, 21 insertions(+), 9 deletions(-) diff --git a/server/core/response.go b/server/core/response.go index 3acc453c..3bce9d91 100644 --- a/server/core/response.go +++ b/server/core/response.go @@ -46,6 +46,11 @@ func (r *Response) Redirect(path string) { http.Redirect(r.writer, r.request, path, http.StatusFound) } +// NotModified sends a response with a 304 status code. +func (r *Response) NotModified() { + r.writer.WriteHeader(http.StatusNotModified) +} + // Cache returns a response with caching headers. func (r *Response) Cache(mimeType, etag string, content []byte, duration time.Duration) { r.writer.Header().Set("Content-Type", mimeType) diff --git a/server/ui/controller/proxy.go b/server/ui/controller/proxy.go index 19a64366..fdbdb4e8 100644 --- a/server/ui/controller/proxy.go +++ b/server/ui/controller/proxy.go @@ -7,15 +7,23 @@ package controller import ( "encoding/base64" "errors" - "github.com/miniflux/miniflux2/helper" - "github.com/miniflux/miniflux2/server/core" "io/ioutil" "log" - "net/http" "time" + + "github.com/miniflux/miniflux2/helper" + "github.com/miniflux/miniflux2/reader/http" + "github.com/miniflux/miniflux2/server/core" ) +// ImageProxy fetch an image from a remote server and sent it back to the browser. func (c *Controller) ImageProxy(ctx *core.Context, request *core.Request, response *core.Response) { + // If we receive a "If-None-Match" header we assume the image in stored in browser cache + if request.Request().Header.Get("If-None-Match") != "" { + response.NotModified() + return + } + encodedURL := request.StringParam("encodedURL", "") if encodedURL == "" { response.HTML().BadRequest(errors.New("No URL provided")) @@ -28,22 +36,21 @@ func (c *Controller) ImageProxy(ctx *core.Context, request *core.Request, respon return } - resp, err := http.Get(string(decodedURL)) + client := http.NewClient(string(decodedURL)) + resp, err := client.Get() if err != nil { - log.Println(err) + log.Println("[ImageProxy]", err) response.HTML().NotFound() return } - defer resp.Body.Close() - if resp.StatusCode != http.StatusOK { + if resp.HasServerFailure() { response.HTML().NotFound() return } body, _ := ioutil.ReadAll(resp.Body) etag := helper.HashFromBytes(body) - contentType := resp.Header.Get("Content-Type") - response.Cache(contentType, etag, body, 72*time.Hour) + response.Cache(resp.ContentType, etag, body, 72*time.Hour) }