从do_POST方法返回之前,SimpleHTTPRequestHandler关闭连接

时间:2011-07-06 09:45:05

标签: python

我在python中编写一个简单的Web服务器。这是我的代码的简化版本:

class StreamerHandler(SimpleHTTPRequestHandler):
    def do_POST(self):
        try:
            length = int(self.headers.getheader('content-length'))
            data = self.rfile.read(length)
            self.send_response(200, "OK")
            #process_data(data, self.client_address)
        except Exception as inst:
            logging.error(type(self).__name__ + "/"  + type(inst).__name__ + " (" + inst.__str__() + ")")

class Streamer(TCPServer):
    def __init__(self, overlay):
        self.allow_reuse_address = True
        TCPServer.__init__(self, ("", port), StreamerHandler)

我想做的是发送响应关闭TCP连接,然后运行process_data方法,这可能需要很长时间才能完成。

有没有办法实现这个目标?我能想到的唯一解决方案是使用专用线程来处理处理。

2 个答案:

答案 0 :(得分:5)

我试过了,你实际上需要两个命令(按顺序)来关闭它: self.finish() self.connection.close()

答案 1 :(得分:3)

因此,SimpleHTTPRequestHandler继承自BaseHTTPServer.BaseHTTPRequestHandlerSocketServer.StreamRequestHandler继承自SocketServer.StreamRequestHandler

rfile中,wfilesetup()伪文件在套接字对象的self.connection方法中创建(称为def setup(self): self.connection = self.request if self.timeout is not None: self.connection.settimeout(self.timeout) if self.disable_nagle_algorithm: self.connection.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, True) self.rfile = self.connection.makefile('rb', self.rbufsize) self.wfile = self.connection.makefile('wb', self.wbufsize) ):

self.connection

套接字self.connection.close()仍可供您使用,因此您可以致电wfile关闭它。但是,self.finish()伪文件可能在其中缓冲了可能丢失的数据,因此您可以/应该调用SocketServer.StreamRequestHandler,也在def finish(self): if not self.wfile.closed: self.wfile.flush() self.wfile.close() self.rfile.close() 中定义:

class StreamerHandler(SimpleHTTPRequestHandler):
    def do_POST(self):
        try:
            length = int(self.headers.getheader('content-length'))
            data = self.rfile.read(length)
            self.send_response(200, "OK")
            self.finish()
            process_data(data, self.client_address)
        except Exception as exc:
            logging.error(
                "{0}/{1}({2})".format(
                    type(self).__name__, type(exc).__name__, str(exc)))

所以,我认为以下内容应该有效(未经测试):

{{1}}