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)))
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With