From 6f75598b70801bbfb6828e5367bc7ed7477ad915 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Hoguin?= Date: Mon, 13 Jun 2016 16:26:00 +0200 Subject: [PATCH] Fix chunked_hello_world example --- examples/chunked_hello_world/README.asciidoc | 60 ++++++++++++++++++- .../src/chunked_hello_world_app.erl | 6 +- .../src/toppage_handler.erl | 10 ++-- test/examples_SUITE.erl | 29 +++++++++ 4 files changed, 96 insertions(+), 9 deletions(-) diff --git a/examples/chunked_hello_world/README.asciidoc b/examples/chunked_hello_world/README.asciidoc index 4b4225da..f3e4c2ad 100644 --- a/examples/chunked_hello_world/README.asciidoc +++ b/examples/chunked_hello_world/README.asciidoc @@ -10,7 +10,7 @@ $ make run Then point your browser to http://localhost:8080 or use `curl` to see the chunks arriving one at a time every second. -== Example output +== HTTP/1.1 example output [source,bash] ---- @@ -26,3 +26,61 @@ World Chunked! curl -i http://localhost:8080 0.01s user 0.00s system 0% cpu 2.015 total ---- + +== HTTP/2 example output + +[source,bash] +---- +$ nghttp -v http://localhost:8080 +[ 0.000] Connected +[ 0.000] send SETTINGS frame + (niv=2) + [SETTINGS_MAX_CONCURRENT_STREAMS(0x03):100] + [SETTINGS_INITIAL_WINDOW_SIZE(0x04):65535] +[ 0.000] send PRIORITY frame + (dep_stream_id=0, weight=201, exclusive=0) +[ 0.000] send PRIORITY frame + (dep_stream_id=0, weight=101, exclusive=0) +[ 0.000] send PRIORITY frame + (dep_stream_id=0, weight=1, exclusive=0) +[ 0.000] send PRIORITY frame + (dep_stream_id=7, weight=1, exclusive=0) +[ 0.000] send PRIORITY frame + (dep_stream_id=3, weight=1, exclusive=0) +[ 0.000] send HEADERS frame + ; END_STREAM | END_HEADERS | PRIORITY + (padlen=0, dep_stream_id=11, weight=16, exclusive=0) + ; Open new stream + :method: GET + :path: / + :scheme: http + :authority: localhost:8080 + accept: */* + accept-encoding: gzip, deflate + user-agent: nghttp2/1.7.1 +[ 0.006] recv SETTINGS frame + (niv=0) +[ 0.006] recv SETTINGS frame + ; ACK + (niv=0) +[ 0.006] send SETTINGS frame + ; ACK + (niv=0) +[ 0.010] recv (stream_id=13) :status: 200 +[ 0.010] recv (stream_id=13) date: Mon, 13 Jun 2016 14:16:26 GMT +[ 0.010] recv (stream_id=13) server: Cowboy +[ 0.010] recv HEADERS frame + ; END_HEADERS + (padlen=0) + ; First response header +Hello +[ 0.010] recv DATA frame +World +[ 1.012] recv DATA frame +Chunked! +[ 2.013] recv DATA frame +[ 2.013] recv DATA frame + ; END_STREAM +[ 2.013] send GOAWAY frame + (last_stream_id=0, error_code=NO_ERROR(0x00), opaque_data(0)=[]) +---- diff --git a/examples/chunked_hello_world/src/chunked_hello_world_app.erl b/examples/chunked_hello_world/src/chunked_hello_world_app.erl index 0032d01c..fe669084 100644 --- a/examples/chunked_hello_world/src/chunked_hello_world_app.erl +++ b/examples/chunked_hello_world/src/chunked_hello_world_app.erl @@ -16,9 +16,9 @@ start(_Type, _Args) -> {"/", toppage_handler, []} ]} ]), - {ok, _} = cowboy:start_http(http, 100, [{port, 8080}], [ - {env, [{dispatch, Dispatch}]} - ]), + {ok, _} = cowboy:start_clear(http, 100, [{port, 8080}], #{ + env => #{dispatch => Dispatch} + }), chunked_hello_world_sup:start_link(). stop(_State) -> diff --git a/examples/chunked_hello_world/src/toppage_handler.erl b/examples/chunked_hello_world/src/toppage_handler.erl index cb1d1307..22e52b9c 100644 --- a/examples/chunked_hello_world/src/toppage_handler.erl +++ b/examples/chunked_hello_world/src/toppage_handler.erl @@ -6,10 +6,10 @@ -export([init/2]). init(Req, Opts) -> - Req2 = cowboy_req:chunked_reply(200, Req), - cowboy_req:chunk("Hello\r\n", Req2), + cowboy_req:chunked_reply(200, Req), + cowboy_req:chunk("Hello\r\n", Req), timer:sleep(1000), - cowboy_req:chunk("World\r\n", Req2), + cowboy_req:chunk("World\r\n", Req), timer:sleep(1000), - cowboy_req:chunk("Chunked!\r\n", Req2), - {ok, Req2, Opts}. + cowboy_req:chunk("Chunked!\r\n", Req), + {ok, Req, Opts}. diff --git a/test/examples_SUITE.erl b/test/examples_SUITE.erl index 046f2fe9..40a8b9c9 100644 --- a/test/examples_SUITE.erl +++ b/test/examples_SUITE.erl @@ -106,6 +106,35 @@ do_hello_world(Transport, Protocol, Config) -> {200, _, <<"Hello world!">>} = do_get(Transport, Protocol, "/", Config), ok. +%% Chunked Hello World. + +chunked_hello_world(Config) -> + doc("Chunked Hello World example."), + try + do_compile_and_start(chunked_hello_world), + do_chunked_hello_world(tcp, http, Config), + do_chunked_hello_world(tcp, http2, Config) + after + do_stop(chunked_hello_world) + end. + +do_chunked_hello_world(Transport, Protocol, Config) -> + ConnPid = gun_open([{port, 8080}, {type, Transport}, {protocol, Protocol}|Config]), + Ref = gun:get(ConnPid, "/"), + {response, nofin, 200, _} = gun:await(ConnPid, Ref), + %% We expect to receive a chunk every second, three total. + {data, nofin, <<"Hello\r\n">>} = gun:await(ConnPid, Ref, 2000), + {data, nofin, <<"World\r\n">>} = gun:await(ConnPid, Ref, 2000), + {data, IsFin, <<"Chunked!\r\n">>} = gun:await(ConnPid, Ref, 2000), + %% We may get an extra empty chunk (last chunk for HTTP/1.1, + %% empty DATA frame with the FIN bit set for HTTP/2). + case IsFin of + fin -> ok; + nofin -> + {data, fin, <<>>} = gun:await(ConnPid, Ref, 500), + ok + end. + %% Echo GET. echo_get(Config) ->