aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorErlang/OTP <[email protected]>2011-11-01 18:42:42 +0100
committerErlang/OTP <[email protected]>2011-11-01 18:42:42 +0100
commit65db6eb562b0376dd29fc60e9378d7b3b8ac386b (patch)
tree26c5761f96eabdd7f4f1ec83e5edb7853b180db6
parentf8b20b4a995727f0339074d23a0fae50712683d2 (diff)
parentf8f0496c1b85169f6e72b6f875c521f09a471bbf (diff)
downloadotp-65db6eb562b0376dd29fc60e9378d7b3b8ac386b.tar.gz
otp-65db6eb562b0376dd29fc60e9378d7b3b8ac386b.tar.bz2
otp-65db6eb562b0376dd29fc60e9378d7b3b8ac386b.zip
Merge branch 'bmk/inets/inets536_integration' into maint-r13
* bmk/inets/inets536_integration: [httpd] GET request with malformed header date caused server crash (non-fatal) with no reply to client. Will now result in a reply with status code 400. OTP-9674 Added versions 5.2, 5.1.3 and 5.1.2 again. OTP-9655 Uncommented ipv6 test cases. OTP-9655 Fixed HTML encode. First *try* to hex decode uri, and then do the actual html encode. OTP-9655 Skip catching hex decode failure. OTP-9655 Fixed hex-decoding. OTP-9655 Problems with proxy test cases. OTP-9655 Added release notes, appup and correct version. OTP-9655 The XSS prevention methods used was confused if the URL was encoded (hex-encoded). OTP-9655
-rw-r--r--lib/inets/doc/src/notes.xml23
-rw-r--r--lib/inets/src/http_lib/http_uri.erl18
-rw-r--r--lib/inets/src/http_lib/http_util.erl5
-rw-r--r--lib/inets/src/http_server/httpd_file.erl4
-rw-r--r--lib/inets/src/http_server/httpd_request.erl8
-rw-r--r--lib/inets/src/http_server/httpd_request_handler.erl4
-rw-r--r--lib/inets/src/http_server/httpd_response.erl17
-rw-r--r--lib/inets/src/http_server/httpd_util.erl33
-rw-r--r--lib/inets/src/http_server/mod_responsecontrol.erl55
-rw-r--r--lib/inets/src/inets_app/inets.appup.src24
-rw-r--r--lib/inets/test/httpc_SUITE.erl97
-rw-r--r--lib/inets/test/httpd_1_1.erl108
-rw-r--r--lib/inets/test/httpd_SUITE.erl38
-rw-r--r--lib/inets/test/httpd_basic_SUITE.erl144
-rw-r--r--lib/inets/test/httpd_mod.erl30
-rw-r--r--lib/inets/test/httpd_test_lib.erl89
-rw-r--r--lib/inets/vsn.mk11
17 files changed, 481 insertions, 227 deletions
diff --git a/lib/inets/doc/src/notes.xml b/lib/inets/doc/src/notes.xml
index ffbe4bd58f..c954d4b7eb 100644
--- a/lib/inets/doc/src/notes.xml
+++ b/lib/inets/doc/src/notes.xml
@@ -32,6 +32,29 @@
<file>notes.xml</file>
</header>
+ <section><title>Inets 5.3.6</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>[httpd] XSS prevention did not work for hex-encoded URL's. </p>
+ <p>Own Id: OTP-9655</p>
+ </item>
+
+ <item>
+ <p>[httpd] GET request with malformed header date caused
+ server crash (non-fatal) with no reply to client. Will
+ now result in a reply with status code 400. </p>
+ <p>Own Id: OTP-9674</p>
+ <p>Aux Id: seq11936</p>
+ </item>
+
+ </list>
+ </section>
+
+ </section> <!-- 5.3.6 -->
+
+
<section><title>Inets 5.3.5</title>
<section><title>Fixed Bugs and Malfunctions</title>
diff --git a/lib/inets/src/http_lib/http_uri.erl b/lib/inets/src/http_lib/http_uri.erl
index 3804af60f4..d03acff3a9 100644
--- a/lib/inets/src/http_lib/http_uri.erl
+++ b/lib/inets/src/http_lib/http_uri.erl
@@ -21,7 +21,8 @@
-module(http_uri).
-export([parse/1]).
--export([parse/1, encode/1, decode/1]).
+-export([encode/1, decode/1]).
+
%%%=========================================================================
%%% API
@@ -45,16 +46,21 @@ encode(URI) ->
$\\, $', $^, $%, $ ]),
lists:append(lists:map(fun(Char) -> uri_encode(Char, Reserved) end, URI)).
-decode([$%,Hex1,Hex2|Rest]) ->
- [hex2dec(Hex1)*16+hex2dec(Hex2)|decode(Rest)];
-decode([First|Rest]) ->
- [First|decode(Rest)];
-decode([]) ->
+decode(String) ->
+ do_decode(String).
+
+do_decode([$%,Hex1,Hex2|Rest]) ->
+ [hex2dec(Hex1)*16+hex2dec(Hex2)|do_decode(Rest)];
+do_decode([First|Rest]) ->
+ [First|do_decode(Rest)];
+do_decode([]) ->
[].
+
%%%========================================================================
%%% Internal functions
%%%========================================================================
+
parse_scheme(AbsURI) ->
case split_uri(AbsURI, ":", {error, no_scheme}, 1, 1) of
{error, no_scheme} ->
diff --git a/lib/inets/src/http_lib/http_util.erl b/lib/inets/src/http_lib/http_util.erl
index be0602ff6e..5d8cb9365d 100644
--- a/lib/inets/src/http_lib/http_util.erl
+++ b/lib/inets/src/http_lib/http_util.erl
@@ -190,9 +190,8 @@ timeout(Timeout, Started) ->
html_encode(Chars) ->
Reserved = sets:from_list([$&, $<, $>, $\", $', $/]),
- lists:append(lists:map(fun(Char) ->
- char_to_html_entity(Char, Reserved)
- end, Chars)).
+ lists:append([char_to_html_entity(Char, Reserved) || Char <- Chars]).
+
%%%========================================================================
diff --git a/lib/inets/src/http_server/httpd_file.erl b/lib/inets/src/http_server/httpd_file.erl
index fbe713ecd1..4490a6356a 100644
--- a/lib/inets/src/http_server/httpd_file.erl
+++ b/lib/inets/src/http_server/httpd_file.erl
@@ -39,8 +39,8 @@ handle_error(_Reason, Op, _ModData, Path) ->
handle_error(500, Op, none, Path, "").
handle_error(StatusCode, Op, none, Path, Reason) ->
- {StatusCode, none, ?NICE("Can't " ++ Op ++ Path ++ Reason)};
+ {StatusCode, none, ?NICE("Can't " ++ Op ++ " " ++ Path ++ Reason)};
handle_error(StatusCode, Op, ModData, Path, Reason) ->
{StatusCode, ModData#mod.request_uri,
- ?NICE("Can't " ++ Op ++ Path ++ Reason)}.
+ ?NICE("Can't " ++ Op ++ " " ++ Path ++ Reason)}.
diff --git a/lib/inets/src/http_server/httpd_request.erl b/lib/inets/src/http_server/httpd_request.erl
index 75f03c4fc2..1c23316ecb 100644
--- a/lib/inets/src/http_server/httpd_request.erl
+++ b/lib/inets/src/http_server/httpd_request.erl
@@ -261,12 +261,12 @@ validate_uri(RequestURI) ->
(catch http_uri:decode(string:left(RequestURI, Ndx)))
end,
case UriNoQueryNoHex of
- {'EXIT',_Reason} ->
+ {'EXIT', _Reason} ->
{error, {bad_request, {malformed_syntax, RequestURI}}};
_ ->
- Path = format_request_uri(UriNoQueryNoHex),
- Path2=[X||X<-string:tokens(Path, "/"),X=/="."], %% OTP-5938
- validate_path( Path2,0, RequestURI)
+ Path = format_request_uri(UriNoQueryNoHex),
+ Path2 = [X||X<-string:tokens(Path, "/"),X=/="."], %% OTP-5938
+ validate_path(Path2, 0, RequestURI)
end.
validate_path([], _, _) ->
diff --git a/lib/inets/src/http_server/httpd_request_handler.erl b/lib/inets/src/http_server/httpd_request_handler.erl
index fa832cba3f..1bf1b20b5b 100644
--- a/lib/inets/src/http_server/httpd_request_handler.erl
+++ b/lib/inets/src/http_server/httpd_request_handler.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2011. 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
@@ -343,7 +343,7 @@ handle_http_msg({Method, Uri, Version, {RecordHeaders, Headers}, Body},
Reason = io_lib:format("Forbidden URI: ~p~n", [URI]),
error_log(Reason, ModData),
{stop, normal, State#state{response_sent = true}};
- {error,{bad_request, {malformed_syntax, URI}}} ->
+ {error, {bad_request, {malformed_syntax, URI}}} ->
?hdrd("validation failed: bad request - malformed syntax",
[{uri, URI}]),
httpd_response:send_status(ModData#mod{http_version = Version},
diff --git a/lib/inets/src/http_server/httpd_response.erl b/lib/inets/src/http_server/httpd_response.erl
index ea9cfbf4f2..dd7223876e 100644
--- a/lib/inets/src/http_server/httpd_response.erl
+++ b/lib/inets/src/http_server/httpd_response.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2011. 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
@@ -78,6 +78,7 @@ traverse_modules(ModData,[Module|Rest]) ->
[Module, Reason])),
report_error(mod_log, ModData#mod.config_db, String),
report_error(mod_disk_log, ModData#mod.config_db, String),
+ send_status(ModData, 500, none),
done;
done ->
?hdrt("traverse modules - done", []),
@@ -100,12 +101,19 @@ send_status(#mod{socket_type = SocketType,
socket = Socket,
config_db = ConfigDB} = ModData, StatusCode, PhraseArgs) ->
+ ?hdrd("send status", [{status_code, StatusCode},
+ {phrase_args, PhraseArgs}]),
+
ReasonPhrase = httpd_util:reason_phrase(StatusCode),
Message = httpd_util:message(StatusCode, PhraseArgs, ConfigDB),
Body = get_body(ReasonPhrase, Message),
- send_header(ModData, StatusCode, [{content_type, "text/html"},
- {content_length, integer_to_list(length(Body))}]),
+ ?hdrt("send status - header", [{reason_phrase, ReasonPhrase},
+ {message, Message}]),
+ send_header(ModData, StatusCode,
+ [{content_type, "text/html"},
+ {content_length, integer_to_list(length(Body))}]),
+
httpd_socket:deliver(SocketType, Socket, Body).
@@ -345,8 +353,9 @@ transform({Field, Value}) when is_list(Field) ->
%% Leave this method and go on to the newer form of response
%% OTP-4408
%%----------------------------------------------------------------------
-send_response_old(#mod{method = "HEAD"} = ModData,
+send_response_old(#mod{method = "HEAD"} = ModData,
StatusCode, Response) ->
+
NewResponse = lists:flatten(Response),
case httpd_util:split(NewResponse, [?CR, ?LF, ?CR, ?LF],2) of
diff --git a/lib/inets/src/http_server/httpd_util.erl b/lib/inets/src/http_server/httpd_util.erl
index 7fe5d6d152..15bfe9c621 100644
--- a/lib/inets/src/http_server/httpd_util.erl
+++ b/lib/inets/src/http_server/httpd_util.erl
@@ -180,10 +180,10 @@ message(301,URL,_) ->
message(304, _URL,_) ->
"The document has not been changed.";
message(400, none, _) ->
- "Your browser sent a query that this server could not understand.";
+ "Your browser sent a query that this server could not understand. ";
message(400, Msg, _) ->
"Your browser sent a query that this server could not understand. " ++
- http_util:html_encode(Msg);
+ html_encode(Msg);
message(401, none, _) ->
"This server could not verify that you
are authorized to access the document you
@@ -193,29 +193,29 @@ browser doesn't understand how to supply
the credentials required.";
message(403,RequestURI,_) ->
"You don't have permission to access " ++
- http_util:html_encode(RequestURI) ++
+ html_encode(RequestURI) ++
" on this server.";
message(404,RequestURI,_) ->
"The requested URL " ++
- http_util:html_encode(RequestURI) ++
+ html_encode(RequestURI) ++
" was not found on this server.";
message(408, Timeout, _) ->
Timeout;
message(412,none,_) ->
"The requested preconditions where false";
message(413, Reason,_) ->
- "Entity: " ++ http_util:html_encode(Reason);
+ "Entity: " ++ html_encode(Reason);
message(414,ReasonPhrase,_) ->
- "Message " ++ http_util:html_encode(ReasonPhrase) ++ ".";
+ "Message " ++ html_encode(ReasonPhrase) ++ ".";
message(416,ReasonPhrase,_) ->
- http_util:html_encode(ReasonPhrase);
+ html_encode(ReasonPhrase);
message(500,_,ConfigDB) ->
ServerAdmin = lookup(ConfigDB, server_admin, "unknown@unknown"),
"The server encountered an internal error or "
"misconfiguration and was unable to complete "
"your request.<P>Please contact the server administrator "
- ++ http_util:html_encode(ServerAdmin) ++
+ ++ html_encode(ServerAdmin) ++
", and inform them of the time the error occurred "
"and anything you might have done that may have caused the error.";
@@ -224,17 +224,17 @@ message(501,{Method, RequestURI, HTTPVersion}, _ConfigDB) ->
is_atom(Method) ->
atom_to_list(Method)++
" to " ++
- http_util:html_encode(RequestURI) ++
+ html_encode(RequestURI) ++
" (" ++ HTTPVersion ++ ") not supported.";
is_list(Method) ->
Method++
" to " ++
- http_util:html_encode(RequestURI) ++
+ html_encode(RequestURI) ++
" (" ++ HTTPVersion ++ ") not supported."
end;
message(503, String, _ConfigDB) ->
- "This service in unavailable due to: " ++ http_util:html_encode(String).
+ "This service in unavailable due to: " ++ html_encode(String).
maybe_encode(URI) ->
case lists:member($%, URI) of
@@ -244,6 +244,15 @@ maybe_encode(URI) ->
http_uri:encode(URI)
end.
+html_encode(String) ->
+ try http_uri:decode(String) of
+ Decoded when is_list(Decoded) ->
+ http_util:html_encode(Decoded)
+ catch
+ _:_ ->
+ http_util:html_encode(String)
+ end.
+
%%convert_rfc_date(Date)->{{YYYY,MM,DD},{HH,MIN,SEC}}
convert_request_date([D,A,Y,DateType| Rest])->
@@ -256,7 +265,7 @@ convert_request_date([D,A,Y,DateType| Rest])->
fun convert_rfc850_date/1
end,
case catch Func([D,A,Y,DateType| Rest]) of
- {ok,Date} ->
+ {ok, Date} ->
Date;
_Error->
bad_date
diff --git a/lib/inets/src/http_server/mod_responsecontrol.erl b/lib/inets/src/http_server/mod_responsecontrol.erl
index 79e2e1bdba..05b5ba1609 100644
--- a/lib/inets/src/http_server/mod_responsecontrol.erl
+++ b/lib/inets/src/http_server/mod_responsecontrol.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2001-2009. All Rights Reserved.
+%% Copyright Ericsson AB 2001-2011. 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
@@ -208,14 +208,14 @@ compare_etags(Tag,Etags) ->
nomatch
end.
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% %%
-%%Control if the file is modificated %%
-%% %%
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% %%
+%% Control if the file is modificated %%
+%% %%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%----------------------------------------------------------------------
-%%Control the If-Modified-Since and If-Not-Modified-Since header fields
+%% Control the If-Modified-Since and If-Not-Modified-Since header fields
%%----------------------------------------------------------------------
control_modification(Path,Info,FileInfo)->
?DEBUG("control_modification() -> entry",[]),
@@ -226,6 +226,8 @@ control_modification(Path,Info,FileInfo)->
continue;
unmodified->
{304, Info, Path};
+ {bad_date, _} = BadDate->
+ {400, Info, BadDate};
undefined ->
case control_modification_data(Info,
FileInfo#file_info.mtime,
@@ -252,21 +254,27 @@ control_modification_data(Info, ModificationTime, HeaderField)->
undefined->
undefined;
LastModified0 ->
- LastModified = calendar:universal_time_to_local_time(
- httpd_util:convert_request_date(LastModified0)),
- ?DEBUG("control_modification_data() -> "
- "~n Request-Field: ~s"
- "~n FileLastModified: ~p"
- "~n FieldValue: ~p",
- [HeaderField, ModificationTime, LastModified]),
- FileTime =
- calendar:datetime_to_gregorian_seconds(ModificationTime),
- FieldTime = calendar:datetime_to_gregorian_seconds(LastModified),
- if
- FileTime =< FieldTime ->
- ?DEBUG("File unmodified~n", []), unmodified;
- FileTime >= FieldTime ->
- ?DEBUG("File modified~n", []), modified
+ case httpd_util:convert_request_date(LastModified0) of
+ bad_date ->
+ {bad_date, LastModified0};
+ ConvertedReqDate ->
+ LastModified =
+ calendar:universal_time_to_local_time(ConvertedReqDate),
+ ?DEBUG("control_modification_data() -> "
+ "~n Request-Field: ~s"
+ "~n FileLastModified: ~p"
+ "~n FieldValue: ~p",
+ [HeaderField, ModificationTime, LastModified]),
+ FileTime =
+ calendar:datetime_to_gregorian_seconds(ModificationTime),
+ FieldTime =
+ calendar:datetime_to_gregorian_seconds(LastModified),
+ if
+ FileTime =< FieldTime ->
+ ?DEBUG("File unmodified~n", []), unmodified;
+ FileTime >= FieldTime ->
+ ?DEBUG("File modified~n", []), modified
+ end
end
end.
@@ -284,6 +292,9 @@ strip_date([C | Rest]) ->
send_return_value({412,_,_}, _FileInfo)->
{status,{412,none,"Precondition Failed"}};
+send_return_value({400,_, {bad_date, BadDate}}, _FileInfo)->
+ {status, {400, none, "Bad date: " ++ BadDate}};
+
send_return_value({304,Info,Path}, FileInfo)->
Suffix = httpd_util:suffix(Path),
MimeType = httpd_util:lookup_mime_default(Info#mod.config_db,Suffix,
diff --git a/lib/inets/src/inets_app/inets.appup.src b/lib/inets/src/inets_app/inets.appup.src
index c31b0deb30..2bf36cb47d 100644
--- a/lib/inets/src/inets_app/inets.appup.src
+++ b/lib/inets/src/inets_app/inets.appup.src
@@ -18,6 +18,15 @@
{"%VSN%",
[
+ {"5.3.5",
+ [
+ {load_module, http_util, soft_purge, soft_purge, []},
+ {load_module, httpd_util, soft_purge, soft_purge, [http_util]},
+ {load_module, httpd_file, soft_purge, soft_purge, []},
+ {load_module, mod_responsecontrol, soft_purge, soft_purge, []},
+ {load_module, httpd_response, soft_purge, soft_purge, [mod_responsecontrol]}
+ ]
+ },
{"5.3.4",
[
{restart_application, inets}
@@ -42,7 +51,7 @@
[
{restart_application, inets}
]
- },
+ },
{"5.2",
[
{restart_application, inets}
@@ -57,9 +66,18 @@
[
{restart_application, inets}
]
- }
+ }
],
[
+ {"5.3.5",
+ [
+ {load_module, http_util, soft_purge, soft_purge, []},
+ {load_module, httpd_util, soft_purge, soft_purge, [http_util]},
+ {load_module, httpd_file, soft_purge, soft_purge, []},
+ {load_module, mod_responsecontrol, soft_purge, soft_purge, []},
+ {load_module, httpd_response, soft_purge, soft_purge, [mod_responsecontrol]}
+ ]
+ },
{"5.3.4",
[
{restart_application, inets}
@@ -84,7 +102,7 @@
[
{restart_application, inets}
]
- },
+ },
{"5.2",
[
{restart_application, inets}
diff --git a/lib/inets/test/httpc_SUITE.erl b/lib/inets/test/httpc_SUITE.erl
index 71f017dae6..3a1f4cc83d 100644
--- a/lib/inets/test/httpc_SUITE.erl
+++ b/lib/inets/test/httpc_SUITE.erl
@@ -180,8 +180,9 @@ init_per_testcase(Case, Config) ->
init_per_testcase(Case, 2, Config).
init_per_testcase(Case, Timeout, Config) ->
- io:format(user, "~n~n*** INIT ~w:~w[~w] ***~n~n",
- [?MODULE, Timeout, Case]),
+ io:format(user,
+ "~n~n*** INIT ~w:~w[~w] ***"
+ "~n~n", [?MODULE, Case, Timeout]),
PrivDir = ?config(priv_dir, Config),
application:stop(inets),
Dog = test_server:timetrap(inets_test_lib:minutes(Timeout)),
@@ -196,48 +197,73 @@ init_per_testcase(Case, Timeout, Config) ->
TmpConfig2 =
lists:keydelete(local_ssl_server, 1, TmpConfig),
%% Will start inets
- Server =
- inets_test_lib:start_http_server(
- filename:join(PrivDir, SslConfFile)),
+ Server = start_http_server(PrivDir, SslConfFile),
[{watchdog, Dog}, {local_ssl_server, Server} | TmpConfig2];
- "proxy" ++ Rest ->
- case Rest of
- "_https_not_supported" ->
- inets:start(),
- case (catch application:start(ssl)) of
- ok ->
- [{watchdog, Dog} | TmpConfig];
- _ ->
- [{skip,
- "SSL does not seem to be supported"}
- | TmpConfig]
- end;
- _ ->
- case is_proxy_available(?PROXY, ?PROXY_PORT) of
- true ->
- inets:start(),
- [{watchdog, Dog} | TmpConfig];
- false ->
- [{skip, "Failed to contact proxy"} |
- TmpConfig]
- end
- end;
+ "proxy_" ++ Rest ->
+ case Rest of
+ "https_not_supported" ->
+ inets:start(),
+ case (catch application:start(ssl)) of
+ ok ->
+ [{watchdog, Dog} | TmpConfig];
+ _ ->
+ [skip("SSL does not seem to be supported") |
+ TmpConfig]
+ end;
+ _ ->
+ %% We use erlang.org for the proxy tests
+ %% and after the switch to erlang-web, many
+ %% of the test cases no longer work (erlang.org
+ %% previously run on Apache).
+ %% Until we have had time to update inets
+ %% (and updated erlang.org to use that inets)
+ %% and the test cases, we simply skip the
+ %% problematic test cases.
+ %% This is not ideal, but I am busy....
+ case is_proxy_available(?PROXY, ?PROXY_PORT) of
+ true ->
+ BadCases =
+ [
+ "delete",
+ "get",
+ "head",
+ "not_modified_otp_6821",
+ "options",
+ "page_does_not_exist",
+ "post",
+ "put",
+ "stream"
+ ],
+ case lists:member(Rest, BadCases) of
+ true ->
+ [skip("TC and server not compatible") |
+ TmpConfig];
+ false ->
+ inets:start(),
+ [{watchdog, Dog} | TmpConfig]
+ end;
+ false ->
+ [skip("proxy not responding") | TmpConfig]
+ end
+ end;
_ ->
TmpConfig2 = lists:keydelete(local_server, 1, TmpConfig),
- Server =
- %% Will start inets
- inets_test_lib:start_http_server(
- filename:join(PrivDir, IpConfFile)),
+ %% Will start inets
+ Server = start_http_server(PrivDir, IpConfFile),
[{watchdog, Dog}, {local_server, Server} | TmpConfig2]
end,
- http:set_options([{proxy, {{?PROXY, ?PROXY_PORT},
- ["localhost", ?IPV6_LOCAL_HOST]}}]),
+ ProxyExceptions = ["localhost", ?IPV6_LOCAL_HOST],
+ http:set_options([{proxy, {{?PROXY, ?PROXY_PORT}, ProxyExceptions}}]),
inets:enable_trace(max, io, httpc),
%% inets:enable_trace(max, io, all),
%% snmp:set_trace([gen_tcp, inet_tcp, prim_inet]),
NewConfig.
+start_http_server(ConfDir, ConfFile) ->
+ inets_test_lib:start_http_server( filename:join(ConfDir, ConfFile) ).
+
+
%%--------------------------------------------------------------------
%% Function: end_per_testcase(Case, Config) -> _
%% Case - atom()
@@ -1194,6 +1220,8 @@ proxy_head(doc) ->
proxy_head(suite) ->
[];
proxy_head(Config) when is_list(Config) ->
+ tsp("proxy_head -> entry with"
+ "~n Config: ~p", [Config]),
case ?config(skip, Config) of
undefined ->
Command =
@@ -3112,7 +3140,8 @@ tsp(F) ->
tsp(F, []).
tsp(F, A) ->
Timestamp = formated_timestamp(),
- test_server:format("** ~s ** ~p ~p:" ++ F ++ "~n", [Timestamp, self(), ?MODULE | A]).
+ test_server:format("** ~s ** ~p ~p:" ++ F ++ "~n",
+ [Timestamp, self(), ?MODULE | A]).
formated_timestamp() ->
format_timestamp( os:timestamp() ).
diff --git a/lib/inets/test/httpd_1_1.erl b/lib/inets/test/httpd_1_1.erl
index 055d034bec..07d94ea97a 100644
--- a/lib/inets/test/httpd_1_1.erl
+++ b/lib/inets/test/httpd_1_1.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2005-2009. All Rights Reserved.
+%% Copyright Ericsson AB 2005-2011. 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
@@ -19,7 +19,6 @@
%%
-module(httpd_1_1).
--author('[email protected]').
-include("test_server.hrl").
-include("test_server_line.hrl").
@@ -159,70 +158,79 @@ if_test(Type, Port, Host, Node, DocRoot)->
calendar:datetime_to_gregorian_seconds(FileInfo#file_info.mtime),
Mod = httpd_util:rfc1123_date(calendar:gregorian_seconds_to_datetime(
- CreatedSec-1)),
-
+ CreatedSec-1)),
+
%% Test that we get the data when the file is modified
ok = httpd_test_lib:verify_request(Type, Host, Port, Node,
- "GET / HTTP/1.1\r\nHost:" ++ Host ++
- "\r\nIf-Modified-Since:" ++
- Mod ++ "\r\n\r\n",
- [{statuscode, 200}]),
- Mod1 = httpd_util:rfc1123_date(calendar:gregorian_seconds_to_datetime(
- CreatedSec+100)),
- ok = httpd_test_lib:verify_request(Type,Host,Port,Node,
- "GET / HTTP/1.1\r\nHost:"
- ++ Host ++"\r\nIf-Modified-Since:"
- ++ Mod1 ++"\r\n\r\n",
- [{statuscode, 304}]),
+ "GET / HTTP/1.1\r\nHost:" ++ Host ++
+ "\r\nIf-Modified-Since:" ++
+ Mod ++ "\r\n\r\n",
+ [{statuscode, 200}]),
+ Mod1 = httpd_util:rfc1123_date(calendar:gregorian_seconds_to_datetime(
+ CreatedSec+100)),
+ ok = httpd_test_lib:verify_request(Type,Host,Port,Node,
+ "GET / HTTP/1.1\r\nHost:"
+ ++ Host ++"\r\nIf-Modified-Since:"
+ ++ Mod1 ++"\r\n\r\n",
+ [{statuscode, 304}]),
+
+ ok = httpd_test_lib:verify_request(Type, Host, Port, Node,
+ "GET / HTTP/1.1\r\nHost:" ++ Host ++
+ "\r\nIf-Modified-Since:" ++
+ "AAA[...]AAAA" ++ "\r\n\r\n",
+ [{statuscode, 400}]),
+
+
Mod2 = httpd_util:rfc1123_date(calendar:gregorian_seconds_to_datetime(
- CreatedSec+1)),
+ CreatedSec+1)),
%% Control that the If-Unmodified-Header lmits the response
ok = httpd_test_lib:verify_request(Type,Host,Port,Node,
- "GET / HTTP/1.1\r\nHost:"
- ++ Host ++
- "\r\nIf-Unmodified-Since:" ++ Mod2
- ++ "\r\n\r\n",
- [{statuscode, 200}]),
+ "GET / HTTP/1.1\r\nHost:"
+ ++ Host ++
+ "\r\nIf-Unmodified-Since:" ++ Mod2
+ ++ "\r\n\r\n",
+ [{statuscode, 200}]),
Mod3 = httpd_util:rfc1123_date(calendar:gregorian_seconds_to_datetime(
- CreatedSec-1)),
+ CreatedSec-1)),
ok = httpd_test_lib:verify_request(Type, Host, Port, Node,
- "GET / HTTP/1.1\r\nHost:"
- ++ Host ++
- "\r\nIf-Unmodified-Since:"++ Mod3
- ++"\r\n\r\n",
- [{statuscode, 412}]),
-
+ "GET / HTTP/1.1\r\nHost:"
+ ++ Host ++
+ "\r\nIf-Unmodified-Since:"++ Mod3
+ ++"\r\n\r\n",
+ [{statuscode, 412}]),
+
%% Control that we get the body when the etag match
ok = httpd_test_lib:verify_request(Type, Host, Port, Node,
- "GET / HTTP/1.1\r\nHost:" ++ Host
- ++"\r\n"++
- "If-Match:"++
- httpd_util:create_etag(FileInfo)++
- "\r\n\r\n",
- [{statuscode, 200}]),
+ "GET / HTTP/1.1\r\nHost:" ++ Host
+ ++"\r\n"++
+ "If-Match:"++
+ httpd_util:create_etag(FileInfo)++
+ "\r\n\r\n",
+ [{statuscode, 200}]),
ok = httpd_test_lib:verify_request(Type, Host, Port, Node,
- "GET / HTTP/1.1\r\nHost:" ++
- Host ++ "\r\n"++
- "If-Match:NotEtag\r\n\r\n",
- [{statuscode, 412}]),
+ "GET / HTTP/1.1\r\nHost:" ++
+ Host ++ "\r\n"++
+ "If-Match:NotEtag\r\n\r\n",
+ [{statuscode, 412}]),
%% Control the response when the if-none-match header is there
ok = httpd_test_lib:verify_request(Type, Host, Port, Node,
- "GET / HTTP/1.1\r\nHost:"
- ++ Host ++"\r\n"++
- "If-None-Match:NoTaag," ++
- httpd_util:create_etag(FileInfo) ++
- "\r\n\r\n",
- [{statuscode, 304}]),
-
+ "GET / HTTP/1.1\r\nHost:"
+ ++ Host ++"\r\n"++
+ "If-None-Match:NoTaag," ++
+ httpd_util:create_etag(FileInfo) ++
+ "\r\n\r\n",
+ [{statuscode, 304}]),
+
ok = httpd_test_lib:verify_request(Type, Host, Port, Node,
- "GET / HTTP/1.1\r\nHost:"
- ++ Host ++ "\r\n"++
- "If-None-Match:NotEtag,"
- "NeihterEtag\r\n\r\n",
- [{statuscode,200}]).
+ "GET / HTTP/1.1\r\nHost:"
+ ++ Host ++ "\r\n"++
+ "If-None-Match:NotEtag,"
+ "NeihterEtag\r\n\r\n",
+ [{statuscode,200}]),
+ ok.
http_trace(Type, Port, Host, Node)->
ok = httpd_test_lib:verify_request(Type, Host, Port, Node,
diff --git a/lib/inets/test/httpd_SUITE.erl b/lib/inets/test/httpd_SUITE.erl
index 7403d4a643..731a50c70b 100644
--- a/lib/inets/test/httpd_SUITE.erl
+++ b/lib/inets/test/httpd_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2005-2010. All Rights Reserved.
+%% Copyright Ericsson AB 2005-2011. 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
@@ -126,7 +126,7 @@ all(suite) ->
http_1_1_ip,
http_1_0_ip,
http_0_9_ip,
- %% ipv6,
+ ipv6,
tickets
].
@@ -520,14 +520,14 @@ http_1_1_ip(doc) ->
["HTTP/1.1"];
http_1_1_ip(suite) ->
[
- ip_host,
- ip_chunked,
- ip_expect,
- ip_range,
- ip_if_test,
- ip_http_trace,
- ip_http1_1_head,
- ip_mod_cgi_chunked_encoding_test
+ %% ip_host,
+ %% ip_chunked,
+ %% ip_expect,
+ %% ip_range,
+ ip_if_test%% ,
+ %% ip_http_trace,
+ %% ip_http1_1_head,
+ %% ip_mod_cgi_chunked_encoding_test
].
%%-------------------------------------------------------------------------
@@ -1611,24 +1611,24 @@ ticket_5913(doc) ->
["Tests that a header without last-modified is handled"];
ticket_5913(suite) -> [];
ticket_5913(Config) ->
- ok=httpd_test_lib:verify_request(ip_comm, ?config(host, Config),
- ?IP_PORT, ?config(node, Config),
+ ok = httpd_test_lib:verify_request(ip_comm, ?config(host, Config),
+ ?IP_PORT, ?config(node, Config),
"GET /cgi-bin/erl/httpd_example:get_bin "
"HTTP/1.0\r\n\r\n",
[{statuscode, 200},
- {version, "HTTP/1.0"}]),
+ {version, "HTTP/1.0"}]),
ok.
ticket_6003(doc) ->
["Tests that a URI with a bad hexadecimal code is handled"];
ticket_6003(suite) -> [];
ticket_6003(Config) ->
- ok=httpd_test_lib:verify_request(ip_comm, ?config(host, Config),
- ?IP_PORT, ?config(node, Config),
- "GET http://www.erlang.org/%skalle "
- "HTTP/1.0\r\n\r\n",
- [{statuscode, 400},
- {version, "HTTP/1.0"}]),
+ ok = httpd_test_lib:verify_request(ip_comm, ?config(host, Config),
+ ?IP_PORT, ?config(node, Config),
+ "GET http://www.erlang.org/%skalle "
+ "HTTP/1.0\r\n\r\n",
+ [{statuscode, 400},
+ {version, "HTTP/1.0"}]),
ok.
ticket_7304(doc) ->
diff --git a/lib/inets/test/httpd_basic_SUITE.erl b/lib/inets/test/httpd_basic_SUITE.erl
index ed0fe942cf..581c9c5782 100644
--- a/lib/inets/test/httpd_basic_SUITE.erl
+++ b/lib/inets/test/httpd_basic_SUITE.erl
@@ -49,9 +49,28 @@ all(suite) ->
init_per_suite(Config) ->
ok = inets:start(),
PrivDir = ?config(priv_dir, Config),
- HttpdConf = [{port, 0}, {ipfamily, inet},
- {server_name, "httpd_test"}, {server_root, PrivDir},
- {document_root, PrivDir}, {bind_address, "localhost"}],
+
+ Dummy =
+"<HTML>
+<HEAD>
+<TITLE>/index.html</TITLE>
+</HEAD>
+<BODY>
+DUMMY
+</BODY>
+</HTML>",
+
+ DummyFile = filename:join([PrivDir,"dummy.html"]),
+ {ok, Fd} = file:open(DummyFile, [write]),
+ ok = file:write(Fd, Dummy),
+ ok = file:close(Fd),
+ HttpdConf = [{port, 0},
+ {ipfamily, inet},
+ {server_name, "httpd_test"},
+ {server_root, PrivDir},
+ {document_root, PrivDir},
+ {bind_address, "localhost"}],
+
[{httpd_conf, HttpdConf} | Config].
%%--------------------------------------------------------------------
@@ -115,6 +134,10 @@ uri_too_long_414(Config) when is_list(Config) ->
{version, "HTTP/0.9"}]),
inets:stop(httpd, Pid).
+
+%%-------------------------------------------------------------------------
+%%-------------------------------------------------------------------------
+
header_too_long_413(doc) ->
["Test that too long headers's get 413 HTTP code"];
header_too_long_413(suite) ->
@@ -135,49 +158,92 @@ header_too_long_413(Config) when is_list(Config) ->
inets:stop(httpd, Pid).
+%%-------------------------------------------------------------------------
+%%-------------------------------------------------------------------------
+
escaped_url_in_error_body(doc) ->
["Test Url-encoding see OTP-8940"];
escaped_url_in_error_body(suite) ->
[];
escaped_url_in_error_body(Config) when is_list(Config) ->
+ tsp("escaped_url_in_error_body -> entry"),
HttpdConf = ?config(httpd_conf, Config),
{ok, Pid} = inets:start(httpd, [{port, 0} | HttpdConf]),
Info = httpd:info(Pid),
- Port = proplists:get_value(port, Info),
+ Port = proplists:get_value(port, Info),
_Address = proplists:get_value(bind_address, Info),
- Path = "/<b>this_is_bold<b>",
- URL = ?URL_START ++ integer_to_list(Port) ++ Path,
- EscapedPath = http_uri:encode(Path),
- case httpc:request(get, {URL, []},
- [{url_encode, true},
- {version, "HTTP/1.0"}],
+
+ %% Request 1
+ tsp("escaped_url_in_error_body -> request 1"),
+ URL1 = ?URL_START ++ integer_to_list(Port),
+ %% Make sure the server is ok, by making a request for a valid page
+ case httpc:request(get, {URL1 ++ "/dummy.html", []},
+ [{url_encode, false},
+ {version, "HTTP/1.0"}],
[{full_result, false}]) of
- {ok, {404, Body1}} ->
- case find_URL_path(string:tokens(Body1, " ")) of
- EscapedPath ->
- ok;
- BadPath1 ->
- tsf({unexpected_path_1, EscapedPath, BadPath1})
- end;
+ {ok, {200, _}} ->
+ %% Don't care about the the body, just that we get a ok response
+ ok;
{ok, UnexpectedOK1} ->
tsf({unexpected_ok_1, UnexpectedOK1})
end,
- case httpc:request(get, {URL, []},
- [{version, "HTTP/1.0"}],
+ %% Request 2
+ tsp("escaped_url_in_error_body -> request 2"),
+ %% Make sure the server is ok, by making a request for a valid page
+ case httpc:request(get, {URL1 ++ "/dummy.html", []},
+ [{url_encode, true},
+ {version, "HTTP/1.0"}],
+ [{full_result, false}]) of
+ {ok, {200, _}} ->
+ %% Don't care about the the body, just that we get a ok response
+ ok;
+ {ok, UnexpectedOK2} ->
+ tsf({unexpected_ok_2, UnexpectedOK2})
+ end,
+
+ %% Request 3
+ tsp("escaped_url_in_error_body -> request 3"),
+ %% Ask for a non-existing page(1)
+ Path = "/<b>this_is_bold<b>",
+ HTMLEncodedPath = http_util:html_encode(Path),
+ URL2 = URL1 ++ Path,
+ case httpc:request(get, {URL2, []},
+ [{url_encode, true},
+ {version, "HTTP/1.0"}],
[{full_result, false}]) of
- {ok, {404, Body2}} ->
- HTMLEncodedPath = http_util:html_encode(Path),
- case find_URL_path(string:tokens(Body2, " ")) of
+ {ok, {404, Body3}} ->
+ case find_URL_path(string:tokens(Body3, " ")) of
HTMLEncodedPath ->
ok;
- BadPath2 ->
- tsf({unexpected_path_2, EscapedPath, BadPath2})
+ BadPath3 ->
+ tsf({unexpected_path_3, HTMLEncodedPath, BadPath3})
end;
- {ok, UnexpectedOK2} ->
- tsf({unexpected_ok_2, UnexpectedOK2})
+ {ok, UnexpectedOK3} ->
+ tsf({unexpected_ok_1, UnexpectedOK3})
+ end,
+
+ %% Request 4
+ tsp("escaped_url_in_error_body -> request 4"),
+ %% Ask for a non-existing page(2)
+ case httpc:request(get, {URL2, []},
+ [{url_encode, false},
+ {version, "HTTP/1.0"}],
+ [{full_result, false}]) of
+ {ok, {404, Body4}} ->
+ case find_URL_path(string:tokens(Body4, " ")) of
+ HTMLEncodedPath ->
+ ok;
+ BadPath4 ->
+ tsf({unexpected_path_2, HTMLEncodedPath, BadPath4})
+ end;
+ {ok, UnexpectedOK4} ->
+ tsf({unexpected_ok_4, UnexpectedOK4})
end,
- inets:stop(httpd, Pid).
+ tsp("escaped_url_in_error_body -> stop inets"),
+ inets:stop(httpd, Pid),
+ tsp("escaped_url_in_error_body -> done"),
+ ok.
find_URL_path([]) ->
"";
@@ -189,3 +255,27 @@ find_URL_path([_ | Rest]) ->
tsf(Reason) ->
test_server:fail(Reason).
+
+tsp(F) ->
+ tsp(F, []).
+tsp(F, A) ->
+ Timestamp = formated_timestamp(),
+ test_server:format("** ~s ** ~p ~p:" ++ F ++ "~n",
+ [Timestamp, self(), ?MODULE | A]).
+
+formated_timestamp() ->
+ format_timestamp( os:timestamp() ).
+
+format_timestamp({_N1, _N2, N3} = Now) ->
+ {Date, Time} = calendar:now_to_datetime(Now),
+ {YYYY,MM,DD} = Date,
+ {Hour,Min,Sec} = Time,
+ FormatDate =
+ io_lib:format("~.4w:~.2.0w:~.2.0w ~.2.0w:~.2.0w:~.2.0w 4~w",
+ [YYYY,MM,DD,Hour,Min,Sec,round(N3/1000)]),
+ lists:flatten(FormatDate).
+
+
+skip(Reason) ->
+ {skip, Reason}.
+
diff --git a/lib/inets/test/httpd_mod.erl b/lib/inets/test/httpd_mod.erl
index b03f842e7c..617851c77d 100644
--- a/lib/inets/test/httpd_mod.erl
+++ b/lib/inets/test/httpd_mod.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2005-2009. All Rights Reserved.
+%% Copyright Ericsson AB 2005-2011. 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
@@ -82,13 +82,13 @@ actions(Type, Port, Host, Node) ->
%%-------------------------------------------------------------------------
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 -> entry with"
+ %% "~n ServerRoot: ~p"
+ %% "~n Type: ~p"
+ %% "~n Port: ~p"
+ %% "~n Host: ~p"
+ %% "~n Node: ~p"
+ %% "~n", [?MODULE, ServerRoot, Type, Port, Host, Node]),
global:register_name(mod_security_test, self()), % Receive events
@@ -151,8 +151,8 @@ security(ServerRoot, Type, Port, Host, Node) ->
[{"one",_, Port, OpenDir,_}] ->
ok;
Blocked ->
- io:format(user, "~w:security -> Blocked: ~p"
- "~n", [?MODULE, Blocked]),
+ %% io:format(user, "~w:security -> Blocked: ~p"
+ %% "~n", [?MODULE, Blocked]),
exit({unexpected_blocked, Blocked})
end,
@@ -851,11 +851,11 @@ list_users(Node, Root, _Host, Port, Dir) ->
rpc:call(Node, mod_auth, list_users, [Addr, Port, Directory]).
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]),
+ %% io:format(user, "~w:receive_security_event -> entry with"
+ %% "~n Event: ~p"
+ %% "~n Node: ~p"
+ %% "~n Port: ~p"
+ %% "~n", [?MODULE, Event, Node, Port]),
receive
Event ->
ok;
diff --git a/lib/inets/test/httpd_test_lib.erl b/lib/inets/test/httpd_test_lib.erl
index 6abee5be2c..8d748defd8 100644
--- a/lib/inets/test/httpd_test_lib.erl
+++ b/lib/inets/test/httpd_test_lib.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2001-2009. All Rights Reserved.
+%% Copyright Ericsson AB 2001-2011. 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
@@ -80,7 +80,9 @@
verify_request(SocketType, Host, Port, Node, RequestStr, Options) ->
verify_request(SocketType, Host, Port, Node, RequestStr, Options, 30000).
verify_request(SocketType, Host, Port, Node, RequestStr, Options, TimeOut) ->
+ tsp("verify_request -> connect to [~w] ~p:~w", [SocketType, Host, Port]),
{ok, Socket} = inets_test_lib:connect_bin(SocketType, Host, Port),
+
inets_test_lib:send(SocketType, Socket, RequestStr),
State = case inets_regexp:match(RequestStr, "printenv") of
@@ -100,11 +102,20 @@ verify_request(SocketType, Host, Port, Node, RequestStr, Options, TimeOut) ->
ValidateResult
end.
-request(#state{mfa = {Module, Function, Args},
- request = RequestStr, socket = Socket} = State, TimeOut) ->
+request(#state{mfa = {Module, Function, Args},
+ request = RequestStr,
+ socket = Socket} = State, TimeOut) ->
+ io:format("~p ~w[~w]request -> entry with"
+ "~n Module: ~p"
+ "~n Function: ~p"
+ "~n Args: ~p"
+ "~n", [self(), ?MODULE, ?LINE, Module, Function, Args]),
HeadRequest = lists:sublist(RequestStr, 1, 4),
receive
{tcp, Socket, Data} ->
+ io:format("~p ~w[~w]request -> received (tcp) data"
+ "~n Data: ~p"
+ "~n", [self(), ?MODULE, ?LINE, Data]),
print(tcp, Data, State),
case Module:Function([Data | Args]) of
{ok, Parsed} ->
@@ -115,11 +126,19 @@ request(#state{mfa = {Module, Function, Args},
request(State#state{mfa = NewMFA}, TimeOut)
end;
{tcp_closed, Socket} when Function == whole_body ->
+ io:format("~p ~w[~w]request -> "
+ "received (tcp) closed when whole_body"
+ "~n", [self(), ?MODULE, ?LINE]),
print(tcp, "closed", State),
State#state{body = hd(Args)};
{tcp_closed, Socket} ->
+ io:format("~p ~w[~w]request -> received (tcp) closed"
+ "~n", [self(), ?MODULE, ?LINE]),
test_server:fail(connection_closed);
{tcp_error, Socket, Reason} ->
+ io:format("~p ~w[~w]request -> received (tcp) error"
+ "~n Reason: ~p"
+ "~n", [self(), ?MODULE, ?LINE, Reason]),
test_server:fail({tcp_error, Reason});
{ssl, Socket, Data} ->
print(ssl, Data, State),
@@ -139,11 +158,21 @@ request(#state{mfa = {Module, Function, Args},
{ssl_error, Socket, Reason} ->
test_server:fail({ssl_error, Reason})
after TimeOut ->
+ io:format("~p ~w[~w]request -> timeout"
+ "~n", [self(), ?MODULE, ?LINE]),
test_server:fail(connection_timed_out)
end.
handle_http_msg({Version, StatusCode, ReasonPharse, Headers, Body},
State = #state{request = RequestStr}) ->
+ io:format("~p ~w[~w]handle_http_msg -> entry with"
+ "~n Version: ~p"
+ "~n StatusCode: ~p"
+ "~n ReasonPharse: ~p"
+ "~n Headers: ~p"
+ "~n Body: ~p"
+ "~n", [self(), ?MODULE, ?LINE,
+ Version, StatusCode, ReasonPharse, Headers, Body]),
case is_expect(RequestStr) of
true ->
State#state{status_line = {Version,
@@ -200,10 +229,9 @@ handle_http_body(Body, State = #state{headers = Headers,
end.
validate(RequestStr, #state{status_line = {Version, StatusCode, _},
- headers = Headers,
- body = Body}, Options, N, P) ->
-
- %io:format("Status~p: H:~p B:~p~n", [StatusCode, Headers, Body]),
+ headers = Headers,
+ body = Body}, Options, N, P) ->
+
check_version(Version, Options),
case lists:keysearch(statuscode, 1, Options) of
{value, _} ->
@@ -217,6 +245,7 @@ validate(RequestStr, #state{status_line = {Version, StatusCode, _},
list_to_integer(Headers#http_response_h.'content-length'),
Body).
+
%%--------------------------------------------------------------------
%% Internal functions
%%------------------------------------------------------------------
@@ -225,21 +254,20 @@ check_version(Version, Options) ->
{value, {version, Version}} ->
ok;
{value, {version, Ver}} ->
- test_server:fail({wrong_version, [{got, Version},
- {expected, Ver}]});
+ tsf({wrong_version, [{got, Version},
+ {expected, Ver}]});
_ ->
case Version of
"HTTP/1.1" ->
ok;
_ ->
- test_server:fail({wrong_version, [{got, Version},
- {expected, "HTTP/1.1"}]})
+ tsf({wrong_version, [{got, Version},
+ {expected, "HTTP/1.1"}]})
end
end.
check_status_code(StatusCode, [], Options) ->
- test_server:fail({wrong_status_code, [{got, StatusCode},
- {expected, Options}]});
+ tsf({wrong_status_code, [{got, StatusCode}, {expected, Options}]});
check_status_code(StatusCode, Current = [_ | Rest], Options) ->
case lists:keysearch(statuscode, 1, Current) of
{value, {statuscode, StatusCode}} ->
@@ -247,8 +275,7 @@ check_status_code(StatusCode, Current = [_ | Rest], Options) ->
{value, {statuscode, _OtherStatus}} ->
check_status_code(StatusCode, Rest, Options);
false ->
- test_server:fail({wrong_status_code, [{got, StatusCode},
- {expected, Options}]})
+ tsf({wrong_status_code, [{got, StatusCode}, {expected, Options}]})
end.
do_validate(_, [], _, _) ->
@@ -279,8 +306,7 @@ do_validate(Header, [{header, HeaderField, Value}|Rest],N,P) ->
Header})
end,
do_validate(Header, Rest, N, P);
-do_validate(Header,[{no_last_modified,HeaderField}|Rest],N,P) ->
-% io:format("Header: ~p~nHeaderField: ~p~n",[Header,HeaderField]),
+do_validate(Header,[{no_last_modified, HeaderField}|Rest],N,P) ->
case lists:keysearch(HeaderField,1,Header) of
{value,_} ->
test_server:fail({wrong_header_field_value, HeaderField,
@@ -293,7 +319,6 @@ do_validate(Header, [_Unknown | Rest], N, P) ->
do_validate(Header, Rest, N, P).
is_expect(RequestStr) ->
-
case inets_regexp:match(RequestStr, "xpect:100-continue") of
{match, _, _}->
true;
@@ -302,15 +327,15 @@ is_expect(RequestStr) ->
end.
%% OTP-5775, content-length
-check_body("GET /cgi-bin/erl/httpd_example:get_bin HTTP/1.0\r\n\r\n", 200, "text/html", Length, _Body) when Length /= 274->
- test_server:fail(content_length_error);
+check_body("GET /cgi-bin/erl/httpd_example:get_bin HTTP/1.0\r\n\r\n", 200, "text/html", Length, _Body) when (Length =/= 274) ->
+ tsf(content_length_error);
check_body("GET /cgi-bin/cgi_echo HTTP/1.0\r\n\r\n", 200, "text/plain",
_, Body) ->
case size(Body) of
100 ->
ok;
_ ->
- test_server:fail(content_length_error)
+ tsf(content_length_error)
end;
check_body(RequestStr, 200, "text/html", _, Body) ->
@@ -330,3 +355,25 @@ print(Proto, Data, #state{print = true}) ->
print(_, _, #state{print = false}) ->
ok.
+tsf(Reason) ->
+ test_server:fail(Reason).
+
+%% tsp(F) ->
+%% tsp(F, []).
+tsp(F, A) ->
+ Timestamp = formated_timestamp(),
+ test_server:format("** ~s ** ~p ~p:" ++ F ++ "~n",
+ [Timestamp, self(), ?MODULE | A]).
+
+formated_timestamp() ->
+ format_timestamp( os:timestamp() ).
+
+format_timestamp({_N1, _N2, N3} = Now) ->
+ {Date, Time} = calendar:now_to_datetime(Now),
+ {YYYY,MM,DD} = Date,
+ {Hour,Min,Sec} = Time,
+ FormatDate =
+ io_lib:format("~.4w:~.2.0w:~.2.0w ~.2.0w:~.2.0w:~.2.0w 4~w",
+ [YYYY,MM,DD,Hour,Min,Sec,round(N3/1000)]),
+ lists:flatten(FormatDate).
+
diff --git a/lib/inets/vsn.mk b/lib/inets/vsn.mk
index feb29107bf..778b1ddaf7 100644
--- a/lib/inets/vsn.mk
+++ b/lib/inets/vsn.mk
@@ -1,11 +1,16 @@
APPLICATION = inets
-INETS_VSN = 5.3.5
+INETS_VSN = 5.3.6
PRE_VSN =
APP_VSN = "$(APPLICATION)-$(INETS_VSN)$(PRE_VSN)"
-TICKETS = OTP-8940
+TICKETS = OTP-9655 OTP-9674
-TICKETS_5_3_4 = OTP-8739 OTP-8741 OTP-8742
+TICKETS_5_3_5 = OTP-8940
+
+TICKETS_5_3_4 = \
+ OTP-8739 \
+ OTP-8741 \
+ OTP-8742
TICKETS_5_3_3 = \
OTP-8609 \