aboutsummaryrefslogtreecommitdiffstats
path: root/lib/inets/test/httpd_SUITE.erl
diff options
context:
space:
mode:
Diffstat (limited to 'lib/inets/test/httpd_SUITE.erl')
-rw-r--r--lib/inets/test/httpd_SUITE.erl308
1 files changed, 268 insertions, 40 deletions
diff --git a/lib/inets/test/httpd_SUITE.erl b/lib/inets/test/httpd_SUITE.erl
index 90192e633c..fc5ca14dcd 100644
--- a/lib/inets/test/httpd_SUITE.erl
+++ b/lib/inets/test/httpd_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2013-2017. All Rights Reserved.
+%% Copyright Ericsson AB 2013-2018. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -75,9 +75,14 @@ all() ->
{group, http_mime_types},
{group, http_logging},
{group, http_post},
+ {group, http_rel_path_script_alias},
{group, http_not_sup},
{group, https_not_sup},
- mime_types_format
+ mime_types_format,
+ erl_script_timeout_default,
+ erl_script_timeout_option,
+ erl_script_timeout_proplist,
+ erl_script_timeout_apache
].
groups() ->
@@ -116,7 +121,8 @@ groups() ->
non_disturbing_0_9,
disturbing_1_1,
disturbing_1_0,
- disturbing_0_9
+ disturbing_0_9,
+ reload_config_file
]},
{post, [], [chunked_post, chunked_chunked_encoded_post, post_204]},
{basic_auth, [], [basic_auth_1_1, basic_auth_1_0, basic_auth_0_9]},
@@ -136,6 +142,7 @@ groups() ->
esi_put, esi_post] ++ http_head() ++ http_get() ++ load()},
{http_1_0, [], [host, cgi, trace] ++ http_head() ++ http_get() ++ load()},
{http_0_9, [], http_head() ++ http_get() ++ load()},
+ {http_rel_path_script_alias, [], [cgi]},
{not_sup, [], [put_not_sup]}
].
@@ -173,6 +180,7 @@ init_per_suite(Config) ->
ServerRoot = filename:join(PrivDir, "server_root"),
inets_test_lib:del_dirs(ServerRoot),
DocRoot = filename:join(ServerRoot, "htdocs"),
+ setup_tmp_dir(PrivDir),
setup_server_dirs(ServerRoot, DocRoot, DataDir),
{ok, Hostname0} = inet:gethostname(),
Inet =
@@ -275,6 +283,9 @@ init_per_group(http_logging, Config) ->
ServerRoot = proplists:get_value(server_root, Config1),
Path = ServerRoot ++ "/httpd_log_transfer",
[{transfer_log, Path} | Config1];
+init_per_group(http_rel_path_script_alias = Group, Config) ->
+ ok = start_apps(Group),
+ init_httpd(Group, [{type, ip_comm},{http_version, "HTTP/1.1"}| Config]);
init_per_group(not_sup, Config) ->
[{http_version, "HTTP/1.1"} | Config];
init_per_group(_, Config) ->
@@ -376,6 +387,10 @@ init_per_testcase(disk_log_bad_file, Config0) ->
ct:timetrap({seconds, 20}),
dbg(disk_log_internal, Config1, init);
+init_per_testcase(erl_script_timeout_default, Config) ->
+ ct:timetrap({seconds, 60}),
+ dbg(erl_script_timeout_default, Config, init);
+
init_per_testcase(Case, Config) ->
ct:timetrap({seconds, 20}),
dbg(Case, Config, init).
@@ -1619,6 +1634,45 @@ non_disturbing(Config) when is_list(Config)->
end,
inets_test_lib:close(Type, Socket),
[{server_name, "httpd_non_disturbing_" ++ Version}] = httpd:info(Server, [server_name]).
+%%-------------------------------------------------------------------------
+reload_config_file(Config) when is_list(Config) ->
+ ServerRoot = proplists:get_value(server_root, Config),
+ HttpdConf = filename:join(get_tmp_dir(Config), "inets_httpd_server.conf"),
+ ServerConfig =
+ "[\n" ++
+ "{bind_address, \"localhost\"}," ++
+ "{port,0}," ++
+ "{server_name,\"httpd_test\"}," ++
+ "{server_root,\"" ++ ServerRoot ++ "\"}," ++
+ "{document_root,\"" ++ proplists:get_value(doc_root, Config) ++ "\"}" ++
+ "].",
+ ok = file:write_file(HttpdConf, ServerConfig),
+ {ok, Server} = inets:start(httpd, [{proplist_file, HttpdConf}]),
+ Port = proplists:get_value(port, httpd:info(Server)),
+ NewConfig =
+ "[\n" ++
+ "{bind_address, \"localhost\"}," ++
+ "{port," ++ integer_to_list(Port) ++ "}," ++
+ "{server_name,\"httpd_test_new\"}," ++
+ "{server_root,\"" ++ ServerRoot ++ "\"}," ++
+ "{document_root,\"" ++ proplists:get_value(doc_root, Config) ++ "\"}" ++
+ "].",
+ NewConfigApache =
+ "BindAddress localhost\n" ++
+ "Port " ++ integer_to_list(Port) ++ "\n" ++
+ "ServerName httpd_test_new_apache\n" ++
+ "ServerRoot " ++ ServerRoot ++ "\n" ++
+ "DocumentRoot " ++ proplists:get_value(doc_root, Config) ++ "\n",
+
+ %% Test Erlang term format
+ ok = file:write_file(HttpdConf, NewConfig),
+ ok = httpd:reload_config(HttpdConf, non_disturbing),
+ "httpd_test_new" = proplists:get_value(server_name, httpd:info(Server)),
+
+ %% Test Apache format
+ ok = file:write_file(HttpdConf, NewConfigApache),
+ ok = httpd:reload_config(HttpdConf, non_disturbing),
+ "httpd_test_new_apache" = proplists:get_value(server_name, httpd:info(Server)).
%%-------------------------------------------------------------------------
mime_types_format(Config) when is_list(Config) ->
@@ -1730,6 +1784,131 @@ mime_types_format(Config) when is_list(Config) ->
{"cpt","application/mac-compactpro"},
{"hqx","application/mac-binhex40"}]} = httpd_conf:load_mime_types(MimeTypes).
+erl_script_timeout_default(Config) when is_list(Config) ->
+ inets:start(),
+ {ok, Pid} = inets:start(httpd,
+ [{port, 0},
+ {server_name,"localhost"},
+ {server_root,"./"},
+ {document_root,"./"},
+ {bind_address, any},
+ {mimetypes, [{"html", "text/html"}]},
+ {modules,[mod_esi]},
+ {erl_script_alias, {"/erl", [httpd_example]}}
+ ]),
+ Info = httpd:info(Pid),
+
+ Port = proplists:get_value(port, Info),
+
+ %% Default erl_script_timeout is 15.
+ %% Verify: 13 =< erl_script_timeout =< 17
+ Url = http_get_url(Port, 500, 13000, 4000),
+
+ {ok, {_, _, Body}} = httpc:request(get, {Url, []}, [{timeout, 45000}], []),
+ ct:log("Response: ~p~n", [Body]),
+ verify_body(Body, 13000),
+ inets:stop().
+
+erl_script_timeout_option(Config) when is_list(Config) ->
+ inets:start(),
+ {ok, Pid} = inets:start(httpd,
+ [{port, 0},
+ {server_name,"localhost"},
+ {server_root,"./"},
+ {document_root,"./"},
+ {bind_address, any},
+ {mimetypes, [{"html", "text/html"}]},
+ {modules,[mod_esi]},
+ {erl_script_timeout, 2},
+ {erl_script_alias, {"/erl", [httpd_example]}}
+ ]),
+ Info = httpd:info(Pid),
+ verify_timeout(Info, 2),
+
+ Port = proplists:get_value(port, Info),
+
+ %% Verify: 1 =< erl_script_timeout =< 3
+ Url = http_get_url(Port, 500, 1000, 2000),
+
+ {ok, {_, _, Body}} = httpc:request(Url),
+ ct:log("Response: ~p~n", [Body]),
+ verify_body(Body, 1000),
+ inets:stop().
+
+erl_script_timeout_proplist(Config) when is_list(Config) ->
+ HttpdConf = filename:join(get_tmp_dir(Config),
+ "httpd_erl_script_timeout_proplist.conf"),
+ ServerConfig =
+ "[{port, 0},\n" ++
+ " {server_name,\"localhost\"},\n" ++
+ " {server_root,\"./\"},\n" ++
+ " {document_root,\"./\"},\n" ++
+ " {bind_address, any},\n" ++
+ " {mimetypes, [{\"html\", \"text/html\"}]},\n" ++
+ " {modules,[mod_esi]},\n" ++
+ " {erl_script_timeout, 5},\n" ++
+ " {erl_script_alias, {\"/erl\", [httpd_example]}}\n" ++
+ "].",
+ ok = file:write_file(HttpdConf, ServerConfig),
+
+ inets:start(),
+ {ok, Pid} = inets:start(httpd,
+ [{proplist_file, HttpdConf}]),
+ Info = httpd:info(Pid),
+ verify_timeout(Info, 5),
+
+ Port = proplists:get_value(port, Info),
+
+ %% Verify: 3 =< erl_script_timeout =< 7
+ Url = http_get_url(Port, 500, 3000, 4000),
+
+ {ok, {_, _, Body}} = httpc:request(Url),
+ ct:log("Response: ~p~n", [Body]),
+ verify_body(Body, 3000),
+ inets:stop().
+
+erl_script_timeout_apache(Config) when is_list(Config) ->
+ HttpdConf = filename:join(get_tmp_dir(Config),
+ "httpd_erl_script_timeout.conf"),
+ MimeTypes = filename:join(get_tmp_dir(Config),
+ "erl_script_timeout_mime_types.conf"),
+
+ MimeTypesConf =
+ "html\n" ++
+ "text/html\n",
+
+ ok = file:write_file(MimeTypes, MimeTypesConf),
+
+ ServerConfig =
+ "Port 0\n" ++
+ "ServerName localhost\n" ++
+ "ServerRoot ./\n" ++
+ "DocumentRoot ./\n" ++
+ "BindAddress 0.0.0.0\n" ++
+ "MimeTypes " ++ MimeTypes ++ "\n" ++
+ "Modules mod_esi\n" ++
+ "ErlScriptTimeout 8\n" ++
+ "ErlScriptAlias /erl httpd_example\n",
+
+ ok = file:write_file(HttpdConf, ServerConfig),
+
+ inets:start(),
+ {ok, Pid} = inets:start(httpd,
+ [{file, HttpdConf}]),
+ Info = httpd:info(Pid),
+ verify_timeout(Info, 8),
+
+ Port = proplists:get_value(port, Info),
+
+ %% Verify: 6 =< erl_script_timeout =< 10
+ Url = http_get_url(Port, 500, 6000, 4000),
+
+ {ok, {_, _, Body}} = httpc:request(Url),
+ ct:log("Response: ~p~n", [Body]),
+ verify_body(Body, 6000),
+ inets:stop().
+
+
%%--------------------------------------------------------------------
%% Internal functions -----------------------------------
%%--------------------------------------------------------------------
@@ -1738,6 +1917,38 @@ url(http, End, Config) ->
{ok,Host} = inet:gethostname(),
?URL_START ++ Host ++ ":" ++ integer_to_list(Port) ++ End.
+http_get_url(Port0, HeaderDelay, ChunkDelay, BadChunkDelay) ->
+ {ok, Host} = inet:gethostname(),
+ Port = integer_to_list(Port0),
+ HD = integer_to_list(HeaderDelay),
+ CD = integer_to_list(ChunkDelay),
+ BD = integer_to_list(BadChunkDelay),
+ "http://" ++ Host ++ ":" ++ Port ++
+ "/erl/httpd_example/get_chunks?header_delay=" ++ HD ++
+ "&chunk_delay=" ++ CD ++
+ "&bad_chunk_delay=" ++ BD.
+
+verify_body(Body, Timeout0) ->
+ Timeout = integer_to_list(Timeout0),
+ Res = string:find(Body, Timeout),
+ ct:log("Result: ~p~n", [Res]),
+ %% Fail if BAD chunk is found.
+ case Res =:= Timeout ++ " ms\r\n" of
+ true ->
+ ok;
+ false ->
+ ct:fail("Unexpected chunk received!")
+ end.
+
+verify_timeout(Info, Expected) ->
+ Timeout = proplists:get_value(erl_script_timeout, Info),
+ case Timeout =:= Expected of
+ true ->
+ ok;
+ false ->
+ ct:fail("Bad Timeout - Expected: ~p Got: ~p", [Expected, Timeout])
+ end.
+
do_max_clients(Config) ->
Version = proplists:get_value(http_version, Config),
Host = proplists:get_value(host, Config),
@@ -1811,7 +2022,15 @@ setup_server_dirs(ServerRoot, DocRoot, DataDir) ->
{ok, FileInfo1} = file:read_file_info(EnvCGI),
ok = file:write_file_info(EnvCGI,
FileInfo1#file_info{mode = 8#00755}).
-
+
+setup_tmp_dir(PrivDir) ->
+ TmpDir = filename:join(PrivDir, "tmp"),
+ ok = file:make_dir(TmpDir).
+
+get_tmp_dir(Config) ->
+ PrivDir = proplists:get_value(priv_dir, Config),
+ filename:join(PrivDir, "tmp").
+
start_apps(Group) when Group == https_basic;
Group == https_limit;
Group == https_custom;
@@ -1838,6 +2057,7 @@ start_apps(Group) when Group == http_basic;
Group == http_reload;
Group == http_post;
Group == http_mime_types;
+ Group == http_rel_path_script_alias;
Group == http_not_sup;
Group == http_mime_types->
inets_test_lib:start_apps([inets]).
@@ -1849,32 +2069,23 @@ server_start(_, HttpdConfig) ->
{Pid, proplists:get_value(port, Info)}.
init_ssl(Group, Config) ->
- PrivDir = proplists:get_value(priv_dir, Config),
- CaKey = {_Trusted,_} =
- erl_make_certs:make_cert([{key, dsa},
- {subject,
- [{name, "Public Key"},
- {?'id-at-name',
- {printableString, "public_key"}},
- {?'id-at-pseudonym',
- {printableString, "pubkey"}},
- {city, "Stockholm"},
- {country, "SE"},
- {org, "erlang"},
- {org_unit, "testing dep"}
- ]}
- ]),
- ok = erl_make_certs:write_pem(PrivDir, "public_key_cacert", CaKey),
-
- CertK1 = {_Cert1, _} = erl_make_certs:make_cert([{issuer, CaKey}]),
- CertK2 = {_Cert2,_} = erl_make_certs:make_cert([{issuer, CertK1},
- {digest, md5},
- {extensions, false}]),
- ok = erl_make_certs:write_pem(PrivDir, "public_key_cert", CertK2),
-
+ ClientFileBase = filename:join([proplists:get_value(priv_dir, Config), "client"]),
+ ServerFileBase = filename:join([proplists:get_value(priv_dir, Config), "server"]),
+ GenCertData =
+ public_key:pkix_test_data(#{server_chain =>
+ #{root => [{key, inets_test_lib:hardcode_rsa_key(1)}],
+ intermediates => [[{key, inets_test_lib:hardcode_rsa_key(2)}]],
+ peer => [{key, inets_test_lib:hardcode_rsa_key(3)}
+ ]},
+ client_chain =>
+ #{root => [{key, inets_test_lib:hardcode_rsa_key(4)}],
+ intermediates => [[{key, inets_test_lib:hardcode_rsa_key(5)}]],
+ peer => [{key, inets_test_lib:hardcode_rsa_key(6)}]}}),
+
+ Conf = inets_test_lib:gen_pem_config_files(GenCertData, ClientFileBase, ServerFileBase),
case start_apps(Group) of
ok ->
- init_httpd(Group, [{type, ssl} | Config]);
+ init_httpd(Group, [{type, ssl}, {ssl_conf, Conf} | Config]);
_ ->
{skip, "Could not start https apps"}
end.
@@ -1968,17 +2179,33 @@ server_config(http, Config) ->
{erl_script_alias, {"/cgi-bin/erl", [httpd_example, io]}},
{eval_script_alias, {"/eval", [httpd_example, io]}}
];
+server_config(http_rel_path_script_alias, Config) ->
+ ServerRoot = proplists:get_value(server_root, Config),
+ [{port, 0},
+ {socket_type, {ip_comm, [{nodelay, true}]}},
+ {server_name,"httpd_test"},
+ {server_root, ServerRoot},
+ {document_root, proplists:get_value(doc_root, Config)},
+ {bind_address, any},
+ {ipfamily, proplists:get_value(ipfamily, Config)},
+ {max_header_size, 256},
+ {max_header_action, close},
+ {directory_index, ["index.html", "welcome.html"]},
+ {mime_types, [{"html","text/html"},{"htm","text/html"}, {"shtml","text/html"},
+ {"gif", "image/gif"}]},
+ {alias, {"/icons/", filename:join(ServerRoot,"icons") ++ "/"}},
+ {alias, {"/pics/", filename:join(ServerRoot,"icons") ++ "/"}},
+ {script_alias, {"/cgi-bin/", "./cgi-bin/"}},
+ {script_alias, {"/htbin/", "./cgi-bin/"}},
+ {erl_script_alias, {"/cgi-bin/erl", [httpd_example, io]}},
+ {eval_script_alias, {"/eval", [httpd_example, io]}}
+ ];
server_config(https, Config) ->
- PrivDir = proplists:get_value(priv_dir, Config),
+ SSLConf = proplists:get_value(ssl_conf, Config),
+ ServerConf = proplists:get_value(server_config, SSLConf),
[{socket_type, {essl,
- [{nodelay, true},
- {cacertfile,
- filename:join(PrivDir, "public_key_cacert.pem")},
- {certfile,
- filename:join(PrivDir, "public_key_cert.pem")},
- {keyfile,
- filename:join(PrivDir, "public_key_cert_key.pem")}
- ]}}] ++ proplists:delete(socket_type, server_config(http, Config)).
+ [{nodelay, true} | ServerConf]}}]
+ ++ proplists:delete(socket_type, server_config(http, Config)).
init_httpd(Group, Config0) ->
Config1 = proplists:delete(port, Config0),
@@ -2020,6 +2247,7 @@ head_status(_) ->
basic_conf() ->
[{modules, [mod_alias, mod_range, mod_responsecontrol,
mod_trace, mod_esi, mod_cgi, mod_get, mod_head]}].
+
not_sup_conf() ->
[{modules, [mod_get]}].
@@ -2235,9 +2463,9 @@ cleanup_mnesia() ->
ok.
transport_opts(ssl, Config) ->
- PrivDir = proplists:get_value(priv_dir, Config),
- [proplists:get_value(ipfamily, Config),
- {cacertfile, filename:join(PrivDir, "public_key_cacert.pem")}];
+ SSLConf = proplists:get_value(ssl_conf, Config),
+ ClientConf = proplists:get_value(client_config, SSLConf),
+ [proplists:get_value(ipfamily, Config) | ClientConf];
transport_opts(_, Config) ->
[proplists:get_value(ipfamily, Config)].