Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

send_file doesn't urlencode ':/' in unicode attachment_filename #3074

Closed
i-akhmadullin opened this issue Jan 15, 2019 · 5 comments
Closed

send_file doesn't urlencode ':/' in unicode attachment_filename #3074

i-akhmadullin opened this issue Jan 15, 2019 · 5 comments
Milestone

Comments

@i-akhmadullin
Copy link

i-akhmadullin commented Jan 15, 2019

Expected Behavior

When sending files with unicode filename (with : or /) they should be downloaded with name from filename* field.

# -*- coding: utf-8 -*-
import os
from flask import Flask, send_from_directory
app = Flask(__name__)
@app.route('/test/', methods=['GET'])
def test_route():
    tmp_dir = os.getcwd()
    tmp_filename = __file__
    attachment_filename = u'тест:тест_тест.py'
    return send_from_directory(
        tmp_dir,
        tmp_filename,
        as_attachment=True,
        attachment_filename=attachment_filename
    )
if __name__ == '__main__':
    app.run(host='::', port=5000)

Actual Behavior

Some browsers (Chrome-based/Safari) ignore filename* field when it contains colon or slash. For example file тест:тест_тест.py gets downloaded in Chrome/Safari as __.py but in Firefox as тест_тест_тест.py which is acceptable in my opinion.

Flask response:
Content-Disposition: attachment; filename*="UTF-8''%D1%82%D0%B5%D1%81%D1%82:%D1%82%D0%B5%D1%81%D1%82_%D1%82%D0%B5%D1%81%D1%82.py"; filename=":_.py"

Environment

  • Python version: 2.7.15
  • Flask version: 1.0.2
  • Werkzeug version: 0.14.1
@eladm26
Copy link
Contributor

eladm26 commented Feb 19, 2019

Hi @i-akhmadullin
according to the RFC: both "filename" and "filename*" are present in a single header field value, recipients SHOULD pick "filename*" and ignore "filename"
So it seems like an issue of chrome rather than flask.

@davidism
Copy link
Member

This was working in Chrome when I implemented this. If they're changing behavior, that's incorrect and needs to be reported to them. I don't think Flask can do anything about it because it still needs to send both for compatibility with other clients.

@i-akhmadullin
Copy link
Author

This issue is about encoding colon and slash in attachment filename, not about filename/filename*.
If we encode colon and slash characters then file gets downloaded with a utf8-name, but with underscores instead colons and slashes. But otherwise this is a lot better result than ascii-only filename (тест_тест_тест.py vs _.py).

Flask uses url_quote from werkzeug where :/ are listed as safe characters, so maybe it just an oversight that they are not escaped.

'filename*': "UTF-8''%s" % url_quote(attachment_filename),

https://github.com/pallets/werkzeug/blob/master/werkzeug/urls.py#L518

@davidism
Copy link
Member

Your description in "actual behavior" makes no mention of how ":/" relate to the issue, it just mentions "filename" and "filename*". Could you review and make sure the issue accurately represents what you're trying to describe?

@i-akhmadullin
Copy link
Author

@davidism sorry for the confusion, should be clearer now

@davidism davidism added this to the 1.0.4 milestone Jun 27, 2019
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Nov 14, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants