diff options
-rw-r--r-- | examples/rest_basic_auth/README.asciidoc | 114 | ||||
-rw-r--r-- | examples/rest_basic_auth/src/rest_basic_auth_app.erl | 6 | ||||
-rw-r--r-- | test/examples_SUITE.erl | 41 |
3 files changed, 150 insertions, 11 deletions
diff --git a/examples/rest_basic_auth/README.asciidoc b/examples/rest_basic_auth/README.asciidoc index 04609b3..ce7ef26 100644 --- a/examples/rest_basic_auth/README.asciidoc +++ b/examples/rest_basic_auth/README.asciidoc @@ -9,7 +9,7 @@ $ make run Then point your browser to http://localhost:8080 -== Example output +== HTTP/1.1 example output Request with no authentication: @@ -38,3 +38,115 @@ content-type: text/plain Hello, Alladin! ---- + +== HTTP/2 example output + +Request with no authentication: + +[source,bash] +---- +$ nghttp -v http://localhost:8080 +[ 0.000] Connected +[ 0.000] send SETTINGS frame <length=12, flags=0x00, stream_id=0> + (niv=2) + [SETTINGS_MAX_CONCURRENT_STREAMS(0x03):100] + [SETTINGS_INITIAL_WINDOW_SIZE(0x04):65535] +[ 0.000] send PRIORITY frame <length=5, flags=0x00, stream_id=3> + (dep_stream_id=0, weight=201, exclusive=0) +[ 0.000] send PRIORITY frame <length=5, flags=0x00, stream_id=5> + (dep_stream_id=0, weight=101, exclusive=0) +[ 0.000] send PRIORITY frame <length=5, flags=0x00, stream_id=7> + (dep_stream_id=0, weight=1, exclusive=0) +[ 0.000] send PRIORITY frame <length=5, flags=0x00, stream_id=9> + (dep_stream_id=7, weight=1, exclusive=0) +[ 0.000] send PRIORITY frame <length=5, flags=0x00, stream_id=11> + (dep_stream_id=3, weight=1, exclusive=0) +[ 0.000] send HEADERS frame <length=38, flags=0x25, stream_id=13> + ; 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.004] recv SETTINGS frame <length=0, flags=0x00, stream_id=0> + (niv=0) +[ 0.004] recv SETTINGS frame <length=0, flags=0x01, stream_id=0> + ; ACK + (niv=0) +[ 0.004] send SETTINGS frame <length=0, flags=0x01, stream_id=0> + ; ACK + (niv=0) +[ 0.004] recv (stream_id=13) :status: 401 +[ 0.004] recv (stream_id=13) content-length: 0 +[ 0.004] recv (stream_id=13) date: Tue, 14 Jun 2016 09:15:56 GMT +[ 0.004] recv (stream_id=13) server: Cowboy +[ 0.004] recv (stream_id=13) www-authenticate: Basic realm="cowboy" +[ 0.004] recv HEADERS frame <length=56, flags=0x04, stream_id=13> + ; END_HEADERS + (padlen=0) + ; First response header +[ 0.004] recv DATA frame <length=0, flags=0x01, stream_id=13> + ; END_STREAM +[ 0.004] send GOAWAY frame <length=8, flags=0x00, stream_id=0> + (last_stream_id=0, error_code=NO_ERROR(0x00), opaque_data(0)=[]) +---- + +Request with authentication: + +[source,bash] +---- +$ nghttp -v -H "Authorization: Basic `echo -n Alladin:open sesame | base64`" http://localhost:8080 +[ 0.000] Connected +[ 0.000] send SETTINGS frame <length=12, flags=0x00, stream_id=0> + (niv=2) + [SETTINGS_MAX_CONCURRENT_STREAMS(0x03):100] + [SETTINGS_INITIAL_WINDOW_SIZE(0x04):65535] +[ 0.000] send PRIORITY frame <length=5, flags=0x00, stream_id=3> + (dep_stream_id=0, weight=201, exclusive=0) +[ 0.000] send PRIORITY frame <length=5, flags=0x00, stream_id=5> + (dep_stream_id=0, weight=101, exclusive=0) +[ 0.000] send PRIORITY frame <length=5, flags=0x00, stream_id=7> + (dep_stream_id=0, weight=1, exclusive=0) +[ 0.000] send PRIORITY frame <length=5, flags=0x00, stream_id=9> + (dep_stream_id=7, weight=1, exclusive=0) +[ 0.001] send PRIORITY frame <length=5, flags=0x00, stream_id=11> + (dep_stream_id=3, weight=1, exclusive=0) +[ 0.001] send HEADERS frame <length=68, flags=0x25, stream_id=13> + ; 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 + authorization: Basic QWxsYWRpbjpvcGVuIHNlc2FtZQ== +[ 0.002] recv SETTINGS frame <length=0, flags=0x00, stream_id=0> + (niv=0) +[ 0.002] recv SETTINGS frame <length=0, flags=0x01, stream_id=0> + ; ACK + (niv=0) +[ 0.002] send SETTINGS frame <length=0, flags=0x01, stream_id=0> + ; ACK + (niv=0) +[ 0.004] recv (stream_id=13) :status: 200 +[ 0.004] recv (stream_id=13) content-length: 16 +[ 0.004] recv (stream_id=13) content-type: text/plain +[ 0.004] recv (stream_id=13) date: Tue, 14 Jun 2016 09:15:48 GMT +[ 0.004] recv (stream_id=13) server: Cowboy +[ 0.004] recv HEADERS frame <length=45, flags=0x04, stream_id=13> + ; END_HEADERS + (padlen=0) + ; First response header +Hello, Alladin! +[ 0.004] recv DATA frame <length=16, flags=0x01, stream_id=13> + ; END_STREAM +[ 0.004] send GOAWAY frame <length=8, flags=0x00, stream_id=0> + (last_stream_id=0, error_code=NO_ERROR(0x00), opaque_data(0)=[]) +---- diff --git a/examples/rest_basic_auth/src/rest_basic_auth_app.erl b/examples/rest_basic_auth/src/rest_basic_auth_app.erl index c19349d..cc1718d 100644 --- a/examples/rest_basic_auth/src/rest_basic_auth_app.erl +++ b/examples/rest_basic_auth/src/rest_basic_auth_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} + }), rest_basic_auth_sup:start_link(). stop(_State) -> diff --git a/test/examples_SUITE.erl b/test/examples_SUITE.erl index 42d0be8..b946625 100644 --- a/test/examples_SUITE.erl +++ b/test/examples_SUITE.erl @@ -185,17 +185,25 @@ rest_hello_world(Config) -> end. do_rest_hello_world(Transport, Protocol, Config) -> - << "<html>", _/bits >> = do_rest_get(Transport, Protocol, "/", undefined, Config), - << "REST Hello World as text!" >> = do_rest_get(Transport, Protocol, "/", <<"text/plain">>, Config), - << "{\"rest\": \"Hello World!\"}" >> = do_rest_get(Transport, Protocol, "/", <<"application/json">>, Config), - not_acceptable = do_rest_get(Transport, Protocol, "/", <<"text/css">>, Config), + << "<html>", _/bits >> = do_rest_get(Transport, Protocol, + "/", undefined, undefined, Config), + << "REST Hello World as text!" >> = do_rest_get(Transport, Protocol, + "/", <<"text/plain">>, undefined, Config), + << "{\"rest\": \"Hello World!\"}" >> = do_rest_get(Transport, Protocol, + "/", <<"application/json">>, undefined, Config), + not_acceptable = do_rest_get(Transport, Protocol, + "/", <<"text/css">>, undefined, Config), ok. -do_rest_get(Transport, Protocol, Path, Accept, Config) -> - ReqHeaders = case Accept of +do_rest_get(Transport, Protocol, Path, Accept, Auth, Config) -> + ReqHeaders0 = case Accept of undefined -> []; _ -> [{<<"accept">>, Accept}] end, + ReqHeaders = case Auth of + undefined -> ReqHeaders0; + _ -> [{<<"authorization">>, [<<"Basic ">>, base64:encode(Auth)]}|ReqHeaders0] + end, case do_get(Transport, Protocol, Path, ReqHeaders, Config) of {200, RespHeaders, Body} -> Accept = case Accept of @@ -205,10 +213,29 @@ do_rest_get(Transport, Protocol, Path, Accept, Config) -> ContentType end, Body; + {401, _, _} -> + unauthorized; {406, _, _} -> not_acceptable end. +%% REST basic auth. + +rest_basic_auth(Config) -> + doc("REST basic authorization example."), + try + do_compile_and_start(rest_basic_auth), + do_rest_basic_auth(tcp, http, Config), + do_rest_basic_auth(tcp, http2, Config) + after + do_stop(rest_basic_auth) + end. + +do_rest_basic_auth(Transport, Protocol, Config) -> + unauthorized = do_rest_get(Transport, Protocol, "/", undefined, undefined, Config), + <<"Hello, Alladin!\n">> = do_rest_get(Transport, Protocol, "/", undefined, "Alladin:open sesame", Config), + ok. + %% File server. file_server(Config) -> @@ -225,7 +252,7 @@ do_file_server(Transport, Protocol, Config) -> %% Directory. {200, DirHeaders, <<"<!DOCTYPE html><html>", _/bits >>} = do_get(Transport, Protocol, "/", Config), {_, <<"text/html">>} = lists:keyfind(<<"content-type">>, 1, DirHeaders), - _ = do_rest_get(Transport, Protocol, "/", <<"application/json">>, Config), + _ = do_rest_get(Transport, Protocol, "/", <<"application/json">>, undefined, Config), %% Files. {200, _, _} = do_get(Transport, Protocol, "/small.mp4", Config), {200, _, _} = do_get(Transport, Protocol, "/small.ogv", Config), |