If you need a very-high throughput or a multithreaded web server to host data for everyone on the web, look at Apache (with CGI), NGINX or https://www.gnu.org/software/libmicrohttpd/
However they are limited by the CGI's basic inability to preserve a context through several HTTP requests and implement efficient sessions : each request must analyse the headers again, check the cookies again, even though the connection with the server was not closed ! Actually you can't even know the order of requests with a multithreaded server, and race conditions are expected if you do anything more than serve static files.
This project solves the problem of implicit sessions with a slower but inherently safer approach : a single-threaded server ensures that the request are received and replied in order. No risk of race conditions from that angle, no need of funky programming techniques to avoid them. A session is congruent with an open TCP/IP connection, which also helps with safety (despite dubious security but it's not the purpose).
The server's code can contain two modules, that each serve a domain and specific purpose:
- Static files server
- HTTaP manager
- (an optional loopback with POST is also planned)
They can be individually disabled but they are usually integrated in the same server because HTTP/JS makes it much more difficult to connect to resources located on a different IP address or IP port.
The client first points the browser to IPaddress:IPport which provides the gateway to the application, with its code, images, text... It looks like a normal web server, probably like yasep.org.
This workflow is ideal when you want to control, configure and interact with embedded devices, over wire or radio link if you need. Your client can be any brand or model as long as it abides to simple web standards. You can code once in JS (with ygwm.org) and run everywhere !
Here I resurrect the source code of the HTTP server that was published in "Comment contrôler les GPIO du Raspberry Pi par HTTP en C" (OpenSilicium n°6, march-may 2013)
Ideally this project supports the design of the #HTTaP protocol (as explained in "GLMF n°173 "HTTaP un protocole de contrôle basé sur HTTP")
The original source code was hosted there : http://ygdes.com/sources/
The code might use the GPIO library that I maintain in another project : #C GPIO library for Raspberry Pi (it was created and forked from the same article in OpenSilicium n°6)
The TCP/IP socket setup was covered in "Un mini serveur HTTP pour dialoguer avec des applications interactives : les sockets réseau" (GNU/Linux Magazine n°141, sept 2011) (where I explain how it supports both IPv4 and IPv6, though IPv6 is currently dropped).
Environment variables and user/group/chmod management were explained in "L'environnement POSIX du mini serveur embarqué en C" (GNU/Linux Magazine n°177, dec. 2014)
Since 20170225, the code has evolved to
serve files and better support HTTP1.1, including persistent connections.
In 2020/04 work resumed to better support the favicon, remove locks caused by multiple simultaneous downloads, and other features.
2. MIME type handling
4. New version
5. Security and sandboxing
6. Overview of the code
7. Timeout and persistence
8. When to enable CORS
9. Files are served
10. Handling user-provided routines
11. Potentian use case: The API of DOOM
13. Back to this project !
14. A more polished version
15. A much better timing system
16. New version : Firefox vs Chromium-browser
17. version 2020/05/01
18. More bugs
22. 72 !
23. A poll() problem...
Since this is a software project, it's hard to create a diagram/illustration but the diagram showing #HTTaP works well because it shows how this server is intended to be used. It's the "HTTaP server" boxes:
The server is not a competitor to Apache and others, but a piece of code that is embedded in other programs to make them web-enabled and work with real time constraints. You can thus control software, hardware, or even both... This is another reason why it is single-threaded : only one user is expected at a given time.
You can adapt the server to recognise SCPI commands if you are not a HTTaP fan.
Here is an example of use : in 2017/03, the server runs on the Pi to drive the "Remote Controlled Car" extension board, for the workshop at IESA. You wouldn't want somebody else to "drive your car" at the same time as you, right ?
The noise you hear is the generated by "bit banging" the loudspeaker pin in the polling loop that drives the server's FSM. It can get really fast, showing that
- The web interface doesn't interfere with proper real-time reactions
- The application can do heavy lifting without race conditions and still remain responsive
In this case, the server is used along with the #C GPIO library for Raspberry Pi and I prepare other libraries to interface with even more peripherals !
See also the #Simon Says learn Pi and IoT project where these building blocks are put together.