From 76e98a93821a0e628a465030bfcb63fd360afc8a Mon Sep 17 00:00:00 2001 From: Micael Karlberg Date: Tue, 22 May 2012 11:45:03 +0200 Subject: [inets/httpc] Cosmetic update to pipeline test case Added (httpc) info printouts to all test case printouts. OYP-10092 --- lib/inets/test/httpc_SUITE.erl | 149 ++++++++++++++++++++++++----------------- 1 file changed, 88 insertions(+), 61 deletions(-) (limited to 'lib') diff --git a/lib/inets/test/httpc_SUITE.erl b/lib/inets/test/httpc_SUITE.erl index a116edef77..c4943cbb4c 100644 --- a/lib/inets/test/httpc_SUITE.erl +++ b/lib/inets/test/httpc_SUITE.erl @@ -761,47 +761,60 @@ http_inets_pipe(Config) when is_list(Config) -> test_pipeline(URL) -> - p("test_pipeline -> entry with" - "~n URL: ~p", [URL]), - - httpc:set_options([{pipeline_timeout, 50000}]), - - p("test_pipeline -> issue (async) request 1"), - {ok, RequestId1} = + p("test_pipeline -> entry with" + "~n URL: ~p", [URL]), + + httpc:set_options([{pipeline_timeout, 50000}]), + + p("test_pipeline -> issue (async) request 1" + "~n when profile info: ~p", [httpc:info()]), + {ok, RequestId1} = httpc:request(get, {URL, []}, [], [{sync, false}]), - test_server:format("RequestId1: ~p~n", [RequestId1]), - p("test_pipeline -> RequestId1: ~p", [RequestId1]), - - %% Make sure pipeline is initiated - p("test_pipeline -> sleep some", []), - test_server:sleep(4000), - - p("test_pipeline -> issue (async) request 2"), - {ok, RequestId2} = + tsp("RequestId1: ~p", [RequestId1]), + p("test_pipeline -> RequestId1: ~p" + "~n when profile info: ~p", [RequestId1, httpc:info()]), + + %% Make sure pipeline is initiated + p("test_pipeline -> sleep some", []), + test_server:sleep(4000), + + p("test_pipeline -> issue (async) request 2" + "~n when profile info: ~p", [httpc:info()]), + {ok, RequestId2} = httpc:request(get, {URL, []}, [], [{sync, false}]), - tsp("RequestId2: ~p", [RequestId2]), - p("test_pipeline -> RequestId2: ~p", [RequestId2]), - - p("test_pipeline -> issue (sync) request 3"), - {ok, {{_,200,_}, [_ | _], [_ | _]}} = + tsp("RequestId2: ~p", [RequestId2]), + p("test_pipeline -> RequestId2: ~p" + "~n when profile info: ~p", [RequestId2, httpc:info()]), + + p("test_pipeline -> issue (sync) request 3"), + {ok, {{_,200,_}, [_ | _], [_ | _]}} = httpc:request(get, {URL, []}, [], []), - - p("test_pipeline -> expect reply for (async) request 1 or 2"), + + p("test_pipeline -> expect reply for (async) request 1 or 2" + "~n when profile info: ~p", [httpc:info()]), receive {http, {RequestId1, {{_, 200, _}, _, _}}} -> - p("test_pipeline -> received reply for (async) request 1 - now wait for 2"), + p("test_pipeline -> " + "received reply for (async) request 1 - now wait for 2" + "~n when profile info: ~p", [httpc:info()]), receive {http, {RequestId2, {{_, 200, _}, _, _}}} -> - p("test_pipeline -> received reply for (async) request 2"), + p("test_pipeline -> " + "received reply for (async) request 2" + "~n when profile info: ~p", [httpc:info()]), ok; {http, Msg1} -> tsf(Msg1) end; {http, {RequestId2, {{_, 200, _}, _, _}}} -> - io:format("test_pipeline -> received reply for (async) request 2 - now wait for 1"), + io:format("test_pipeline -> " + "received reply for (async) request 2 - now wait for 1" + "~n when profile info: ~p", [httpc:info()]), receive {http, {RequestId1, {{_, 200, _}, _, _}}} -> - io:format("test_pipeline -> received reply for (async) request 1"), + io:format("test_pipeline -> " + "received reply for (async) request 1" + "~n when profile info: ~p", [httpc:info()]), ok; {http, Msg2} -> tsf(Msg2) @@ -814,38 +827,49 @@ test_pipeline(URL) -> tsf({error, {timeout, Any1}}) end end, - - p("test_pipeline -> sleep some"), - test_server:sleep(4000), - - p("test_pipeline -> issue (async) request 4"), - {ok, RequestId3} = + + p("test_pipeline -> sleep some" + "~n when profile info: ~p", [httpc:info()]), + test_server:sleep(4000), + + p("test_pipeline -> issue (async) request 4" + "~n when profile info: ~p", [httpc:info()]), + {ok, RequestId3} = httpc:request(get, {URL, []}, [], [{sync, false}]), - tsp("RequestId3: ~p", [RequestId3]), - p("test_pipeline -> RequestId3: ~p", [RequestId3]), - - p("test_pipeline -> issue (async) request 5"), - {ok, RequestId4} = + tsp("RequestId3: ~p", [RequestId3]), + p("test_pipeline -> RequestId3: ~p" + "~n when profile info: ~p", [RequestId3, httpc:info()]), + + p("test_pipeline -> issue (async) request 5" + "~n when profile info: ~p", [httpc:info()]), + {ok, RequestId4} = httpc:request(get, {URL, []}, [], [{sync, false}]), - tsp("RequestId4: ~p~n", [RequestId4]), - p("test_pipeline -> RequestId4: ~p", [RequestId4]), - - p("test_pipeline -> cancel (async) request 4"), - ok = httpc:cancel_request(RequestId3), - - p("test_pipeline -> expect *no* reply for cancelled (async) request 4 (for 3 secs)"), - receive - {http, {RequestId3, _}} -> - tsf(http_cancel_request_failed) - after 3000 -> - ok - end, - - p("test_pipeline -> expect reply for (async) request 4"), - Body = + tsp("RequestId4: ~p", [RequestId4]), + p("test_pipeline -> RequestId4: ~p" + "~n when profile info: ~p", [RequestId4, httpc:info()]), + + p("test_pipeline -> cancel (async) request 4" + "~n when profile info: ~p", [httpc:info()]), + ok = httpc:cancel_request(RequestId3), + + p("test_pipeline -> " + "expect *no* reply for cancelled (async) request 4 (for 3 secs)" + "~n when profile info: ~p", [httpc:info()]), + receive + {http, {RequestId3, _}} -> + tsf(http_cancel_request_failed) + after 3000 -> + ok + end, + + p("test_pipeline -> expect reply for (async) request 4" + "~n when profile info: ~p", [httpc:info()]), + Body = receive {http, {RequestId4, {{_, 200, _}, _, BinBody4}}} = Res -> - p("test_pipeline -> received reply for (async) request 5"), + p("test_pipeline -> " + "received reply for (async) request 5" + "~n when profile info: ~p", [httpc:info()]), tsp("Receive : ~p", [Res]), BinBody4; {http, Msg4} -> @@ -856,19 +880,22 @@ test_pipeline(URL) -> tsf({error, {timeout, Any2}}) end end, - - p("test_pipeline -> check reply for (async) request 5"), + + p("test_pipeline -> check reply for (async) request 5" + "~n when profile info: ~p", [httpc:info()]), inets_test_lib:check_body(binary_to_list(Body)), - - p("test_pipeline -> ensure no unexpected incomming"), + + p("test_pipeline -> ensure no unexpected incomming" + "~n when profile info: ~p", [httpc:info()]), receive {http, Any} -> tsf({unexpected_message, Any}) after 500 -> ok end, - - p("test_pipeline -> done"), + + p("test_pipeline -> done" + "~n when profile info: ~p", [httpc:info()]), ok. %%------------------------------------------------------------------------- -- cgit v1.2.3 From 2c27a2e2a57d37df1f33f481dc0edbfd2cc83db3 Mon Sep 17 00:00:00 2001 From: Micael Karlberg Date: Tue, 22 May 2012 14:53:45 +0200 Subject: [inets/httpc] Cancel request does not work Cancel request does not work due to incorrect handler table creation (wrong keypos). OTP-10092 --- lib/inets/src/http_client/httpc_manager.erl | 105 +++++++++-------- lib/inets/test/httpc_SUITE.erl | 177 +++++++++++++++------------- lib/inets/test/inets_test_lib.erl | 4 + 3 files changed, 154 insertions(+), 132 deletions(-) (limited to 'lib') diff --git a/lib/inets/src/http_client/httpc_manager.erl b/lib/inets/src/http_client/httpc_manager.erl index b225b43214..771968e169 100644 --- a/lib/inets/src/http_client/httpc_manager.erl +++ b/lib/inets/src/http_client/httpc_manager.erl @@ -59,17 +59,9 @@ options = #options{} }). --record(handler_info, - { - id, % Id of the request: request_id() - starter, % Pid of the handler starter process (temp): pid() - handler, % Pid of the handler process: pid() - from, % From for the request: from() - state % State of the handler: initiating | started | operational | canceled - }). - -define(DELAY, 500). + %%==================================================================== %% Internal Application API %%==================================================================== @@ -379,8 +371,7 @@ do_init(ProfileName, CookiesDir) -> %% Create handler db ?hcrt("create handler/request db", []), HandlerDbName = handler_db_name(ProfileName), - ets:new(HandlerDbName, - [protected, set, named_table, {keypos, #handler_info.id}]), + ets:new(HandlerDbName, [protected, set, named_table, {keypos, 1}]), %% Cookie DB ?hcrt("create cookie db", []), @@ -414,9 +405,10 @@ handle_call({request, Request}, _, State) -> {stop, Error, httpc_response:error(Request, Error), State} end; -handle_call({cancel_request, RequestId}, From, State) -> +handle_call({cancel_request, RequestId}, From, + #state{handler_db = HandlerDb} = State) -> ?hcri("cancel_request", [{request_id, RequestId}]), - case ets:lookup(State#state.handler_db, RequestId) of + case ets:lookup(HandlerDb, RequestId) of [] -> %% The request has allready compleated make sure %% it is deliverd to the client process queue so @@ -428,9 +420,9 @@ handle_call({cancel_request, RequestId}, From, State) -> {noreply, State}; [{_, Pid, _}] -> httpc_handler:cancel(RequestId, Pid, From), - {noreply, State#state{cancel = - [{RequestId, Pid, From} | - State#state.cancel]}} + {noreply, + State#state{cancel = + [{RequestId, Pid, From} | State#state.cancel]}} end; handle_call(reset_cookies, _, #state{cookie_db = CookieDb} = State) -> @@ -645,7 +637,7 @@ code_change(_, code_change(_, State, _) -> {ok, State}. -%% This function is to catch everything that calls through the cracks... +%% This function is used to catch everything that falls through the cracks... update_session_table(SessionDB, Transform) -> ets:safe_fixtable(SessionDB, true), update_session_table(SessionDB, ets:first(SessionDB), Transform), @@ -678,35 +670,42 @@ get_manager_info(#state{handler_db = HDB, CookieInfo = httpc_cookie:which_cookies(CDB), [{handlers, HandlerInfo}, {cookies, CookieInfo}]. +sort_handlers(Unsorted) -> + sort_handlers2(lists:keysort(1, Unsorted)). + +sort_handlers2([]) -> + []; +sort_handlers2([{HandlerPid, RequestId}|L]) -> + {Handler, Rest} = sort_handlers2(HandlerPid, [RequestId], L), + [Handler | sort_handlers2(Rest)]. + +sort_handlers2(HandlerPid, Reqs, []) -> + {{HandlerPid, lists:sort(Reqs)}, []}; +sort_handlers2(HandlerPid, Reqs, [{HandlerPid, ReqId}|Rest]) -> + sort_handlers2(HandlerPid, [ReqId|Reqs], Rest); +sort_handlers2(HandlerPid1, Reqs, [{HandlerPid2, _}|_] = Rest) + when HandlerPid1 =/= HandlerPid2 -> + {{HandlerPid1, lists:sort(Reqs)}, Rest}. + get_handler_info(Tab) -> - Pattern = #handler_info{handler = '$1', - state = '$2', - _ = '_'}, - Handlers1 = [{Pid, State} || [Pid, State] <- ets:match(Tab, Pattern)], - F = fun({Pid, State} = Elem, Acc) when State =/= canceled -> - case lists:keymember(Pid, 1, Acc) of - true -> - Acc; - false -> - [Elem | Acc] - end; - (_, Acc) -> - Acc - end, - Handlers2 = lists:foldl(F, [], Handlers1), - Handlers3 = [{Pid, State, - case (catch httpc_handler:info(Pid)) of - {'EXIT', _} -> + Pattern = {'$2', '$1', '_'}, + Handlers1 = [{Pid, Id} || [Pid, Id] <- ets:match(Tab, Pattern)], + Handlers2 = sort_handlers(Handlers1), + Handlers3 = [{Pid, Reqs, + try + begin + httpc_handler:info(Pid) + end + catch + _:_ -> %% Why would this crash? %% Only if the process has died, but we don't %% know about it? - []; - Else -> - Else - end} || - {Pid, State} <- Handlers2], + [] + end} || {Pid, Reqs} <- Handlers2], Handlers3. + handle_request(#request{settings = #http_options{version = "HTTP/0.9"}} = Request, State) -> @@ -758,19 +757,21 @@ handle_request(Request, State = #state{options = Options}) -> {reply, {ok, NewRequest#request.id}, State}. -start_handler(Request, State) -> +start_handler(#request{id = Id, + from = From} = Request, + #state{profile_name = ProfileName, + handler_db = HandlerDb, + options = Options}) -> {ok, Pid} = case is_inets_manager() of true -> httpc_handler_sup:start_child([whereis(httpc_handler_sup), - Request, State#state.options, - State#state.profile_name]); + Request, Options, ProfileName]); false -> - httpc_handler:start_link(self(), Request, State#state.options, - State#state.profile_name) + httpc_handler:start_link(self(), Request, Options, ProfileName) end, - ets:insert(State#state.handler_db, {Request#request.id, - Pid, Request#request.from}), + HandlerInfo = {Id, Pid, From}, + ets:insert(HandlerDb, HandlerInfo), erlang:monitor(process, Pid). @@ -827,12 +828,14 @@ select_session(Candidates, Max) -> {ok, HandlerPid} end. -pipeline_or_keep_alive(Request, HandlerPid, State) -> +pipeline_or_keep_alive(#request{id = Id, + from = From} = Request, + HandlerPid, + #state{handler_db = HandlerDb} = State) -> case (catch httpc_handler:send(Request, HandlerPid)) of ok -> - ets:insert(State#state.handler_db, {Request#request.id, - HandlerPid, - Request#request.from}); + HandlerInfo = {Id, HandlerPid, From}, + ets:insert(HandlerDb, HandlerInfo); _ -> % timeout pipelining failed start_handler(Request, State) end. diff --git a/lib/inets/test/httpc_SUITE.erl b/lib/inets/test/httpc_SUITE.erl index c4943cbb4c..1cdd96f0b0 100644 --- a/lib/inets/test/httpc_SUITE.erl +++ b/lib/inets/test/httpc_SUITE.erl @@ -768,120 +768,83 @@ test_pipeline(URL) -> p("test_pipeline -> issue (async) request 1" "~n when profile info: ~p", [httpc:info()]), - {ok, RequestId1} = + {ok, RequestIdA1} = httpc:request(get, {URL, []}, [], [{sync, false}]), - tsp("RequestId1: ~p", [RequestId1]), - p("test_pipeline -> RequestId1: ~p" - "~n when profile info: ~p", [RequestId1, httpc:info()]), + tsp("RequestIdA1: ~p", [RequestIdA1]), + p("test_pipeline -> RequestIdA1: ~p" + "~n when profile info: ~p", [RequestIdA1, httpc:info()]), %% Make sure pipeline is initiated p("test_pipeline -> sleep some", []), test_server:sleep(4000), - p("test_pipeline -> issue (async) request 2" + p("test_pipeline -> issue (async) request A2, A3 and A4" "~n when profile info: ~p", [httpc:info()]), - {ok, RequestId2} = + {ok, RequestIdA2} = httpc:request(get, {URL, []}, [], [{sync, false}]), - tsp("RequestId2: ~p", [RequestId2]), - p("test_pipeline -> RequestId2: ~p" - "~n when profile info: ~p", [RequestId2, httpc:info()]), + {ok, RequestIdA3} = + httpc:request(get, {URL, []}, [], [{sync, false}]), + {ok, RequestIdA4} = + httpc:request(get, {URL, []}, [], [{sync, false}]), + tsp("RequestIdAs => A2: ~p, A3: ~p and A4: ~p", + [RequestIdA2, RequestIdA3, RequestIdA4]), + p("test_pipeline -> RequestIds => A2: ~p, A3: ~p and A4: ~p" + "~n when profile info: ~p", + [RequestIdA2, RequestIdA3, RequestIdA4, httpc:info()]), p("test_pipeline -> issue (sync) request 3"), {ok, {{_,200,_}, [_ | _], [_ | _]}} = httpc:request(get, {URL, []}, [], []), - p("test_pipeline -> expect reply for (async) request 1 or 2" + p("test_pipeline -> expect reply for (async) request A1, A2, A3 and A4" "~n when profile info: ~p", [httpc:info()]), - receive - {http, {RequestId1, {{_, 200, _}, _, _}}} -> - p("test_pipeline -> " - "received reply for (async) request 1 - now wait for 2" - "~n when profile info: ~p", [httpc:info()]), - receive - {http, {RequestId2, {{_, 200, _}, _, _}}} -> - p("test_pipeline -> " - "received reply for (async) request 2" - "~n when profile info: ~p", [httpc:info()]), - ok; - {http, Msg1} -> - tsf(Msg1) - end; - {http, {RequestId2, {{_, 200, _}, _, _}}} -> - io:format("test_pipeline -> " - "received reply for (async) request 2 - now wait for 1" - "~n when profile info: ~p", [httpc:info()]), - receive - {http, {RequestId1, {{_, 200, _}, _, _}}} -> - io:format("test_pipeline -> " - "received reply for (async) request 1" - "~n when profile info: ~p", [httpc:info()]), - ok; - {http, Msg2} -> - tsf(Msg2) - end; - {http, Msg3} -> - tsf(Msg3) - after 60000 -> - receive Any1 -> - tsp("received crap after timeout: ~n ~p", [Any1]), - tsf({error, {timeout, Any1}}) - end - end, - + pipeline_await_async_reply([{RequestIdA1, a1, 200}, + {RequestIdA2, a2, 200}, + {RequestIdA3, a3, 200}, + {RequestIdA4, a4, 200}], ?MINS(1)), + p("test_pipeline -> sleep some" "~n when profile info: ~p", [httpc:info()]), test_server:sleep(4000), - p("test_pipeline -> issue (async) request 4" + p("test_pipeline -> issue (async) request B1, B2, B3 and B4" "~n when profile info: ~p", [httpc:info()]), - {ok, RequestId3} = + {ok, RequestIdB1} = httpc:request(get, {URL, []}, [], [{sync, false}]), - tsp("RequestId3: ~p", [RequestId3]), - p("test_pipeline -> RequestId3: ~p" - "~n when profile info: ~p", [RequestId3, httpc:info()]), - - p("test_pipeline -> issue (async) request 5" - "~n when profile info: ~p", [httpc:info()]), - {ok, RequestId4} = + {ok, RequestIdB2} = + httpc:request(get, {URL, []}, [], [{sync, false}]), + {ok, RequestIdB3} = httpc:request(get, {URL, []}, [], [{sync, false}]), - tsp("RequestId4: ~p", [RequestId4]), - p("test_pipeline -> RequestId4: ~p" - "~n when profile info: ~p", [RequestId4, httpc:info()]), + {ok, RequestIdB4} = + httpc:request(get, {URL, []}, [], [{sync, false}]), + tsp("RequestIdBs => B1: ~p, B2: ~p, B3: ~p and B4: ~p", + [RequestIdB1, RequestIdB2, RequestIdB3, RequestIdB4]), + p("test_pipeline -> RequestIdBs => B1: ~p, B2: ~p, B3: ~p and B4: ~p" + "~n when profile info: ~p", + [RequestIdB1, RequestIdB2, RequestIdB3, RequestIdB4, httpc:info()]), - p("test_pipeline -> cancel (async) request 4" + p("test_pipeline -> cancel (async) request B2" "~n when profile info: ~p", [httpc:info()]), - ok = httpc:cancel_request(RequestId3), + ok = httpc:cancel_request(RequestIdB2), p("test_pipeline -> " - "expect *no* reply for cancelled (async) request 4 (for 3 secs)" + "expect *no* reply for cancelled (async) request B2 (for 3 secs)" "~n when profile info: ~p", [httpc:info()]), receive - {http, {RequestId3, _}} -> + {http, {RequestIdB2, _}} -> tsf(http_cancel_request_failed) after 3000 -> ok end, - p("test_pipeline -> expect reply for (async) request 4" + p("test_pipeline -> expect reply for (async) request B1, B3 and B4" "~n when profile info: ~p", [httpc:info()]), - Body = - receive - {http, {RequestId4, {{_, 200, _}, _, BinBody4}}} = Res -> - p("test_pipeline -> " - "received reply for (async) request 5" - "~n when profile info: ~p", [httpc:info()]), - tsp("Receive : ~p", [Res]), - BinBody4; - {http, Msg4} -> - tsf(Msg4) - after 60000 -> - receive Any2 -> - tsp("received crap after timeout: ~n ~p", [Any2]), - tsf({error, {timeout, Any2}}) - end - end, - - p("test_pipeline -> check reply for (async) request 5" + Bodies = pipeline_await_async_reply([{RequestIdB1, b1, 200}, + {RequestIdB3, b3, 200}, + {RequestIdB4, b4, 200}], ?MINS(1)), + [{b1, Body}|_] = Bodies, + + p("test_pipeline -> check reply for (async) request B1" "~n when profile info: ~p", [httpc:info()]), inets_test_lib:check_body(binary_to_list(Body)), @@ -898,6 +861,58 @@ test_pipeline(URL) -> "~n when profile info: ~p", [httpc:info()]), ok. +pipeline_await_async_reply(ReqIds, Timeout) -> + pipeline_await_async_reply(ReqIds, Timeout, []). + +pipeline_await_async_reply([], _, Acc) -> + lists:keysort(1, Acc); +pipeline_await_async_reply(ReqIds, Timeout, Acc) when Timeout > 0 -> + T1 = inets_test_lib:timestamp(), + p("pipeline_await_async_reply -> await replies" + "~n ReqIds: ~p" + "~n Timeout: ~p", [ReqIds, Timeout]), + receive + {http, {RequestId, {{_, Status, _}, _, Body}}} -> + p("pipeline_await_async_reply -> received reply for" + "~n RequestId: ~p" + "~n Status: ~p", [RequestId, Status]), + case lists:keysearch(RequestId, 1, ReqIds) of + {value, {RequestId, N, Status}} -> + p("pipeline_await_async_reply -> " + "found expected request ~w", [N]), + ReqIds2 = lists:keydelete(RequestId, 1, ReqIds), + NewTimeout = Timeout - (inets_test_lib:timestamp()-T1), + pipeline_await_async_reply(ReqIds2, NewTimeout, + [{N, Body} | Acc]); + {value, {RequestId, N, WrongStatus}} -> + p("pipeline_await_async_reply -> " + "found request ~w with wrong status", [N]), + tsf({reply_with_unexpected_status, + {RequestId, N, WrongStatus}}); + false -> + tsf({unexpected_reply, {RequestId, Status}}) + end; + {http, Msg} -> + tsf({unexpected_reply, Msg}) + after Timeout -> + receive + Any -> + tsp("pipeline_await_async_reply -> " + "received unknown data after timeout: " + "~n ~p", [Any]), + tsf({timeout, {unknown, Any}}) + end + end; +pipeline_await_async_reply(ReqIds, _, Acc) -> + tsp("pipeline_await_async_reply -> " + "timeout: " + "~n ~p" + "~nwhen" + "~n ~p", [ReqIds, Acc]), + tsf({timeout, ReqIds, Acc}). + + + %%------------------------------------------------------------------------- http_trace(doc) -> ["Perform a TRACE request that goes through a proxy."]; diff --git a/lib/inets/test/inets_test_lib.erl b/lib/inets/test/inets_test_lib.erl index c94be796cd..7f4b0ec8d8 100644 --- a/lib/inets/test/inets_test_lib.erl +++ b/lib/inets/test/inets_test_lib.erl @@ -31,6 +31,7 @@ send/3, close/2]). -export([copy_file/3, copy_files/2, copy_dirs/2, del_dirs/1]). -export([info/4, log/4, debug/4, print/4]). +-export([timestamp/0, formated_timestamp/0]). -export([tsp/1, tsp/2, tsf/1, tss/1]). -export([check_body/1]). -export([millis/0, millis_diff/2, hours/1, minutes/1, seconds/1, sleep/1]). @@ -642,6 +643,9 @@ tsf(Reason) -> tss(Time) -> test_server:sleep(Time). +timestamp() -> + http_util:timestamp(). + formated_timestamp() -> format_timestamp( os:timestamp() ). -- cgit v1.2.3 From b1d12bf8623c5585017b1777236c18da1f5a83a4 Mon Sep 17 00:00:00 2001 From: Micael Karlberg Date: Tue, 22 May 2012 15:01:06 +0200 Subject: [inets/httpc] Updated version, release nodes and appup OTP-10092 --- lib/inets/doc/src/notes.xml | 91 +++++++++++++++++++++++++++++++++ lib/inets/src/inets_app/inets.appup.src | 10 ++++ lib/inets/vsn.mk | 2 +- 3 files changed, 102 insertions(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/inets/doc/src/notes.xml b/lib/inets/doc/src/notes.xml index dfdeb4016c..9e1da12f4a 100644 --- a/lib/inets/doc/src/notes.xml +++ b/lib/inets/doc/src/notes.xml @@ -33,6 +33,97 @@ +
Inets 5.9.1 + +
Improvements and New Features +

