App Engine socket invalid argument

后端 未结 1 949
[愿得一人]
[愿得一人] 2021-01-16 06:42

I am using PyAPNS to connect to APNs from Python. When running as a stand alone script, all is working fine and push messages get delivered. When running in the Google App E

1条回答
  •  一生所求
    2021-01-16 06:50

    Not sure if this is still useful or if you found answers elsewhere.

    I had a pretty similar issue trying to use the requests library in pretty standard app engine code.

    tl;dr - App Engine patches/provides a sandboxed socket. The ssl module snapshots objects from socket's namespace on its own import. If socket (and _socket) is not the correct version when ssl is imported, ssl will end up with GAE-patch/sandbox based values for SOL_SOCKET and SO_TYPE (probably incorrect), rather than what should have come from a base system installation. If you make sure your copy of socket (and _socket) is correct, ssl will work.

    I filed a support ticket with Google and got push-back to implement this.

    It's not actually that trivial for me to just swap out the physical socket.py implementation, so I went the route of this solution instead.

    Which got me most of the way there, but the issue still cropped up because of SSL.

    I have tested something practically identical to the below code to get SSL working with raw sockets (rather than URLFetch) when making HTTP requests in an App Engine development sandbox (i.e dev_appserver.py):

    import os
    
    def _patch_ssl_support():
    
        # Only patch SSL support if it's local dev.
        if not os.environ.get('SERVER_SOFTWARE', '').startswith('Development'):
            return
    
        import imp
        import inspect
        from google.appengine.tools.devappserver2.python import sandbox
    
        # Allow the sandbox to read _ssl and _socket.
        sandbox._WHITE_LIST_C_MODULES += ['_socket', '_ssl']
    
        # Use the system socket.
        # I used inspect here, but many core modules should work. 
        # It ultimately depends on your python installation.
        runtime_path = os.path.realpath(inspect.getsourcefile(inspect))
        runtime_dir = os.path.dirname(runtime_path)
    
        # Patch and reload the socket module implementation.
        system_socket = os.path.join(runtime_dir, 'socket.py')
        imp.load_source('socket', system_socket)
    
        # Patch and reload the ssl module implementation.
        system_ssl = os.path.join(runtime_dir, 'ssl.py')
        imp.load_source('ssl', system_ssl)
    
        # Patch and/or reload any other libraries you suspect may have copied values
        #   from the socket or ssl namespaces.
    
    # Patch SSL support before you do anything else.
    _patch_ssl_support()
    
    import webapp2
    
    # Setup app engine application, or something that runs in an app engine runtime:
    app = webapp2.WSGIApplication(routes)
    

    0 讨论(0)
提交回复
热议问题