5

I am having a django form to get the username,password. when the user posts data, i see that the post dictionary contains the following(traceback), Traceback (most recent call last):

File "/usr/lib/python2.4/site-packages/django/core/handlers/base.py", line 111, in get_response
response = callback(request, *callback_args, **callback_kwargs)

File "/usr/lib/python2.4/site-packages/django/views/decorators/csrf.py", line 39, in wrapped_view
resp = view_func(*args, **kwargs)

File "/usr/lib/python2.4/site-packages/django/views/decorators/csrf.py", line 52, in wrapped_view
return view_func(*args, **kwargs)

File "/public/gdp/trunk/src/ukl/lis/process/utils/error_handler.py", line 17, in __call__
return self.function(*args, **kwargs)

File "/usr/lib/python2.4/site-packages/django/views/decorators/cache.py", line 66, in _cache_controlled
response = viewfunc(request, *args, **kw)

File "/public/gdp/trunk/src/ukl/lis/process/authentication/views.py", line 530, in process_login
form = loginForm(request.POST)

File "/usr/lib/python2.4/site-packages/django/core/handlers/modpython.py", line 101, in _get_post
self._load_post_and_files()

File "/usr/lib/python2.4/site-packages/django/http/__init__.py", line 270, in _load_post_and_files
if self.META.get('CONTENT_TYPE', '').startswith('multipart'):

AttributeError: 'NoneType' object has no attribute 'startswith'

<ModPythonRequest
path:/login.html,
GET:<QueryDict: {}>,
POST:<could not parse>,
COOKIES:{'__utma': '115966011.1553834174.1346687405.1346687405.1346687045.1',
'__utmb': '115962011.4.10.1346687045',},
META:{'AUTH_TYPE': None,
'CONTENT_LENGTH': '85',
'CONTENT_TYPE': None,
'GATEWAY_INTERFACE': 'CGI/1.1',
'HTTP_ACCEPT': 'text/html, application/xhtml+xml, */*',
'HTTP_ACCEPT_ENCODING': 'gzip, deflate',
'HTTP_ACCEPT_LANGUAGE': 'en-GB',
'HTTP_CACHE_CONTROL': 'no-cache',
'HTTP_CONNECTION': 'Keep-Alive',
'HTTP_CONTENT_LENGTH': '85',
'HTTP_COOKIE': 'flavor=desktop; sessionid=4a2f2ab6f61315493f3038338524cfc7;    tmsid=e7c921af-9cae-4f58-8825-13f9bc2ba95f; uniqid=6f69c607-6aca-4e92-a112-b83691805155; __utma=115962011.1553833174.1346687005.1346687005.1346687005.1; __utmb=115962011.4.10.1346687005; __utmz=115962011.1346687005.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none); __utmc=115962011',
'HTTP_HOST': 'example.com',
'HTTP_REFERER': 'http://example.com/',
'HTTP_USER_AGENT': 'Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64;  Trident/5.0)',
'PATH_INFO': u'/login.html',
'PATH_TRANSLATED': None,
'QUERY_STRING': None,
'REMOTE_ADDR': 'xx.xx.xx.xx',
'REMOTE_HOST': None,
'REMOTE_IDENT': None,
'REMOTE_USER': None,
'REQUEST_METHOD': 'POST',
'SCRIPT_NAME': '',
'SERVER_NAME': 'example.com',
'SERVER_PORT': 443,
'SERVER_PROTOCOL': 'HTTP/1.1',
'SERVER_SOFTWARE': 'mod_python'}>

Why is the post dict has "<could not parse>" and why is CONTENT_TYPE None? This prevents me from crossing the login page.

This is my form,

   <form method="POST">{% csrf_token %}
       <tr>
     <td><label>Email Id</label></td>
     <td>{{form.username}}</td>
     <td><label>Password</label></td>
     <td>{{form.password}}</td>
   </tr>
    <input type="submit" name="btn_login" id="btn_login" class="btn_login" value="Login" /></td>

  </form>

Forms.py:

