Question

I'd like to be able to respond to a GET by immediately returning a message and then starting a process to run in the background and finish a task. This works fine with BaseHTTPServer.HTTPServer and extending BaseHTTPRequestHandler. However, when I follow the instructions here to add SSL to the server, the response isn't sent until the subprocess finishes. Assuming that Firefox is displaying what it receives as it receives it, and double-checking with Firebug, it looks like nothing at all is sent until the subprocess completes. I tested in Chrome and saw the same result. Code below; I'm at a loss for how to continue debugging.

class SecureHTTPServer(HTTPServer):
  def __init__(self, server_address, HandlerClass):
    BaseServer.__init__(self, server_address, HandlerClass)
    ctx = SSL.Context(SSL.SSLv3_METHOD)
    ctx.use_privatekey_file(SSL_CERT)
    ctx.use_certificate_file(SSL_CERT)
    self.socket = SSL.Connection(ctx, socket.socket(self.address_family, self.socket_type))
    self.server_bind()
    self.server_activate()
  def shutdown_request(self, request):
    request.shutdown()

class RecordingHandler(BaseHTTPRequestHandler):
  def setup(self):
    self.connection = self.request
    self.rfile = socket._fileobject(self.request, "rb", self.rbufsize)
    self.wfile = socket._fileobject(self.request, "wb", self.wbufsize)
  def do_GET(self):
    key = 'abc'
    p = Process(target = some_func, args = (key,))
    # Some_func takes ~15 seconds to complete, and it logs its progress so that it's clear that the response is only sent after some_func is complete.
    p.daemon = True
    p.start()
    self.send_response(200)
    self.end_headers()
    self.wfile.write('recording key ' + key)

def run():
  try:
    server = SecureHTTPServer(('', 8080), RecordingHandler)
    print 'Waiting for input on port 8080.'
    server.serve_forever()
  except KeyboardInterrupt:
    print 'Received keyboard interrupt, exiting.'
    server.shutdown()
Was it helpful?

Solution

Apparently I just needed to give up, restart, and try googling things again. I found this solution:

import BaseHTTPServer, SimpleHTTPServer
import ssl

httpd = BaseHTTPServer.HTTPServer(('localhost', 4443), SimpleHTTPServer.SimpleHTTPRequestHandler)
httpd.socket = ssl.wrap_socket (httpd.socket, certfile='path/to/localhost.pem', server_side=True)
httpd.serve_forever()

I still have no idea what was wrong with the previous setup, but this works just fine.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top