HTTP/2

Pure Crystal implementation of the HTTP/2 protocol.

Status

To add HTTP/2 support to your HTTP servers written in Crystal, if they're built on top of HTTP::Server or a framework using HTTP::Server internally, add the http2 shard to your shard.yml, then require one file:

require "http2/server"

That's it. Now every HTTP::Server instance is HTTP/2 compliant! ✨

Well, that's enough for curl and other CLI tools, because the HTTP/2 RFC allows unencrypted HTTP/2 connections, and has multiple ways to upgrade a HTTP/1 connection into a HTTP/2 connection, but the big browsers (Firefox, Chrome, Safari) all require a TLS connection... even on localhost. You must prepare a TLS certificate, instantiate an OpenSSL::SSL::Context::Server and call HTTP::Server#bind_tls.

context = OpenSSL::SSL::Context::Server.new
context.certificate_chain = File.join(TLS_PATH, "crt.pem")
context.private_key = File.join(TLS_PATH, "key.pem")

server = HTTP::Server.new(handlers)
server.bind_tls(host, port, context)
server.listen

Tests

Build and run the bin/server server, then execute h2spec.

$ make bin/server CRFLAGS=-Dh2spec

Test against HTTP:

$ bin/server
$ ./h2spec -p 9292 -S

Test against HTTPS:

$ TLS=1 bin/server
$ ./h2spec -p 9292 -k -t -S

NOTE h2spec hasn't been updated since 2020 while a revised version of the HTTP/2 RFC was released in 2022 (RFC 9113).

RFC

HTTP/2

HTTP/1

HTTP