aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMicael Karlberg <[email protected]>2011-10-26 12:20:29 +0200
committerMicael Karlberg <[email protected]>2011-10-26 12:20:29 +0200
commit1577983b9b3883b74e3e460ed4f8f6916ffaa3a5 (patch)
tree2986bd8b98369c69d36957c674a965839b6f9d28
parent500557baeab33eb1999d34910aa2bb76a0e38f48 (diff)
downloadotp-1577983b9b3883b74e3e460ed4f8f6916ffaa3a5.tar.gz
otp-1577983b9b3883b74e3e460ed4f8f6916ffaa3a5.tar.bz2
otp-1577983b9b3883b74e3e460ed4f8f6916ffaa3a5.zip
Fixed hex-decoding.
OTP-9655
-rw-r--r--lib/inets/src/http_lib/http_uri.erl33
-rw-r--r--lib/inets/src/http_server/httpd_request_handler.erl4
-rw-r--r--lib/inets/src/http_server/httpd_response.erl16
-rw-r--r--lib/inets/src/http_server/httpd_util.erl2
-rw-r--r--lib/inets/src/inets_app/inets.appup.src14
-rw-r--r--lib/inets/test/httpc_SUITE.erl27
-rw-r--r--lib/inets/test/httpd_SUITE.erl4
-rw-r--r--lib/inets/test/httpd_test_lib.erl58
8 files changed, 101 insertions, 57 deletions
diff --git a/lib/inets/src/http_lib/http_uri.erl b/lib/inets/src/http_lib/http_uri.erl
index 3804af60f4..b470fd0b46 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,33 @@ 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) ->
+ try
+ begin
+ do_decode(String)
+ end
+ catch
+ throw:{bad_hex_value, _BadChar} ->
+ %% The string is either badly encoded or a string
+ %% containing a % followed by a non-hex char.
+ %% In any case, return as-is since there is nothing
+ %% we can do...
+ %% Note that the valid hex-chars are: 0-9, a-f and A-F.
+ String
+ end.
+
+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} ->
@@ -138,4 +156,5 @@ uri_encode(Char, Reserved) ->
hex2dec(X) when (X>=$0) andalso (X=<$9) -> X-$0;
hex2dec(X) when (X>=$A) andalso (X=<$F) -> X-$A+10;
-hex2dec(X) when (X>=$a) andalso (X=<$f) -> X-$a+10.
+hex2dec(X) when (X>=$a) andalso (X=<$f) -> X-$a+10;
+hex2dec(X) -> throw({bad_hex_value, X}).
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..1301f27081 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
@@ -100,12 +100,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 +352,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 2e0752bcc0..366843354e 100644
--- a/lib/inets/src/http_server/httpd_util.erl
+++ b/lib/inets/src/http_server/httpd_util.erl
@@ -183,7 +183,7 @@ message(400, none, _) ->
"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. " ++
- html_encode(http_uri:decode(Msg));
+ html_encode(Msg);
message(401, none, _) ->
"This server could not verify that you
are authorized to access the document you
diff --git a/lib/inets/src/inets_app/inets.appup.src b/lib/inets/src/inets_app/inets.appup.src
index ea696b9155..528a3601a4 100644
--- a/lib/inets/src/inets_app/inets.appup.src
+++ b/lib/inets/src/inets_app/inets.appup.src
@@ -20,9 +20,10 @@
[
{"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, 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, httpd_response, soft_purge, soft_purge, []}
]
},
{"5.3.4",
@@ -54,9 +55,10 @@
[
{"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, 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, httpd_response, soft_purge, soft_purge, []}
]
},
{"5.3.4",
diff --git a/lib/inets/test/httpc_SUITE.erl b/lib/inets/test/httpc_SUITE.erl
index c52e3d25cd..3a1f4cc83d 100644
--- a/lib/inets/test/httpc_SUITE.erl
+++ b/lib/inets/test/httpc_SUITE.erl
@@ -197,9 +197,7 @@ 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
@@ -209,9 +207,8 @@ init_per_testcase(Case, Timeout, Config) ->
ok ->
[{watchdog, Dog} | TmpConfig];
_ ->
- [{skip,
- "SSL does not seem to be supported"}
- | TmpConfig]
+ [skip("SSL does not seem to be supported") |
+ TmpConfig]
end;
_ ->
%% We use erlang.org for the proxy tests
@@ -239,23 +236,20 @@ init_per_testcase(Case, Timeout, Config) ->
],
case lists:member(Rest, BadCases) of
true ->
- [{skip,
- "TC and server not compatible"}|
+ [skip("TC and server not compatible") |
TmpConfig];
false ->
inets:start(),
[{watchdog, Dog} | TmpConfig]
end;
false ->
- [{skip, "proxy not responding"} | TmpConfig]
+ [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,
@@ -264,11 +258,12 @@ init_per_testcase(Case, Timeout, Config) ->
inets:enable_trace(max, io, httpc),
%% inets:enable_trace(max, io, all),
%% snmp:set_trace([gen_tcp, inet_tcp, prim_inet]),
- io:format(user, "~n~n*** INIT ~w:~w ***~n"
- " NewConfig: ~p~n~n",
- [?MODULE, Case, NewConfig]),
NewConfig.
+start_http_server(ConfDir, ConfFile) ->
+ inets_test_lib:start_http_server( filename:join(ConfDir, ConfFile) ).
+
+
%%--------------------------------------------------------------------
%% Function: end_per_testcase(Case, Config) -> _
%% Case - atom()
diff --git a/lib/inets/test/httpd_SUITE.erl b/lib/inets/test/httpd_SUITE.erl
index 7403d4a643..7d95cdbebd 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
@@ -1627,7 +1627,7 @@ ticket_6003(Config) ->
?IP_PORT, ?config(node, Config),
"GET http://www.erlang.org/%skalle "
"HTTP/1.0\r\n\r\n",
- [{statuscode, 400},
+ [{statuscode, 404},
{version, "HTTP/1.0"}]),
ok.
diff --git a/lib/inets/test/httpd_test_lib.erl b/lib/inets/test/httpd_test_lib.erl
index 6abee5be2c..becb54e479 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
@@ -200,10 +202,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 +218,7 @@ validate(RequestStr, #state{status_line = {Version, StatusCode, _},
list_to_integer(Headers#http_response_h.'content-length'),
Body).
+
%%--------------------------------------------------------------------
%% Internal functions
%%------------------------------------------------------------------
@@ -225,21 +227,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 +248,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 +279,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 +292,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 +300,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 +328,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).
+