Skip to content

Commit

Permalink
Proxying Accept-Encoding and Accept headers for /asis
Browse files Browse the repository at this point in the history
  • Loading branch information
dooman87 committed Jan 30, 2025
1 parent 705606f commit 837ff1b
Show file tree
Hide file tree
Showing 4 changed files with 92 additions and 25 deletions.
13 changes: 1 addition & 12 deletions img/loader/http.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ func (r *Http) Load(url string, ctx context.Context) (*img.Image, error) {
}
}

if moreHeaders, ok := headerFromContext(ctx); ok {
if moreHeaders, ok := img.HeaderFromContext(ctx); ok {
for k, v := range *moreHeaders {
for _, headerVal := range v {
req.Header.Add(k, headerVal)
Expand Down Expand Up @@ -78,14 +78,3 @@ func (r *Http) Load(url string, ctx context.Context) (*img.Image, error) {
MimeType: contentType,
}, nil
}

type headersKey int

func NewContextWithHeaders(ctx context.Context, headers *http.Header) context.Context {
return context.WithValue(ctx, headersKey(0), headers)
}

func headerFromContext(ctx context.Context) (*http.Header, bool) {
header, ok := ctx.Value(headersKey(0)).(*http.Header)
return header, ok
}
29 changes: 27 additions & 2 deletions img/loader/http_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package loader_test

import (
"context"
"github.com/Pixboost/transformimgs/v8/img"
"github.com/Pixboost/transformimgs/v8/img/loader"
"github.com/dooman87/kolibri/test"
"net/http"
Expand Down Expand Up @@ -72,7 +73,7 @@ func TestHttp_LoadImgErrorResponseStatus(t *testing.T) {
)
}

func TestHttp_LoadCustomHeaders(t *testing.T) {
func TestHttp_LoadCustomGlobalHeaders(t *testing.T) {
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.Header.Get("this-is-header") != "wow" {
w.WriteHeader(http.StatusInternalServerError)
Expand Down Expand Up @@ -100,7 +101,7 @@ func TestHttp_LoadCustomHeaders(t *testing.T) {
)
}

func FuzzHttp_LoadCustomHeaders(f *testing.F) {
func FuzzHttp_LoadCustomGlobalHeaders(f *testing.F) {
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Add("Content-Type", "cool/stuff")
w.Write([]byte("123"))
Expand Down Expand Up @@ -137,3 +138,27 @@ func FuzzHttp_LoadCustomHeaders(f *testing.F) {
}
})
}

func TestHttp_LoadCustomContextHeaders(t *testing.T) {
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.Header.Get("this-is-header") != "wow" {
w.WriteHeader(http.StatusInternalServerError)
} else {
w.Header().Add("Content-Type", "cool/stuff")
w.Write([]byte("123"))
}
}))
defer server.Close()

httpLoader := &loader.Http{}

image, err := httpLoader.Load(server.URL, img.NewContextWithHeaders(context.Background(), &http.Header{
"This-Is-Header": []string{"wow"},
}))

test.Error(t,
test.Nil(err, "error"),
test.Equal("cool/stuff", image.MimeType, "content type"),
test.Equal("123", string(image.Data), "resulted image"),
)
}
27 changes: 22 additions & 5 deletions img/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import (
"context"
"errors"
"fmt"
"github.com/Pixboost/transformimgs/v8/img/loader"
"github.com/dooman87/glogi"
"github.com/gorilla/mux"
"net/http"
Expand Down Expand Up @@ -193,10 +192,17 @@ func (r *Service) AsIs(resp http.ResponseWriter, req *http.Request) {

Log.Printf("Requested image %s as is\n", imgUrl)

var proxyHeaders http.Header
proxyHeaders.Add("Accept", req.Header.Get("Accept"))
proxyHeaders.Add("Accept-Encoding", req.Header.Get("Accept-Encoding"))
result, err := r.Loader.Load(imgUrl, loader.NewContextWithHeaders(req.Context(), &proxyHeaders))
var proxyHeaders = make(http.Header)

accept := req.Header.Get("Accept")
if len(accept) > 0 {
proxyHeaders.Add("Accept", accept)
}
acceptEncoding := req.Header.Get("Accept-Encoding")
if len(acceptEncoding) > 0 {
proxyHeaders.Add("Accept-Encoding", acceptEncoding)
}
result, err := r.Loader.Load(imgUrl, NewContextWithHeaders(req.Context(), &proxyHeaders))

if err != nil {
sendError(resp, err)
Expand Down Expand Up @@ -395,3 +401,14 @@ func sendError(resp http.ResponseWriter, err error) {
}
}
}

type headersKey int

func NewContextWithHeaders(ctx context.Context, headers *http.Header) context.Context {
return context.WithValue(ctx, headersKey(0), headers)
}

func HeaderFromContext(ctx context.Context) (*http.Header, bool) {
header, ok := ctx.Value(headersKey(0)).(*http.Header)
return header, ok
}
48 changes: 42 additions & 6 deletions img/service_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ const (
ImgLowQualityOut = "12"
ImgLowerQualityOut = "1"
ImgBorderTrimmed = "777"
ImgGzipSvg = "888"

EmptyGifBase64Out = "R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw=="
)
Expand Down Expand Up @@ -122,23 +123,40 @@ func (r *resizerMock) resultImage(config *img.TransformationConfig) *img.Image {

type loaderMock struct{}

func (l *loaderMock) Load(url string, _ context.Context) (*img.Image, error) {
if url == "http://site.com/img.png" {
func (l *loaderMock) Load(url string, ctx context.Context) (*img.Image, error) {
switch url {
case "http://site.com/img.png":
return &img.Image{
Data: []byte(ImgSrc),
MimeType: "image/png",
Id: url,
}, nil
}
if url == "http://site.com/img2.png" {
case "http://site.com/img2.png":
return &img.Image{
Data: []byte(NoContentTypeImgSrc),
MimeType: "image/png",
Id: url,
}, nil
}
if url == "http://site.com/custom_error.png" {
case "http://site.com/custom_error.png":
return nil, img.NewHttpError(http.StatusTeapot, "Uh oh :(")

case "http://site.com/img.svg":
if acceptEncoding, ok := img.HeaderFromContext(ctx); ok && acceptEncoding.Get("Accept-Encoding") == "gzip" {
return &img.Image{
Data: []byte(ImgSrc),
MimeType: "svg/gzip",
Id: url,
}, nil
}
}

if url == "http://site.com/img.png" {
}

if url == "" {
}
if url == "" {

}
return nil, errors.New("read_error")
}
Expand Down Expand Up @@ -575,6 +593,24 @@ func TestService_AsIs(t *testing.T) {
)
},
},
{
Description: "Success with custom accept encoding",
Request: &http.Request{
Method: "GET",
URL: parseUrl("http://localhost/img/http%3A%2F%2Fsite.com/img.svg/asis", t),
Header: map[string][]string{
"Accept-Encoding": {"gzip"},
},
},
Handler: func(w *httptest.ResponseRecorder, t *testing.T) {
test.Error(t,
test.Equal("public, max-age=86400", w.Header().Get("Cache-Control"), "Cache-Control header"),
test.Equal("3", w.Header().Get("Content-Length"), "Content-Length header"),
test.Equal("svg/gzip", w.Header().Get("Content-Type"), "Content-Type header"),
test.Equal("", w.Header().Get("Vary"), "No Vary header"),
)
},
},
{
Request: &http.Request{
Method: "GET",
Expand Down

0 comments on commit 837ff1b

Please sign in to comment.