Gzip compresion disable, but an header encoding gzip is set in the response
Summary
If gzip is disable, but a request is send to gitlab with "Accept-Encoding: gzip", the response will include an header "content-encoding: gzip", indifferently of the compression of the contents. As that, the contents is still send witout compression but the header in the response create an error while gzip uncompression processs is running.
Step to reproduce :
- change configuration if gitlab like
- nginx['gzip_enabled'] = false
- nginx['gzip'] = "off"
- use TLS 1.3 & http 2
curl a static contents like main javascript with an header "Accept-Encoding: gzip":
curl -v -i -H "Accept-Encoding: gzip" https://<host>/assets/application-a9308f85e95b00007892d451fd9f6beabcd8792b4c5f8cd7524ba7e941d479c9.css > /dev/null
* TCP_NODELAY set
* Connected to <host> (<ip>) port 443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* successfully set certificate verify locations:
* CAfile: /etc/ssl/certs/ca-certificates.crt
CApath: /etc/ssl/certs
} [5 bytes data]
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
} [512 bytes data]
* TLSv1.3 (IN), TLS handshake, Server hello (2):
{ [122 bytes data]
* TLSv1.3 (IN), TLS handshake, Encrypted Extensions (8):
{ [19 bytes data]
* TLSv1.3 (IN), TLS handshake, Certificate (11):
{ [2800 bytes data]
* TLSv1.3 (IN), TLS handshake, CERT verify (15):
{ [112 bytes data]
* TLSv1.3 (IN), TLS handshake, Finished (20):
{ [52 bytes data]
* TLSv1.3 (OUT), TLS change cipher, Change cipher spec (1):
} [1 bytes data]
* TLSv1.3 (OUT), TLS handshake, Finished (20):
} [52 bytes data]
* SSL connection using TLSv1.3 / TLS_AES_256_GCM_SHA384
* ALPN, server accepted to use h2
* Server certificate:
* subject: CN=....
* start date: ...
* expire date: ...
* subjectAltName: host "..." matched cert's "..."
* issuer: C=US; O=...; CN=...
* SSL certificate verify ok.
* Using HTTP2, server supports multi-use
* Connection state changed (HTTP/2 confirmed)
* Copying HTTP/2 data in stream buffer to connection buffer after upgrade: len=0
} [5 bytes data]
* Using Stream ID: 1 (easy handle 0x556cd4149db0)
} [5 bytes data]
> GET /assets/application-a9308f85e95b00007892d451fd9f6beabcd8792b4c5f8cd7524ba7e941d479c9.css HTTP/2
> Host: <host>
> user-agent: curl/7.68.0
> accept: */*
> accept-encoding: gzip
>
{ [5 bytes data]
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
{ [249 bytes data]
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
{ [249 bytes data]
* old SSL session ID is stale, removing
{ [5 bytes data]
* Connection state changed (MAX_CONCURRENT_STREAMS == 100)!
} [5 bytes data]
< HTTP/2 200
< server: nginx
< date: Mon, 10 Aug 2020 21:47:43 GMT
< content-type: text/css; charset=utf-8
< cache-control: public
< content-encoding: gzip
< expires: Tue, 10 Aug 2021 21:47:43 GMT
< last-modified: Wed, 05 Aug 2020 11:07:44 GMT
< strict-transport-security: max-age=31536000
< referrer-policy: strict-origin-when-cross-origin
<
{ [11508 bytes data]
* HTTP/2 stream 0 was not closed cleanly: INTERNAL_ERROR (err 2)
* stopped the pause stream!
100 11508 0 11508 0 0 88523 0 --:--:-- --:--:-- --:--:-- 88523
* Connection #0 to host <host> left intact
curl: (92) HTTP/2 stream 0 was not closed cleanly: INTERNAL_ERROR (err 2)
Same curl but without the header "Accept-Encoding: gzip":
curl -v -i https://<host>/assets/application-a9308f85e95b00007892d451fd9f6beabcd8792b4c5f8cd7524ba7e941d479c9.css > /dev/null
* TCP_NODELAY set
* Connected to <host> (<ip>) port 443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* successfully set certificate verify locations:
* CAfile: /etc/ssl/certs/ca-certificates.crt
CApath: /etc/ssl/certs
} [5 bytes data]
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
} [512 bytes data]
* TLSv1.3 (IN), TLS handshake, Server hello (2):
{ [122 bytes data]
* TLSv1.3 (IN), TLS handshake, Encrypted Extensions (8):
{ [19 bytes data]
* TLSv1.3 (IN), TLS handshake, Certificate (11):
{ [2800 bytes data]
* TLSv1.3 (IN), TLS handshake, CERT verify (15):
{ [111 bytes data]
* TLSv1.3 (IN), TLS handshake, Finished (20):
{ [52 bytes data]
* TLSv1.3 (OUT), TLS change cipher, Change cipher spec (1):
} [1 bytes data]
* TLSv1.3 (OUT), TLS handshake, Finished (20):
} [52 bytes data]
* SSL connection using TLSv1.3 / TLS_AES_256_GCM_SHA384
* ALPN, server accepted to use h2
* Server certificate:
* subject: CN=...
* start date: ...
* expire date: ...
* subjectAltName: host "..." matched cert's "..."
* issuer: C=US; O=...; CN=...
* SSL certificate verify ok.
* Using HTTP2, server supports multi-use
* Connection state changed (HTTP/2 confirmed)
* Copying HTTP/2 data in stream buffer to connection buffer after upgrade: len=0
} [5 bytes data]
* Using Stream ID: 1 (easy handle 0x560c1a867db0)
} [5 bytes data]
> GET /assets/application-a9308f85e95b00007892d451fd9f6beabcd8792b4c5f8cd7524ba7e941d479c9.css HTTP/2
> Host: <host>
> user-agent: curl/7.68.0
> accept: */*
>
{ [5 bytes data]
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
{ [249 bytes data]
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
{ [249 bytes data]
* old SSL session ID is stale, removing
{ [5 bytes data]
* Connection state changed (MAX_CONCURRENT_STREAMS == 100)!
} [5 bytes data]
< HTTP/2 200
< server: nginx
< date: Mon, 10 Aug 2020 21:48:21 GMT
< content-type: text/css; charset=utf-8
< content-length: 1606726
< cache-control: public
< expires: Tue, 10 Aug 2021 21:48:21 GMT
< last-modified: Wed, 05 Aug 2020 11:07:44 GMT
< strict-transport-security: max-age=31536000
< referrer-policy: strict-origin-when-cross-origin
< accept-ranges: bytes
<
{ [7445 bytes data]
100 1569k 100 1569k 0 0 5603k 0 --:--:-- --:--:-- --:--:-- 5583k
* Connection #0 to host <host> left intact
Same result with chrome or firefox. In firefox, by default, the about:config, encoding-secure option is set to gzip, deflate... and you will having the issue. When you clean the option value, you have no more error, exactly like the curl with or without the header.
Workaround
Add nginx['custom_gitlab_server_config'] = "gzip off;\n"
to your /etc/gitlab/gitlab.rb
file and run sudo gitlab-ctl reconfigure
. Nginx should be restarted as part of the reconfigure but you can run sudo gitlab-ctl restart nginx
afterwards to be sure.