How to use Cowboy with HTTP/2 instead of HTTP/1.1?

When I open http://127.0.0.1:8080/ in the browser, I can see it uses HTTP/1.1. How can I make it use HTTP/2.0 instead and prefer it over HTTP/1.1?

My current code:

hello_server_app.erl

-module(hello_server_app).

-behaviour(application).

-export([start/2, stop/1]).

start(_StartType, _StartArgs) ->
    Dispatch = cowboy_router:compile([
        {'_', [{"/", hello_handler, []}]}
    ]),
    {ok, _} = cowboy:start_clear(
        hello_listener,
        [{port, 8080}],
        #{env => #{dispatch => Dispatch}}
    ),
    hello_server_sup:start_link().

stop(_State) ->
    ok.

hello_handler.erl

-module(hello_handler).
-behaviour(cowboy_handler).
-export([init/2]).

init(Req0, State) ->
    Req = cowboy_req:reply(
        200,
        #{<<"content-type">> => <<"text/plain">>},
        <<"Hello Erlang!">>,
        Req0
    ),
    {ok, Req, State}.

I’ve made this project using rebar3 new release hello_server. Thank you.

1 Like

Solved - turns out HTTP/2 only works with TLS. Therefore I have to use start_tls instead of start_clear and provide a self-signed certificate for it to use HTTP/2 locally.

2 Likes

If you are interested in why that is, watch this speech by Daniel Steinberg at FOSDEM 2020, starting about 7 minutes in :smile:

5 Likes