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

标签 python sockets unix-socket basehttprequesthandler

我正在尝试创建一个绑定(bind)到 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()

然后我使用 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

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

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

谢谢!

最佳答案

我结束了 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)

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

这不是最干净的解决方案,但也不是最骇人听闻的解决方案。

关于python - 将 BaseHTTPRequestHandler 与 UnixStreamServer 一起使用会导致异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38363758/

相关文章:

python - Cloudera CDH 5群集的mrjob NoFIleFound异常

c - cygwin 和 eclipse 的 sockets.h 问题

python - 从 Twisted 中的 SSL 套接字读取

java - 在 C++ 和 Java 之间传输数据最快的方法是什么

c - 为什么 UNIX 域数据报套接字的 recvfrom() 返回无效参数?

objective-c - 由本地 http 服务器生成的自定义 FCGI 应用程序的套接字路径是什么? (即apache/mod_fcgid、lighttpd/mod_fastcgi等)

python - 通过 netcat 将线路发送到 Python 的问题

python - 过滤字典的值

python - 如何在numpy中跨多个轴连接多个数组

sockets - 套接字对和成对的未命名管道之间有什么区别吗?