Changes between Version 3 and Version 6 of Ticket #29276
- Timestamp:
- Mar 30, 2018, 10:04:14 AM (7 years ago)
Legend:
- Unmodified
- Added
- Removed
- Modified
-
Ticket #29276
- Property Summary Turn the headers of HTTPResponse from str to bytes automatically → Compatibility of charset works not well when there are non-ascii characters in HTTPResponse headers
- Property Type Cleanup/optimization → Bug
-
Ticket #29276 – Description
v3 v6 1 1 Python: 3.6.4 2 2 Django: 2.0.3 3 Browser: Chrome v65 3 4 4 When I return a HttpResponse object, Django library will do the job for me: turn my content from str to bytes silently. 5 But Django will not do the same work to the headers of HTTPResponse. 5 To tell the browser to download a file, my code as below: 6 6 7 That is to say, the sample as below in the official document is not precisely correct.8 (Page: https://docs.djangoproject.com/en/2.0/ref/request-response/)9 7 {{{ 10 >>> response = HttpResponse(my_data, content_type='application/vnd.ms-excel')11 >>> response['Content-Disposition'] = 'attachment; filename="foo.xls"'8 response = HttpResponse(my_data, content_type='text/plain') 9 response['Content-Disposition'] = 'attachment; filename="中中foo.xls"' 12 10 }}} 13 The precise usage should be: 11 (Note: there are non-ascii characters in the filename.) 12 My code worked well in Python2.7 and Django1.8. 13 14 But when I transform my version to Django v2 and Python v3. The behavior of the browser changed: Chrome opened my file directly and wouldn't download the file as an attachment any more. 15 I catch the network packet, and found the response headers become as: 16 14 17 {{{ 15 >>> response['Content-Disposition'] = 'attachment; filename="foo.xls"'.encode('utf-8') 18 Content-Disposition: =?utf-8?b?YXR0YWNobWVudDsgZmlsZW5hbWU9IuS4reS4rWZvby54bHMi?= 19 Content-Length: 13 20 Content-Type: text/plain 16 21 }}} 17 Otherwise, everthing will out of control If I have a Chinse character in the filename. 18 Wrong: 22 23 Very strange header "Content-Disposition", isn't it? 24 I guess there is an unexpected code path in the Django lib file "response.py". 25 I tracked it, and found the code running into an exception statement, line 125, file "response.py" 26 19 27 {{{ 20 >>> response['Content-Disposition'] = 'attachment; filename="中中中中中foo.xls"' 28 except UnicodeError as e: 29 if mime_encode: 30 print(value) 31 value = Header(value, 'utf-8', maxlinelen=sys.maxsize).encode() 32 print(value) 21 33 }}} 22 Correct: 34 The output of these two print statement are: 35 23 36 {{{ 24 >>> response['Content-Disposition'] = 'attachment; filename=中中中中中foo.xls'.encode('utf-8') 37 attachment; filename="中中foo.xls" 38 =?utf-8?b?YXR0YWNobWVudDsgZmlsZW5hbWU9IuS4reS4rWZvby54bHMi?= 25 39 }}} 26 Can we accept this ticket and do a minor improvement? Then we would happily only handle str in Django other than str and bytes together. 40 41 27 42 Thanks. 28 29 Yong Li