【问题标题】:how to get client ip in soap web service method?如何在肥皂网络服务方法中获取客户端 IP?
【发布时间】:2011-08-05 11:30:22
【问题描述】:

我正在为 SOAP Web 服务使用 soaplib 库, 当我的 Web 服务方法中发出客户端请求时,我想访问客户端的 IP 地址。

class HelloWorldService(DefinitionBase):
    @soap(String, Integer, _returns=Array(String))
    def say_hello(self, name, times):
        # here I want to Access client's IP Address
        pass

这是我的服务器的伪代码...

server = make_server('localhost',
                     7789, 
                     HelloWorldApplication(Application([HelloWorldService], 'hello')))
print "serving http://localhost:7789/hello?wsdl"
server.serve_forever()

【问题讨论】:

    标签: python web-services soaplib


    【解决方案1】:

    make_server 我假设您正在使用BaseHTTPServer 或构建在它之上的软件包之一。

    在您的请求处理代码中,您应该能够找到对客户端套接字的引用。使用它来获取getsockname() 并检索客户端 IP 和 TCP 源端口。

    例如,如果套接字引用在基类中为socket,您可以:

    class HelloWorldService(DefinitionBase):
        @soap(String, Integer, _returns=Array(String))
        def say_hello(self, name, times):
            # here I want to Access client's IP Address
            print "Client IP:", self.socket.getsockname()[0]
    

    我的破解示例,检索服务器上侦听套接字的 IP:(这不是客户端套接字!)

    >>> httpd = make_server('', 8000, simple_app)
    >>> dir(httpd)
    ['RequestHandlerClass', '_BaseServer__is_shut_down', '_BaseServer__shutdown_request', '__doc__', '__init__', '__module__', '_handle_request_noblock', 'address_family', 'allow_reuse_address', 'application', 'base_environ', 'close_request', 'fileno', 'finish_request', 'get_app', 'get_request', 'handle_error', 'handle_request', 'handle_timeout', 'process_request', 'request_queue_size', 'serve_forever', 'server_activate', 'server_address', 'server_bind', 'server_close', 'server_name', 'server_port', 'set_app', 'setup_environ', 'shutdown', 'shutdown_request', 'socket', 'socket_type', 'timeout', 'verify_request']
    >>> dir(httpd.socket)
    ['__class__', '__delattr__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__slots__', '__str__', '__subclasshook__', '__weakref__', '_sock', 'accept', 'bind', 'close', 'connect', 'connect_ex', 'dup', 'family', 'fileno', 'getpeername', 'getsockname', 'getsockopt', 'gettimeout', 'listen', 'makefile', 'proto', 'recv', 'recv_into', 'recvfrom', 'recvfrom_into', 'send', 'sendall', 'sendto', 'setblocking', 'setsockopt', 'settimeout', 'shutdown', 'type']
    >>> httpd.socket.getsockname()
    ('0.0.0.0', 8000)
    

    获取实际客户端 IP 是一个更复杂的示例,因为在调用请求处理程序回调之前,您不会获得对客户端套接字对象的引用。使用 BaseHTTPServer 的示例:

    import BaseHTTPServer
    
    class Handler(BaseHTTPServer.BaseHTTPRequestHandler):
    
        def do_GET(self):
            self.send_response(200)
            self.send_header("Content-type", "text/html")
            self.end_headers()
            self.wfile.write("Client IP: %s" % self.connection.getsockname()[0])
    
    httpd = BaseHTTPServer.HTTPServer(("", 8000), Handler)
    httpd.serve_forever()
    

    我在系统上没有soaplib 来给你一个更精确的例子,但是套接字对象隐藏在某个地方。

    【讨论】:

    • 我需要客户端 IP 地址而不是服务器一,httpd.socket.getsockname() 将返回服务器的 IP 地址...而 DefinitionBase 没有任何名为 socket 的属性,所以 self.socket 是 AttributeError 在HelloWorldService上课!
    • 我没有soaplib 的副本来查找DefinitionBase 的参考。在 BaseHTTPServer 客户端对象中,套接字对象称为连接。 self.connection.getsockname() 返回客户端 IP。我会更新帖子。您必须在 DefinitionBase 中找到正确的套接字引用。它就在某个地方。
    • SOAP 本身是独立于传输的,因此对 IP 地址一无所知,我可以在 on_wsdl_call 中获取 IP 地址,但它在 wsgi.Application 类中!!
    【解决方案2】:

    已解决:

    's/self.connection.getsockname()[0]/self.client_address[0]/' 
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-07-29
      • 2017-01-16
      • 2017-12-10
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多