Skip to content
Maru Berezin edited this page Feb 15, 2018 · 1 revision

This week was all about ALPN, Continuous Integration, git branches, and design decisions.

Code

What I learned this week:

  • ALPN is a TLS extension for application-layer protocol negotiation.

    The client sends to the server the list of supported application protocols (such as h2, http/1.1, grpc-exp), and the server chooses one of them and sends the selected protocol. The application protocol negotiation is thus accomplished within the TLS handshake.

    openssl s_client -connect google.com:443 -alpn 'h2'
    
    
    CONNECTED(00000003)
    [...]
    ---
    New, TLSv1.2, Cipher is ECDHE-RSA-CHACHA20-POLY1305
    Server public key is 2048 bit
    Secure Renegotiation IS supported
    Compression: NONE
    Expansion: NONE
    ALPN protocol: h2
    [...]
    

    ALPN is enabled by default in MHD if the gnutls library supports it. This option is independent of HTTP/2.

  • Added a .travis.yml file for Travis-CI automatic builds.

    If you are new to Continuous Integration, there is a nice introduction for beginners.

    Manually building your application after every change takes valuable time (and less time, less coding!), so the automation of builds, testing and deployment is very helpful.

  • Don't be afraid of creating branches for experimenting. In fact, do create a branch every time you code.

    It's easier to manage branches and work on them, and then when everything is checked, testing succeeds, and coding merges are defined, you can create a pull request and introduce the changes into the master code.

    Git gives the possibility of squashing all the commits of a branch into one commit to master.

Design

I've taken the following design decisions:

  • On the one hand, when compiling MHD with HTTP/1 only, MHD should work and have the same performance as the legacy code. The functions MHD_connection_handle_read, MHD_connection_handle_idle and MHD_connection_handle_write will be respectively called for the three connection states: read, idle, and write.

    HTTP/2 functionality (and code) is not available.

  • On the other hand, when HTTP/2 is enabled (using the configure option --enable-http2), both H1 and H2 have the corresponding callbacks (read_cls, idle_cls, write_cls) for these connection states.

    The functions MHD_connection_handle_read, MHD_connection_handle_idle and MHD_connection_handle_write are still called, but inside them, these functions are called for special H1/H2 functionality.

    The future of this decision is to introduce a separation between the HTTP connection and the protocol version used by it.

    When creating an MHD application, the following cases are possible:

    • Server only accepts HTTP/1 (MHD_USE_HTTP2 flag is not set). H1 callbacks are set when a new connection is added.

    And when the flag MHD_USE_HTTP2 is set:

    • Server only accepts HTTP/2. H2 callbacks are set when a new connection is added.

    • Server accepts both HTTP/1 and HTTP/2 and provides a TLS connection. H1/H2 callbacks are set when the ALPN protocol is negotiated. H2 upgrade is allowed.

    • Server accepts both HTTP/1 and HTTP/2 and uses cleartext. H1/H2 callbacks are set when inspecting the first bytes sent by the client (to determine the HTTP version). H2 upgrade is allowed.

    In this first version of the prototype, when the flag MHD_USE_HTTP2 is set, only HTTP/2 connections will be handled (issue #7).

Clone this wiki locally