Experiments with HTTP/2 server

Table of Contents

[in package TLS-SERVER]

I wanted to play with different options for HTTP/2 server implementations. While I have a more correct implementation of HTTP/2, I wanted something simple to test different client handling options, as well as speed limits and impact of different choices.

So this repository implements:

1 Generic server interface

The functions below implement server creation on an abstract level. Individual server types implement appropriate methods to ensure desired behaviour.

2 Implementations

Following implementations are defined:

3 Work with octets

[in package TLS-SERVER/UTILS]

Simplify work with octet vectors

4 HTTP/2 protocol.

[in package TLS-SERVER/MINI-HTTP2]

Simplified - and incorrect in many corner cases - HTTP/2 protocol implemented here is is as follows. This should be sufficient to respond to a browser, curl or h2load.

4.1 Prebuild frames

4.2 Header parsing

Following function extract appropriate parameter from the header.

4.3 Error conditions

5 TLS with CL+SSL

[in package TLS-SERVER/MINI-HTTP2]

HTTP/2 in most cases needs TLS as an underlying layer.

We use MAKE-HTTP2-TLS-CONTEXT to prepare a context that is later stored in *HTTP2-TLS-CONTEXT* to have (some) parameters set up properly

Servers using usocket and Lisp streams use WRAP-TO-TLS to establish TLS.

6 Synchronous implementations

[in package TLS-SERVER/SYNCHRONOUS]

Simplest implementation is a single thread that reads and handles the requests. Once the request from a client is received, this client is listened to until finished, and then can next client connect.

Obviously not ideal, but simple.

Another implementation is a thread for the listener, and new thread for each client. Now this is used by Hunchentoot and other non-lisp implementations, and works quite well under many conditions.

This version has supposedly disadvantage when there are too many clients/threads (RAM for threads needed, etc).

The speed for single client is comparable to the single-client version.

Also, this version (as well as the single client one) can be ported to most CL implementations, as it uses standard libraries - bordeaux-threads, cl+ssl and usocket.

7 Server built using HTTP2 package.

[in package TLS-SERVER/MINI-HTTP2]

Server implementations so far used the simplified HTTP/2 protocol described above. Now we do the same using HTTP2, still synchronously to compare the ease of implementation and speed.

8 CL-ASYNC based implementation (asynchronous)

[in package TLS-SERVER/ASYNC]

9 Asynchronous TLS server

[in package TLS-SERVER/ASYNC/TLS]

9.1 Client actions loop

Each client has a STATE that encapsulates what actions are effectively possible. SELECT-NEXT-ACTION selects appropriate action. When no new action is available, next client is handled and eventually POLL called when all clients were served.

When POLL returns, new action is available for some client (read from a socket or write to it).

The actions are in general indicated by arrows in the diagram:

9.2 HTTP2 handling

10 New locatives

[in package TLS-SERVER/UTILS]

Define a locative to document CFFI callbacks.

11 Packages

12 Experiments

12.1 Clips

[in package TLS-SERVER/MEASURE]