5

ユーザー名、パスワードを取得するためのdjangoフォームがあります。ユーザーがデータを投稿すると、投稿辞書に次の (トレースバック)、トレースバック (最新の呼び出しが最後) が含まれていることがわかります。

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

post dict に「<could not parse>」が含まれているのはなぜですか? CONTENT_TYPE None はなぜですか? これにより、ログインページを横切ることができなくなります。

これが私のフォーム、

   <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 からのみ送信されていることもわかりました。もう1人のユーザーが同じ問題を抱えているようです

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

4

4 に答える 4

5

エラーは開発スタックでは発生しないため、本番環境では時々、Djangoコードに何かがあるとは思えません。

どのようにマシンに連絡していますか?リクエストはローカルホストに送信されます。本番マシンでブラウザを実行していますか、それともその前にプロキシまたはロードバランサがありますか?

プロキシであれ、誤って構成されたsslであれ、mod_pythonに到達する前に、何かがリクエストを操作しているように見えます。

症状は、壊れたリクエストを受け取ることです。問題は、Pythonアプリから、クライアント側のすべてのOSIレイヤーまで、クライアント側のすべてのOSIレイヤーまでのどこかにある可能性があります。間にあるすべてのものの全体像を把握し、体系的にそれらを除外するようにしてください。

TCP / IPスタックは正常に機能しているようです。そうでない場合は、他のリクエストやサービスも影響を受けます。したがって、セッション層の下にあるすべてのものを除外できます。これにより、プレゼンテーション層(SSL)とアプリケーション層(HTTP)が残ります。

  1. SSL

    SERVER_PORTは443で、SSLがここで機能しています。リクエストヘッダー(HTTP_REFERERなど)には有効な文字列が含まれているため、SSLは正常に機能しているようです。しかし、私は以前にいくつかの奇妙な混乱したTLSセッションを見たことがあります。

  2. HTTP

    このレイヤーのプレイヤー:

    • あなたのApachehttpd
    • あなたの側のリバースプロキシ
    • あなたとクライアントの間のフォワードプロキシ。REMOTE_ADDRはすべて同じサブネット内にありますか、プロキシが壊れているモバイルオペレーターがいますか?
    • クライアントユーザーエージェント。すべてのブラックベリーは壊れていますか?最も失敗していると思われるブラウザを手に入れてみてください。

そして、ロードバランサーはどのレイヤーで動作していますか?

主な問題は、POSTリクエストにContent-Typeヘッダーがないことであると思われます。したがって、アプリで使用されることは言うまでもなく、pprintを使用してきれいに印刷できないPOSTコンテンツのPython表現の値です。

私がBlackberry開発者の参考文献で見つけたものを無視して: Simonが提案したように明示的にenctypeを設定しようとしましたか?変化application/x-www-form-urlencodedさせてみてくださいmultipart/form-data

何よりも、自分で再現してみてください。そのような要求を記録するtcpdumpを作成してみてください。記録されたダンプはwiresharkで分析できます。

于 2012-09-17T16:07:37.117 に答える
4

mod_python の代わりに mod_wsgi でデプロイしてみてはいかがでしょうか? 私はそこから始めますが、おそらくdjangoエラーではないか、そうでなければ、クラックベリーユーザーだけでなく、誰もがエラーを受け取ることになります. mod_python は古く、mod_wsgi 以外にも多くの問題がありました。

于 2012-09-18T18:26:44.993 に答える
3

Blackberry クライアントは帯域幅を節約するために POST 本文を gzip 圧縮するのでしょうか? Django は gzip されたメッセージを自動的にデコードしません (少なくとも Django 1.3.1 では)。ビューで、生の POST データをデコードしてみてください:

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

通常はHTTP_CONTENT_ENCODINGHTTP ヘッダーを設定する必要がありますが、ロード バランサーによって誤って削除されてしまうのではないでしょうか?

于 2012-09-18T08:02:20.430 に答える
3

django/core/handlers/wsgi.py にメッセージが表示されているようです。コードをハックして、そこに str(exception) を入れることもできます。

ただし、文字セットを正しく指定していないと思います。djangoはUTF-8を想定しており、フォームはPythonがデコードできない完全にランダムな文字セットで送信されていますか? また、しばらくの間 CSRF ミドルウェアを削除して、それがなくても機能するかどうかを試してみてください。

于 2012-09-13T11:56:32.397 に答える