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

Added support for non-ascii filenames in content-disposition. #17

Merged
merged 6 commits into from Nov 22, 2013
Merged

Added support for non-ascii filenames in content-disposition. #17

merged 6 commits into from Nov 22, 2013

Conversation

jdufresne
Copy link
Contributor

Using the details outlined at:
http://kbyanc.blogspot.hk/2010/07/serving-file-downloads-with-non-ascii.html

To support older browsers, an ascii only filename is added to the
content-dispostion. The unicode version is properly encoded and added
to the header. The argument attachment_filename may now be False to
send no filename. Added and fixed unit tests to verify the new
behavior.

This change introduces a new dependency on Unidecode https://pypi.python.org/pypi/Unidecode. I have tested this change with Python 2.7.5 and Django 1.6. All unit tests and manual test cases worked for me. Please review the changes. If any other configurations do not work please let me know with version numbers.

Using the details outlined at:
http://kbyanc.blogspot.hk/2010/07/serving-file-downloads-with-non-ascii.html

To support older browsers, an ascii only filename is added to the
content-dispostion. The unicode version is properly encoded and added
to the header. The argument attachment_filename may now be False to
send no filename. Added and fixed unit tests to verify the new
behavior.
@schinckel
Copy link

The linked page says that this doesn't work in "WebKit-based browsers", i.e., that it saves with a percent-encoded filename.

Omitting the filename would appear to be a better solution, as this works regardless of browser.

@jdufresne
Copy link
Contributor Author

The linked page says that this doesn't work in "WebKit-based browsers", i.e., that it saves with a percent-encoded filename.

According to the latest tests, this now works in Safari 6. Are you able to test with Safari? From what I understand, Safari 5 will continue to show the percents but Safari 6 was released over a year ago, July 25, 2012. The original article describing the issue and solution was written July 1, 2010.

Omitting the filename would appear to be a better solution, as this works regardless of browser.

My patch supports this by passing the argument attachment_filename=False. If attachment_filename is passed normally, the filename is encoded properly.

If you find any bugs with the patch let me know and I'll try to address them. Thanks.

Jon Dufresne and others added 2 commits November 16, 2013 10:03
Tested on older versions of Django, realized the try/except is
unnecassary. Should probably use force_text() instead of smart_text()
as the unidecode() functions requires an actual unicode string.
To help some older browsers, such as Safari 5, the url quoted filename
is only added if the filename contains non-ascii characters. In the
ascii case, use the old style filename attachment. Fixed unittests.
@jdufresne
Copy link
Contributor Author

@johnsensible Any chance on getting the code reviewed and possibly merged for a release? If you have any reservations or require more testing, please let me know. I'd be happy to look into it.

@johnsensible
Copy link
Owner

Sorry, it's been a bit crazy here at work.

Will try and look at this tomorrow.

@johnsensible
Copy link
Owner

@jdufresne ok just had a quick look.

  • the unidecode import needs to be moved into the sendfile function - otherwise setup.py won't run until it's installed
  • I take it that you're modifications to add unidecode to setup.py means it will install that when doing pip install?
  • force_text isn't available in django 1.3 - seems a shame to drop support for 1.3 just for the sake of that one function? Perhaps just add a try/except and import "force_unicode as force_text" to deal with that?

Otherwise I think it looks ok so far.

cheers,

John

@johnsensible
Copy link
Owner

Oh and probably also best to move all of the django related imports inside of the functions as well (for same reason as moving the unidecode import).

@jdufresne
Copy link
Contributor Author

the unidecode import needs to be moved into the sendfile function - otherwise setup.py won't run until it's installed

Oh and probably also best to move all of the django related imports inside of the functions as well (for same reason as moving the unidecode import).

Will do.

I take it that you're modifications to add unidecode to setup.py means it will install that when doing pip install?

I believe so. That is my intent. I will do some testing to try to verify this.

force_text isn't available in django 1.3 - seems a shame to drop support for 1.3 just for the sake of that one function? Perhaps just add a try/except and import "force_unicode as force_text" to deal with that?

According to setup.py, Django >= 1.4.2 is a requirement of django-sendfile. Is this not correct? This is why I removed the try/except. Should I change the requirement to >=1.3 as well as falling back to force_unicode?

@jdufresne
Copy link
Contributor Author

I did the first two tests and changes requested. Please review.

I'll wait to do the last fix when I get confirmation on the Django requirement.

Fallback from force_text to force_unicode as it is named in Django
1.3. Fixed the requirements in setup.py to reflect that Django 1.3 is
supported.
@jdufresne
Copy link
Contributor Author

I went ahead and ran several tests with Django 1.3. The test suite passes no problem so I added the fallback back in. Django 1.3 is now listed as the requirement (not 1.4).

@johnsensible
Copy link
Owner

Hmmm. That Django 1.4.2 requirement got added in by a contributor a while ago. Think I must have just overlooked it.

Ok, well lets just stick with 1.4.2 then. I'll give your code another look now.

@johnsensible johnsensible merged commit b80d2f9 into johnsensible:master Nov 22, 2013
@johnsensible
Copy link
Owner

Ok all merged in. I see you already change the requirements to Django 1.3. I've tested against 1.3 and it all seems to be ok.

Should be appearing in PyPi shortly (version 0.3.3).

Cheers,

John

@jdufresne
Copy link
Contributor Author

Thanks!

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.

None yet

3 participants