class loginForm(ModelForm):
    username = forms.CharField(max_length=50)
    password = forms.CharField(max_length=50, widget=forms.PasswordInput(attrs=  {"autocomplete":"off"}))

    class Meta:
        model = User

View:

def login(request):
 if request.method == "POST":
   log.inof(request)
 else:
  request.session.set_test_cookie()
  form = loginForm()
  return render_to_response('login.html', {'form':form},context_instance=RequestContext(request))

NOTE: I also found that all requests are coming from only mobile devices especially Blackberry. Seems one more user has the same problem

REF: https://stackoverflow.com/questions/12471661/mod-python-could-not-parse-the-django-post-request-for-blackberry-and-some-andro

Community
  • 1
  • 1
Vivek S
  • 5,384
  • 8
  • 51
  • 72
  • what is your template/html for the form? – Rohan Sep 04 '12 at 06:04
  • show your views.py and forms.py.... – lakshmen Sep 04 '12 at 06:24
  • 2
    Your form is missing a submit button and a [`{% csrf_token %}`](https://docs.djangoproject.com/en/dev/ref/contrib/csrf/#how-to-use-it) tag. Add those, and then check if it still errors out. – Burhan Khalid Sep 04 '12 at 06:27
  • Read this helps : https://docs.djangoproject.com/en/dev/topics/forms/?from=olddocs – lakshmen Sep 04 '12 at 06:31
  • @BurhanKhalid i have just posted a part of the form and missed those things, submit button is in my template – Vivek S Sep 04 '12 at 06:32
  • should it be log.info instead of log.inof? – lakshmen Sep 04 '12 at 07:07
  • yeah, small typo and its just a logger – Vivek S Sep 04 '12 at 07:11
  • `action` attribute of your form is missing. You also did not specify the `method` of the form, like `method=POST` – Mp0int Sep 04 '12 at 08:32
  • @FallenAngel `action` is not required, `method` is there – Alexander Larikov Sep 04 '12 at 08:38
  • Sorry i missed it. How often that error occurs? Always or not? – Mp0int Sep 04 '12 at 08:48
  • not always, and i cant replicate this in my dev servers. it occurs only in production server – Vivek S Sep 04 '12 at 10:41
  • That is not about django, its about your apache server and mod_python. That (http://stackoverflow.com/questions/3823280/ioerror-request-data-read-error) is a far different example but the basics of the problems are the same (i guess). So you may dig apache logs for possible clues. Another possible reason might be usage of `mod_python`, because `mod_python` is quite out of date (not updated for a long time) and django deprecated it already, and will remove it totally in the 1.5 release. – Mp0int Sep 04 '12 at 11:47
  • As an addition to FallenAngel's comment does this work with the dev server i.e. is the error only in apache or not? – Ilian Iliev Sep 13 '12 at 07:34
  • i cant replicate the error in dev server, it occurs only in production – Vivek S Sep 13 '12 at 08:40
  • 1
    Can you add an explicit `enctype="application/x-www-form-urlencoded"` attribute to the form and see what happens? Do you have the same mod_python version on both production and dev server? Are you running SSL on the dev server as well? – Simon Sep 13 '12 at 10:25
  • yes both production and dev have same mod_python version,and ssl is enabled in dev too – Vivek S Sep 13 '12 at 10:36
  • check your middleware classes in the settings(SessionMiddleware and AuthenticationMiddleware ) for more information look into https://docs.djangoproject.com/en/dev/topics/auth/ – user1115370 Sep 14 '12 at 18:40
  • @Simon from the [Blackberry browser dev guide](http://docs.blackberry.com/en/developers/deliverables/1143/browser_devguide.pdf): _**enctype** This attribute is ignored. Form data is encoded with the content type application/x-www-formurlencoded._ – Chris Wesseling Sep 18 '12 at 12:54
  • Thanks all guys,will migrate to wsgi and see if i get the problem – Vivek S Sep 19 '12 at 16:49

4 Answers4

5

Since the error doesn't occur on your development stack, just sometimes on production I doubt it is something in your Django code.

How are you contacting the machine? The requests is going to localhost.. Are you running a browser on your production machine or is there some proxy or load balancer in front of it?

It appears to me that something is mangling your requests before they hit mod_python, be it a proxy or misconfigured ssl.

The symptom is you receive broken requests. The problem could be anywhere from your python app down all OSI layers on your end, up all OSI layers on the clients end. Try to make full picture of all things in between and systematically rule them out.

Your TCP/IP stack seems to work fine, or you would see other requests and services suffer too. So we can rule out everything below the Session Layer. That leaves the Presentation Layer (SSL) and the Application Layer (HTTP).

  1. SSL

    SERVER_PORT is 443, SSL is in play here. The request headers (HTTP_REFERER etc.) contain valid strings, so SSL seems to work fine. But I've seen some weirdly messed up TLS sessions before.

  2. HTTP

    The players at this layer:

    • your Apache httpd
    • any reverse proxies on your end
    • any forward proxies between you and client. Are REMOTE_ADDR all in the same subnet, is there some mobile operator out there with broken proxies?
    • the client user agent. Are all blackberries broken? Try to get your hands on the browser you see failing most.

And at what layer are your loadbalancers operating?

Seems the main problem is a missing Content-Type header on the POST request, and hence a value on the Python representation of the POSTed content that can't be pretty printed using pprint, let alone used by your app.

Disregarding what I found in the Blackberry developer ref: have you tried setting enctype explicitly as Simon suggested? Try varying application/x-www-form-urlencoded and multipart/form-data.

Best of all try to reproduce it yourself. Try making a tcpdump that records such a request. You can analyse a recorded dump with wireshark.

Community
  • 1
  • 1
Chris Wesseling
  • 6,226
  • 2
  • 36
  • 72
  • yeah i have a load balancer, but how does this tampers my request? Also i could find that the user agent of the traceback is always mobile. Does mobile devices have anything to do with it? – Vivek S Sep 18 '12 at 03:58
  • No,i have changed the server name to localhost. my actual server name appears there instead of localhost – Vivek S Sep 18 '12 at 08:36
  • if you want i can post the exact traceback without editing too – Vivek S Sep 18 '12 at 08:36
  • look at this... http://stackoverflow.com/questions/12471661/mod-python-could-not-parse-the-django-post-request-for-blackberry-and-some-andro – Vivek S Sep 18 '12 at 08:58
  • @InternalServerError What does de traceback contain? Does it show the same Exception every time? – Chris Wesseling Sep 19 '12 at 08:31
  • I get the same traceback every time, and i have posted in my question now – Vivek S Sep 19 '12 at 08:35
  • Python 2.4... I thought I was the last one to migrate off of that early this year. Guess there are still people stuck with it.. – Chris Wesseling Sep 19 '12 at 15:12
4

Could you try to deploy with mod_wsgi instead of mod_python? I would start there, its probably not a django error or else everyone would be getting the error and not just the crackberry users. Mod_python is old and I've had many more issues with it that mod_wsgi.

reptilicus
  • 10,290
  • 6
  • 55
  • 79
3

django/core/handlers/wsgi.py seems to put the message there; you could hack the code and put the str(exception) there too.

My guess however is that you did not specify the charset correctly; django assuming UTF-8, and the form is submitting in some completely random charset that python cannot decode, perhaps? Also, you might want to try removing the CSRF middleware for a time and try if it works without it.

3

Maybe Blackberry clients gzip their POST bodies to save bandwidth? Django does not automatically decode gzipped messages (at least in Django 1.3.1). In your view, try decoding the raw POST data:

import zlib
post_data = zlib.decompress(request.raw_post_data, 16+zlib.MAX_WBITS)

Usually, the HTTP_CONTENT_ENCODING HTTP header should be set, but maybe the load balancer strips it away accidentally?

Community
  • 1
  • 1
Simon
  • 12,018
  • 4
  • 34
  • 39
  • My production servers are running under apache, so apache should decode it as i have mentioned gzip enabled – Vivek S Sep 18 '12 at 08:21
  • Can you post a hexdump of what is actually in `request.raw_post_data` (`print request.raw_post_data.encode('hex')`)? Maybe we can find out from there what's going on. – Simon Sep 18 '12 at 10:43