werkzeug
werkzeug copied to clipboard
send_file not inserting quote around filename
Overview
The function send_file does not insert quotes around the filename in the Content-Disposition
header when the sent file does not have spaces. (See here for MDN docs)
This causes browser (tested on Windows 11 - last version to date of Firefox and Chrome) to download the file with a blank name (respectively as undefined
and undefined.txt
)
To recap:
- when
test.pdf
is sent with send_file the followingContent-Disposition
header is set to:attachment; filename=test.pdf
-> Correct file is sent but with wrong filename - when
test 1.pdf
is sent with send_file the followingContent-Disposition
header is set to:attachment; filename="test 1.pdf"
-> Works perfectly
Bug replication
Send a file without spaces in name:
from flask import Flask, send_file
app = Flask(__name__)
filepath = "test.pdf"
if filepath:
response = send_file(filepath, as_attachment=True)
Expected behavior:
- when
test.pdf
is sent with send_file the followingContent-Disposition
header is set to:attachment; filename="test.pdf"
- when
test 1.pdf
is sent with send_file the followingContent-Disposition
header is set to:attachment; filename="test 1.pdf"
Environment:
- Python version: 3.11
- Flask version: 3.0.0
- Waitress: 2.1.2
The problem comes from these lines in quote_header_value
:
https://github.com/pallets/werkzeug/blob/d3dd65a27388fbd39d146caacf2563639ba622f0/src/werkzeug/http.py#L165-L169
This is used called from dump_options_header
.
Do you know if this is true for all headers? If yes, it may be safer to default to allow_token = False
.
If not dump_options_header
, _options_header_vkw
and Headers.set
should accept allow_token
and pass it on.
Honestly I don't know, manually adding the quotes using a regex fixed the problem, but I imagine it is not the correct solution, it's just a workaround.
I can't reproduce this issue. Sending a filename without spaces is downloaded with the correct filename by Firefox, Vivaldi (Chrome), and Safari. The Content-Disposition
filename
parameter can be either unquoted token chars, or a quoted string if needed, https://httpwg.org/specs/rfc6266.html#header.field.definition, both are valid.
The problem can be reproduced if you set your language to italian and you try firefox to download any file like "test.pdf"