6

I want to provide one of my applications with a web interface. To achieve that, I subclass BaseHTTPRequestHandler from the BaseHTTPServer package (into a class I call _RequestHandler) and implement my own handlers for HTTP HEAD / GET / POST / PUT requests.

When I get a request for a "normal file", I just open it, read it from the file system and serve it to the browser. That works fine. However, being a web interface, I also want to communicate certain requests to the application backend. To do this, I want my server to provide an interface, over which callback functions for certain URLs can be registered (by the backend), which will be called when there is a request incoming for the registered URL and pass the request head and body to the request handler (= callback function) registered for that URL.

I. e. I want to be able to do something like this.

def callback_function(request):
   # Do some processing.
   return response

srv = WebServer(port = 8080, webroot = "htdocs/")
srv.register("/cgi-bin/test", callback_function)
srv.run()

Now, when someone requests some arbitrary URL with the browser, that has not been registered, the web server will load the specified file (relative to a the "web root") and deliver it.

I know how to implement this in principle. Place the URLs that should be handled differently in a dictionary. For each request, check if the requested URL is in the dictionary. If yes, put the request data (HTTP header and body) into a "request object", call the callback function registered for that URL and pass it that request object. Acquire the response object from the callback function, extract its contents (HTTP header and body) and serve it to the client. If the URL is not in the "special handled" dictionary, just load the file from the file system (relative to the "web root") and serve it.

The problem is, that in order to run the web server, I have to do something like this.

server = HTTPServer(("localhost", port), _RequestHandler)
server.serve_forever()

Now the problem is that I cannot pass an object, an instance of _RequestHandler to the constructor of HTTPServer. I have to pass the class itself. HTTPServer will create the instance for me, which will be inaccessible to me, so I cannot call methods on it and thus not register a callback function to it (or pass a dictionary of callback functions to the constructor or whatever).

What can I do? There must be some way of getting a custom data object into the _RequestHandler instance, right? I mean if there isn't, then all that server stuff appears to be seriously restricted. I don't see how I can do that though, since I don't have access to the instance of _RequestHandler. It will be created by the HTTPServer class for me and not be passed to the outside.

Any suggestions?

Dami
  • 677
  • 6
  • 12
no.human.being
  • 365
  • 3
  • 9
  • 1
    Don't kill the messenger, but: Do **not** do this. Use `Flask`, `CherryPy`, `web2py` or whatever. Routing and static files are a piece of cake then and also embedding your web app into a web server to get operability, scalability and security. Only exception is if you really want to *learn* the basics, but no exception when your objective is to actually *serve your app*. – flaschbier Mar 24 '16 at 17:49
  • 1
    @flaschbier The thing is: I have done something like this before (in Go with "net/http" package) and it worked like a charm. Now I'd like to do it with Python. I just want to get a request in and out, nothing more. (Yes, I know the HTTP server will run in its own thread so I'll have to make this thread-safe.) It's for controlling an application with "web" (say AJAX/jQuery) as "UI" (instead of, say, Qt). Single (local) user, no "heavy" patterns like Model-View-Controller or Model-View-Presenter, no "heavy" web server like Apache. CherryPy might be acceptable, as it seems to be lightweight. – no.human.being Mar 24 '16 at 19:43
  • @no.human.being I am stuck with the same problem. Did you eventually find the answer? or did you use Flash or CherryPy? What was the solution?? – Dami May 25 '20 at 07:39
  • Does this answer your question? [BaseHTTPRequestHandler with custom instance](https://stackoverflow.com/questions/18444395/basehttprequesthandler-with-custom-instance) – Dami May 25 '20 at 08:26
  • Check this one https://stackoverflow.com/questions/18444395/basehttprequesthandler-with-custom-instance – Dami May 25 '20 at 08:40

0 Answers0