Skip to content

fix: Set content type for file downloads in viewer handler#570

Merged
rusq merged 3 commits intorusq:masterfrom
lbeckman314:fix/canvas-viewer
Nov 14, 2025
Merged

fix: Set content type for file downloads in viewer handler#570
rusq merged 3 commits intorusq:masterfrom
lbeckman314:fix/canvas-viewer

Conversation

@lbeckman314
Copy link
Copy Markdown
Contributor

@lbeckman314 lbeckman314 commented Nov 13, 2025

Overview

Minor fix that resolves #569 by setting Content Header for all files to allow for successful serving of non-extension files (e.g Canvas files).

Tip

See Issue Comment for steps run and new behavior.

Limitations ⚠️

1. Canvas Link

Canvases are only included in the __uploads directory in the dump file if a link to that canvas is included in the channel messages:

Canvas link example

Note

Without this link, the Canvas will be not included in the final dump file.

2. Files in the Canvas

Files uploaded to the Canvas are not downloaded and are only represented as File URL links in the Canvas dump:

__uploads/<Channel ID>/Example_Canvas:

<h1 id='temp:C:RVRac19dd8f6f69470d97606823c'>Example Canvas</h1>

<p id='temp:C:RVR614bc135fec24118aae3a9a89' class='line'>Example Text</p>

<p class='embedded-file'>File ID: F09TPE73WTA File URL: https://ohsucomputationalbio.slack.com/files/U042WA9K4DB/F09TPE73WTA/image.png</p>   <---- Example file is not downloaded

3. Test Failure

Caution

All tests passing except for Test_exportV3 (need to investigate further...):

➜ gh repo set-default rusq/slackdump
✓ Set rusq/slackdump as the default repository for the current directory

➜ gh pr checkout 570
Switched to branch 'fix/canvas-viewer'

➜ make test
go test -race -cover ./...
...
--- FAIL: Test_exportV3 (0.00s)
    --- FAIL: Test_exportV3/guest_user (0.00s)
        v3_test.go:57: stat ../../../../tmp/guest: no such file or directory
FAIL
coverage: 2.9% of statements
FAIL    github.com/rusq/slackdump/v3/cmd/slackdump/internal/export      0.771s
        github.com/rusq/slackdump/v3/cmd/slackdump/internal/format      coverage: 0.0% of statements
...
FAIL
make: *** [test] Error 1

Copilot AI review requested due to automatic review settings November 13, 2025 23:56
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR addresses issue #569 by setting the Content-Type header for file downloads to support files without extensions, such as Canvas files. The change ensures that http.ServeFileFS serves these files correctly.

Key Changes

  • Added Content-Type header set to "application/octet-stream" in the file handler to ensure proper serving of extensionless files

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +215 to +216
// Setting content type to application/octet-stream to support any files without extensions (e.g. Canvas files)
w.Header().Set("Content-Type", "application/octet-stream")
Copy link

Copilot AI Nov 13, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Content-Type header is being set before request validation. If the validation fails (lines 217-220), the response will include this header even though it's a 404 error response. This could be confusing and is not semantically correct.

Consider moving the header setting to after validation and before calling http.ServeFileFS:

if id == "" || filename == "" || isInvalid(filename) || isInvalid(id) {
    http.NotFound(w, r)
    return
}
lg := v.lg.With("in", "fileHandler", "id", id, "filename", filename)
fsys := v.src.Files().FS()
path, err := v.src.Files().File(id, filename)
if err != nil {
    if errors.Is(err, fs.ErrNotExist) {
        http.NotFound(w, r)
        return
    }
    lg.ErrorContext(ctx, "File", "error", err)
    http.Error(w, err.Error(), http.StatusInternalServerError)
    return
}

// Setting content type to application/octet-stream to support any files without extensions (e.g. Canvas files)
w.Header().Set("Content-Type", "application/octet-stream")
http.ServeFileFS(w, r, fsys, path)

This ensures the Content-Type header is only set for successful file serving.

Copilot uses AI. Check for mistakes.
@rusq
Copy link
Copy Markdown
Owner

rusq commented Nov 14, 2025

Hey @lbeckman314, thanks a lot for this! Don't worry about the tmp/guest failing test - it used to be a test that used [unpublished] files on my machine. It is not executed in the CI, and doesn't relate to this change, of course.

@rusq rusq merged commit b2e1696 into rusq:master Nov 14, 2025
3 checks passed
@lbeckman314 lbeckman314 deleted the fix/canvas-viewer branch December 10, 2025 07:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

v3.1.9: Canvas missing in slackdump view <DUMP>?

3 participants