From 0c08f65be14584d3d034d8b953e783f04a758d3b Mon Sep 17 00:00:00 2001 From: Benny Date: Sun, 6 Dec 2020 14:02:17 +0800 Subject: [PATCH] fix unsupported browser + proxyMode bug, return 400 for not allow files instead of 500 (#64) unsupported browser will go for origin, while in proxyMode we don't have cache images. resolve #61 --- Makefile | 2 +- config.go | 6 +++--- helper.go | 5 ++++- helper_test.go | 8 ++++++++ router.go | 40 +++++++++++++++++++++++++--------------- router_test.go | 19 ++++++++++++++----- 6 files changed, 55 insertions(+), 25 deletions(-) diff --git a/Makefile b/Makefile index 3d5f6d0..8eb452f 100644 --- a/Makefile +++ b/Makefile @@ -19,7 +19,7 @@ all: ./scripts/build.sh $(OS) $(ARCH) test: - go test -coverprofile=coverage.txt -covermode=atomic + go test -v -coverprofile=coverage.txt -covermode=atomic clean: rm -rf builds diff --git a/config.go b/config.go index 3cb0dee..38311bc 100644 --- a/config.go +++ b/config.go @@ -19,9 +19,9 @@ var ( dumpConfig, dumpSystemd bool verboseMode, showVersion bool prefetch, proxyMode bool - - config Config - version = "0.3.1" + remoteRaw = "remote-raw" + config Config + version = "0.3.1" ) const ( diff --git a/helper.go b/helper.go index d2c393e..88a9372 100644 --- a/helper.go +++ b/helper.go @@ -119,9 +119,12 @@ func genWebpAbs(RawImagePath string, ExhaustPath string, ImgFilename string, req } func genEtag(ImgAbsPath string) string { + if proxyMode { + ImgAbsPath = path.Join(remoteRaw, strings.Replace(ImgAbsPath, config.ImgPath, "", -1)) + } data, err := ioutil.ReadFile(ImgAbsPath) if err != nil { - log.Info(err) + log.Warn(err) } crc := crc32.ChecksumIEEE(data) return fmt.Sprintf(`W/"%d-%08X"`, len(data), crc) diff --git a/helper_test.go b/helper_test.go index 05d1735..309e73c 100644 --- a/helper_test.go +++ b/helper_test.go @@ -61,6 +61,14 @@ func TestGenEtag(t *testing.T) { assert.Equalf(t, result, expected, "Result: [%s], Expected: [%s]", result, expected) + // proxy mode + proxyMode = true + config.ImgPath = "https://github.com/webp-sh/webp_server_go/raw/master/" + remoteRaw = "" + data = "https://github.com/webp-sh/webp_server_go/raw/master/pics/webp_server.png" + result = genEtag(data) + assert.Equal(t, result, "W/\"269387-6FFD6D2D\"") + } func TestGoOrigin(t *testing.T) { diff --git a/router.go b/router.go index 4a3ed2f..c6f8b0e 100644 --- a/router.go +++ b/router.go @@ -5,6 +5,7 @@ import ( "fmt" "github.com/gofiber/fiber/v2" log "github.com/sirupsen/logrus" + "net/http" "net/url" "os" "path" @@ -15,22 +16,31 @@ import ( func convert(c *fiber.Ctx) error { //basic vars - var reqURI, _ = url.QueryUnescape(c.Path()) // /mypic/123.jpg - var rawImageAbs = path.Join(config.ImgPath, reqURI) // /home/xxx/mypic/123.jpg - var imgFilename = path.Base(reqURI) // pure filename, 123.jpg - var finalFile string // We'll only need one c.sendFile() + var reqURI, _ = url.QueryUnescape(c.Path()) // /mypic/123.jpg + var rawImageAbs string + if proxyMode { + rawImageAbs = config.ImgPath + reqURI + } else { + rawImageAbs = path.Join(config.ImgPath, reqURI) // /home/xxx/mypic/123.jpg + } + var imgFilename = path.Base(reqURI) // pure filename, 123.jpg + var finalFile string // We'll only need one c.sendFile() var ua = c.Get("User-Agent") var accept = c.Get("accept") log.Debugf("Incoming connection from %s@%s with %s", ua, c.IP(), imgFilename) needOrigin := goOrigin(accept, ua) if needOrigin { - log.Infof("A Safari/IE/whatever user has arrived...%s", ua) - // Check for Safari users. If they're Safari, just simply ignore everything. - etag := genEtag(rawImageAbs) - c.Set("ETag", etag) + log.Debugf("A Safari/IE/whatever user has arrived...%s", ua) + c.Set("ETag", genEtag(rawImageAbs)) c.Set("X-Compression-Rate", NotCompressed) - return c.SendFile(rawImageAbs) + if proxyMode { + localRemoteTmpPath := remoteRaw + reqURI + _ = fetchRemoteImage(localRemoteTmpPath, rawImageAbs) + return c.SendFile(localRemoteTmpPath) + } else { + return c.SendFile(rawImageAbs) + } } // check ext @@ -49,13 +59,14 @@ func convert(c *fiber.Ctx) error { if !allowed { msg := "File extension not allowed! " + imgFilename log.Warn(msg) - _ = c.Send([]byte(msg)) if imageExists(rawImageAbs) { - etag := genEtag(rawImageAbs) - c.Set("ETag", etag) + c.Set("ETag", genEtag(rawImageAbs)) return c.SendFile(rawImageAbs) + } else { + c.Status(http.StatusBadRequest) + _ = c.Send([]byte(msg)) + return nil } - return errors.New(msg) } // Start Proxy Mode @@ -72,9 +83,8 @@ func convert(c *fiber.Ctx) error { return c.SendFile(localEtagImagePath) } else { // Temporary store of remote file. - // ./remote-raw/node.png cleanProxyCache(config.ExhaustPath + reqURI + "*") - localRemoteTmpPath := "./remote-raw" + reqURI + localRemoteTmpPath := remoteRaw + reqURI _ = fetchRemoteImage(localRemoteTmpPath, realRemoteAddr) q, _ := strconv.ParseFloat(config.Quality, 32) _ = os.MkdirAll(path.Dir(localEtagImagePath), 0755) diff --git a/router_test.go b/router_test.go index 31fa4ea..67e3032 100644 --- a/router_test.go +++ b/router_test.go @@ -15,7 +15,7 @@ import ( var ( chromeUA = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.183 Safari/537.36" - SafariUA = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_4) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.1 Safari/605.1.15" + safariUA = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_4) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.1 Safari/605.1.15" ) func setupParam() { @@ -23,6 +23,9 @@ func setupParam() { config.ImgPath = "./pics" config.ExhaustPath = "./exhaust" config.AllowedTypes = []string{"jpg", "png", "jpeg", "bmp"} + + proxyMode = false + remoteRaw = "remote-raw" } func requestToServer(url string, app *fiber.App, ua string) (*http.Response, []byte) { @@ -48,7 +51,7 @@ func TestServerHeaders(t *testing.T) { assert.NotEqual(t, "", etag) // test for safari - response, _ = requestToServer(url, app, SafariUA) + response, _ = requestToServer(url, app, safariUA) ratio = response.Header.Get("X-Compression-Rate") etag = response.Header.Get("Etag") @@ -58,6 +61,7 @@ func TestServerHeaders(t *testing.T) { func TestConvert(t *testing.T) { setupParam() + // TODO: old-style test, better update it with accept headers var testChromeLink = map[string]string{ "http://127.0.0.1:3333/webp_server.jpg": "image/webp", "http://127.0.0.1:3333/webp_server.bmp": "image/webp", @@ -92,7 +96,7 @@ func TestConvert(t *testing.T) { // test Safari for url, respType := range testSafariLink { - _, data := requestToServer(url, app, SafariUA) + _, data := requestToServer(url, app, safariUA) contentType := getFileContentType(data) assert.Equal(t, respType, contentType) } @@ -126,8 +130,8 @@ func TestConvertProxyModeBad(t *testing.T) { var app = fiber.New() app.Get("/*", convert) - // this is local image, should be 500 - url := "http://127.0.0.1:3333/webp_server.bmp" + // this is local random image, should be 500 + url := "http://127.0.0.1:3333/webp_8888server.bmp" resp, _ := requestToServer(url, app, chromeUA) assert.Equal(t, http.StatusInternalServerError, resp.StatusCode) @@ -146,4 +150,9 @@ func TestConvertProxyModeWork(t *testing.T) { resp, data := requestToServer(url, app, chromeUA) assert.Equal(t, http.StatusOK, resp.StatusCode) assert.Equal(t, "image/webp", getFileContentType(data)) + + // test proxyMode with Safari + resp, data = requestToServer(url, app, safariUA) + assert.Equal(t, http.StatusOK, resp.StatusCode) + assert.Equal(t, "image/jpeg", getFileContentType(data)) }