Log viewer shows the log in binary when opened in Chrome in Windows, but works correctly in Firfox/Linux
Here is an example:
https://dashboard.kernelci.org/log-viewer?itemId=ti%3Ad7378c1959574935bc056d7b&o=ti&type=test&url=http%3A%2F%2Ffiles.kernelci.org%2F%2Fti%2Fnext%2Fmaster%2Fnext-20260508%2Farm64%2Fdefconfig%2Blab-setup%2Bkselftest%2Fgcc-14%2Fbaseline-nfs-boot.nfs-j721e-idk-gw-8_132543899.txt.gz
Here is how it looks in Chrome:
Here is the AI analysis of this issue:
.gz Log Decompression Bug Analysis
Why it fails in Chrome (Windows) but works in Firefox (Linux)
Server Response Headers
Fetching a .gz log file from files.kernelci.org returns:
Content-Type: application/gzip
Content-Disposition: attachment; filename="...txt.gz"
No Content-Encoding: gzip header. This is the root cause of the divergence.
The Full Chain
Proxy behavior (same for both browsers)
The Django proxy (proxyView.py:85) uses Python requests to fetch the file.
With no Content-Encoding: gzip, requests does not auto-decompress -- raw gzip
bytes flow through. The proxy then forwards the Content-Disposition: attachment
header to the browser (proxyView.py:101-104).
Chrome on Windows
Chrome sees Content-Disposition: attachment + Content-Type: application/gzip
on the XHR response and triggers a native OS download. The response is intercepted
before pako ever runs. The "compressed file" received in Chrome is not a JavaScript
error -- it is Chrome downloading the file.
Firefox on Linux
Firefox correctly ignores Content-Disposition: attachment on XHR responses
(the spec only requires browsers to honor it on navigation requests, not on
XMLHttpRequest). The raw gzip bytes are passed to axios and then to pako.inflate.
Firefox on Linux likely also auto-decompresses responses with
Content-Type: application/gzip before handing them to JavaScript, which sidesteps
the inflate vs ungzip bug entirely.
Two Bugs, Two Fixes
Bug 1 -- Wrong pako function
File: dashboard/dashboard/src/api/logViewer.ts:33
// Before (wrong -- pako.inflate expects zlib format, not gzip)
const decompressedData = pako.inflate(uint8ArrayResponse);
// After (correct -- pako.ungzip handles the gzip header)
const decompressedData = pako.ungzip(uint8ArrayResponse);
Bug 2 -- Proxy forwards Content-Disposition: attachment
File: dashboard/backend/kernelCI_app/views/proxyView.py:101-104
# Remove this block entirely.
# Content-Disposition from the origin is for direct file downloads,
# not for the proxy-to-browser XHR leg. Forwarding it causes Chrome
# to trigger a native download instead of letting JavaScript process the bytes.
if "Content-Disposition" in response.headers:
proxy_response["Content-Disposition"] = response.headers[
"Content-Disposition"
]
Log viewer shows the log in binary when opened in Chrome in Windows, but works correctly in Firfox/Linux
Here is an example:
https://dashboard.kernelci.org/log-viewer?itemId=ti%3Ad7378c1959574935bc056d7b&o=ti&type=test&url=http%3A%2F%2Ffiles.kernelci.org%2F%2Fti%2Fnext%2Fmaster%2Fnext-20260508%2Farm64%2Fdefconfig%2Blab-setup%2Bkselftest%2Fgcc-14%2Fbaseline-nfs-boot.nfs-j721e-idk-gw-8_132543899.txt.gz
Here is how it looks in Chrome:
Here is the AI analysis of this issue:
.gzLog Decompression Bug AnalysisWhy it fails in Chrome (Windows) but works in Firefox (Linux)
Server Response Headers
Fetching a
.gzlog file fromfiles.kernelci.orgreturns:No
Content-Encoding: gzipheader. This is the root cause of the divergence.The Full Chain
Proxy behavior (same for both browsers)
The Django proxy (
proxyView.py:85) uses Pythonrequeststo fetch the file.With no
Content-Encoding: gzip,requestsdoes not auto-decompress -- raw gzipbytes flow through. The proxy then forwards the
Content-Disposition: attachmentheader to the browser (
proxyView.py:101-104).Chrome on Windows
Chrome sees
Content-Disposition: attachment+Content-Type: application/gzipon the XHR response and triggers a native OS download. The response is intercepted
before pako ever runs. The "compressed file" received in Chrome is not a JavaScript
error -- it is Chrome downloading the file.
Firefox on Linux
Firefox correctly ignores
Content-Disposition: attachmenton XHR responses(the spec only requires browsers to honor it on navigation requests, not on
XMLHttpRequest). The raw gzip bytes are passed to axios and then topako.inflate.Firefox on Linux likely also auto-decompresses responses with
Content-Type: application/gzipbefore handing them to JavaScript, which sidestepsthe
inflatevsungzipbug entirely.Two Bugs, Two Fixes
Bug 1 -- Wrong pako function
File:
dashboard/dashboard/src/api/logViewer.ts:33Bug 2 -- Proxy forwards
Content-Disposition: attachmentFile:
dashboard/backend/kernelCI_app/views/proxyView.py:101-104