AppEngine dev_appserver - urllib2.urlopen与localhost url的问题

时间:2015-07-02 22:08:35

标签: google-app-engine urllib2 google-app-engine-python

更新

App Engine SDK 1.9.24已于2015年7月20日发布,因此,如果您仍然遇到此问题,您应该只需通过更新即可解决此问题。有关确切问题和解决方案的解释,请参阅下面的+ jpatokal答案。

原始问题

我有一个应用程序,我在本地开发时遇到麻烦并遇到麻烦。

我们有一些共享代码,使用urllib2.urlopen检查我们的应用的auth服务器。当我在本地开发时,我的应用程序上的404被AppEngine请求拒绝了,但是请求从终端获得成功。

我在端口localhost:8000上运行了appengine,在localhost:8001

上运行了auth服务器
import urllib2

url = "http://localhost:8001/api/CheckAuthentication/?__client_id=dev&token=c7jl2y3smhzzqabhxnzrlyq5r5sdyjr8&username=amadison&__signature=6IXnj08bAnKoIBvJQUuBG8O1kBuBCWS8655s3DpBQIE="

try:
  r = urllib2.urlopen(url)
  print(r.geturl())
  print(r.read())
except urllib2.HTTPError as e:
  print("got error: {} - {}".format(e.code, e.reason))

从AppEngine

中产生got error: 404 - Not Found

似乎AppEngine正在将模式,主机和端口添加到我试图点击的URL的PATH部分,因为这是我在auth服务器上看到的:

[02/Jul/2015 16:54:16] "GET http://localhost:8001/api/CheckAuthentication/?__client_id=dev&token=c7jl2y3smhzzqabhxnzrlyq5r5sdyjr8&username=amadison&__signature=6IXnj08bAnKoIBvJQUuBG8O1kBuBCWS8655s3DpBQIE= HTTP/1.1" 404 10146

从请求标题中我们可以看到整个方案,主机和端口作为路径的一部分传递(下面的标题部分):

 'HTTP_HOST': 'localhost:8001',
 'PATH_INFO': u'http://localhost:8001/api/CheckAuthentication/',
 'SERVER_PORT': '8001',
 'SERVER_PROTOCOL': 'HTTP/1.1',

有没有办法让AppEngine Dev服务器在另一个端口上将这个请求劫持到localhost?或者我不是在误解发生了什么?在我们的域名不同的生产中,一切都很好。

提前感谢任何有助于指明我正确方向的协助。

2 个答案:

答案 0 :(得分:4)

这是urlfetch_stub实现引入的烦人问题。我不确定gcloud sdk版本引入了什么。

我已经通过修补gcloud SDK来解决这个问题 - 直到谷歌。

这意味着这个答案很快就会无关紧要

  1. 查找并打开urlfetch_stub.py,通常可以在~/google-cloud-sdk/platform/google_appengine/google/appengine/api/urlfetch_stub.py找到

  2. 围绕第380行(取决于版本),找到:

  3. full_path = urlparse.urlunsplit((protocol, host, path, query, ''))
    

    并将其替换为:

    full_path = urlparse.urlunsplit(('', '', path, query, ''))
    

    更多信息

    您认为问题是一个损坏的PATH_INFO标题是正确的。在建立连接后传递full_path

    声明

    我可能很容易通过此补丁破坏代理请求。因为我希望谷歌能够修复它,所以我不会太疯狂。

    非常清楚此错误仅与LOCAL应用程序开发相关 - 您不会在生产中看到此错误。

答案 1 :(得分:1)

App Engine SDK 1.9.24已于2015年7月20日发布,因此如果您仍然遇到此问题,您应该只需更新即可解决此问题。

以下是对所发生事件的简要说明。在1.9.21之前,SDK正在使用相对路径格式化URL提取请求,如下所示:

GET /test/ HTTP/1.1
Host: 127.0.0.1:5000

在1.9.22中,为了更好地支持代理,这改为绝对路径:

GET http://127.0.0.1:5000/test/ HTTP/1.1
Host: 127.0.0.1:5000

根据HTTP / 1.1规范,这两种格式都是完全合法的,请参阅RFC 2616, section 5.1.2。然而,虽然该规范可以追溯到1999年,但显然有很多HTTP请求处理程序没有正确地解析绝对形式,而只是天真地将路径和主机连接在一起。

因此,为了兼容性,先前的行为已经恢复。 (除非您使用代理,否则RFC需要绝对路径。)