python-requests进行GET而不是POST请求

时间:2015-04-06 19:29:39

标签: python nginx python-requests uwsgi http-status-code-405

我有一个每日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(&#39; / validate /&#39;,methods = [&#39; POST&#39;]) @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)

应用程序路由可能会失败,returns块中有一些try,但即使这些失败或有一个expcetion,也没有什么可以提升405这个块中的错误代码,只有403这个很少发生,因为我构建并从cron手动登录用户。

我发现了类似的事情here,但是从那里开始有一个从HTTP到HTTPS版本的重定向,我也有重定向存在于服务器中,但是请求的URL具有其中有HTTPS,所以我怀疑这是原因。

我正在运行的堆栈是uwsgi + nginx + flask。谁能看到可能导致这种情况的原因?重复一遍,它不会一直发生,所以有时它按预期工作,有时不工作。我最近从apachemod_wsgi迁移到了这个新堆栈,从那时起我开始意识到这个错误;我无法在apache环境中看到它。

谢谢!

1 个答案:

答案 0 :(得分:3)

我们唯一一次将POST请求更改为GET是我们处理重定向的时间。根据重定向代码,我们将更改请求方法。如果您想确保我们不遵循重定向,您需要通过allow_redirects=False。也就是说,您需要弄清楚您的应用程序为何会生成重定向(包括重定向到HTTP或其他域,或使用特定的状态代码)。