Recently, I've heard about the browserver project, that turns your browser in a pseudo web-server by using web-sockets. While the form is surely new, I found the idea quite familiar. Indeed, there has been quite a few attempts at embedding a web server in every user's browser: for example this add-on for the (discontinued) Opera Unite promised to revolutionize the way you shared files with friends by embedding a web server in your browser.
Furthermore, my recent efforts to control Rdio's web
app from the command-line have led me to explore Firefox's add-on SDK in
order to… have an extension start its own web server. The good thing
httpd module normally available to run unit tests. Sure, I'm not
really writing unit tests here, but it couldn't just sit here unused,
Abusing Mozilla's add-on SDK for fun and profit
While Firefox's documentation on how to create an add-on and get it running is
excellent (so this won't be covered here), it is quite sparse when it comes to
abusing its unit-testing modules. The
httpd module is available for us add-on
platform, which can be used in unit tests.” Let's use that for more creative
The first example from Mozilla, pasted here, is about serving files from a directory:
OK, that was sort of instructive. But don't despair yet, you can also do your own thing:
And that's about it for the add-on's documentation.
Of course, the required module's source is available and quite
interesting if you care to have a look at it: the
httpd.js file is
bundled with the add-on SDK, and also available on Github. If
you have even more time on your hands you can also read the
lower-level interface definitions. While these are a
instructive read on which behavior you should expect from the underlying
Getting to know your browser's httpd
By following the latest example, you should have created an instance of
nsHttpServer, which you can now start and stop with the following:
There are a handful of other (public) methods, but I'll only cover a couple here that can be used to actually serve content.
Match a path (a
String) to a handler:
From there you can already query your awesome server with whatever HTTP verb, it does not care:
$ curl localhost:8000 Hello world! $ curl -XPUT localhost:8000 Hello world!
This method allows you to catch generic HTTP errors by matching a status-code.
For example: throwing a generic exception in a path-handler will trigger the
callback registered with the code
Note that setting the appropriate HTTP headers to indicate the status in the response is up to you.
Requests and responses
When registering a path — or error — handler, the callback receives two
Response, in that order.
- With no big surprises,
Requestprovides information on the incoming request:
Responseallows you to write a response to the world, with two main methods:
writeaccepts "data", e.g.:
setStatusLinesets the HTTP status-line header, e.g.:
setStatusLine("1.1", 200, "OK")
As a side-note, if you're interested in hacking around this, maybe you'd
like to have a nicer interface than
registerPathHandler. I started a
very simple wrapper that provides a somewhat nicer
interface. Maybe reading about this will inspire