Google App Engine - 在开发服务器

时间:2018-03-21 15:02:21

标签: python sockets google-app-engine proxy tunneling

免责声明:这不是重复的!

我正在使用请求库,猴子在GAE标准环境下修补,除了我在请求调用中添加额外proxy参数的时候,一切都运行良好。此代理事项意味着隧道和套接字操作,默认情况下由开发和部署环境的标准配置禁用:

NotImplementedError: HTTP CONNECT Tunnelling is not supported https://pastebin.com/YDsG9we7

很好,所以我们需要在GAE平台下启用真正的套接字支持,因此添加:

env_variables: GAE_USE_SOCKETS_HTTPLIB : "True"

即使没有处理请求toolbelt monkey补丁(根本不使用urlfetch),我们也会获得权限拒绝:https://pastebin.com/ifBFKi3K

这通常发生在沙箱认为您正在访问禁用的服务器位置或端口时,但代理功能完全正常并且猜测是什么,我已经测试了相同的代码(没有任何代码)由于开发或部署服务器作为当前环境而添加/删除了功能)并且通过使请求完全成功(如果我们在没有启用httplib套接字的情况下尝试,它在部署时正常工作,没有任何Permission denied错误)在这两种情况下我们仍然会得到Tunnelling is not supported错误,这是预期的行为。)

现在,我已经在部署上获得了一个可行的解决方案(这是它真正重要的),但这对我来说还不够,我只想通过我的开发服务器和环境下的代理来测试这些请求,所以我试图做的是以下几点:

  • 让我们通过应用这些来导入我们自己的标准套接字库:"ImportError: No module named _ssl" with dev_appserver.py from Google App Engine
    • 无法修补sandbox.py文件的白名单_sockets_ssl等等,没问题,我已经硬盘直接在磁盘上修补原始文件
    • 使用标准的pythonic替换内存中的默认套接字,httplib导入等
    • 问题ValueError: select only supported on socket objects. https://pastebin.com/gHFM6QiF;由于标准的sockets导入,但由于GAE自己的select(并且从解释器的内存中删除select)只会导致更多因为预期的套接字对象与预期的套接字对象不同,所以预计会发生这种情况。问题或根本不工作),所以我想用标准的pythonic替换select模块(内置),我该怎么做?

...没关系

有没有什么方法可以让这场噩梦结束并仍在使用标准环境?如果它在没有任何补丁的情况下在部署服务器上运行,为什么不能同时使用dev_appserver工具呢?

我只是不想再做补丁了,我只是想通过使用完全相同的代码逻辑来解决未在远程部署服务器下引发的Permission denied错误,无论我们是否使用请求,urlfetch,httplib,套接字等(只是代理所需的隧道事物)。

1 个答案:

答案 0 :(得分:2)

进一步深入研究这个问题,似乎是在这个文件中:

platform / google_appengine / google / appengine / api / remote_socket / _remote_socket_stub.py 其中有一些模拟的套接字对(level,option)在常量_MOCK_SOCKET_OPTIONS中找不到( 1,3对和我的意思是下面的级别和选项的产品之一(我想星号是所需的值):

级别(值:1):

  • SOCKET_TCP_NODELAY
  • SOCKET_IP_TOS
  • SOCKET_SOL_SOCKET *
  • SOCKET_SO_DEBUG

选项(值:3):

  • SOCKET_IP_HDRINCL
  • SOCKET_SO_TYPE *
  • SOCKET_TCP_CORK

因此,通过设置代理,我想我要求 SOL_SOCKET:SO_TYPE 组,但是模拟的值是什么,这是一个十六进制二进制相关字符串" 00000000" (对于keepalive)和" 01000000" (reuseaddr):https://github.com/GoogleCloudPlatform/python-compat-runtime/blob/master/appengine-compat/exported_appengine_sdk/google/appengine/api/remote_socket/_remote_socket_stub.py#L97

在哪里可以找到(1,3)缺失对的值?

稍后编辑:

我添加了" SOL_SOCKET:SO_TYPE = 80000000"现在它在ssl模块上打破了(为了支持https,需要启用它;不需要修补,只需在app.yaml中启用它):https://pastebin.com/9KQjdEgL 通过识别 128 的套接字类型,我猜这可能是以下常量之一:

  • socket.MSG_EOR
  • socket.SOMAXCONN
  • socket.TIPC_SRC_DROPPABLE

后来......

所以我意识到128值实际上是我上面的小端模拟值,因此我将组改为:&#34; SOL_SOCKET:SO_TYPE = 01000000&#34;并且这可以识别socket.SOCK_STREAM套接字类型,它实际上只适用于此检查,但是再次崩溃,因为ssl不理解GAE的自定义套接字对象:{{ 3}}(<google.appengine.api.remote_socket._remote_socket.socket object at 0x7f0cd037f690>)。尝试使用和不使用requests猴子补丁来尝试此操作。

我的结论

GAE自定义socket无法完全使用SSL(隧道传输),而Python标准socket无法使用GAE(我猜不到补丁){{1关于dev_appserver沙箱的模块。

解决方案:将远程部署的相同行为带入本地开发环境。