【发布时间】:2015-06-11 06:15:55
【问题描述】:
我有一个每日 cron 来处理我的应用程序中的一些重复事件,我不时注意到日志中弹出一个奇怪的错误。除其他外,cron 对一些代码进行验证,它使用在同一服务器上运行的 webapp,因此验证请求是通过带有一些数据的 POST 请求发出的。
url = 'https://example.com/validate/'
payload = {'pin': pin, 'sku': sku, 'phone': phone, 'AR': True}
validation_post = requests.post(url, data=payload)
所以,这发出了实际的请求,我记录了响应。有时,最近多达 50% 的请求,响应包含来自 nginx 的以下消息:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
<title>405 Method Not Allowed</title>
<h1>Method Not Allowed</h1>
<p>The method GET is not allowed for the requested URL.</p>
因此,实际请求是使用 GET 方法发出的,而不是代码中指示的 POST。在 nginx access.log 我可以看到那个条目:
123.123.123.123 - - [18/Feb/2015:12:26:50 -0500] "GET /validate/ HTTP/1.1" 405 182 "-" "python-requests/2.2.1 CPython/2.7.6 Linux/3.13.0-37-generic"
应用程序的 uwsgi 日志显示类似的内容:
[pid: 6888|app: 0|req: 1589/58763] 123.123.123.123 () {40 vars in 613 bytes} [Mon Apr 6 11:42:41 2015] GET /validate/ => generated 182 bytes in 1 msecs (HTTP/1.1 405) 4 headers in 234 bytes (1 switches on core 0)
所以,一切都表明实际请求不是使用 POST 发出的。处理此代码的应用程序路由很简单,摘录如下: @app.route('/validate/', methods=['POST']) @login_required
def validate():
if isinstance(current_user.user, Sales):
try:
#do the stuff here
except Exception, e:
app.logger.exception(str(e))
return 0
abort(403)
应用程序路由可能失败,try 块内有一些 returns,但即使这些失败或有异常,也没有什么可以引发此块中的 405 错误代码,只有 403 很少发生,因为我从 cron 手动构建和登录用户。
我发现了类似的东西here,但是有一个从 HTTP 到 HTTPS 版本的重定向,我在服务器中也有该重定向,但是发出请求的 URL 包含 HTTPS它,所以我怀疑这是原因。
我运行它的堆栈是uwsgi+nginx+flask。谁能看到可能导致这种情况的原因?重复一遍,它并不总是发生,所以有时它按预期工作,有时不是。我最近从apache 和mod_wsgi 迁移到这个新堆栈,从那时起我开始遇到这个错误;不记得曾经在apache 环境中看到过它。
谢谢!
【问题讨论】:
标签: python nginx python-requests uwsgi http-status-code-405