@@ -10,6 +10,7 @@ import (
10
10
"bufio"
11
11
"bytes"
12
12
"compress/gzip"
13
+ "compress/zlib"
13
14
"context"
14
15
"crypto/tls"
15
16
"encoding/json"
@@ -6161,6 +6162,111 @@ func TestUnsupportedTransferEncodingsReturn501(t *testing.T) {
6161
6162
}
6162
6163
}
6163
6164
6165
+ func TestContentEncodingNoSniffing_h1 (t * testing.T ) {
6166
+ testContentEncodingNoSniffing (t , h1Mode )
6167
+ }
6168
+
6169
+ func TestContentEncodingNoSniffing_h2 (t * testing.T ) {
6170
+ t .Skip ("Waiting for h2_bundle.go update after https://golang.org/issue/31753" )
6171
+ testContentEncodingNoSniffing (t , h2Mode )
6172
+ }
6173
+
6174
+ // Issue 31753: don't sniff when Content-Encoding is set
6175
+ func testContentEncodingNoSniffing (t * testing.T , h2 bool ) {
6176
+ setParallel (t )
6177
+ defer afterTest (t )
6178
+
6179
+ type setting struct {
6180
+ name string
6181
+ body []byte
6182
+
6183
+ // setting contentEncoding as an interface instead of a string
6184
+ // directly, so as to differentiate between 3 states:
6185
+ // unset, empty string "" and set string "foo/bar".
6186
+ contentEncoding interface {}
6187
+ wantContentType string
6188
+ }
6189
+
6190
+ settings := []* setting {
6191
+ {
6192
+ name : "gzip content-encoding, gzipped" , // don't sniff.
6193
+ contentEncoding : "application/gzip" ,
6194
+ wantContentType : "" ,
6195
+ body : func () []byte {
6196
+ buf := new (bytes.Buffer )
6197
+ gzw := gzip .NewWriter (buf )
6198
+ gzw .Write ([]byte ("doctype html><p>Hello</p>" ))
6199
+ gzw .Close ()
6200
+ return buf .Bytes ()
6201
+ }(),
6202
+ },
6203
+ {
6204
+ name : "zlib content-encoding, zlibbed" , // don't sniff.
6205
+ contentEncoding : "application/zlib" ,
6206
+ wantContentType : "" ,
6207
+ body : func () []byte {
6208
+ buf := new (bytes.Buffer )
6209
+ zw := zlib .NewWriter (buf )
6210
+ zw .Write ([]byte ("doctype html><p>Hello</p>" ))
6211
+ zw .Close ()
6212
+ return buf .Bytes ()
6213
+ }(),
6214
+ },
6215
+ {
6216
+ name : "no content-encoding" , // must sniff.
6217
+ wantContentType : "application/x-gzip" ,
6218
+ body : func () []byte {
6219
+ buf := new (bytes.Buffer )
6220
+ gzw := gzip .NewWriter (buf )
6221
+ gzw .Write ([]byte ("doctype html><p>Hello</p>" ))
6222
+ gzw .Close ()
6223
+ return buf .Bytes ()
6224
+ }(),
6225
+ },
6226
+ {
6227
+ name : "phony content-encoding" , // don't sniff.
6228
+ contentEncoding : "foo/bar" ,
6229
+ body : []byte ("doctype html><p>Hello</p>" ),
6230
+ },
6231
+ {
6232
+ name : "empty but set content-encoding" ,
6233
+ contentEncoding : "" ,
6234
+ wantContentType : "audio/mpeg" ,
6235
+ body : []byte ("ID3" ),
6236
+ },
6237
+ }
6238
+
6239
+ for _ , tt := range settings {
6240
+ t .Run (tt .name , func (t * testing.T ) {
6241
+ cst := newClientServerTest (t , h2 , HandlerFunc (func (rw ResponseWriter , r * Request ) {
6242
+ if tt .contentEncoding != nil {
6243
+ rw .Header ().Set ("Content-Encoding" , tt .contentEncoding .(string ))
6244
+ }
6245
+ rw .Write (tt .body )
6246
+ }))
6247
+ defer cst .close ()
6248
+
6249
+ res , err := cst .c .Get (cst .ts .URL )
6250
+ if err != nil {
6251
+ t .Fatalf ("Failed to fetch URL: %v" , err )
6252
+ }
6253
+ defer res .Body .Close ()
6254
+
6255
+ if g , w := res .Header .Get ("Content-Encoding" ), tt .contentEncoding ; g != w {
6256
+ if w != nil { // The case where contentEncoding was set explicitly.
6257
+ t .Errorf ("Content-Encoding mismatch\n \t got: %q\n \t want: %q" , g , w )
6258
+ } else if g != "" { // "" should be the equivalent when the contentEncoding is unset.
6259
+ t .Errorf ("Unexpected Content-Encoding %q" , g )
6260
+ }
6261
+ }
6262
+
6263
+ if g , w := res .Header .Get ("Content-Type" ), tt .wantContentType ; g != w {
6264
+ t .Errorf ("Content-Type mismatch\n \t got: %q\n \t want: %q" , g , w )
6265
+ }
6266
+ })
6267
+ }
6268
+ }
6269
+
6164
6270
// fetchWireResponse is a helper for dialing to host,
6165
6271
// sending http1ReqBody as the payload and retrieving
6166
6272
// the response as it was sent on the wire.
0 commit comments