SimpleHTTPRequestHandler closes the connection before returning from the do_POST method

I am writing a simple web server in python. here's 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 send a response to close the TCP connection and then run the process_data method, which can take a lot of time.

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

+6
source share
2 answers

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

+3
source

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

In SocketServer.StreamRequestHandler pseudo rfile and wfile are created in the setup() method from a 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 self.connection socket is still available to you, so you can call self.connection.close() to close it. However, the pseudo wfile may contain buffered data that may 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))) 
+2
source

Source: https://habr.com/ru/post/892116/


All Articles