Opened 8 years ago

Closed 4 years ago

#3496 closed (fixed)

WSGI handler dies on a form containing only empty checkboxes

Reported by: mikko@… Owned by: nobody
Component: Core (Other) Version: master
Severity: Keywords: wsgi checkbox post request zero
Cc: Triage Stage: Unreviewed
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: UI/UX:

Description

WSGI handler hangs when submitting a form containing only empty checkboxes. Because checkboxes are unchecked, HTTP POST request has zero content-length in this case. This zero is passed forward to a socket read function which never returns.

I have attached a patch which modifies WSGI to propeply deal with this case.

Cheers,
Mikko Ohtamaa
Oulu, Finland

Attachments (2)

wsgi_patch.diff (1.2 KB) - added by mikko@… 8 years ago.
Fixes empty checkbox bug in WSGI handler
wsgi_patch2.diff (1.2 KB) - added by cephelo@… 8 years ago.
Patch that applies cleanly against trunk

Download all attachments as: .zip

Change History (10)

Changed 8 years ago by mikko@…

Fixes empty checkbox bug in WSGI handler

Changed 8 years ago by cephelo@…

Patch that applies cleanly against trunk

comment:1 Changed 8 years ago by cephelo@…

  • Needs documentation unset
  • Needs tests unset
  • Patch needs improvement unset

See also: #3089 (has no patch).

comment:2 Changed 8 years ago by SmileyChris

Is this in any way related to #2924 (supposedly fixed in [4144])?

comment:3 Changed 8 years ago by Michael Radziej <mir@…>

#3089 marked as duplicate of this ticket (tentatively ;-)

comment:4 Changed 8 years ago by anonymous

  • Owner changed from nobody to anonymous
  • Status changed from new to assigned

comment:5 Changed 8 years ago by anonymous

  • Owner changed from anonymous to nobody
  • Status changed from assigned to new

comment:6 Changed 7 years ago by mtredinnick

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

(In [6592]) Fixed #3496 -- Handle the case of missing (and hence '0') Content-Length header
in a POST to the wsgi handler. Based on a patch from Mikko Ohtamaa.

comment:7 Changed 4 years ago by jvdongen

  • Resolution fixed deleted
  • Status changed from closed to reopened

I'm currently running into this issue again, using Django trunk, revision 15821. Replication is simple: submit an empty form (all checkboxes unchecked) and try to access request.POST in view. The wsgi handler dies as soon as you try to access request.POST. Putting a single hidden form input on the form solves the issue.

The source code of the wsgi handler seems to be significantly modified since this patch was created and applied - so far I've been unable to pin down the exact location where the bug originates, as Django does not emit any debugging information in this case (I've tried adding extra debug logging at various places early in the request processing chain - but they don't output anything).

My wsgi container (uwsgi) does output the following it its logging (with harakiri mode disabled - otherwise the django process is simply killed after 10 seconds), but I suspect that this is just the end game of a situation where Django's trying to read something that isn't there:

SIGPIPE: writing to a closed pipe/socket/fd (probably the client disconnected) on request /XXXX/ !!!
writev(): Broken pipe [wsgi_headers.c line 168]
SIGPIPE: writing to a closed pipe/socket/fd (probably the client disconnected) on request /XXXX/ !!!
write(): Broken pipe [pyutils.c line 101]

comment:8 Changed 4 years ago by anonymous

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

After 3 years this is surely a somewhat different problem than the original so it deserves its own ticket. Also FWIW I cannot recreate any problem with the wsgi handler and a content length of 0 (using Apache/mod_wsgi, so the issue may be related to uwsgi specifically). Using this view:

from django import forms
from django.shortcuts import render
from django.views.decorators.csrf import csrf_exempt

class YNForm(forms.Form):
    yes_or_no = forms.BooleanField(required=False)

@csrf_exempt
def testme(request):
    if request.method == 'POST':
        ynform = YNForm(request.POST)
        msg = 'Posted successfully, content length is %s, request.POST is %r' % \
            (request.META['CONTENT_LENGTH'], request.POST)
    else:
        ynform = YNForm()
        msg = 'Blank form retrieved via %s' % request.method
    return render(request, 'ynform.html', {'msg': msg, 'form': ynform})

and this template:

<html xmlns="http://www.w3.org/1999/xhtml" lang="en-us" xml:lang="en-us" >
<head>
<title>Yes or No?</title>
</head>
<body>
<p>{{ msg }}</p>
<form name="myform" method='post' action='.'>
{{ form.as_p }}
<p><a href="javascript: document.myform.submit();">Submit</a></p>
</form>
</body>
</html>

I when I click the link to post the form without having the checkbox checked the message I get back is:

Posted successfully, content length is 0, request.POST is <QueryDict: {}>

To investigate whatever issue you are seeing, please open a new ticket with more specifics (as above) of what exactly your view/submitting HTML looks like.

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