Export Content-Disposition drops the plain filename= fallback for ASCII names

Open Beginner friendly
#5,929 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Assessment

Difficulty
2/5
Estimated time
1-3 hours
Newbie friendliness
72/100
Issue type
Bug
Clarity
Clearly specified
Activity status
Active
Tech stack
fastapi, python
Domain
api, backend

Research direction

Start at the POST /api/v1/research/{id}/export/{format} route and trace the code that constructs its Content-Disposition header. Confirm the existing behavior for ASCII and non-ASCII names, then verify that the completed change emits a sanitised filename= alongside filename*= for compatible downloads.

Written by the indexing model from the issue text.

Description

Found while combing #3299. Narrow compatibility regression for API consumers.

What changed

Flask used Werkzeug's send_file, which emits:

  • ASCII filenames -> filename="report.pdf"
  • non-ASCII -> both filename=<ascii-fallback> and filename*=UTF-8''<encoded>

The FastAPI version hand-builds the header and always emits filename*=UTF-8''<encoded> only, with no plain filename= even when the name is pure ASCII.

Route: POST /api/v1/research/{id}/export/{format}.

Who breaks

Every modern browser handles RFC 5987 filename*=, so interactive downloads are fine. The breakage is for API consumers that regex the quoted filename="..." form — a common enough pattern in scripts that scrape the header rather than parse it properly.

Fix

Emit both forms, as Werkzeug does: a sanitised ASCII filename= alongside filename*=. Strictly more compatible, costs nothing.

Also worth knowing (separate, no action proposed)

GET /api/research/{id}/logs changed its timestamp field from RFC 822 (Flask's jsonify) to ISO 8601 (FastAPI's jsonable_encoder). The code comment says this was deliberate, aligning it with /logs/export, which already emitted ISO 8601.

In-repo consumers are unaffected — logpanel.js uses new Date(), which parses both. Third-party consumers with a strict RFC 822 parser would break.

Narrower than it first appears: ResearchHistory.created_at / completed_at are Text columns rather than real datetimes, so they do not carry this change.

Dominant language
Python
Stars
9.1k
Forks
824
Avg merge
3d 4h
Merged PRs (30d)
289

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from LearningCircuit/local-deep-research

All issues in LearningCircuit/local-deep-research

Similar issues

More Python issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.