-

+ + + +
+ +
Fixed Bugs and Malfunctions + + + + +

[httpc] Cancel request does not work due to incorrect + handler table creation (wrong keypos).

+

Vyacheslav Vorobyov

+

Own Id: OTP-10092

+
+ +
+ +
+ +
+ Incompatibilities +

-

+ + + +
+ +
+ +
Inets 5.9
Improvements and New Features diff --git a/lib/inets/src/inets_app/inets.appup.src b/lib/inets/src/inets_app/inets.appup.src index c7029f7b31..0a69636851 100644 --- a/lib/inets/src/inets_app/inets.appup.src +++ b/lib/inets/src/inets_app/inets.appup.src @@ -18,6 +18,11 @@ {"%VSN%", [ + {"5.9", + [ + {update, httpc_handler, soft, soft_purge, soft_purge, []} + ] + }, {"5.8.1", [ {load_module, http_uri, soft_purge, soft_purge, []}, @@ -74,6 +79,11 @@ } ], [ + {"5.9", + [ + {update, httpc_handler, soft, soft_purge, soft_purge, []} + ] + }, {"5.8.1", [ {load_module, http_uri, soft_purge, soft_purge, []}, diff --git a/lib/inets/vsn.mk b/lib/inets/vsn.mk index 488947c3a1..949eceea7f 100644 --- a/lib/inets/vsn.mk +++ b/lib/inets/vsn.mk @@ -18,7 +18,7 @@ # %CopyrightEnd% APPLICATION = inets -INETS_VSN = 5.9 +INETS_VSN = 5.9.1 PRE_VSN = APP_VSN = "$(APPLICATION)-$(INETS_VSN)$(PRE_VSN)" -- cgit v1.2.3 From ef14221acafe78b7a77b5d42b6a615fa7333750d Mon Sep 17 00:00:00 2001 From: Micael Karlberg Date: Tue, 22 May 2012 15:35:26 +0200 Subject: [inets/httpc] Corrected appup file OTP-10092 --- lib/inets/src/inets_app/inets.appup.src | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'lib') diff --git a/lib/inets/src/inets_app/inets.appup.src b/lib/inets/src/inets_app/inets.appup.src index 0a69636851..93fd5b9595 100644 --- a/lib/inets/src/inets_app/inets.appup.src +++ b/lib/inets/src/inets_app/inets.appup.src @@ -20,7 +20,7 @@ [ {"5.9", [ - {update, httpc_handler, soft, soft_purge, soft_purge, []} + {update, httpc_manager, soft, soft_purge, soft_purge, []} ] }, {"5.8.1", @@ -40,6 +40,7 @@ {load_module, httpd_script_env, soft_purge, soft_purge, []}, {load_module, inets, soft_purge, soft_purge, [inets_trace]}, + {update, httpc_manager, soft, soft_purge, soft_purge, []}, {update, httpc_handler, soft, soft_purge, soft_purge, []}, {update, httpd_sup, soft, soft_purge, soft_purge, []}, {add_module, inets_trace} @@ -81,7 +82,7 @@ [ {"5.9", [ - {update, httpc_handler, soft, soft_purge, soft_purge, []} + {update, httpc_manager, soft, soft_purge, soft_purge, []} ] }, {"5.8.1", @@ -101,6 +102,7 @@ {load_module, httpd_script_env, soft_purge, soft_purge, []}, {load_module, inets, soft_purge, soft_purge, []}, + {update, httpc_manager, soft, soft_purge, soft_purge, []}, {update, httpc_handler, soft, soft_purge, soft_purge, []}, {update, httpd_sup, soft, soft_purge, soft_purge, []}, {remove, {inets_trace, soft_purge, brutal_purge}} -- cgit v1.2.3 From 022bc68b6dd10624b58779dc2b3b0e392e3e04f5 Mon Sep 17 00:00:00 2001 From: Micael Karlberg Date: Tue, 22 May 2012 17:37:33 +0200 Subject: [inets/httpc] Better handling of session db update failure A failure to update the session database will now result in an informative error message and a controlled (handler) exit rather then an ugly crash. Also debug functions to retrieve sessions info and updated the info function with more info (sessions and options). OTP-10093 --- lib/inets/src/http_client/httpc.erl | 26 +++++++- lib/inets/src/http_client/httpc_handler.erl | 27 ++++++++- lib/inets/src/http_client/httpc_manager.erl | 92 ++++++++++++++++++++++++++--- 3 files changed, 135 insertions(+), 10 deletions(-) (limited to 'lib') diff --git a/lib/inets/src/http_client/httpc.erl b/lib/inets/src/http_client/httpc.erl index f4802fb96d..b6e7708353 100644 --- a/lib/inets/src/http_client/httpc.erl +++ b/lib/inets/src/http_client/httpc.erl @@ -39,6 +39,7 @@ cookie_header/1, cookie_header/2, cookie_header/3, which_cookies/0, which_cookies/1, reset_cookies/0, reset_cookies/1, + which_sessions/0, which_sessions/1, stream_next/1, default_profile/0, profile_name/1, profile_name/2, @@ -267,6 +268,7 @@ set_option(Key, Value, Profile) -> %% Reason - term() %% Description: Retrieves the current options. %%------------------------------------------------------------------------- + get_options() -> record_info(fields, options). @@ -373,8 +375,6 @@ cookie_header(Url, Opts, Profile) {error, {not_started, Profile}} end. - - %%-------------------------------------------------------------------------- %% which_cookies() -> [cookie()] @@ -397,6 +397,28 @@ which_cookies(Profile) -> end. +%%-------------------------------------------------------------------------- +%% which_sessions() -> {GoodSession, BadSessions, NonSessions} +%% which_sessions(Profile) -> {GoodSession, BadSessions, NonSessions} +%% +%% Description: Debug function, dumping the sessions database, sorted +%% into three groups (Good-, Bad- and Non-sessions). +%%------------------------------------------------------------------------- +which_sessions() -> + which_sessions(default_profile()). + +which_sessions(Profile) -> + ?hcrt("which sessions", [{profile, Profile}]), + try + begin + httpc_manager:which_sessions(profile_name(Profile)) + end + catch + exit:{noproc, _} -> + {[], [], []} + end. + + %%-------------------------------------------------------------------------- %% info() -> list() %% info(Profile) -> list() diff --git a/lib/inets/src/http_client/httpc_handler.erl b/lib/inets/src/http_client/httpc_handler.erl index b8c34bd99b..6fe05dec80 100644 --- a/lib/inets/src/http_client/httpc_handler.erl +++ b/lib/inets/src/http_client/httpc_handler.erl @@ -1713,7 +1713,32 @@ update_session(ProfileName, #session{id = SessionId} = Session, Pos, Value) -> catch error:undef -> % This could happen during code upgrade Session2 = erlang:setelement(Pos, Session, Value), - insert_session(Session2, ProfileName) + insert_session(Session2, ProfileName); + T:E -> + error_logger:error_msg("Failed updating session: " + "~n ProfileName: ~p" + "~n SessionId: ~p" + "~n Pos: ~p" + "~n Value: ~p" + "~nwhen" + "~n Session (db) info: ~p" + "~n Session (db): ~p" + "~n Session (record): ~p" + "~n T: ~p" + "~n E: ~p", + [ProfileName, SessionId, Pos, Value, + (catch httpc_manager:which_session_info(ProfileName)), + Session, + (catch httpc_manager:lookup_session(ProfileName, SessionId)), + T, E]), + exit({failed_updating_session, + [{profile, ProfileName}, + {session_id, SessionId}, + {pos, Pos}, + {value, Value}, + {etype, T}, + {error, E}, + {stacktrace, erlang:get_stacktrace()}]}) end. diff --git a/lib/inets/src/http_client/httpc_manager.erl b/lib/inets/src/http_client/httpc_manager.erl index 771968e169..3612b331e7 100644 --- a/lib/inets/src/http_client/httpc_manager.erl +++ b/lib/inets/src/http_client/httpc_manager.erl @@ -34,8 +34,11 @@ retry_request/2, redirect_request/2, insert_session/2, + lookup_session/2, update_session/4, delete_session/2, + which_sessions/1, + which_session_info/1, set_options/2, get_options/2, store_cookies/3, @@ -186,6 +189,21 @@ insert_session(Session, ProfileName) -> ets:insert(SessionDbName, Session). +%%-------------------------------------------------------------------- +%% Function: lookup_session(SessionId, ProfileName) -> _ +%% SessionId - term() +%% ProfileName - atom() +%% +%% Description: Looks up a session record in the httpc manager +%% table __session_db. +%%-------------------------------------------------------------------- + +lookup_session(SessionId, ProfileName) -> + SessionDbName = session_db_name(ProfileName), + ?hcrt("lookup session", [{session_id, SessionId}, {profile, ProfileName}]), + ets:lookup(SessionDbName, SessionId). + + %%-------------------------------------------------------------------- %% Function: update_session(ProfileName, SessionId, Pos, Value) -> _ %% Session - #session{} @@ -193,7 +211,7 @@ insert_session(Session, ProfileName) -> %% %% Description: Update, only one field (Pos) of the session record %% identified by the SessionId, the session information -%% of the httpc manager table _session_db. +%% of the httpc manager table __session_db. %% Intended to be called by the httpc request handler process. %%-------------------------------------------------------------------- @@ -208,12 +226,12 @@ update_session(ProfileName, SessionId, Pos, Value) -> %%-------------------------------------------------------------------- -%% Function: delete_session(SessionId, ProfileName) -> _ +%% Function: delete_session(SessionId, ProfileName) -> void() %% SessionId - {{Host, Port}, HandlerPid} %% ProfileName - atom() %% %% Description: Deletes session information from the httpc manager -%% table httpc_manager_session_db_. Intended to be called by +%% table __session_db. Intended to be called by %% the httpc request handler process. %%-------------------------------------------------------------------- @@ -223,6 +241,57 @@ delete_session(SessionId, ProfileName) -> ets:delete(SessionDbName, SessionId). +%%-------------------------------------------------------------------- +%% Function: which sessions(ProfileName) -> SessionsInfo +%% ProfileName - atom() +%% SessionsInfo - {GoodSessions, BadSessions, NonSessions} +%% GoodSessions - [#session{}] +%% BadSessions - [tuple()] +%% NonSessions - [term()] +%% +%% Description: Produces a list of all sessions in the session db. +%% Used for debugging and since that is the intent, there is some +%% checking and transforming done, which produces the results. +%%-------------------------------------------------------------------- + +which_sessions(ProfileName) -> + ?hcrt("which_sessions", [{profile, ProfileName}]), + SessionDbName = session_db_name(ProfileName), + which_sessions2(SessionDbName). + +which_sessions2(SessionDbName) -> + Sessions = which_sessions_order(ets:tab2list(SessionDbName)), + GoodSessions = [GoodSession || {good_session, GoodSession} <- Sessions], + BadSessions = [BadSession || {bad_session, BadSession} <- Sessions], + NonSessions = [NonSession || {non_session, NonSession} <- Sessions], + {lists:keysort(#session.id, GoodSessions), + lists:keysort(#session.id, BadSessions), + lists:sort(NonSessions)}. + +which_sessions_order([]) -> + []; +which_sessions_order([Session|Sessions]) when is_record(Session, session) -> + [{good_session, Session} | which_sessions_order(Sessions)]; +which_sessions_order([BadSession|Sessions]) + when is_tuple(BadSession) andalso + (element(1, BadSession) =:= session) -> + [{bad_session, BadSession} | which_sessions_order(Sessions)]; +which_sessions_order([NonSession|Sessions]) -> + [{non_session, NonSession} | which_sessions_order(Sessions)]. + + +%%-------------------------------------------------------------------- +%% Function: which session_info(ProfileName) -> list() +%% +%% Description: Produces a ets table info list of the sessions table +%%-------------------------------------------------------------------- + +which_session_info(ProfileName) -> + SessionDbName = session_db_name(ProfileName), + ?hcrt("which_session_info", [{profile, ProfileName}]), + ets:info(SessionDbName). + + %%-------------------------------------------------------------------- %% Function: set_options(Options, ProfileName) -> ok %% @@ -449,8 +518,8 @@ handle_call({which_cookies, Url, Options}, _, handle_call({get_options, OptionItems}, _, #state{options = Options} = State) -> ?hcrv("get options", [{option_items, OptionItems}]), - Reply = [{OptionItem, get_option(OptionItem, Options)} || OptionItem <- - OptionItems], + Reply = [{OptionItem, get_option(OptionItem, Options)} || + OptionItem <- OptionItems], {reply, Reply, State}; handle_call(info, _, State) -> @@ -665,10 +734,19 @@ update_session_table(SessionDB, Key, Transform) -> %%-------------------------------------------------------------------- get_manager_info(#state{handler_db = HDB, - cookie_db = CDB} = _State) -> + session_db = SDB, + cookie_db = CDB, + options = Options} = _State) -> HandlerInfo = get_handler_info(HDB), + SessionInfo = which_sessions2(SDB), + OptionsInfo = + [{Item, get_option(Item, Options)} || + Item <- record_info(fields, options)], CookieInfo = httpc_cookie:which_cookies(CDB), - [{handlers, HandlerInfo}, {cookies, CookieInfo}]. + [{handlers, HandlerInfo}, + {sessions, SessionInfo}, + {options, OptionsInfo}, + {cookies, CookieInfo}]. sort_handlers(Unsorted) -> sort_handlers2(lists:keysort(1, Unsorted)). -- cgit v1.2.3 From 76ffc030fc320d436b0a540a20783d5d317ae761 Mon Sep 17 00:00:00 2001 From: Micael Karlberg Date: Tue, 22 May 2012 18:05:07 +0200 Subject: [inets/httpc] Updated docs, release notes and appup Added documentation for new (httpc:which_sessions/0,1) and updated (httpc:info/0,1) functions. Also updated appup. OTP-10093 --- lib/inets/doc/src/httpc.xml | 38 ++++++++++++ lib/inets/doc/src/notes.xml | 101 ++++++++++---------------------- lib/inets/src/inets_app/inets.appup.src | 68 ++++----------------- 3 files changed, 83 insertions(+), 124 deletions(-) (limited to 'lib') diff --git a/lib/inets/doc/src/httpc.xml b/lib/inets/doc/src/httpc.xml index 70c845bade..0e6abf3c65 100644 --- a/lib/inets/doc/src/httpc.xml +++ b/lib/inets/doc/src/httpc.xml @@ -648,6 +648,8 @@ apply(Module, Function, [ReplyInfo | Args])

Resets (clears) the cookie database for the specified Profile. If no profile is specified the default profile will be used.

+ + @@ -667,6 +669,42 @@ apply(Module, Function, [ReplyInfo | Args])

This function produces a list of the entire cookie database. It is intended for debugging/testing purposes. If no profile is specified the default profile will be used.

+ + + + + + + which_sessions() -> session_info() + which_sessions(Profile) -> session_info() + Produces a slightly processed dump of the sessions database. + + Profile = profile() | pid() (when started stand_alone) + session_info() = {GoodSessions, BadSessions, NonSessions} + GoodSessions = session() + BadSessions = tuple() + NonSessions = term() + + +

This function produces a slightly processed dump of the session + database. It is intended for debugging. + If no profile is specified the default profile will be used.

+ + +
+
+ + + info() -> list() + info(Profile) -> list() + Produces a list of miscelleneous info + + Profile = profile() | pid() (when started stand_alone) + + +

This function produces a list of miscelleneous info. + It is intended for debugging. + If no profile is specified the default profile will be used.

diff --git a/lib/inets/doc/src/notes.xml b/lib/inets/doc/src/notes.xml index 9e1da12f4a..8ed07f5c94 100644 --- a/lib/inets/doc/src/notes.xml +++ b/lib/inets/doc/src/notes.xml @@ -36,53 +36,23 @@
Inets 5.9.1
Improvements and New Features + -
@@ -103,11 +73,11 @@
+
+-->
@@ -193,11 +163,11 @@ + +--> @@ -376,31 +346,6 @@ -
- Incompatibilities - - - - -

[httpc] Deprecated interface module http has been removed. - It has (long) been replaced by http client interface module - httpc.

-

Own Id: OTP-9359

-
- - -

[httpc|httpd] The old ssl implementation (based on OpenSSL), - has been deprecated. The config option that specified usage of - this version of the ssl app, ossl, has been removed.

-

Own Id: OTP-9522

-
- -
- -
-
Fixed Bugs and Malfunctions +
diff --git a/lib/inets/src/inets_app/inets.appup.src b/lib/inets/src/inets_app/inets.appup.src index 93fd5b9595..a3a3205f65 100644 --- a/lib/inets/src/inets_app/inets.appup.src +++ b/lib/inets/src/inets_app/inets.appup.src @@ -20,7 +20,9 @@ [ {"5.9", [ - {update, httpc_manager, soft, soft_purge, soft_purge, []} + {load_module, httpc, soft_purge, soft_purge, [httpc_manager]}, + {update, httpc_handler, soft, soft_purge, soft_purge, [httpc_manager]}, + {update, httpc_manager, soft, soft_purge, soft_purge, []} ] }, {"5.8.1", @@ -30,7 +32,6 @@ {load_module, httpc, soft_purge, soft_purge, [http_uri, httpc_manager]}, - {update, httpc_manager, soft, soft_purge, soft_purge, [http_uri]}, {load_module, inets_app, soft_purge, soft_purge, [inets_sup]}, {update, inets_sup, soft, soft_purge, soft_purge, []}, @@ -40,37 +41,15 @@ {load_module, httpd_script_env, soft_purge, soft_purge, []}, {load_module, inets, soft_purge, soft_purge, [inets_trace]}, - {update, httpc_manager, soft, soft_purge, soft_purge, []}, - {update, httpc_handler, soft, soft_purge, soft_purge, []}, + {update, httpc_manager, soft, soft_purge, soft_purge, [http_uri]}, + {update, httpc_handler, soft, soft_purge, soft_purge, [httpc_manager]}, {update, httpd_sup, soft, soft_purge, soft_purge, []}, {add_module, inets_trace} ] }, - {"5.8", + {"5.8", [ - {load_module, http_uri, soft_purge, soft_purge, []}, - {load_module, httpc_response, soft_purge, soft_purge, [http_uri]}, - - {load_module, httpc, soft_purge, soft_purge, - [http_uri, httpc_manager]}, - - {load_module, inets_app, soft_purge, soft_purge, [inets_sup]}, - {update, inets_sup, soft, soft_purge, soft_purge, []}, - - {load_module, inets, soft_purge, soft_purge, [inets_trace]}, - - {load_module, httpd_conf, soft_purge, soft_purge, []}, - {load_module, httpd_response, soft_purge, soft_purge, []}, - {load_module, httpd_script_env, soft_purge, soft_purge, []}, - - {load_module, ftp, soft_purge, soft_purge, []}, - {update, httpc_handler, {advanced, upgrade_from_pre_5_8_1}, - soft_purge, soft_purge, []}, - {update, httpc_manager, {advanced, upgrade_from_pre_5_8_1}, - soft_purge, soft_purge, [http_uri, httpc_handler]}, - {update, httpd_sup, soft, soft_purge, soft_purge, []}, - - {add_module, inets_trace} + {restart_application, inets} ] }, {"5.7.2", @@ -82,7 +61,9 @@ [ {"5.9", [ - {update, httpc_manager, soft, soft_purge, soft_purge, []} + {load_module, httpc, soft_purge, soft_purge, [httpc_manager]}, + {update, httpc_handler, soft, soft_purge, soft_purge, [httpc_manager]}, + {update, httpc_manager, soft, soft_purge, soft_purge, []} ] }, {"5.8.1", @@ -92,7 +73,6 @@ {load_module, httpc, soft_purge, soft_purge, [http_uri, httpc_manager]}, - {update, httpc_manager, soft, soft_purge, soft_purge, [http_uri]}, {load_module, inets_app, soft_purge, soft_purge, [inets_sup]}, {update, inets_sup, soft, soft_purge, soft_purge, []}, @@ -102,37 +82,15 @@ {load_module, httpd_script_env, soft_purge, soft_purge, []}, {load_module, inets, soft_purge, soft_purge, []}, - {update, httpc_manager, soft, soft_purge, soft_purge, []}, - {update, httpc_handler, soft, soft_purge, soft_purge, []}, + {update, httpc_manager, soft, soft_purge, soft_purge, [http_uri]}, + {update, httpc_handler, soft, soft_purge, soft_purge, [httpc_manager]}, {update, httpd_sup, soft, soft_purge, soft_purge, []}, {remove, {inets_trace, soft_purge, brutal_purge}} ] }, {"5.8", [ - {load_module, http_uri, soft_purge, soft_purge, []}, - {load_module, httpc_response, soft_purge, soft_purge, [http_uri]}, - - {load_module, httpc, soft_purge, soft_purge, - [http_uri, httpc_manager]}, - - {load_module, inets_app, soft_purge, soft_purge, [inets_sup]}, - {update, inets_sup, soft, soft_purge, soft_purge, []}, - - {load_module, inets, soft_purge, soft_purge, []}, - - {load_module, httpd_conf, soft_purge, soft_purge, []}, - {load_module, httpd_response, soft_purge, soft_purge, []}, - {load_module, httpd_script_env, soft_purge, soft_purge, []}, - - {load_module, ftp, soft_purge, soft_purge, []}, - {update, httpc_handler, {advanced, upgrade_from_pre_5_8_1}, - soft_purge, soft_purge, []}, - {update, httpc_manager, {advanced, upgrade_from_pre_5_8_1}, - soft_purge, soft_purge, [http_uri, httpc_handler]}, - {update, httpd_sup, soft, soft_purge, soft_purge, []}, - - {remove, {inets_trace, soft_purge, brutal_purge}} + {restart_application, inets} ] }, {"5.7.2", -- cgit v1.2.3 From 4c5c287cfe234b8daaf8ead712edc43aa419949b Mon Sep 17 00:00:00 2001 From: Micael Karlberg Date: Wed, 23 May 2012 14:54:56 +0200 Subject: [inets] Removed R14B compatible version of behaviour definition Removed R14B compatible version of (inets-service and tftp) behaviour definition. OTP-10095 --- lib/inets/doc/src/notes.xml | 10 ++++++++-- lib/inets/src/inets_app/inets.appup.src | 10 ++++++++++ lib/inets/src/inets_app/inets.mk | 6 +----- lib/inets/src/inets_app/inets_service.erl | 17 +---------------- lib/inets/src/tftp/tftp.erl | 18 +----------------- 5 files changed, 21 insertions(+), 40 deletions(-) (limited to 'lib') diff --git a/lib/inets/doc/src/notes.xml b/lib/inets/doc/src/notes.xml index 8ed07f5c94..9a2fced12e 100644 --- a/lib/inets/doc/src/notes.xml +++ b/lib/inets/doc/src/notes.xml @@ -42,16 +42,22 @@ -

Better handling of errorI(s) during update of the session +

Better handling of error(s) during update of the session database.

Also added and updated some debugging functions - which_sessions/10,1 + which_sessions/0,1 and info/0.

Own Id: OTP-10093

Aux Id: Seq 12062

+ +

Removed R14B compatible version of (inets-service and + tftp) behaviour definition.

+

Own Id: OTP-10095

+
+
diff --git a/lib/inets/src/inets_app/inets.appup.src b/lib/inets/src/inets_app/inets.appup.src index a3a3205f65..2adb2a0fc8 100644 --- a/lib/inets/src/inets_app/inets.appup.src +++ b/lib/inets/src/inets_app/inets.appup.src @@ -20,6 +20,8 @@ [ {"5.9", [ + {load_module, tftp, soft_purge, soft_purge, [inets_service]}, + {load_module, inets_service, soft_purge, soft_purge, []}, {load_module, httpc, soft_purge, soft_purge, [httpc_manager]}, {update, httpc_handler, soft, soft_purge, soft_purge, [httpc_manager]}, {update, httpc_manager, soft, soft_purge, soft_purge, []} @@ -27,6 +29,9 @@ }, {"5.8.1", [ + {load_module, tftp, soft_purge, soft_purge, [inets_service]}, + {load_module, inets_service, soft_purge, soft_purge, []}, + {load_module, http_uri, soft_purge, soft_purge, []}, {load_module, httpc_response, soft_purge, soft_purge, [http_uri]}, @@ -61,6 +66,8 @@ [ {"5.9", [ + {load_module, tftp, soft_purge, soft_purge, [inets_service]}, + {load_module, inets_service, soft_purge, soft_purge, []}, {load_module, httpc, soft_purge, soft_purge, [httpc_manager]}, {update, httpc_handler, soft, soft_purge, soft_purge, [httpc_manager]}, {update, httpc_manager, soft, soft_purge, soft_purge, []} @@ -68,6 +75,9 @@ }, {"5.8.1", [ + {load_module, tftp, soft_purge, soft_purge, [inets_service]}, + {load_module, inets_service, soft_purge, soft_purge, []}, + {load_module, http_uri, soft_purge, soft_purge, []}, {load_module, httpc_response, soft_purge, soft_purge, [http_uri]}, diff --git a/lib/inets/src/inets_app/inets.mk b/lib/inets/src/inets_app/inets.mk index d24cc0aea3..adef32dc19 100644 --- a/lib/inets/src/inets_app/inets.mk +++ b/lib/inets/src/inets_app/inets.mk @@ -2,7 +2,7 @@ # %CopyrightBegin% # -# Copyright Ericsson AB 2010-2011. All Rights Reserved. +# Copyright Ericsson AB 2010-2012. All Rights Reserved. # # The contents of this file are subject to the Erlang Public License, # Version 1.1, (the "License"); you may not use this file except in @@ -33,10 +33,6 @@ ifeq ($(WARN_UNUSED_WARS), true) ERL_COMPILE_FLAGS += +warn_unused_vars endif -ifeq ($(shell erl -noshell -eval 'io:format("~4s", [erlang:system_info(otp_release)])' -s init stop), R14B) -INETS_ERL_COMPILE_FLAGS += -D'OTP-R14B-COMPILER' -endif - INETS_APP_VSN_COMPILE_FLAGS = \ +'{parse_transform,sys_pre_attributes}' \ +'{attribute,insert,app_vsn,$(APP_VSN)}' diff --git a/lib/inets/src/inets_app/inets_service.erl b/lib/inets/src/inets_app/inets_service.erl index a057a51e2c..d17fdfe13e 100644 --- a/lib/inets/src/inets_app/inets_service.erl +++ b/lib/inets/src/inets_app/inets_service.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2007-2011. All Rights Reserved. +%% Copyright Ericsson AB 2007-2012. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -20,20 +20,6 @@ -module(inets_service). --ifdef('OTP-R14B-COMPILER'). - --export([behaviour_info/1]). - -behaviour_info(callbacks) -> - [{start_standalone, 1}, - {start_service, 1}, - {stop_service, 1}, - {services, 0}, - {service_info, 1}]; -behaviour_info(_) -> - undefined. - --else. %% Starts service stand-alone %% start_standalone(Config) -> % {ok, Pid} | {error, Reason} @@ -83,4 +69,3 @@ behaviour_info(_) -> -callback service_info(Service :: term()) -> {ok, [{Property :: term(), Value :: term()}]} | {error, Reason :: term()}. --endif. diff --git a/lib/inets/src/tftp/tftp.erl b/lib/inets/src/tftp/tftp.erl index 0d7ae1a89e..1621add246 100644 --- a/lib/inets/src/tftp/tftp.erl +++ b/lib/inets/src/tftp/tftp.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2005-2011. All Rights Reserved. +%% Copyright Ericsson AB 2005-2012. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -224,20 +224,6 @@ service_info/1 ]). --ifdef('OTP-R14B-COMPILER'). - --export([behaviour_info/1]). - -behaviour_info(callbacks) -> - [{prepare, 6}, - {open, 6}, - {read, 1}, - {write, 2}, - {abort, 3}]; -behaviour_info(_) -> - undefined. - --else. -type peer() :: {PeerType :: inet | inet6, PeerHost :: inet:ip_address(), @@ -280,8 +266,6 @@ behaviour_info(_) -> -callback abort(Code :: error_code(), string(), State :: term()) -> 'ok'. --endif. - -include("tftp.hrl"). -- cgit v1.2.3 From 517315f2a0f5f9f51ba6b58959f93a38ad24047c Mon Sep 17 00:00:00 2001 From: Micael Karlberg Date: Wed, 23 May 2012 18:46:56 +0200 Subject: [inets] Fixed release notes OTP-10095 --- lib/inets/doc/src/notes.xml | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'lib') diff --git a/lib/inets/doc/src/notes.xml b/lib/inets/doc/src/notes.xml index 9a2fced12e..b6e8be467f 100644 --- a/lib/inets/doc/src/notes.xml +++ b/lib/inets/doc/src/notes.xml @@ -44,10 +44,11 @@

Better handling of error(s) during update of the session database.

-

Also added and updated some debugging functions - which_sessions/0,1 - and - info/0.

+

Also added + (which_sessions/0,1) + and updated and documented + (info/0) + some debugging functions.

Own Id: OTP-10093

Aux Id: Seq 12062

-- cgit v1.2.3 From 1bc041bd68040220081e8af275701f92f4a07aae Mon Sep 17 00:00:00 2001 From: Jesper Louis Andersen Date: Fri, 8 Jun 2012 19:18:06 +0200 Subject: Elaborate on timeouts in the httpc documentation All timeouts are in milliseconds. Reflect this in the documentation so it is explicit that it is so. --- lib/inets/doc/src/httpc.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'lib') diff --git a/lib/inets/doc/src/httpc.xml b/lib/inets/doc/src/httpc.xml index 70c845bade..f032ac96e1 100644 --- a/lib/inets/doc/src/httpc.xml +++ b/lib/inets/doc/src/httpc.xml @@ -488,7 +488,7 @@ apply(Module, Function, [ReplyInfo | Args]) KeepAliveTimeout = integer() Default is 120000 (= 2 min). If a persistent connection is idle longer than the - keep_alive_timeout the client will close the connection. + keep_alive_timeout in milliseconds, the client will close the connection. The server may also have such a time out but you should not count on it! MaxPipeline = integer() @@ -498,7 +498,7 @@ apply(Module, Function, [ReplyInfo | Args]) Default is 0, which will result in pipelining not being used. If a persistent connection is idle longer than the - pipeline_timeout the client will close the connection. + pipeline_timeout in milliseconds the client will close the connection. CookieMode = enabled | disabled | verify Default is disabled. If Cookies are enabled all valid cookies will automatically be -- cgit v1.2.3 From 134eb88158b5ccb49afc054091deea38580e9f86 Mon Sep 17 00:00:00 2001 From: Micael Karlberg Date: Thu, 14 Jun 2012 12:56:25 +0200 Subject: Added missing comma and set proper version --- lib/inets/doc/src/httpc.xml | 105 +++++++++++++++++++++++--------------------- lib/inets/vsn.mk | 2 +- 2 files changed, 55 insertions(+), 52 deletions(-) (limited to 'lib') diff --git a/lib/inets/doc/src/httpc.xml b/lib/inets/doc/src/httpc.xml index f032ac96e1..f4d3b97122 100644 --- a/lib/inets/doc/src/httpc.xml +++ b/lib/inets/doc/src/httpc.xml @@ -480,66 +480,69 @@ apply(Module, Function, [ReplyInfo | Args]) ex: "134.138" or "[FEDC:BA98" (all IP-addresses starting with 134.138 or FEDC:BA98), "66.35.250.150" or "[2010:836B:4179::836B:4179]" (a complete IP-address). MaxSessions = integer() Default is 2. - Maximum number of persistent connections to a host. + Maximum number of persistent connections to a host. MaxKeepAlive = integer() - Default is 5. - Maximum number of outstanding requests on the same connection to - a host. - KeepAliveTimeout = integer() - Default is 120000 (= 2 min). - If a persistent connection is idle longer than the - keep_alive_timeout in milliseconds, the client will close the connection. - The server may also have such a time out but you should - not count on it! + Default is 5. + Maximum number of outstanding requests on the same connection to + a host. + KeepAliveTimeout = integer() + Default is 120000 (= 2 min). + If a persistent connection is idle longer than the + keep_alive_timeout in milliseconds, + the client will close the connection. + The server may also have such a time out but you should + not count on it! MaxPipeline = integer() - Default is 2. - Maximum number of outstanding requests on a pipelined connection to a host. - PipelineTimeout = integer() - Default is 0, - which will result in pipelining not being used. - If a persistent connection is idle longer than the - pipeline_timeout in milliseconds the client will close the connection. + Default is 2. + Maximum number of outstanding requests on a pipelined connection + to a host. + PipelineTimeout = integer() + Default is 0, + which will result in pipelining not being used. + If a persistent connection is idle longer than the + pipeline_timeout in milliseconds, + the client will close the connection. CookieMode = enabled | disabled | verify Default is disabled. - If Cookies are enabled all valid cookies will automatically be - saved in the client manager's cookie database. - If the option verify is used the function store_cookies/2 - has to be called for the cookies to be saved. - IpFamily = inet | inet6 | inet6fb4 - By default inet. - When it is set to inet6fb4 you can use both ipv4 and ipv6. - It first tries inet6 and if that does not works falls back to inet. - The option is here to provide a workaround for buggy ipv6 stacks to ensure that - ipv4 will always work. + If Cookies are enabled all valid cookies will automatically be + saved in the client manager's cookie database. + If the option verify is used the function store_cookies/2 + has to be called for the cookies to be saved. + IpFamily = inet | inet6 | inet6fb4 + By default inet. + When it is set to inet6fb4 you can use both ipv4 and ipv6. + It first tries inet6 and if that does not works falls back to inet. + The option is here to provide a workaround for buggy ipv6 stacks to ensure that + ipv4 will always work. IpAddress = ip_address() - If the host has several network interfaces, this option specifies which one to use. - See gen_tcp:connect/3,4 for more info. + If the host has several network interfaces, this option specifies which one to use. + See gen_tcp:connect/3,4 for more info. Port = integer() - Specify which local port number to use. - See gen_tcp:connect/3,4 for more info. - VerboseMode = false | verbose | debug | trace - Default is false. - This option is used to switch on (or off) - different levels of erlang trace on the client. - It is a debug feature. + Specify which local port number to use. + See gen_tcp:connect/3,4 for more info. + VerboseMode = false | verbose | debug | trace + Default is false. + This option is used to switch on (or off) + different levels of erlang trace on the client. + It is a debug feature. Profile = profile() | pid() (when started stand_alone) -

Sets options to be used for subsequent requests.

- -

If possible the client will keep its connections - alive and use persistent connections - with or without pipeline depending on configuration - and current circumstances. The HTTP/1.1 specification does not - provide a guideline for how many requests would be - ideal to be sent on a persistent connection, - this very much depends on the - application. Note that a very long queue of requests may cause a - user perceived delay as earlier requests may take a long time - to complete. The HTTP/1.1 specification does suggest a - limit of 2 persistent connections per server, which is the - default value of the max_sessions option.

-
+

Sets options to be used for subsequent requests.

+ +

If possible the client will keep its connections + alive and use persistent connections + with or without pipeline depending on configuration + and current circumstances. The HTTP/1.1 specification does not + provide a guideline for how many requests would be + ideal to be sent on a persistent connection, + this very much depends on the + application. Note that a very long queue of requests may cause a + user perceived delay as earlier requests may take a long time + to complete. The HTTP/1.1 specification does suggest a + limit of 2 persistent connections per server, which is the + default value of the max_sessions option.

+
diff --git a/lib/inets/vsn.mk b/lib/inets/vsn.mk index 488947c3a1..949eceea7f 100644 --- a/lib/inets/vsn.mk +++ b/lib/inets/vsn.mk @@ -18,7 +18,7 @@ # %CopyrightEnd% APPLICATION = inets -INETS_VSN = 5.9 +INETS_VSN = 5.9.1 PRE_VSN = APP_VSN = "$(APPLICATION)-$(INETS_VSN)$(PRE_VSN)" -- cgit v1.2.3 From 6549340d9920df8f8c29223fe1853a37e30f0a41 Mon Sep 17 00:00:00 2001 From: Micael Karlberg Date: Wed, 11 Jul 2012 11:07:30 +0200 Subject: [inets] Updated release notes and improved parts of the doc Updated release and improved (httpc-) documentation for KeepAlive and Pipeline timeout options. OTP-10095, OTP-10114 --- lib/inets/doc/src/notes.xml | 110 ++++++++++++++++++++++---------------------- 1 file changed, 54 insertions(+), 56 deletions(-) (limited to 'lib') diff --git a/lib/inets/doc/src/notes.xml b/lib/inets/doc/src/notes.xml index b6e8be467f..437fa7b9d4 100644 --- a/lib/inets/doc/src/notes.xml +++ b/lib/inets/doc/src/notes.xml @@ -13,12 +13,12 @@ compliance with the License. You should have received a copy of the Erlang Public License along with this software. If not, it can be retrieved online at http://www.erlang.org/. - + Software distributed under the License is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for the specific language governing rights and limitations under the License. - + Inets Release Notes @@ -32,42 +32,37 @@ notes.xml - -
Inets 5.9.1 - -
Improvements and New Features - - + +
+ Inets 5.9.1 + +
+ Improvements and New Features + + - -

Better handling of error(s) during update of the session - database.

-

Also added - (which_sessions/0,1) - and updated and documented - (info/0) - some debugging functions.

-

Own Id: OTP-10093

-

Aux Id: Seq 12062

-
- - -

Removed R14B compatible version of (inets-service and + +

Removed R14B compatible version of (inets-service and tftp) behaviour definition.

Own Id: OTP-10095

-
- + + + +

[httpc] Documentation of KeepAlive and Pipeline timeout + options have been improved.

+

Own Id: OTP-10114

+
- +
-
Fixed Bugs and Malfunctions - - +
+ Fixed Bugs and Malfunctions +

-

+ +
- - +
---> - +
- -
Inets 5.9 - -
Improvements and New Features - - + +
+ Inets 5.9 + +
+ Improvements and New Features + + - +

[httpd] Make the server header configurable with new config option server_tokens. -- cgit v1.2.3 From 84f2859757a7fbf3d1280648f995e0a7d0e0754b Mon Sep 17 00:00:00 2001 From: Micael Karlberg Date: Wed, 18 Jul 2012 12:52:57 +0200 Subject: Add error reason ehostunreach when trying with IPv4 If a IPv6 (inet6) connect fails, we try to connect with IPv4 (inet) again. Added error reason ehostunreach for which it is ok to try again (with IPv4). --- lib/inets/test/inets_test_lib.erl | 28 +++++++++------------------- 1 file changed, 9 insertions(+), 19 deletions(-) (limited to 'lib') diff --git a/lib/inets/test/inets_test_lib.erl b/lib/inets/test/inets_test_lib.erl index 7f4b0ec8d8..4ec8a6002f 100644 --- a/lib/inets/test/inets_test_lib.erl +++ b/lib/inets/test/inets_test_lib.erl @@ -536,25 +536,15 @@ connect(ip_comm, Host, Port, Opts, Type) -> tsp("connect success"), {ok, Socket}; - {error, nxdomain} when Type =:= inet6 -> - tsp("connect error nxdomain when" - "~n Opts: ~p", [Opts]), - connect(ip_comm, Host, Port, Opts -- [inet6], inet); - {error, eafnosupport} when Type =:= inet6 -> - tsp("connect error eafnosupport when" - "~n Opts: ~p", [Opts]), - connect(ip_comm, Host, Port, Opts -- [inet6], inet); - {error, econnreset} when Type =:= inet6 -> - tsp("connect error econnreset when" - "~n Opts: ~p", [Opts]), - connect(ip_comm, Host, Port, Opts -- [inet6], inet); - {error, enetunreach} when Type =:= inet6 -> - tsp("connect error eafnosupport when" - "~n Opts: ~p", [Opts]), - connect(ip_comm, Host, Port, Opts -- [inet6], inet); - {error, econnrefused} when Type =:= inet6 -> - tsp("connect error econnrefused when" - "~n Opts: ~p", [Opts]), + {error, Reason} when ((Type =:= inet6) andalso + ((Reason =:= nxdomain) orelse + (Reason =:= eafnosupport) orelse + (Reason =:= econnreset) orelse + (Reason =:= enetunreach) orelse + (Reason =:= econnrefused) orelse + (Reason =:= ehostunreach))) -> + tsp("connect error ~w when" + "~n Opts: ~p", [Reason, Opts]), connect(ip_comm, Host, Port, Opts -- [inet6], inet); Error -> -- cgit v1.2.3 From 3d639df53de38e398a208f4f57cc9a7969733c63 Mon Sep 17 00:00:00 2001 From: Micael Karlberg Date: Fri, 20 Jul 2012 10:14:09 +0200 Subject: Improved debug printouts --- lib/inets/test/inets_test_lib.erl | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'lib') diff --git a/lib/inets/test/inets_test_lib.erl b/lib/inets/test/inets_test_lib.erl index 4ec8a6002f..ef6529025f 100644 --- a/lib/inets/test/inets_test_lib.erl +++ b/lib/inets/test/inets_test_lib.erl @@ -543,12 +543,14 @@ connect(ip_comm, Host, Port, Opts, Type) -> (Reason =:= enetunreach) orelse (Reason =:= econnrefused) orelse (Reason =:= ehostunreach))) -> - tsp("connect error ~w when" - "~n Opts: ~p", [Reason, Opts]), + tsp("connect(ip_comm) -> Connect error: " + "~n Reason: ~p" + "~n Type: ~p" + "~n Opts: ~p", [Reason, Type, Opts]), connect(ip_comm, Host, Port, Opts -- [inet6], inet); Error -> - tsp("connect(ip_conn) -> Fatal connect error: " + tsp("connect(ip_comm) -> Fatal connect error: " "~n Error: ~p" "~nwhen" "~n Host: ~p" -- cgit v1.2.3 From 3f61f4daccc11658e838771b696c205fccac709e Mon Sep 17 00:00:00 2001 From: Micael Karlberg Date: Tue, 24 Jul 2012 12:57:20 +0200 Subject: Add connect timeout --- lib/inets/test/inets_test_lib.erl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/inets/test/inets_test_lib.erl b/lib/inets/test/inets_test_lib.erl index ef6529025f..e7c44391c7 100644 --- a/lib/inets/test/inets_test_lib.erl +++ b/lib/inets/test/inets_test_lib.erl @@ -531,7 +531,7 @@ connect(ip_comm, Host, Port, Opts, Type) -> "~n Opts: ~p" "~n Type: ~p", [Host, Port, Opts, Type]), - case gen_tcp:connect(Host, Port, Opts) of + case gen_tcp:connect(Host, Port, Opts, timer:seconds(10)) of {ok, Socket} -> tsp("connect success"), {ok, Socket}; -- cgit v1.2.3 From 5031e2277c1b1af83bde2d3990d2fc4ab3f119c5 Mon Sep 17 00:00:00 2001 From: Micael Karlberg Date: Wed, 25 Jul 2012 08:46:36 +0200 Subject: Did not handle timeout reason when IPv6 --- lib/inets/test/inets_test_lib.erl | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/inets/test/inets_test_lib.erl b/lib/inets/test/inets_test_lib.erl index e7c44391c7..0f8671b682 100644 --- a/lib/inets/test/inets_test_lib.erl +++ b/lib/inets/test/inets_test_lib.erl @@ -537,7 +537,8 @@ connect(ip_comm, Host, Port, Opts, Type) -> {ok, Socket}; {error, Reason} when ((Type =:= inet6) andalso - ((Reason =:= nxdomain) orelse + ((Reason =:= timeout) orelse + (Reason =:= nxdomain) orelse (Reason =:= eafnosupport) orelse (Reason =:= econnreset) orelse (Reason =:= enetunreach) orelse -- cgit v1.2.3 From 4a7c3d856148c447f07150d86f04f078c82be33f Mon Sep 17 00:00:00 2001 From: Micael Karlberg Date: Mon, 30 Jul 2012 13:52:26 +0200 Subject: [inets/httpd] Add prinouts to the security test case --- lib/inets/test/httpd_mod.erl | 229 ++++++++++++++++++++++++++++++++----------- 1 file changed, 173 insertions(+), 56 deletions(-) (limited to 'lib') diff --git a/lib/inets/test/httpd_mod.erl b/lib/inets/test/httpd_mod.erl index cb1214b7fb..b548eba6b7 100644 --- a/lib/inets/test/httpd_mod.erl +++ b/lib/inets/test/httpd_mod.erl @@ -82,19 +82,23 @@ actions(Type, Port, Host, Node) -> [{statuscode, 200}, {version, "HTTP/1.0"}]). + %%------------------------------------------------------------------------- security(ServerRoot, Type, Port, Host, Node) -> - %% io:format(user, "~w:security -> entry with" - %% "~n ServerRoot: ~p" - %% "~n Type: ~p" - %% "~n Port: ~p" - %% "~n Host: ~p" - %% "~n Node: ~p" - %% "~n", [?MODULE, ServerRoot, Type, Port, Host, Node]), - -%% io:format(user, "~w:security -> register~n", [?MODULE]), + tsp("security -> " + "entry with" + "~n ServerRoot: ~p" + "~n Type: ~p" + "~n Port: ~p" + "~n Host: ~p" + "~n Node: ~p", [ServerRoot, Type, Port, Host, Node]), + + tsp("security -> " + "register - receive security events"), global:register_name(mod_security_test, self()), % Receive events + tsp("security -> " + "sleep"), test_server:sleep(5000), OpenDir = filename:join([ServerRoot, "htdocs", "open"]), @@ -102,133 +106,240 @@ security(ServerRoot, Type, Port, Host, Node) -> %% Test blocking / unblocking of users. %% /open, require user one Aladdin -%% io:format(user, "~w:security -> remove user~n", [?MODULE]), + tsp("security -> " + "blocking and unblocking of users - " + "remove all existing users"), remove_users(Node, ServerRoot, Host, Port, "open"), -%% io:format(user, "~w:security -> auth request~n", [?MODULE]), + tsp("security -> " + "blocking and unblocking of users - " + "auth request for nonex user 'one' - expect 401"), auth_request(Type, Host, Port, Node, "/open/", "one", "onePassword", [{statuscode, 401}]), -%% io:format(user, "~w:security -> await fail security event~n", [?MODULE]), + + tsp("security -> " + "blocking and unblocking of users - " + "await fail security event"), receive_security_event({event, auth_fail, Port, OpenDir, [{user, "one"}, {password, "onePassword"}]}, Node, Port), -%% io:format(user, "~w:security -> auth request~n", [?MODULE]), + tsp("security -> " + "blocking and unblocking of users - " + "auth request for nonex user 'two' - expect 401"), auth_request(Type,Host,Port,Node,"/open/", "two", "twoPassword", [{statuscode, 401}]), -%% io:format(user, "~w:security -> await fail security event~n", [?MODULE]), + + tsp("security -> " + "blocking and unblocking of users - " + "await fail security event"), receive_security_event({event, auth_fail, Port, OpenDir, [{user, "two"}, {password, "twoPassword"}]}, Node, Port), -%% io:format(user, "~w:security -> auth request~n", [?MODULE]), + tsp("security -> " + "blocking and unblocking of users - " + "auth request for nonex user 'Alladin' - expect 401"), auth_request(Type, Host, Port, Node,"/open/", "Aladdin", "AladdinPassword", [{statuscode, 401}]), -%% io:format(user, "~w:security -> await fail security event~n", [?MODULE]), + + tsp("security -> " + "blocking and unblocking of users - " + "await fail security event"), receive_security_event({event, auth_fail, Port, OpenDir, [{user, "Aladdin"}, {password, "AladdinPassword"}]}, Node, Port), -%% io:format(user, "~w:security -> add users~n", [?MODULE]), + tsp("security -> " + "blocking and unblocking of users - " + "add user 'one'"), add_user(Node, ServerRoot, Port, "open", "one", "onePassword", []), + + tsp("security -> " + "blocking and unblocking of users - " + "add user 'two'"), add_user(Node, ServerRoot, Port, "open", "two", "twoPassword", []), -%% io:format(user, "~w:security -> auth request~n", [?MODULE]), + tsp("security -> " + "blocking and unblocking of users - " + "auth request 1 for user 'one' with wrong password - expect 401"), auth_request(Type, Host, Port, Node,"/open/", "one", "WrongPassword", [{statuscode, 401}]), -%% io:format(user, "~w:security -> await fail security event~n", [?MODULE]), + + tsp("security -> " + "blocking and unblocking of users - " + "await fail security event"), receive_security_event({event, auth_fail, Port, OpenDir, [{user, "one"}, {password, "WrongPassword"}]}, Node, Port), -%% io:format(user, "~w:security -> auth request~n", [?MODULE]), + tsp("security -> " + "blocking and unblocking of users - " + "auth request 2 for user 'one' with wrong password - expect 401"), auth_request(Type, Host, Port, Node,"/open/", "one", "WrongPassword", [{statuscode, 401}]), -%% io:format(user, "~w:security -> await fail security event~n", [?MODULE]), + + tsp("security -> " + "blocking and unblocking of users - " + "await fail security event"), receive_security_event({event, auth_fail, Port, OpenDir, [{user, "one"}, {password, "WrongPassword"}]}, Node, Port), -%% io:format(user, "~w:security -> await block security event~n", [?MODULE]), + tsp("security -> " + "blocking and unblocking of users - " + "await block security event (two failed attempts)"), receive_security_event({event, user_block, Port, OpenDir, [{user, "one"}]}, Node, Port), -%% io:format(user, "~w:security -> unregister~n", [?MODULE]), + tsp("security -> " + "blocking and unblocking of users - " + "unregister - no more security events"), global:unregister_name(mod_security_test), % No more events. -%% io:format(user, "~w:security -> auth request~n", [?MODULE]), + tsp("security -> " + "blocking and unblocking of users - " + "auth request for user 'one' with wrong password - expect 401"), auth_request(Type, Host, Port, Node,"/open/", "one", "WrongPassword", [{statuscode, 401}]), -%% io:format(user, "~w:security -> auth request~n", [?MODULE]), + tsp("security -> " + "blocking and unblocking of users - " + "auth request for user 'one' with correct password - expect 403"), auth_request(Type, Host, Port, Node,"/open/", "one", "onePassword", [{statuscode, 403}]), %% User "one" should be blocked now.. - %% [{"one",_, Port, OpenDir,_}] = list_blocked_users(Node,Port), -%% io:format(user, "~w:security -> list blocked users~n", [?MODULE]), + tsp("security -> " + "blocking and unblocking of users - " + "list blocked users - 'one' should be the only one"), case list_blocked_users(Node, Port) of [{"one",_, Port, OpenDir,_}] -> ok; Blocked -> - %% io:format(user, "~w:security -> Blocked: ~p" - %% "~n", [?MODULE, Blocked]), + tsp(" *** unexpected blocked users ***" + "~n Blocked: ~p", [Blocked]), exit({unexpected_blocked, Blocked}) end, - -%% io:format(user, "~w:security -> list blocked users~n", [?MODULE]), - [{"one",_, Port, OpenDir,_}] = list_blocked_users(Node,Port,OpenDir), -%% io:format(user, "~w:security -> unblock user~n", [?MODULE]), + tsp("security -> " + "blocking and unblocking of users - " + "list users blocked for dir '~p' - " + "user 'one' should be the only one", [OpenDir]), + [{"one",_, Port, OpenDir,_}] = list_blocked_users(Node, Port, OpenDir), + + tsp("security -> " + "blocking and unblocking of users - " + "unblock user 'one' for dir '~p'", [OpenDir]), true = unblock_user(Node, "one", Port, OpenDir), - %% User "one" should not be blocked any more.. -%% io:format(user, "~w:security -> list blocked users~n", [?MODULE]), + %% User "one" should not be blocked any more. + + tsp("security -> " + "blocking and unblocking of users - " + "ensure user 'one' is no longer blocked"), [] = list_blocked_users(Node, Port), -%% io:format(user, "~w:security -> list blocked users~n", [?MODULE]), - [] = list_blocked_users(Node, Port, OpenDir), -%% io:format(user, "~w:security -> auth request~n", [?MODULE]), + + + tsp("security -> " + "blocking and unblocking of users - " + "auth request for user 'one' with correct password - expect 200"), auth_request(Type, Host, Port, Node,"/open/", "one", "onePassword", [{statuscode, 200}]), + + %% Test list_auth_users & auth_timeout -%% io:format(user, "~w:security -> list blocked users~n", [?MODULE]), + + tsp("security -> " + "list-auth-users and auth-timeout - " + "list auth users - expect user 'one'"), ["one"] = list_auth_users(Node, Port), -%% io:format(user, "~w:security -> list blocked users~n", [?MODULE]), - ["one"] = list_auth_users(Node, Port, OpenDir), -%% io:format(user, "~w:security -> auth request~n", [?MODULE]), + + tsp("security -> " + "list-auth-users and auth-timeout - " + "auth request for user 'two' with wrong password - expect 401"), auth_request(Type, Host, Port, Node,"/open/", "two", "onePassword", [{statuscode, 401}]), -%% io:format(user, "~w:security -> list blocked users~n", [?MODULE]), + + tsp("security -> " + "list-auth-users and auth-timeout - " + "list auth users - expect user 'one'"), ["one"] = list_auth_users(Node, Port), -%% io:format(user, "~w:security -> list blocked users~n", [?MODULE]), + + tsp("security -> " + "list-auth-users and auth-timeout - " + "list auth users for dir '~p' - expect user 'one'", [OpenDir]), ["one"] = list_auth_users(Node, Port, OpenDir), -%% io:format(user, "~w:security -> auth request~n", [?MODULE]), + + tsp("security -> " + "list-auth-users and auth-timeout - " + "auth request for user 'two' with correct password - expect 401"), auth_request(Type, Host, Port, Node,"/open/", "two", "twoPassword", [{statuscode, 401}]), -%% io:format(user, "~w:security -> list blocked users~n", [?MODULE]), + + tsp("security -> " + "list-auth-users and auth-timeout - " + "list auth users - expect user 'one'"), ["one"] = list_auth_users(Node, Port), -%% io:format(user, "~w:security -> list blocked users~n", [?MODULE]), + + tsp("security -> " + "list-auth-users and auth-timeout - " + "list auth users for dir '~p' - expect user 'one'", [OpenDir]), ["one"] = list_auth_users(Node, Port, OpenDir), + %% Wait for successful auth to timeout. + tsp("security -> " + "list-auth-users and auth-timeout - " + "wait for successful auth to timeout"), test_server:sleep(?AUTH_TIMEOUT*1001), -%% io:format(user, "~w:security -> list blocked users~n", [?MODULE]), + + tsp("security -> " + "list-auth-users and auth-timeout - " + "list auth users - expect none"), [] = list_auth_users(Node, Port), -%% io:format(user, "~w:security -> list blocked users~n", [?MODULE]), + + tsp("security -> " + "list-auth-users and auth-timeout - " + "list auth users for dir '~p'~n - expect none", [OpenDir]), [] = list_auth_users(Node, Port, OpenDir), + %% "two" is blocked. -%% io:format(user, "~w:security -> unblock user~n", [?MODULE]), + + tsp("security -> " + "list-auth-users and auth-timeout - " + "unblock user 'two' for dir '~p'", [OpenDir]), true = unblock_user(Node, "two", Port, OpenDir), + + %% Test explicit blocking. Block user 'two'. -%% io:format(user, "~w:security -> list blocked users~n", [?MODULE]), + + tsp("security -> " + "explicit blocking - list blocked users - should be none"), [] = list_blocked_users(Node,Port,OpenDir), -%% io:format(user, "~w:security -> block user~n", [?MODULE]), + + tsp("security -> " + "explicit blocking - " + "block user 'two' for dir '~p'", [OpenDir]), true = block_user(Node, "two", Port, OpenDir, 10), -%% io:format(user, "~w:security -> auth request~n", [?MODULE]), + + tsp("security -> " + "explicit blocking - " + "auth request for user 'two' with correct password - expect 401"), auth_request(Type, Host, Port, Node,"/open/", "two", "twoPassword", - [{statuscode, 401}]). + [{statuscode, 401}]), + tsp("security -> " + "done"). + %%------------------------------------------------------------------------- auth(Type, Port, Host, Node) -> + tsp("auth -> " + "entry with" + "~n Type: ~p" + "~n Port: ~p" + "~n Host: ~p" + "~n Node: ~p", [Type, Port, Host, Node]), + %% Authentication required! ok = httpd_test_lib:verify_request(Type,Host,Port,Node, "GET /open/ HTTP/1.0\r\n\r\n", @@ -1027,8 +1138,14 @@ check_lists_members1(L1,L2) -> {error,{lists_not_equal,L1,L2}}. -%% tsp(F) -> -%% inets_test_lib:tsp(F). +%% p(F) -> +%% p(F, []). + +%% p(F, A) -> +%% io:format(user, "~w:" ++ F ++ "~n", [?MODULE|A]). + +tsp(F) -> + inets_test_lib:tsp(F). tsp(F, A) -> inets_test_lib:tsp(F, A). -- cgit v1.2.3 From d8633aded52b5dc96707667cca72ef632e414296 Mon Sep 17 00:00:00 2001 From: Micael Karlberg Date: Mon, 30 Jul 2012 14:38:13 +0200 Subject: [inets/httpd] Add another (cosmetic) printout for security test case --- lib/inets/test/httpd_mod.erl | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) (limited to 'lib') diff --git a/lib/inets/test/httpd_mod.erl b/lib/inets/test/httpd_mod.erl index b548eba6b7..387263ce58 100644 --- a/lib/inets/test/httpd_mod.erl +++ b/lib/inets/test/httpd_mod.erl @@ -1024,13 +1024,11 @@ list_users(Node, Root, _Host, Port, Dir) -> receive_security_event(Event, Node, Port) -> - %% io:format(user, "~w:receive_security_event -> entry with" - %% "~n Event: ~p" - %% "~n Node: ~p" - %% "~n Port: ~p" - %% "~n", [?MODULE, Event, Node, Port]), + tsp("receive_security_event -> await ~w event", [element(2, Event)]), receive Event -> + tsp("receive_security_event -> " + "received expected ~w event", [element(2, Event)]), ok; {'EXIT', _, _} -> receive_security_event(Event, Node, Port) -- cgit v1.2.3