Coffee Space


Listen:

Server Concept

Preview Image

I have been a big fan of [@nothings](https://github.com/nothings) single_file_libs project for quite some time. It was through this that I found [@hellerf](https://github.com/hellerf)’s EmbeddableWebServer (EWS), offering a lightweight and simple web server that can be used in C/C++ projects.

I have used this in a RoboCup project as part of a debug interface for our platform. It has served me incredibly well in a few projects now - it is lightweight and ‘just works’ for the most part. If you are looking for something that deals with HTTP requests, it’s well worth a look.

I do have some thoughts on this though (and by no means do I detract from EWS):

  1. Uses multiple threads - This is mostly a feature, but during these days I am more interested in systems that fail reliably. Currently it will randomly fall over and eat some unknown number of resources.
  2. Many features - It offers GET, POST, JSON parsing, form handling - and much more. Some of these design decisions are a little too much in my opinion. If for example you want JSON parsing, then it is more than likely that you already use some JSON library in your application already. Worst still, the web server’s implementation of JSON may not match the one use elsewhere in your application.
  3. No content caching - For the most part, most servers offer up tonnes of static content. For small files, it makes sense to just load these into RAM as much as reasonably possible.
  4. Large-ish source - Sure, it is single header file, but actually it is almost 2.5k likes of source (with sensible spacing and comments). It’s no so easy to work on such large files in reality.

Proposal

So how many we address these points?

Recently I hacked together a telnet chat server, where I learned about TCP_CORK. TCP_CORK utilizes the Linux network stack to buffer communications on the network stack until you are ready to send them, reducing the total bandwidth usage. Using this and some other ideas, I found it possible to serve several clients at a time on a single thread - quite efficiently at that!

Regarding features, I am only really interested in handling GET and POST - and a minimal subset of those at most. The intention is to keep the project as simple as possible, perhaps under 256 lines of code.

Regarding caching, it should be useful to load content when requested into RAM and only periodically check it for changes. This could be achieved by checking the modified time stamp on a file to see whether it matches some internal value in the cache.

There would likely be several functions:

Future

In the future I may look towards writing a thin wrapper around such a server to support HTTPS and to serve the entire website from it. For the most part, pages are on an order of a few kilobytes at most (not including other resources). Most requests could almost fit within their own TCP packet.

I also slowly work on a lightweight replacement of cgit, which, despite the claim of being ‘hyperfast’, is actually not so much so - especially when your only aim is to offer a mirror for repositories of interest.

Additionally I intend to provide some utilities for the PDA project, namely as a lightweight web-page proxy that could lend itself to being sent over very minimal networks such as LoRA, something the Pine64 project will likely want when their system goes live. This would likely look something like http://coffeespace.org.uk/<COMMAND>/<URL>, where <COMMAND> could be a request for a small piece of a web page. This could be used for serving Wikis for example over LoRa.

As you can see, I have some plans for such a library. I will be looking to implement this in the near future.