Skip to content

Log Viewer shows the compressed binary of the full test log #1887

@minash-ti

Description

@minash-ti

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:

Image

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"
    ]

Metadata

Metadata

Assignees

No one assigned

    Labels

    FrontendMost or all of the changes for this issue will be in the frontend code.

    Type

    Projects

    Status

    In Review

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions