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
This commit is contained in:
Benny 2020-12-06 14:02:17 +08:00 committed by GitHub
parent 37d8d8ba13
commit 0c08f65be1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 55 additions and 25 deletions

View File

@ -19,7 +19,7 @@ all:
./scripts/build.sh $(OS) $(ARCH) ./scripts/build.sh $(OS) $(ARCH)
test: test:
go test -coverprofile=coverage.txt -covermode=atomic go test -v -coverprofile=coverage.txt -covermode=atomic
clean: clean:
rm -rf builds rm -rf builds

View File

@ -19,7 +19,7 @@ var (
dumpConfig, dumpSystemd bool dumpConfig, dumpSystemd bool
verboseMode, showVersion bool verboseMode, showVersion bool
prefetch, proxyMode bool prefetch, proxyMode bool
remoteRaw = "remote-raw"
config Config config Config
version = "0.3.1" version = "0.3.1"
) )

View File

@ -119,9 +119,12 @@ func genWebpAbs(RawImagePath string, ExhaustPath string, ImgFilename string, req
} }
func genEtag(ImgAbsPath string) string { func genEtag(ImgAbsPath string) string {
if proxyMode {
ImgAbsPath = path.Join(remoteRaw, strings.Replace(ImgAbsPath, config.ImgPath, "", -1))
}
data, err := ioutil.ReadFile(ImgAbsPath) data, err := ioutil.ReadFile(ImgAbsPath)
if err != nil { if err != nil {
log.Info(err) log.Warn(err)
} }
crc := crc32.ChecksumIEEE(data) crc := crc32.ChecksumIEEE(data)
return fmt.Sprintf(`W/"%d-%08X"`, len(data), crc) return fmt.Sprintf(`W/"%d-%08X"`, len(data), crc)

View File

@ -61,6 +61,14 @@ func TestGenEtag(t *testing.T) {
assert.Equalf(t, result, expected, "Result: [%s], Expected: [%s]", result, expected) 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) { func TestGoOrigin(t *testing.T) {

View File

@ -5,6 +5,7 @@ import (
"fmt" "fmt"
"github.com/gofiber/fiber/v2" "github.com/gofiber/fiber/v2"
log "github.com/sirupsen/logrus" log "github.com/sirupsen/logrus"
"net/http"
"net/url" "net/url"
"os" "os"
"path" "path"
@ -16,7 +17,12 @@ import (
func convert(c *fiber.Ctx) error { func convert(c *fiber.Ctx) error {
//basic vars //basic vars
var reqURI, _ = url.QueryUnescape(c.Path()) // /mypic/123.jpg var reqURI, _ = url.QueryUnescape(c.Path()) // /mypic/123.jpg
var rawImageAbs = path.Join(config.ImgPath, reqURI) // /home/xxx/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 imgFilename = path.Base(reqURI) // pure filename, 123.jpg
var finalFile string // We'll only need one c.sendFile() var finalFile string // We'll only need one c.sendFile()
var ua = c.Get("User-Agent") var ua = c.Get("User-Agent")
@ -25,13 +31,17 @@ func convert(c *fiber.Ctx) error {
needOrigin := goOrigin(accept, ua) needOrigin := goOrigin(accept, ua)
if needOrigin { if needOrigin {
log.Infof("A Safari/IE/whatever user has arrived...%s", ua) log.Debugf("A Safari/IE/whatever user has arrived...%s", ua)
// Check for Safari users. If they're Safari, just simply ignore everything. c.Set("ETag", genEtag(rawImageAbs))
etag := genEtag(rawImageAbs)
c.Set("ETag", etag)
c.Set("X-Compression-Rate", NotCompressed) c.Set("X-Compression-Rate", NotCompressed)
if proxyMode {
localRemoteTmpPath := remoteRaw + reqURI
_ = fetchRemoteImage(localRemoteTmpPath, rawImageAbs)
return c.SendFile(localRemoteTmpPath)
} else {
return c.SendFile(rawImageAbs) return c.SendFile(rawImageAbs)
} }
}
// check ext // check ext
var allowed = false var allowed = false
@ -49,13 +59,14 @@ func convert(c *fiber.Ctx) error {
if !allowed { if !allowed {
msg := "File extension not allowed! " + imgFilename msg := "File extension not allowed! " + imgFilename
log.Warn(msg) log.Warn(msg)
_ = c.Send([]byte(msg))
if imageExists(rawImageAbs) { if imageExists(rawImageAbs) {
etag := genEtag(rawImageAbs) c.Set("ETag", genEtag(rawImageAbs))
c.Set("ETag", etag)
return c.SendFile(rawImageAbs) return c.SendFile(rawImageAbs)
} else {
c.Status(http.StatusBadRequest)
_ = c.Send([]byte(msg))
return nil
} }
return errors.New(msg)
} }
// Start Proxy Mode // Start Proxy Mode
@ -72,9 +83,8 @@ func convert(c *fiber.Ctx) error {
return c.SendFile(localEtagImagePath) return c.SendFile(localEtagImagePath)
} else { } else {
// Temporary store of remote file. // Temporary store of remote file.
// ./remote-raw/node.png
cleanProxyCache(config.ExhaustPath + reqURI + "*") cleanProxyCache(config.ExhaustPath + reqURI + "*")
localRemoteTmpPath := "./remote-raw" + reqURI localRemoteTmpPath := remoteRaw + reqURI
_ = fetchRemoteImage(localRemoteTmpPath, realRemoteAddr) _ = fetchRemoteImage(localRemoteTmpPath, realRemoteAddr)
q, _ := strconv.ParseFloat(config.Quality, 32) q, _ := strconv.ParseFloat(config.Quality, 32)
_ = os.MkdirAll(path.Dir(localEtagImagePath), 0755) _ = os.MkdirAll(path.Dir(localEtagImagePath), 0755)

View File

@ -15,7 +15,7 @@ import (
var ( 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" 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() { func setupParam() {
@ -23,6 +23,9 @@ func setupParam() {
config.ImgPath = "./pics" config.ImgPath = "./pics"
config.ExhaustPath = "./exhaust" config.ExhaustPath = "./exhaust"
config.AllowedTypes = []string{"jpg", "png", "jpeg", "bmp"} config.AllowedTypes = []string{"jpg", "png", "jpeg", "bmp"}
proxyMode = false
remoteRaw = "remote-raw"
} }
func requestToServer(url string, app *fiber.App, ua string) (*http.Response, []byte) { 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) assert.NotEqual(t, "", etag)
// test for safari // test for safari
response, _ = requestToServer(url, app, SafariUA) response, _ = requestToServer(url, app, safariUA)
ratio = response.Header.Get("X-Compression-Rate") ratio = response.Header.Get("X-Compression-Rate")
etag = response.Header.Get("Etag") etag = response.Header.Get("Etag")
@ -58,6 +61,7 @@ func TestServerHeaders(t *testing.T) {
func TestConvert(t *testing.T) { func TestConvert(t *testing.T) {
setupParam() setupParam()
// TODO: old-style test, better update it with accept headers
var testChromeLink = map[string]string{ var testChromeLink = map[string]string{
"http://127.0.0.1:3333/webp_server.jpg": "image/webp", "http://127.0.0.1:3333/webp_server.jpg": "image/webp",
"http://127.0.0.1:3333/webp_server.bmp": "image/webp", "http://127.0.0.1:3333/webp_server.bmp": "image/webp",
@ -92,7 +96,7 @@ func TestConvert(t *testing.T) {
// test Safari // test Safari
for url, respType := range testSafariLink { for url, respType := range testSafariLink {
_, data := requestToServer(url, app, SafariUA) _, data := requestToServer(url, app, safariUA)
contentType := getFileContentType(data) contentType := getFileContentType(data)
assert.Equal(t, respType, contentType) assert.Equal(t, respType, contentType)
} }
@ -126,8 +130,8 @@ func TestConvertProxyModeBad(t *testing.T) {
var app = fiber.New() var app = fiber.New()
app.Get("/*", convert) app.Get("/*", convert)
// this is local image, should be 500 // this is local random image, should be 500
url := "http://127.0.0.1:3333/webp_server.bmp" url := "http://127.0.0.1:3333/webp_8888server.bmp"
resp, _ := requestToServer(url, app, chromeUA) resp, _ := requestToServer(url, app, chromeUA)
assert.Equal(t, http.StatusInternalServerError, resp.StatusCode) assert.Equal(t, http.StatusInternalServerError, resp.StatusCode)
@ -146,4 +150,9 @@ func TestConvertProxyModeWork(t *testing.T) {
resp, data := requestToServer(url, app, chromeUA) resp, data := requestToServer(url, app, chromeUA)
assert.Equal(t, http.StatusOK, resp.StatusCode) assert.Equal(t, http.StatusOK, resp.StatusCode)
assert.Equal(t, "image/webp", getFileContentType(data)) 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))
} }