django request.POST contains <could not parse>

社会主义新天地 提交于 2019-12-05 10:54:05
Chris Wesseling

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.

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.

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.

Simon

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?

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!