django request.POST包含<could not =“”parse =“”> </could>

时间:2012-09-04 06:02:52

标签: python django apache django-views mod-python

我有一个django表单来获取用户名,密码。当用户发布数据时,我看到帖子字典包含以下内容(traceback), 回溯(最近一次调用最后一次):

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'}>

为什么帖子字典有“&lt;无法解析&gt;”为什么CONTENT_TYPE没有?这可以防止我越过登录页面。

这是我的表格,

   <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

查看:

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))

注意:我还发现所有请求都来自移动设备,尤其是Blackberry。似乎还有一个用户遇到了同样的问题

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

4 个答案:

答案 0 :(得分:5)

由于开发堆栈上没有出现错误,只有有时在生产中我怀疑它是你的Django代码中的东西。

您是如何联系机器的?请求将转到localhost ..您是在生产计算机上运行浏览器还是在它前面有一些代理或负载均衡器?

在我看来,在他们点击mod_python之前,某些东西会破坏你的请求,无论是代理还是配置错误的ssl。

症状是您收到了破碎的请求。问题可能在于您的python应用程序向下到您端的所有OSI层,以及客户端上的所有OSI层。试着全面了解其间的所有事情,并系统地排除它们。

您的TCP / IP堆栈似乎工作正常,或者您会看到其他请求和服务也受到影响。因此,我们可以排除会话层下的所有内容。这留下了表示层(SSL)和应用层(HTTP)。

  1. SSL

    SERVER_PORT是443,SSL在这里播放。请求标头(HTTP_REFERER等)包含有效的字符串,因此SSL似乎工作正常。但我之前看到过一些奇怪的混乱TLS会话。

  2. HTTP

    这一层的球员:

    • 你的Apache httpd
    • 您最后的任何反向代理
    • 您和客户之间的任何转发代理。 REMOTE_ADDR是否都在同一个子网中,是否有一些移动运营商在那里有破损的代理?
    • 客户端用户代理。黑莓都破了吗?尝试使用您认为最失败的浏览器。
  3. 您的负载均衡器在哪一层运行?

    似乎主要问题是POST请求中缺少Content-Type标头,因此POST文件内容的Python表示值无法使用pprint进行打印,更不用说应用程序了。

    忽略Blackberry开发人员参考中的I found:您是否尝试将enctype明确设置为Simon suggested?尝试改变application/x-www-form-urlencodedmultipart/form-data

    最重要的是尝试自己重现它。尝试制作记录此类请求的tcpdump。您可以使用wireshark分析记录的转储。

答案 1 :(得分:4)

您可以尝试使用mod_wsgi而不是mod_python进行部署吗?我会从那里开始,它可能不是django错误,否则每个人都会得到错误而不仅仅是crackberry用户。 Mod_python很老了,我还有很多mod_wsgi的问题。

答案 2 :(得分:3)

django / core / handlers / wsgi.py似乎把信息放在那里;你可以破解代码并将str(异常)放在那里。

我的猜测是你没有正确指定字符集; django假设UTF-8,并且表单是在一些完全随机的字符集中提交的,python无法解码,也许?此外,您可能希望尝试删除CSRF中间件一段时间,并尝试在没有它的情况下工作。

答案 3 :(得分:3)

也许Blackberry客户端gzip他们的POST机构以节省带宽? Django不会自动解码gzip压缩消息(至少在Django 1.3.1中)。在您看来,请尝试decoding the raw POST data

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

通常情况下,应设置HTTP_CONTENT_ENCODING HTTP标头,但负载平衡器可能会意外剥离它吗?