diff options
Diffstat (limited to 'deps/ibrowse/test')
-rw-r--r-- | deps/ibrowse/test/Makefile | 19 | ||||
-rw-r--r-- | deps/ibrowse/test/ibrowse_lib_tests.erl | 135 | ||||
-rw-r--r-- | deps/ibrowse/test/ibrowse_test_server.erl | 195 |
3 files changed, 349 insertions, 0 deletions
diff --git a/deps/ibrowse/test/Makefile b/deps/ibrowse/test/Makefile new file mode 100644 index 00000000..2851ed2e --- /dev/null +++ b/deps/ibrowse/test/Makefile @@ -0,0 +1,19 @@ +ERL_FILES = ibrowse_test_server.erl + + +INCLUDE_DIRS = -I./ + +ERLC ?= erlc +ERLC_EMULATOR ?= erl -boot start_clean +COMPILER_OPTIONS = -W +warn_unused_vars +nowarn_shadow_vars +warn_unused_import + +.SUFFIXES: .erl .beam $(SUFFIXES) + +all: $(ERL_FILES:%.erl=%.beam) + +%.beam: %.erl + ${ERLC} $(COMPILER_OPTIONS) $(INCLUDE_DIRS) -o ./ $< + +clean: + rm -f *.beam + diff --git a/deps/ibrowse/test/ibrowse_lib_tests.erl b/deps/ibrowse/test/ibrowse_lib_tests.erl new file mode 100644 index 00000000..6f613e96 --- /dev/null +++ b/deps/ibrowse/test/ibrowse_lib_tests.erl @@ -0,0 +1,135 @@ +%%% File : ibrowse_lib.erl +%%% Authors : Chandrashekhar Mullaparthi <chandrashekhar.mullaparthi@t-mobile.co.uk>, +%%% Filipe David Manana <fdmanana@apache.org> +%%% Description : Tests for the module ibrowse_lib.erl +%%% Created : 12 April 2011 by Filipe David Manana <fdmanana@apache.org> + +-module(ibrowse_lib_tests). +-include_lib("eunit/include/eunit.hrl"). +-include_lib("ibrowse/include/ibrowse.hrl"). + + +parse_urls_test_() -> + {timeout, 60, [fun parse_urls/0]}. + + +parse_urls() -> + ?assertMatch(#url{ + abspath = "http://localhost", + host = "localhost", + host_type = hostname, + port = 80, + path = "/", + username = undefined, + password = undefined, + protocol = http + }, + ibrowse_lib:parse_url("http://localhost")), + ?assertMatch(#url{ + abspath = "http://localhost:80/", + host = "localhost", + host_type = hostname, + port = 80, + path = "/", + username = undefined, + password = undefined, + protocol = http + }, + ibrowse_lib:parse_url("http://localhost:80/")), + ?assertMatch(#url{ + abspath = "http://127.0.0.1:8000/", + host = "127.0.0.1", + host_type = ipv4_address, + port = 8000, + path = "/", + username = undefined, + password = undefined, + protocol = http + }, + ibrowse_lib:parse_url("http://127.0.0.1:8000/")), + ?assertMatch(#url{ + abspath = "https://foo:bar@127.0.0.1:8000/test", + host = "127.0.0.1", + host_type = ipv4_address, + port = 8000, + path = "/test", + username = "foo", + password = "bar", + protocol = https + }, + ibrowse_lib:parse_url("https://foo:bar@127.0.0.1:8000/test")), + ?assertMatch(#url{ + abspath = "https://[::1]", + host = "::1", + host_type = ipv6_address, + port = 443, + path = "/", + username = undefined, + password = undefined, + protocol = https + }, + ibrowse_lib:parse_url("https://[::1]")), + ?assertMatch(#url{ + abspath = "http://[::1]:8080", + host = "::1", + host_type = ipv6_address, + port = 8080, + path = "/", + username = undefined, + password = undefined, + protocol = http + }, + ibrowse_lib:parse_url("http://[::1]:8080")), + ?assertMatch(#url{ + abspath = "http://[FEDC:BA98:7654:3210:FEDC:BA98:7654:3210]:8081/index.html", + host = "FEDC:BA98:7654:3210:FEDC:BA98:7654:3210", + host_type = ipv6_address, + port = 8081, + path = "/index.html", + username = undefined, + password = undefined, + protocol = http + }, + ibrowse_lib:parse_url("http://[FEDC:BA98:7654:3210:FEDC:BA98:7654:3210]:8081/index.html")), + ?assertMatch(#url{ + abspath = "http://[1080:0:0:0:8:800:200C:417A]/foo/bar", + host = "1080:0:0:0:8:800:200C:417A", + host_type = ipv6_address, + port = 80, + path = "/foo/bar", + username = undefined, + password = undefined, + protocol = http + }, + ibrowse_lib:parse_url("http://[1080:0:0:0:8:800:200C:417A]/foo/bar")), + ?assertMatch(#url{ + abspath = "http://[1080:0:0:0:8:800:200C:417A]:8080/foo/bar", + host = "1080:0:0:0:8:800:200C:417A", + host_type = ipv6_address, + port = 8080, + path = "/foo/bar", + username = undefined, + password = undefined, + protocol = http + }, + ibrowse_lib:parse_url("http://[1080:0:0:0:8:800:200C:417A]:8080/foo/bar")), + ?assertMatch(#url{ + abspath = "http://[::192.9.5.5]:6000/foo?q=bar", + host = "::192.9.5.5", + host_type = ipv6_address, + port = 6000, + path = "/foo?q=bar", + username = undefined, + password = undefined, + protocol = http + }, + ibrowse_lib:parse_url("http://[::192.9.5.5]:6000/foo?q=bar")), + ?assertMatch({error, {invalid_ipv6_address, ":1080:0:0:0:8:800:200C:417A:"}}, + ibrowse_lib:parse_url("http://[:1080:0:0:0:8:800:200C:417A:]:6000/foo?q=bar")), + ?assertMatch({error, {invalid_ipv6_address, "12::z"}}, + ibrowse_lib:parse_url("http://[12::z]")), + ?assertMatch({error, {invalid_username_or_host, _}}, + ibrowse_lib:parse_url("http://foo[1080:0:0:0:8:800:200C:417A]:6000")), + ?assertMatch({error, missing_password}, + ibrowse_lib:parse_url("http://foo:[1080:0:0:0:8:800:200C:417A]:6000")), + ok. diff --git a/deps/ibrowse/test/ibrowse_test_server.erl b/deps/ibrowse/test/ibrowse_test_server.erl new file mode 100644 index 00000000..45c69587 --- /dev/null +++ b/deps/ibrowse/test/ibrowse_test_server.erl @@ -0,0 +1,195 @@ +%%% File : ibrowse_test_server.erl +%%% Author : Chandrashekhar Mullaparthi <chandrashekhar.mullaparthi@t-mobile.co.uk> +%%% Description : A server to simulate various test scenarios +%%% Created : 17 Oct 2010 by Chandrashekhar Mullaparthi <chandrashekhar.mullaparthi@t-mobile.co.uk> + +-module(ibrowse_test_server). +-export([ + start_server/2, + stop_server/1 + ]). + +-record(request, {method, uri, version, headers = [], body = []}). + +-define(dec2hex(X), erlang:integer_to_list(X, 16)). + +start_server(Port, Sock_type) -> + Fun = fun() -> + register(server_proc_name(Port), self()), + case do_listen(Sock_type, Port, [{active, false}, + {reuseaddr, true}, + {nodelay, true}, + {packet, http}]) of + {ok, Sock} -> + do_trace("Server listening on port: ~p~n", [Port]), + accept_loop(Sock, Sock_type); + Err -> + erlang:error( + lists:flatten( + io_lib:format( + "Failed to start server on port ~p. ~p~n", + [Port, Err]))), + exit({listen_error, Err}) + end + end, + spawn_link(Fun). + +stop_server(Port) -> + exit(whereis(server_proc_name(Port)), kill). + +server_proc_name(Port) -> + list_to_atom("ibrowse_test_server_"++integer_to_list(Port)). + +do_listen(tcp, Port, Opts) -> + gen_tcp:listen(Port, Opts); +do_listen(ssl, Port, Opts) -> + application:start(crypto), + application:start(ssl), + ssl:listen(Port, Opts). + +do_accept(tcp, Listen_sock) -> + gen_tcp:accept(Listen_sock); +do_accept(ssl, Listen_sock) -> + ssl:ssl_accept(Listen_sock). + +accept_loop(Sock, Sock_type) -> + case do_accept(Sock_type, Sock) of + {ok, Conn} -> + Pid = spawn_link( + fun() -> + server_loop(Conn, Sock_type, #request{}) + end), + set_controlling_process(Conn, Sock_type, Pid), + Pid ! {setopts, [{active, true}]}, + accept_loop(Sock, Sock_type); + Err -> + Err + end. + +set_controlling_process(Sock, tcp, Pid) -> + gen_tcp:controlling_process(Sock, Pid); +set_controlling_process(Sock, ssl, Pid) -> + ssl:controlling_process(Sock, Pid). + +setopts(Sock, tcp, Opts) -> + inet:setopts(Sock, Opts); +setopts(Sock, ssl, Opts) -> + ssl:setopts(Sock, Opts). + +server_loop(Sock, Sock_type, #request{headers = Headers} = Req) -> + receive + {http, Sock, {http_request, HttpMethod, HttpUri, HttpVersion}} -> + server_loop(Sock, Sock_type, Req#request{method = HttpMethod, + uri = HttpUri, + version = HttpVersion}); + {http, Sock, {http_header, _, _, _, _} = H} -> + server_loop(Sock, Sock_type, Req#request{headers = [H | Headers]}); + {http, Sock, http_eoh} -> + process_request(Sock, Sock_type, Req), + server_loop(Sock, Sock_type, #request{}); + {http, Sock, {http_error, Err}} -> + do_trace("Error parsing HTTP request:~n" + "Req so far : ~p~n" + "Err : ", [Req, Err]), + exit({http_error, Err}); + {setopts, Opts} -> + setopts(Sock, Sock_type, Opts), + server_loop(Sock, Sock_type, Req); + {tcp_closed, Sock} -> + do_trace("Client closed connection~n", []), + ok; + Other -> + do_trace("Recvd unknown msg: ~p~n", [Other]), + exit({unknown_msg, Other}) + after 5000 -> + do_trace("Timing out client connection~n", []), + ok + end. + +do_trace(Fmt, Args) -> + do_trace(get(my_trace_flag), Fmt, Args). + +do_trace(true, Fmt, Args) -> + io:format("~s -- " ++ Fmt, [ibrowse_lib:printable_date() | Args]); +do_trace(_, _, _) -> + ok. + +process_request(Sock, Sock_type, + #request{method='GET', + headers = Headers, + uri = {abs_path, "/ibrowse_stream_once_chunk_pipeline_test"}} = Req) -> + Req_id = case lists:keysearch("X-Ibrowse-Request-Id", 3, Headers) of + false -> + ""; + {value, {http_header, _, _, _, Req_id_1}} -> + Req_id_1 + end, + Req_id_header = ["x-ibrowse-request-id: ", Req_id, "\r\n"], + do_trace("Recvd req: ~p~n", [Req]), + Body = string:join([integer_to_list(X) || X <- lists:seq(1,100)], "-"), + Chunked_body = chunk_request_body(Body, 50), + Resp_1 = [<<"HTTP/1.1 200 OK\r\n">>, + Req_id_header, + <<"Transfer-Encoding: chunked\r\n\r\n">>], + Resp_2 = Chunked_body, + do_send(Sock, Sock_type, Resp_1), + timer:sleep(100), + do_send(Sock, Sock_type, Resp_2); +process_request(Sock, Sock_type, Req) -> + do_trace("Recvd req: ~p~n", [Req]), + Resp = <<"HTTP/1.1 200 OK\r\nContent-Length: 0\r\n\r\n">>, + do_send(Sock, Sock_type, Resp). + +do_send(Sock, tcp, Resp) -> + ok = gen_tcp:send(Sock, Resp); +do_send(Sock, ssl, Resp) -> + ok = ssl:send(Sock, Resp). + + +%%------------------------------------------------------------------------------ +%% Utility functions +%%------------------------------------------------------------------------------ + +chunk_request_body(Body, _ChunkSize) when is_tuple(Body) orelse + is_function(Body) -> + Body; +chunk_request_body(Body, ChunkSize) -> + chunk_request_body(Body, ChunkSize, []). + +chunk_request_body(Body, _ChunkSize, Acc) when Body == <<>>; Body == [] -> + LastChunk = "0\r\n", + lists:reverse(["\r\n", LastChunk | Acc]); +chunk_request_body(Body, ChunkSize, Acc) when is_binary(Body), + size(Body) >= ChunkSize -> + <<ChunkBody:ChunkSize/binary, Rest/binary>> = Body, + Chunk = [?dec2hex(ChunkSize),"\r\n", + ChunkBody, "\r\n"], + chunk_request_body(Rest, ChunkSize, [Chunk | Acc]); +chunk_request_body(Body, _ChunkSize, Acc) when is_binary(Body) -> + BodySize = size(Body), + Chunk = [?dec2hex(BodySize),"\r\n", + Body, "\r\n"], + LastChunk = "0\r\n", + lists:reverse(["\r\n", LastChunk, Chunk | Acc]); +chunk_request_body(Body, ChunkSize, Acc) when length(Body) >= ChunkSize -> + {ChunkBody, Rest} = split_list_at(Body, ChunkSize), + Chunk = [?dec2hex(ChunkSize),"\r\n", + ChunkBody, "\r\n"], + chunk_request_body(Rest, ChunkSize, [Chunk | Acc]); +chunk_request_body(Body, _ChunkSize, Acc) when is_list(Body) -> + BodySize = length(Body), + Chunk = [?dec2hex(BodySize),"\r\n", + Body, "\r\n"], + LastChunk = "0\r\n", + lists:reverse(["\r\n", LastChunk, Chunk | Acc]). + +split_list_at(List, N) -> + split_list_at(List, N, []). + +split_list_at([], _, Acc) -> + {lists:reverse(Acc), []}; +split_list_at(List2, 0, List1) -> + {lists:reverse(List1), List2}; +split_list_at([H | List2], N, List1) -> + split_list_at(List2, N-1, [H | List1]). + |