Skip to content

Commit b39aa95

Browse files
authored
Merge pull request #55 from Pixboost/bugfix/#32/accept-encoding
Bugfix/#32/accept encoding
2 parents 87004b4 + 0d0c6d2 commit b39aa95

File tree

11 files changed

+179
-55
lines changed

11 files changed

+179
-55
lines changed

.github/workflows/action.yml

Lines changed: 22 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -17,24 +17,21 @@ jobs:
1717
steps:
1818
- name: Checkout
1919
uses: actions/checkout@v4
20-
-
21-
name: Set up Docker Buildx
20+
- name: Set up Docker Buildx
2221
uses: docker/setup-buildx-action@v3
2322
- name: Login to DockerHub
2423
uses: docker/login-action@v3
2524
with:
2625
username: ${{ secrets.DOCKERHUB_USERNAME }}
2726
password: ${{ secrets.DOCKERHUB_TOKEN }}
28-
-
29-
name: Cache Docker layers
27+
- name: Cache Docker layers
3028
uses: actions/cache@v4
3129
with:
3230
path: /tmp/.buildx-cache
3331
key: ${{ runner.os }}-buildx-${{ github.sha }}
3432
restore-keys: |
3533
${{ runner.os }}-buildx-
36-
-
37-
name: Build a dev image
34+
- name: Build a dev image
3835
id: docker_build_dev
3936
uses: docker/build-push-action@v5
4037
with:
@@ -45,16 +42,24 @@ jobs:
4542
tags: transformimgs-dev
4643
cache-from: type=local,src=/tmp/.buildx-cache
4744
cache-to: type=local,dest=/tmp/.buildx-cache
48-
-
49-
name: Run tests
45+
- name: Gosec
46+
id: gosec
5047
run: |
51-
docker run --entrypoint=/go/src/github.com/Pixboost/transformimgs/test.sh -v $(pwd):/go/src/github.com/Pixboost/transformimgs transformimgs-dev
52-
-
53-
name: Code coverage
48+
CWD=$(pwd)
49+
cd /tmp
50+
curl -L https://github.com/securego/gosec/releases/download/v2.22.0/gosec_2.22.0_linux_amd64.tar.gz | tar zx
51+
cd $CWD
52+
/tmp/gosec -exclude-dir illustration ./...
53+
cd illustration
54+
/tmp/gosec ./...
55+
- name: Run tests
5456
run: |
55-
bash <(curl -s https://codecov.io/bash)
56-
-
57-
name: Build a prod image
57+
docker run --entrypoint=/go/src/github.com/Pixboost/transformimgs/test.sh -v $(pwd):/go/src/github.com/Pixboost/transformimgs transformimgs-dev
58+
- id: codecov
59+
uses: codecov/codecov-action@v5
60+
with:
61+
token: ${{ secrets.CODECOV_TOKEN }}
62+
- name: Build a prod image
5863
id: docker_build_prod
5964
uses: docker/build-push-action@v5
6065
with:
@@ -67,17 +72,14 @@ jobs:
6772
"BRANCH=${{ github.ref_name }}"
6873
cache-from: type=local,src=/tmp/.buildx-cache
6974
cache-to: type=local,dest=/tmp/.buildx-cache
70-
-
71-
name: Run the service
75+
- name: Run the service
7276
run: |
7377
docker run -p 8080:8080 -d transformimgs
7478
sleep 5
75-
-
76-
name: Smoketest
79+
- name: Smoketest
7780
run: |
7881
curl -o /dev/null -f http://localhost:8080/img/https://pixboost.com/img/homepage/hero.jpg/resize?size=x600
79-
-
80-
name: Publish image
82+
- name: Publish image
8183
if: ${{ github.event_name == 'release' }}
8284
uses: docker/build-push-action@v5
8385
with:

cmd/main.go

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import (
99
"net/http"
1010
"os"
1111
"runtime"
12+
"time"
1213
)
1314

1415
func main() {
@@ -46,7 +47,13 @@ func main() {
4647
router.HandleFunc("/health", health.Health)
4748

4849
img.Log.Printf("Running the application on port 8080...\n")
49-
err = http.ListenAndServe(":8080", router)
50+
server := http.Server{
51+
Addr: ":8080",
52+
Handler: router,
53+
ReadTimeout: 5 * time.Second,
54+
WriteTimeout: 10 * time.Second,
55+
}
56+
err = server.ListenAndServe()
5057

5158
if err != nil {
5259
img.Log.Errorf("Error while stopping application: %+v", err)

illustration/main.go

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -63,9 +63,9 @@ func main() {
6363
count uint
6464
currColor *imagick.PixelWand
6565
pixelsCount = uint(0)
66-
totalPixelsCount = float32(mw.GetImageHeight() * mw.GetImageWidth())
67-
tenPercent = uint(totalPixelsCount * 0.1)
68-
fiftyPercent = uint(totalPixelsCount * 0.5)
66+
totalPixelsCount = mw.GetImageHeight() * mw.GetImageWidth()
67+
tenPercent = totalPixelsCount / 10
68+
fiftyPercent = totalPixelsCount / 2
6969
isBackground = false
7070
lastBackgroundColor *imagick.PixelWand
7171
colorsInBackground = uint(0)
@@ -108,14 +108,17 @@ func main() {
108108
pixelsInBackground = 0
109109
} else {
110110
pixelsCount += count
111-
fiftyPercent = uint((totalPixelsCount - float32(pixelsInBackground)) * 0.5)
111+
fiftyPercent = (totalPixelsCount - pixelsInBackground) / 2
112112
}
113113
}
114114
default:
115115
pixelsCount += count
116116
}
117117
}
118118

119+
if colorIdx < 0 {
120+
log.Fatal("colorIdx < 0")
121+
}
119122
colorsCntIn50Pct := uint(colorIdx) - colorsInBackground
120123

121124
fmt.Print(colorsCntIn50Pct < 10 || (float32(colorsCntIn50Pct)/float32(colorsCnt)) <= 0.02)

img/loader/http.go

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ var client = &http.Client{
3333
},
3434
}
3535

36-
func (r *Http) Load(url string, _ context.Context) (*img.Image, error) {
36+
func (r *Http) Load(url string, ctx context.Context) (*img.Image, error) {
3737
req, err := http.NewRequest("GET", url, nil)
3838
if err != nil {
3939
return nil, err
@@ -44,6 +44,14 @@ func (r *Http) Load(url string, _ context.Context) (*img.Image, error) {
4444
}
4545
}
4646

47+
if moreHeaders, ok := img.HeaderFromContext(ctx); ok {
48+
for k, v := range *moreHeaders {
49+
for _, headerVal := range v {
50+
req.Header.Add(k, headerVal)
51+
}
52+
}
53+
}
54+
4755
resp, err := client.Do(req)
4856
if err != nil {
4957
return nil, err
@@ -58,15 +66,17 @@ func (r *Http) Load(url string, _ context.Context) (*img.Image, error) {
5866
}
5967

6068
contentType := resp.Header.Get("Content-Type")
69+
contentEncoding := resp.Header.Get("Content-Encoding")
6170

6271
result, err := ioutil.ReadAll(resp.Body)
6372
if err != nil {
6473
return nil, err
6574
}
6675

6776
return &img.Image{
68-
Id: url,
69-
Data: result,
70-
MimeType: contentType,
77+
Id: url,
78+
Data: result,
79+
MimeType: contentType,
80+
ContentEncoding: contentEncoding,
7181
}, nil
7282
}

img/loader/http_test.go

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package loader_test
22

33
import (
44
"context"
5+
"github.com/Pixboost/transformimgs/v8/img"
56
"github.com/Pixboost/transformimgs/v8/img/loader"
67
"github.com/dooman87/kolibri/test"
78
"net/http"
@@ -72,7 +73,7 @@ func TestHttp_LoadImgErrorResponseStatus(t *testing.T) {
7273
)
7374
}
7475

75-
func TestHttp_LoadCustomHeaders(t *testing.T) {
76+
func TestHttp_LoadCustomGlobalHeaders(t *testing.T) {
7677
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
7778
if r.Header.Get("this-is-header") != "wow" {
7879
w.WriteHeader(http.StatusInternalServerError)
@@ -100,7 +101,7 @@ func TestHttp_LoadCustomHeaders(t *testing.T) {
100101
)
101102
}
102103

103-
func FuzzHttp_LoadCustomHeaders(f *testing.F) {
104+
func FuzzHttp_LoadCustomGlobalHeaders(f *testing.F) {
104105
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
105106
w.Header().Add("Content-Type", "cool/stuff")
106107
w.Write([]byte("123"))
@@ -137,3 +138,27 @@ func FuzzHttp_LoadCustomHeaders(f *testing.F) {
137138
}
138139
})
139140
}
141+
142+
func TestHttp_LoadCustomContextHeaders(t *testing.T) {
143+
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
144+
if r.Header.Get("this-is-header") != "wow" {
145+
w.WriteHeader(http.StatusInternalServerError)
146+
} else {
147+
w.Header().Add("Content-Type", "cool/stuff")
148+
w.Write([]byte("123"))
149+
}
150+
}))
151+
defer server.Close()
152+
153+
httpLoader := &loader.Http{}
154+
155+
image, err := httpLoader.Load(server.URL, img.NewContextWithHeaders(context.Background(), &http.Header{
156+
"This-Is-Header": []string{"wow"},
157+
}))
158+
159+
test.Error(t,
160+
test.Nil(err, "error"),
161+
test.Equal("cool/stuff", image.MimeType, "content type"),
162+
test.Equal("123", string(image.Data), "resulted image"),
163+
)
164+
}

img/processor/imagemagick.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -252,7 +252,7 @@ func (p *ImageMagick) Optimise(config *img.TransformationConfig) (*img.Image, er
252252

253253
func (p *ImageMagick) execImagemagick(in *bytes.Reader, args []string, imgId string) ([]byte, error) {
254254
var out, cmderr bytes.Buffer
255-
cmd := exec.Command(p.convertCmd)
255+
cmd := exec.Command(p.convertCmd) // #nosec G204 - sanitizing before assigning
256256

257257
cmd.Args = append(cmd.Args, args...)
258258

@@ -295,7 +295,7 @@ func (p *ImageMagick) LoadImageInfo(src *img.Image) (*img.Info, error) {
295295
var out, cmderr bytes.Buffer
296296
imgId := src.Id
297297
in := bytes.NewReader(src.Data)
298-
cmd := exec.Command(p.identifyCmd)
298+
cmd := exec.Command(p.identifyCmd) // #nosec G204 - sanitizing before assigning
299299
cmd.Args = append(cmd.Args, "-format", "%m %Q %[opaque] %w %h", "-")
300300

301301
cmd.Stdin = in

img/service.go

Lines changed: 33 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -192,17 +192,23 @@ func (r *Service) AsIs(resp http.ResponseWriter, req *http.Request) {
192192

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

195-
result, err := r.Loader.Load(imgUrl, req.Context())
195+
var proxyHeaders = make(http.Header)
196+
accept := req.Header.Get("Accept")
197+
if len(accept) > 0 {
198+
proxyHeaders.Add("Accept", accept)
199+
}
200+
acceptEncoding := req.Header.Get("Accept-Encoding")
201+
if len(acceptEncoding) > 0 {
202+
proxyHeaders.Add("Accept-Encoding", acceptEncoding)
203+
}
204+
205+
result, err := r.Loader.Load(imgUrl, NewContextWithHeaders(req.Context(), &proxyHeaders))
196206

197207
if err != nil {
198208
sendError(resp, err)
199209
return
200210
}
201211

202-
if len(result.MimeType) > 0 {
203-
resp.Header().Add("Content-Type", result.MimeType)
204-
}
205-
206212
r.execOp(&Command{
207213
Config: &TransformationConfig{
208214
Src: &Image{
@@ -239,11 +245,15 @@ func (r *Service) getQueue() *Queue {
239245

240246
// Adds Content-Length and Cache-Control headers
241247
func addHeaders(resp http.ResponseWriter, image *Image) {
248+
headers := resp.Header()
242249
if len(image.MimeType) != 0 {
243-
resp.Header().Add("Content-Type", image.MimeType)
250+
headers.Add("Content-Type", image.MimeType)
251+
}
252+
if len(image.ContentEncoding) != 0 {
253+
headers.Add("Content-Encoding", image.ContentEncoding)
244254
}
245-
resp.Header().Add("Content-Length", strconv.Itoa(len(image.Data)))
246-
resp.Header().Add("Cache-Control", fmt.Sprintf("public, max-age=%d", CacheTTL))
255+
headers.Add("Content-Length", strconv.Itoa(len(image.Data)))
256+
headers.Add("Cache-Control", fmt.Sprintf("public, max-age=%d", CacheTTL))
247257
}
248258

249259
func getQueryParam(url *url.URL, name string) (string, bool) {
@@ -391,3 +401,18 @@ func sendError(resp http.ResponseWriter, err error) {
391401
}
392402
}
393403
}
404+
405+
type headersKey int
406+
407+
func NewContextWithHeaders(ctx context.Context, headers *http.Header) context.Context {
408+
return context.WithValue(ctx, headersKey(0), headers)
409+
}
410+
411+
func HeaderFromContext(ctx context.Context) (*http.Header, bool) {
412+
if ctx == nil {
413+
return nil, false
414+
}
415+
416+
header, ok := ctx.Value(headersKey(0)).(*http.Header)
417+
return header, ok
418+
}

0 commit comments

Comments
 (0)