python - 将 BaseHTTPRequestHandler 与 UnixStreamServer 一起使用会导致异常

mrj*_*ogo 4 python sockets unix-socket basehttprequesthandler

我正在尝试创建一个绑定到 Unix 域套接字的基本 HTTP 服务器,但是将 BaseHTTPRequestHandler 子类与 UnixStreamServer 一起使用会创建一个异常,表明它们不能一起工作。

玩具服务器.py:

from SocketServer import UnixStreamServer
from BaseHTTPServer import BaseHTTPRequestHandler

class MyHandler(BaseHTTPRequestHandler):
  def do_GET(self):
    self.send_response(200)
    self.send_header("Content-Type", "text/plain")
    self.end_headers()
    self.wfile.write("Hi!")

server = UnixStreamServer('./mysocket.sock', MyHandler)
server.serve_forever()
Run Code Online (Sandbox Code Playgroud)

然后我发送一个带有 的请求curl --unix-socket ./mysocket.sock http:/hello,这会导致服务器上出现以下异常(使用 Python 2.7.11):

Exception happened during processing of request from 
Traceback (most recent call last):
  File "/usr/lib/python2.7/SocketServer.py", line 290, in _handle_request_noblock
    self.process_request(request, client_address)
  File "/usr/lib/python2.7/SocketServer.py", line 318, in process_request
    self.finish_request(request, client_address)
  File "/usr/lib/python2.7/SocketServer.py", line 331, in finish_request
    self.RequestHandlerClass(request, client_address, self)
  File "/usr/lib/python2.7/SocketServer.py", line 652, in __init__
    self.handle()
  File "/usr/lib/python2.7/BaseHTTPServer.py", line 340, in handle
    self.handle_one_request()
  File "/usr/lib/python2.7/BaseHTTPServer.py", line 328, in handle_one_request
    method()
  File "server.py", line 6, in do_GET
    self.send_response(200)
  File "/usr/lib/python2.7/BaseHTTPServer.py", line 385, in send_response
    self.log_request(code)
  File "/usr/lib/python2.7/BaseHTTPServer.py", line 422, in log_request
    self.requestline, str(code), str(size))
  File "/usr/lib/python2.7/BaseHTTPServer.py", line 456, in log_message
    (self.client_address[0],
IndexError: string index out of range
Run Code Online (Sandbox Code Playgroud)

我做了一些挖掘,问题与sock.accept()返回空字符串作为地址的事实有关,大概是因为在 UDS 调用中没有客户端地址的概念。然而,BaseHTTPRequestHandler 需要一个日志记录(可能还有其他东西)

有没有一种方法可以解决这个问题,而不涉及猴子修补或通过这个小改动重新实现 BaseHTTPServer?BaseHTTPRequestHandler 甚至打算与 UnixDataStream 一起工作吗?对 Python 中的轻量级 UDS HTTP 服务器的更好建议?

谢谢!

mrj*_*ogo 5

我最终继承了 UnixStreamServer 并覆盖了 get_request(这是打算覆盖的 TCPServer 方法之一):

class UnixHTTPServer(UnixStreamServer):
  def get_request(self):
    request, client_address = self.socket.accept()
    # BaseHTTPRequestHandler expects a tuple with the client address at index
    # 0, so we fake one
    if len(client_address) == 0:
      client_address = (self.server_address,)
    return (request, client_address)
Run Code Online (Sandbox Code Playgroud)

(注意 self.server_address 给出了用于 UDS 的文件描述符的路径)

这不是最干净的解决方案,但也不是最黑客的。