开发者

SimpleHTTPRequestHandler close connection before returning from do_POST method

开发者 https://www.devze.com 2023-03-18 20:11 出处:网络
I\'m writing a simple webserver in python. here follows a simplified version of my code: class StreamerHandler(SimpleHTTPRequestHandler):

I'm writing a simple webserver in python. here follows a simplified version of my code:

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)

What I would like to do is to send the response close the TCP connection and then run the process_data method which may开发者_运维百科 take a long time to complete.

Is there way to achieve this? The only solution I can think is to use a dedicated thread to handle the processing.


I tried it out, you actually need both commands (in order) to close it: self.finish() self.connection.close()


So, SimpleHTTPRequestHandler inherits from BaseHTTPServer.BaseHTTPRequestHandler, which in turn inherits from SocketServer.StreamRequestHandler.

In SocketServer.StreamRequestHandler, the rfile and wfile pseudo files get created in the setup() method from the socket object (known as 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)

The socket self.connection is still available to you, so you could call self.connection.close() to close it. However, the wfile pseudo-file might have buffered data inside it which could be lost, so you could/should instead call self.finish(), also defined in SocketServer.StreamRequestHandler:

def finish(self):
    if not self.wfile.closed:
        self.wfile.flush()
    self.wfile.close()
    self.rfile.close()

So, I think the following should work (untested):

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)))
0

精彩评论

暂无评论...
验证码 换一张
取 消