Skip to content

Commit 045c781

Browse files
authored
Merge pull request moby#3788 from sipsma/unset-accept-encoding
Fix gzip decoding of HTTP sources.
2 parents 333ee91 + cf2698c commit 045c781

File tree

3 files changed

+57
-4
lines changed

3 files changed

+57
-4
lines changed

client/client_test.go

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package client
33
import (
44
"archive/tar"
55
"bytes"
6+
"compress/gzip"
67
"context"
78
"crypto/rand"
89
"crypto/rsa"
@@ -2196,6 +2197,49 @@ func testBuildHTTPSource(t *testing.T, sb integration.Sandbox) {
21962197
require.Equal(t, http.MethodHead, allReqs[1].Method)
21972198
require.Equal(t, "gzip", allReqs[1].Header.Get("Accept-Encoding"))
21982199

2200+
require.NoError(t, os.RemoveAll(filepath.Join(tmpdir, "foo")))
2201+
2202+
// update the content at the url to be gzipped now, the final output
2203+
// should remain the same
2204+
modTime = time.Now().Add(-23 * time.Hour)
2205+
var buf bytes.Buffer
2206+
gw := gzip.NewWriter(&buf)
2207+
_, err = gw.Write(resp.Content)
2208+
require.NoError(t, err)
2209+
require.NoError(t, gw.Close())
2210+
gzipBytes := buf.Bytes()
2211+
respGzip := httpserver.Response{
2212+
Etag: identity.NewID(),
2213+
Content: gzipBytes,
2214+
LastModified: &modTime,
2215+
ContentEncoding: "gzip",
2216+
}
2217+
server.SetRoute("/foo", respGzip)
2218+
2219+
_, err = c.Solve(sb.Context(), def, SolveOpt{
2220+
Exports: []ExportEntry{
2221+
{
2222+
Type: ExporterLocal,
2223+
OutputDir: tmpdir,
2224+
},
2225+
},
2226+
}, nil)
2227+
require.NoError(t, err)
2228+
2229+
require.Equal(t, server.Stats("/foo").AllRequests, 4)
2230+
require.Equal(t, server.Stats("/foo").CachedRequests, 1)
2231+
2232+
dt, err = os.ReadFile(filepath.Join(tmpdir, "foo"))
2233+
require.NoError(t, err)
2234+
require.Equal(t, resp.Content, dt)
2235+
2236+
allReqs = server.Stats("/foo").Requests
2237+
require.Equal(t, 4, len(allReqs))
2238+
require.Equal(t, http.MethodHead, allReqs[2].Method)
2239+
require.Equal(t, "gzip", allReqs[2].Header.Get("Accept-Encoding"))
2240+
require.Equal(t, http.MethodGet, allReqs[3].Method)
2241+
require.Equal(t, "gzip", allReqs[3].Header.Get("Accept-Encoding"))
2242+
21992243
// test extra options
22002244
st = llb.HTTP(server.URL+"/foo", llb.Filename("bar"), llb.Chmod(0741), llb.Chown(1000, 1000))
22012245

@@ -2212,7 +2256,7 @@ func testBuildHTTPSource(t *testing.T, sb integration.Sandbox) {
22122256
}, nil)
22132257
require.NoError(t, err)
22142258

2215-
require.Equal(t, server.Stats("/foo").AllRequests, 3)
2259+
require.Equal(t, server.Stats("/foo").AllRequests, 5)
22162260
require.Equal(t, server.Stats("/foo").CachedRequests, 1)
22172261

22182262
dt, err = os.ReadFile(filepath.Join(tmpdir, "bar"))

source/http/httpsource.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,10 @@ func (hs *httpSourceHandler) CacheKey(ctx context.Context, g session.Group, inde
205205
resp.Body.Close()
206206
}
207207
req.Method = "GET"
208+
// Unset explicit Accept-Encoding for GET, otherwise the go http library will not
209+
// transparently decompress the response body when it is gzipped. It will still add
210+
// this header implicitly when the request is made though.
211+
req.Header.Del("Accept-Encoding")
208212
}
209213

210214
resp, err := client.Do(req)

util/testutil/httpserver/server.go

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,10 @@ func (s *TestServer) ServeHTTP(w http.ResponseWriter, r *http.Request) {
5151
w.Header().Set("Last-Modified", resp.LastModified.Format(time.RFC850))
5252
}
5353

54+
if resp.ContentEncoding != "" {
55+
w.Header().Set("Content-Encoding", resp.ContentEncoding)
56+
}
57+
5458
if resp.Etag != "" {
5559
w.Header().Set("ETag", resp.Etag)
5660
if match := r.Header.Get("If-None-Match"); match == resp.Etag {
@@ -75,9 +79,10 @@ func (s *TestServer) Stats(name string) (st Stat) {
7579
}
7680

7781
type Response struct {
78-
Content []byte
79-
Etag string
80-
LastModified *time.Time
82+
Content []byte
83+
Etag string
84+
LastModified *time.Time
85+
ContentEncoding string
8186
}
8287

8388
type Stat struct {

0 commit comments

Comments
 (0)