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