Code

Opened 6 years ago

Closed 6 years ago

#9014 closed (fixed)

django admin MultiPartParserError in google chrome

Reported by: aliixx Owned by: nobody
Component: Uncategorized Version: 1.0
Severity: Keywords:
Cc: Triage Stage: Accepted
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: UI/UX:

Description (last modified by kmtracey)

Following exception gets thrown in google chrome when you either save and continue editing or save and add another for any item in the django admin.
tested in Firefox 3 and IE 8 beta and i cannot replicate the error. Maybe its an issue with the way Chrome handles multipart form posts.

Environment:

Request Method: GET
Request URL: http://....
Django Version: 1.0-final-SVN-unknown
Python Version: 2.5.2
Installed Applications:
['django.contrib.auth',
 'django.contrib.contenttypes',
 'django.contrib.sessions',
 'django.contrib.sites',
 'django.contrib.admin',
 'django.contrib.admindocs',
 'django.contrib.flatpages',
 'bbs.clients',
 'bbs.channels',
 'bbs.advertisers']
Installed Middleware:
('django.middleware.common.CommonMiddleware',
 'django.contrib.sessions.middleware.SessionMiddleware',
 'django.contrib.auth.middleware.AuthenticationMiddleware',
 'django.middleware.doc.XViewMiddleware',
 'django.contrib.flatpages.middleware.FlatpageFallbackMiddleware')


Traceback:
File "C:\Python25\Lib\site-packages\django\core\handlers\base.py" in get_response
  86.                 response = callback(request, *callback_args, **callback_kwargs)
File "C:\Python25\Lib\site-packages\django\contrib\admin\sites.py" in root
  158.                 return self.model_page(request, *url.split('/', 2))
File "C:\Python25\lib\site-packages\django\views\decorators\cache.py" in _wrapped_view_func
  44.         response = view_func(request, *args, **kwargs)
File "C:\Python25\Lib\site-packages\django\contrib\admin\sites.py" in model_page
  177.         return admin_obj(request, rest_of_url)
File "C:\Python25\Lib\site-packages\django\contrib\auth\admin.py" in __call__
  42.         return super(UserAdmin, self).__call__(request, url)
File "C:\Python25\Lib\site-packages\django\contrib\admin\options.py" in __call__
  197.             return self.change_view(request, unquote(url))
File "C:\Python25\Lib\site-packages\django\db\transaction.py" in _commit_on_success
  238.                 res = func(*args, **kw)
File "C:\Python25\Lib\site-packages\django\contrib\admin\options.py" in change_view
  570.         if request.POST and request.POST.has_key("_saveasnew"):
File "C:\Python25\Lib\site-packages\django\core\handlers\modpython.py" in _get_post
  107.             self._load_post_and_files()
File "C:\Python25\Lib\site-packages\django\core\handlers\modpython.py" in _load_post_and_files
  81.                 self._post, self._files = self.parse_file_upload(self.META, self._req)
File "C:\Python25\Lib\site-packages\django\http\__init__.py" in parse_file_upload
  123.         parser = MultiPartParser(META, post_data, self.upload_handlers, self.encoding)
File "C:\Python25\Lib\site-packages\django\http\multipartparser.py" in __init__
  82.             raise MultiPartParserError("Invalid content length: %r" % content_length)

Exception Type: MultiPartParserError at /admin/auth/user/2/
Exception Value: Invalid content length: 0

Attachments (0)

Change History (8)

comment:1 Changed 6 years ago by kmtracey

  • Description modified (diff)
  • Needs documentation unset
  • Needs tests unset
  • Patch needs improvement unset

[Fixed formatting.]

I cannot recreate this, using either the original Chrome I downloaded a few days ago nor the update available today (0.2.149.29). Do you really get this saving anything in admin? I tried users, since that is what you show in your traceback, and a few other models of my own (some with inlines and some without), but in all cases it just works.

comment:2 Changed 6 years ago by kmtracey

I am also puzzled by this part of the debug info:

Environment:

Request Method: GET
Request URL: http://....

First, traceback shows we are going down the path of handling a POST, not a GET. Second, what happened to the URL?

comment:3 Changed 6 years ago by aaron

I've run into the same error but on one of the forms on our own site. It only seems to happen with apache and mod_python, not the django test server.

comment:4 Changed 6 years ago by aaron

Ok, it seems that the issue is related to the way chrome handles 302 redirect responses from a POST request. Most browsers send a normal get request, but Chrome keeps the Content-Type header it sent with the original POST and sends it again with the GET. The same thing happens with a 303. I'm not sure if this is a bug -- it seems like one.

When you access POST:
File "C:\Python25\Lib\site-packages\django\contrib\admin\options.py" in change_view

  1. if request.POST and request.POST.has_key("_saveasnew"):

Django never actually checks that the request method was POST before it tries to parse it. It only checks that the Content-Type header starts with 'Multipart' and then assumes it is dealing with a POST request, and since the request is actually GET and has no body, it chokes.

I'm not sure what the best way to proceed is here. It seems like it would be pretty simple to add a check for the request method and return an empty QueryDict (or None) for request.POST. Any django pros have an opinion?

comment:5 Changed 6 years ago by aaron

I just noticed that django.core.handlers.wsgi has just such a check for self.method == 'POST'. Not sure why this isn't in django.core.handlers.modpython as well -- looks like some almost-duplicate code in there.

comment:6 Changed 6 years ago by kmtracey

  • Triage Stage changed from Unreviewed to Accepted

Interesting. I wonder what's different with mod_python that we only see this there? Previously I tried to recreate with mod_wsgi and could not, nor with the dev server.

(Obviously the previous was written before the last comment. Accepting since it sounds like this is a case the wsgi handler has already been coded to handled so probably the modpython one should be doing similar.)

comment:7 Changed 6 years ago by mtredinnick

(In [9063]) Changed a slightly suspicious usage of request.POST to request.method == 'POST'.
Refs #9014 (not the root cause of that bug, but discovered whilst people were
diagnosing it).

comment:8 Changed 6 years ago by mtredinnick

  • Resolution set to fixed
  • Status changed from new to closed

(In [9064]) Fixed #9014 -- Check that we really are processing a POST before processing
POST data. Some nice debugging form aaron to track this down.

Add Comment

Modify Ticket

Change Properties
<Author field>
Action
as closed
as The resolution will be set. Next status will be 'closed'
The resolution will be deleted. Next status will be 'new'
Author


E-mail address and user name can be saved in the Preferences.

 
Note: See TracTickets for help on using tickets.