Opened 11 years ago

Closed 10 years ago

#19802 closed Bug (fixed)

HttpResponse.set_cookie doesn't handle unicode data

Reported by: django@… Owned by: QingFeng
Component: HTTP handling Version: 1.5
Severity: Normal Keywords: cookie
Cc: semenov@… Triage Stage: Ready for checkin
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

When calling HttpResponse.set_cookie as below, you get an error from translate saying it doesn't expect two variables. The backtrace is (relevant parts only):

TypeError at /js/utils/cookie/set/
translate() takes exactly one argument (2 given)

...

Traceback:
File "/home/patrick/spng/lib/python2.7/site-packages/django/core/handlers/base.py" in get_response
  111.                         response = callback(request, *callback_args, **callback_kwargs)
File "/home/patrick/spng/src/utils/views.py" in ajax_set_cookie
  210.             response.set_cookie(key, value)
File "/home/patrick/spng/lib/python2.7/site-packages/django/http/__init__.py" in set_cookie
  657.         self.cookies[key] = value
File "/usr/lib/python2.7/Cookie.py" in __setitem__
  592.         self.__set(key, rval, cval)
File "/home/patrick/spng/lib/python2.7/site-packages/django/http/__init__.py" in _BaseCookie__set
  103.                     M.set(key, real_value, coded_value)
File "/usr/lib/python2.7/Cookie.py" in set
  459.         if "" != translate(key, idmap, LegalChars):
File "/usr/lib/python2.7/string.py" in translate
  493.         return s.translate(table, deletions)

Exception Type: TypeError at /js/utils/cookie/set/
Exception Value: translate() takes exactly one argument (2 given)

This is happening under Django 1.4.2 and Python 2.7.3 (both latest from the Ubuntu 12.10 repository). The code used to trigger this bug is:

from django.http import HttpResponse

def view(request):
    response = HttpResponse()
    response.set_cookie(u'unicode_string', 'does not work!')
    return response


Change History (10)

comment:1 by Claude Paroz, 11 years ago

Component: Core (Other)HTTP handling
Resolution: worksforme
Status: newclosed

Django 1.5 should support unicode cookie keys. On 1.4, you can workaround this by encoding the key (e.g. u'unicode_string'.encode('utf-8')).

comment:2 by Ilya Semenov, 10 years ago

Cc: semenov@… added
Resolution: worksforme
Status: closednew
Type: UncategorizedBug
Version: 1.41.5

This is still broken in 1.5. To reproduce the bug, use the experiment file below:

# Put this in a file called experiment19802.py and run it with:
# django-admin.py runserver --settings=experiment19802

from django.conf.urls import patterns, url
from django.http import HttpResponse

DEBUG = True
ROOT_URLCONF = 'experiment19802'
SECRET_KEY = 'whatever'

def view(request):
        res = HttpResponse('OK')
        res.set_cookie('test', request.GET.get('cookie', ''))
        return res

urlpatterns = patterns('',
    url(r'.*', view),
)

and try to open: http://localhost:8000/?cookie=M%C3%BCller

It will raise the exception:

Traceback:
File "/Users/semenov/work/xxx/venv/lib/python2.7/site-packages/django/core/handlers/base.py" in get_response
  115.                         response = callback(request, *callback_args, **callback_kwargs)
File "/Users/semenov/tmp/19802/experiment19802.py" in view
  13. 	res.set_cookie('test', request.GET.get('cookie', ''))
File "/Users/semenov/work/xxx/venv/lib/python2.7/site-packages/django/http/response.py" in set_cookie
  157.         self.cookies[key] = value
File "/usr/local/Cellar/python/2.7.6/Frameworks/Python.framework/Versions/2.7/lib/python2.7/Cookie.py" in __setitem__
  591.         rval, cval = self.value_encode(value)
File "/usr/local/Cellar/python/2.7.6/Frameworks/Python.framework/Versions/2.7/lib/python2.7/Cookie.py" in value_encode
  680.         strval = str(val)

Exception Type: UnicodeEncodeError at /
Exception Value: 'ascii' codec can't encode character u'\xfc' in position 1: ordinal not in range(128)

comment:3 by Sasha Romijn, 10 years ago

Triage Stage: UnreviewedAccepted

I can reproduce this issue on current master.

comment:4 by Sasha Romijn, 10 years ago

However, it is only reproducible on Python 2 - it works fine for me in Python 3.3. So, it seems the issue is that Python 2 cookielib coerces str() on the cookie contents. Not sure what the proper solution would be here.

comment:5 by anonymous, 10 years ago

Has patch: set
Needs tests: set
Owner: changed from nobody to anonymous
Status: newassigned

comment:6 by QingFeng, 10 years ago

Owner: changed from anonymous to QingFeng

comment:7 by QingFeng, 10 years ago

@erikr @claudep pls review, thanks :beer:

comment:8 by Tim Graham, 10 years ago

Needs tests: unset
Patch needs improvement: set

I left comments for improvement on PR. Please uncheck "Patch needs improvement" when you update it, thanks.

comment:9 by Claude Paroz, 10 years ago

Patch needs improvement: unset
Triage Stage: AcceptedReady for checkin

For the committer, please just add in the commit message that this is a Python 2 only issue.

comment:10 by Tim Graham <timograham@…>, 10 years ago

Resolution: fixed
Status: assignedclosed

In 0d23450e81dc355c354a873fe187687e4aaa4886:

Fixed #19802 -- Fixed HttpResponse.set_cookie() with unicode data on Python 2.

Thanks django at patrickbregman.eu for the report.

Note: See TracTickets for help on using tickets.
Back to Top