diff options
Diffstat (limited to 'test')
-rw-r--r-- | test/http_SUITE.erl | 97 | ||||
-rw-r--r-- | test/http_SUITE_data/rest_post_charset_resource.erl | 15 | ||||
-rw-r--r-- | test/spdy_SUITE.erl | 171 |
3 files changed, 227 insertions, 56 deletions
diff --git a/test/http_SUITE.erl b/test/http_SUITE.erl index 21cdd4b..2d7f420 100644 --- a/test/http_SUITE.erl +++ b/test/http_SUITE.erl @@ -64,6 +64,7 @@ -export([rest_options_default/1]). -export([rest_param_all/1]). -export([rest_patch/1]). +-export([rest_post_charset/1]). -export([rest_postonly/1]). -export([rest_resource_etags/1]). -export([rest_resource_etags_if_none_match/1]). @@ -138,6 +139,7 @@ groups() -> rest_options_default, rest_param_all, rest_patch, + rest_post_charset, rest_postonly, rest_resource_etags, rest_resource_etags_if_none_match, @@ -187,9 +189,13 @@ init_per_suite(Config) -> application:start(crypto), application:start(ranch), application:start(cowboy), - Config. + Dir = ?config(priv_dir, Config) ++ "/static", + ct_helper:create_static_dir(Dir), + [{static_dir, Dir}|Config]. -end_per_suite(_Config) -> +end_per_suite(Config) -> + Dir = ?config(static_dir, Config), + ct_helper:delete_static_dir(Dir), application:stop(cowboy), application:stop(ranch), application:stop(crypto), @@ -197,62 +203,58 @@ end_per_suite(_Config) -> init_per_group(http, Config) -> Transport = ranch_tcp, - Config1 = init_static_dir(Config), {ok, _} = cowboy:start_http(http, 100, [{port, 0}], [ - {env, [{dispatch, init_dispatch(Config1)}]}, + {env, [{dispatch, init_dispatch(Config)}]}, {max_keepalive, 50}, {timeout, 500} ]), Port = ranch:get_port(http), {ok, Client} = cowboy_client:init([]), [{scheme, <<"http">>}, {port, Port}, {opts, []}, - {transport, Transport}, {client, Client}|Config1]; + {transport, Transport}, {client, Client}|Config]; init_per_group(https, Config) -> Transport = ranch_ssl, {_, Cert, Key} = ct_helper:make_certs(), Opts = [{cert, Cert}, {key, Key}], - Config1 = init_static_dir(Config), application:start(public_key), application:start(ssl), {ok, _} = cowboy:start_https(https, 100, Opts ++ [{port, 0}], [ - {env, [{dispatch, init_dispatch(Config1)}]}, + {env, [{dispatch, init_dispatch(Config)}]}, {max_keepalive, 50}, {timeout, 500} ]), Port = ranch:get_port(https), {ok, Client} = cowboy_client:init(Opts), [{scheme, <<"https">>}, {port, Port}, {opts, Opts}, - {transport, Transport}, {client, Client}|Config1]; + {transport, Transport}, {client, Client}|Config]; init_per_group(http_compress, Config) -> Transport = ranch_tcp, - Config1 = init_static_dir(Config), {ok, _} = cowboy:start_http(http_compress, 100, [{port, 0}], [ {compress, true}, - {env, [{dispatch, init_dispatch(Config1)}]}, + {env, [{dispatch, init_dispatch(Config)}]}, {max_keepalive, 50}, {timeout, 500} ]), Port = ranch:get_port(http_compress), {ok, Client} = cowboy_client:init([]), [{scheme, <<"http">>}, {port, Port}, {opts, []}, - {transport, Transport}, {client, Client}|Config1]; + {transport, Transport}, {client, Client}|Config]; init_per_group(https_compress, Config) -> Transport = ranch_ssl, {_, Cert, Key} = ct_helper:make_certs(), Opts = [{cert, Cert}, {key, Key}], - Config1 = init_static_dir(Config), application:start(public_key), application:start(ssl), {ok, _} = cowboy:start_https(https_compress, 100, Opts ++ [{port, 0}], [ {compress, true}, - {env, [{dispatch, init_dispatch(Config1)}]}, + {env, [{dispatch, init_dispatch(Config)}]}, {max_keepalive, 50}, {timeout, 500} ]), Port = ranch:get_port(https_compress), {ok, Client} = cowboy_client:init(Opts), [{scheme, <<"https">>}, {port, Port}, {opts, Opts}, - {transport, Transport}, {client, Client}|Config1]; + {transport, Transport}, {client, Client}|Config]; init_per_group(onrequest, Config) -> Transport = ranch_tcp, {ok, _} = cowboy:start_http(onrequest, 100, [{port, 0}], [ @@ -301,15 +303,11 @@ init_per_group(set_env, Config) -> [{scheme, <<"http">>}, {port, Port}, {opts, []}, {transport, Transport}, {client, Client}|Config]. -end_per_group(Group, Config) when Group =:= https; Group =:= https_compress -> - cowboy:stop_listener(https), +end_per_group(Name, _) when Name =:= https; Name =:= https_compress -> + cowboy:stop_listener(Name), application:stop(ssl), application:stop(public_key), - end_static_dir(Config), ok; -end_per_group(Group, Config) when Group =:= http; Group =:= http_compress -> - cowboy:stop_listener(http), - end_static_dir(Config); end_per_group(Name, _) -> cowboy:stop_listener(Name), ok. @@ -357,7 +355,7 @@ init_dispatch(Config) -> {"/static_specify_file/[...]", cowboy_static, [{directory, ?config(static_dir, Config)}, {mimetypes, [{<<".css">>, [<<"text/css">>]}]}, - {file, <<"test_file.css">>}]}, + {file, <<"style.css">>}]}, {"/multipart", http_multipart, []}, {"/echo/body", http_echo_body, []}, {"/echo/body_qs", http_body_qs, []}, @@ -370,6 +368,7 @@ init_dispatch(Config) -> {"/missing_get_callbacks", rest_missing_callbacks, []}, {"/missing_put_callbacks", rest_missing_callbacks, []}, {"/nodelete", rest_nodelete_resource, []}, + {"/post_charset", rest_post_charset_resource, []}, {"/postonly", rest_postonly_resource, []}, {"/patch", rest_patch_resource, []}, {"/resetags", rest_resource_etags, []}, @@ -381,29 +380,6 @@ init_dispatch(Config) -> ]} ]). -init_static_dir(Config) -> - Dir = filename:join(?config(priv_dir, Config), "static"), - Level1 = fun(Name) -> filename:join(Dir, Name) end, - ok = file:make_dir(Dir), - ok = file:write_file(Level1("test_file"), "test_file\n"), - ok = file:write_file(Level1("test_file.css"), "test_file.css\n"), - ok = file:write_file(Level1("test_noread"), "test_noread\n"), - ok = file:change_mode(Level1("test_noread"), 8#0333), - ok = file:write_file(Level1("test.html"), "test.html\n"), - ok = file:make_dir(Level1("test_dir")), - [{static_dir, Dir}|Config]. - -end_static_dir(Config) -> - Dir = ?config(static_dir, Config), - Level1 = fun(Name) -> filename:join(Dir, Name) end, - ok = file:delete(Level1("test_file")), - ok = file:delete(Level1("test_file.css")), - ok = file:delete(Level1("test_noread")), - ok = file:delete(Level1("test.html")), - ok = file:del_dir(Level1("test_dir")), - ok = file:del_dir(Dir), - Config. - %% Convenience functions. quick_raw(Data, Config) -> @@ -513,9 +489,9 @@ check_status(Config) -> {400, "/static/%2f"}, {400, "/static/%2e"}, {400, "/static/%2e%2e"}, - {403, "/static/test_dir"}, - {403, "/static/test_dir/"}, - {403, "/static/test_noread"}, + {403, "/static/directory"}, + {403, "/static/directory/"}, + {403, "/static/unreadable"}, {404, "/not/found"}, {404, "/static/not_found"}, {500, "/handler_errors?case=handler_before_reply"}, @@ -999,6 +975,15 @@ rest_patch(Config) -> ok end || {Status, Headers, Body} <- Tests]. +rest_post_charset(Config) -> + Client = ?config(client, Config), + Headers = [ + {<<"content-type">>, <<"text/plain;charset=UTF-8">>} + ], + {ok, Client2} = cowboy_client:request(<<"POST">>, + build_url("/post_charset", Config), Headers, "12345", Client), + {ok, 204, _, _} = cowboy_client:response(Client2). + rest_postonly(Config) -> Client = ?config(client, Config), Headers = [ @@ -1114,9 +1099,9 @@ slowloris2(Config) -> static_attribute_etag(Config) -> Client = ?config(client, Config), {ok, Client2} = cowboy_client:request(<<"GET">>, - build_url("/static_attribute_etag/test.html", Config), Client), + build_url("/static_attribute_etag/index.html", Config), Client), {ok, Client3} = cowboy_client:request(<<"GET">>, - build_url("/static_attribute_etag/test.html", Config), Client2), + build_url("/static_attribute_etag/index.html", Config), Client2), {ok, 200, Headers1, Client4} = cowboy_client:response(Client3), {ok, 200, Headers2, _} = cowboy_client:response(Client4), {<<"etag">>, ETag1} = lists:keyfind(<<"etag">>, 1, Headers1), @@ -1127,9 +1112,9 @@ static_attribute_etag(Config) -> static_function_etag(Config) -> Client = ?config(client, Config), {ok, Client2} = cowboy_client:request(<<"GET">>, - build_url("/static_function_etag/test.html", Config), Client), + build_url("/static_function_etag/index.html", Config), Client), {ok, Client3} = cowboy_client:request(<<"GET">>, - build_url("/static_function_etag/test.html", Config), Client2), + build_url("/static_function_etag/index.html", Config), Client2), {ok, 200, Headers1, Client4} = cowboy_client:response(Client3), {ok, 200, Headers2, _} = cowboy_client:response(Client4), {<<"etag">>, ETag1} = lists:keyfind(<<"etag">>, 1, Headers1), @@ -1150,7 +1135,7 @@ static_function_etag(Arguments, etag_data) -> static_mimetypes_function(Config) -> Client = ?config(client, Config), {ok, Client2} = cowboy_client:request(<<"GET">>, - build_url("/static_mimetypes_function/test.html", Config), Client), + build_url("/static_mimetypes_function/index.html", Config), Client), {ok, 200, Headers, _} = cowboy_client:response(Client2), {<<"content-type">>, <<"text/html">>} = lists:keyfind(<<"content-type">>, 1, Headers). @@ -1162,7 +1147,7 @@ static_specify_file(Config) -> {ok, 200, Headers, Client3} = cowboy_client:response(Client2), {<<"content-type">>, <<"text/css">>} = lists:keyfind(<<"content-type">>, 1, Headers), - {ok, <<"test_file.css\n">>, _} = cowboy_client:response_body(Client3). + {ok, <<"body{color:red}\n">>, _} = cowboy_client:response_body(Client3). static_specify_file_catchall(Config) -> Client = ?config(client, Config), @@ -1171,12 +1156,12 @@ static_specify_file_catchall(Config) -> {ok, 200, Headers, Client3} = cowboy_client:response(Client2), {<<"content-type">>, <<"text/css">>} = lists:keyfind(<<"content-type">>, 1, Headers), - {ok, <<"test_file.css\n">>, _} = cowboy_client:response_body(Client3). + {ok, <<"body{color:red}\n">>, _} = cowboy_client:response_body(Client3). static_test_file(Config) -> Client = ?config(client, Config), {ok, Client2} = cowboy_client:request(<<"GET">>, - build_url("/static/test_file", Config), Client), + build_url("/static/unknown", Config), Client), {ok, 200, Headers, _} = cowboy_client:response(Client2), {<<"content-type">>, <<"application/octet-stream">>} = lists:keyfind(<<"content-type">>, 1, Headers). @@ -1184,7 +1169,7 @@ static_test_file(Config) -> static_test_file_css(Config) -> Client = ?config(client, Config), {ok, Client2} = cowboy_client:request(<<"GET">>, - build_url("/static/test_file.css", Config), Client), + build_url("/static/style.css", Config), Client), {ok, 200, Headers, _} = cowboy_client:response(Client2), {<<"content-type">>, <<"text/css">>} = lists:keyfind(<<"content-type">>, 1, Headers). diff --git a/test/http_SUITE_data/rest_post_charset_resource.erl b/test/http_SUITE_data/rest_post_charset_resource.erl new file mode 100644 index 0000000..9ccfa61 --- /dev/null +++ b/test/http_SUITE_data/rest_post_charset_resource.erl @@ -0,0 +1,15 @@ +-module(rest_post_charset_resource). +-export([init/3, allowed_methods/2, content_types_accepted/2, from_text/2]). + +init(_Transport, _Req, _Opts) -> + {upgrade, protocol, cowboy_rest}. + +allowed_methods(Req, State) -> + {[<<"POST">>], Req, State}. + +content_types_accepted(Req, State) -> + {[{{<<"text">>, <<"plain">>, [{<<"charset">>, <<"utf-8">>}]}, + from_text}], Req, State}. + +from_text(Req, State) -> + {true, Req, State}. diff --git a/test/spdy_SUITE.erl b/test/spdy_SUITE.erl new file mode 100644 index 0000000..1089991 --- /dev/null +++ b/test/spdy_SUITE.erl @@ -0,0 +1,171 @@ +%% Copyright (c) 2013, Loïc Hoguin <[email protected]> +%% +%% Permission to use, copy, modify, and/or distribute this software for any +%% purpose with or without fee is hereby granted, provided that the above +%% copyright notice and this permission notice appear in all copies. +%% +%% THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +%% WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +%% MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +%% ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +%% WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +%% ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +%% OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +-module(spdy_SUITE). + +-include_lib("common_test/include/ct.hrl"). +-include("../src/cowboy_spdy.hrl"). + +%% ct. +-export([all/0]). +-export([groups/0]). +-export([init_per_suite/1]). +-export([end_per_suite/1]). +-export([init_per_group/2]). +-export([end_per_group/2]). + +%% Tests. +-export([check_status/1]). + +%% ct. + +all() -> + [{group, spdy}]. + +groups() -> + [{spdy, [], [ + check_status + ]}]. + +init_per_suite(Config) -> + application:start(crypto), + application:start(ranch), + application:start(cowboy), + application:start(public_key), + application:start(ssl), + Dir = ?config(priv_dir, Config) ++ "/static", + ct_helper:create_static_dir(Dir), + [{static_dir, Dir}|Config]. + +end_per_suite(Config) -> + Dir = ?config(static_dir, Config), + ct_helper:delete_static_dir(Dir), + application:stop(ssl), + application:stop(public_key), + application:stop(cowboy), + application:stop(ranch), + application:stop(crypto), + ok. + +init_per_group(Name, Config) -> + {_, Cert, Key} = ct_helper:make_certs(), + Opts = [{cert, Cert}, {key, Key}], + {ok, _} = cowboy:start_spdy(Name, 100, Opts ++ [{port, 0}], [ + {env, [{dispatch, init_dispatch(Config)}]} + ]), + Port = ranch:get_port(Name), + [{port, Port}|Config]. + +end_per_group(Name, _) -> + cowboy:stop_listener(Name), + ok. + +%% Dispatch configuration. + +init_dispatch(Config) -> + cowboy_router:compile([ + {"localhost", [ + {"/static/[...]", cowboy_static, + [{directory, ?config(static_dir, Config)}, + {mimetypes, [{<<".css">>, [<<"text/css">>]}]}]}, + {"/chunked", http_chunked, []}, + {"/", http_handler, []} + ]} + ]). + +%% Convenience functions. + +quick_get(Host, Path, ExpectedFlags, Config) -> + {_, Port} = lists:keyfind(port, 1, Config), + {ok, Socket} = ssl:connect("localhost", Port, [ + binary, {active, false}, + {client_preferred_next_protocols, client, [<<"spdy/3">>]} + ]), + {Zdef, Zinf} = zlib_init(), + ReqHeaders = headers_encode(Zdef, [ + {<<":method">>, <<"GET">>}, + {<<":path">>, list_to_binary(Path)}, + {<<":version">>, <<"HTTP/1.1">>}, + {<<":host">>, list_to_binary(Host)}, + {<<":scheme">>, <<"https">>} + ]), + ReqLength = 10 + byte_size(ReqHeaders), + StreamID = 1, + ok = ssl:send(Socket, << 1:1, 3:15, 1:16, 0:8, ReqLength:24, + 0:1, StreamID:31, 0:1, 0:31, 0:3, 0:5, 0:8, ReqHeaders/binary >>), + {ok, Packet} = ssl:recv(Socket, 0, 1000), + << 1:1, 3:15, 2:16, Flags:8, RespLength:24, + _:1, StreamID:31, RespHeaders/bits >> = Packet, + Flags = ExpectedFlags, + RespLength = 4 + byte_size(RespHeaders), + [<< NbHeaders:32, Rest/bits >>] = try + zlib:inflate(Zinf, RespHeaders) + catch _:_ -> + ok = zlib:inflateSetDictionary(Zinf, ?ZDICT), + zlib:inflate(Zinf, <<>>) + end, + RespHeaders2 = headers_decode(Zinf, Rest, []), + NbHeaders = length(RespHeaders2), + {_, << Status:3/binary, _/bits >>} + = lists:keyfind(<<":status">>, 1, RespHeaders2), + StatusCode = list_to_integer(binary_to_list(Status)), + ok = ssl:close(Socket), + zlib_terminate(Zdef, Zinf), + {StatusCode, RespHeaders2}. + +zlib_init() -> + Zdef = zlib:open(), + ok = zlib:deflateInit(Zdef), + _ = zlib:deflateSetDictionary(Zdef, ?ZDICT), + Zinf = zlib:open(), + ok = zlib:inflateInit(Zinf), + {Zdef, Zinf}. + +zlib_terminate(Zdef, Zinf) -> + zlib:close(Zdef), + zlib:close(Zinf). + +headers_encode(Zdef, Headers) -> + NbHeaders = length(Headers), + Headers2 = << << (begin + SizeN = byte_size(N), + SizeV = byte_size(V), + << SizeN:32, N/binary, SizeV:32, V/binary >> + end)/binary >> || {N, V} <- Headers >>, + Headers3 = << NbHeaders:32, Headers2/binary >>, + iolist_to_binary(zlib:deflate(Zdef, Headers3, full)). + +headers_decode(_, <<>>, Acc) -> + lists:reverse(Acc); +headers_decode(Zinf, << SizeN:32, Rest/bits >>, Acc) -> + << Name:SizeN/binary, SizeV:32, Rest2/bits >> = Rest, + << Value:SizeV/binary, Rest3/bits >> = Rest2, + headers_decode(Zinf, Rest3, [{Name, Value}|Acc]). + +%% Tests. + +check_status(Config) -> + Tests = [ + {200, nofin, "localhost", "/"}, + {200, nofin, "localhost", "/chunked"}, + {200, nofin, "localhost", "/static/style.css"}, + {400, fin, "bad-host", "/"}, + {400, fin, "localhost", "bad-path"}, + {404, fin, "localhost", "/this/path/does/not/exist"} + ], + _ = [{Status, Fin, Host, Path} = begin + RespFlags = case Fin of fin -> 1; nofin -> 0 end, + {Ret, _} = quick_get(Host, Path, RespFlags, Config), + {Ret, Fin, Host, Path} + end || {Status, Fin, Host, Path} <- Tests]. |