aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lib/inets/src/http_client/Makefile27
-rw-r--r--lib/inets/src/http_client/http.erl772
-rw-r--r--lib/inets/src/http_client/httpc_response.erl19
-rw-r--r--lib/inets/src/http_lib/Makefile22
-rw-r--r--lib/inets/src/http_lib/http_chunk.erl21
-rw-r--r--lib/inets/src/http_lib/http_transport.erl11
-rw-r--r--lib/inets/src/http_lib/http_util.erl35
-rw-r--r--lib/inets/src/http_server/Makefile15
-rw-r--r--lib/inets/src/http_server/httpd.erl14
-rw-r--r--lib/inets/src/http_server/httpd_conf.erl19
-rw-r--r--lib/inets/src/http_server/httpd_instance_sup.erl16
-rw-r--r--lib/inets/src/http_server/httpd_request.erl17
-rw-r--r--lib/inets/src/http_server/httpd_sup.erl12
-rw-r--r--lib/inets/src/http_server/mod_alias.erl111
-rw-r--r--lib/inets/src/http_server/mod_cgi.erl12
-rw-r--r--lib/inets/src/http_server/mod_esi.erl51
-rw-r--r--lib/inets/src/inets_app/Makefile24
-rw-r--r--lib/inets/src/inets_app/inets.app.src15
-rw-r--r--lib/inets/src/inets_app/inets.appup.src24
-rw-r--r--lib/inets/src/inets_app/inets.erl16
-rw-r--r--lib/inets/src/tftp/Makefile20
-rw-r--r--lib/inets/test/Makefile78
-rw-r--r--lib/inets/test/ftp_SUITE_data/TAR.exclude2
-rw-r--r--lib/inets/test/ftp_SUITE_data/ftpd_hosts.skel17
-rw-r--r--lib/inets/test/ftp_SUITE_data/inets_test_hosts15
-rw-r--r--lib/inets/test/ftp_suite_lib.erl116
-rw-r--r--lib/inets/test/ftp_ticket_test.erl13
-rw-r--r--lib/inets/test/httpc_SUITE.erl794
-rw-r--r--lib/inets/test/httpc_cookie_SUITE.erl201
-rw-r--r--lib/inets/test/httpd_SUITE.erl128
-rw-r--r--lib/inets/test/inets_SUITE.erl153
-rw-r--r--lib/inets/test/inets_sup_SUITE.erl92
32 files changed, 1478 insertions, 1404 deletions
diff --git a/lib/inets/src/http_client/Makefile b/lib/inets/src/http_client/Makefile
index 23170f439f..628c91421f 100644
--- a/lib/inets/src/http_client/Makefile
+++ b/lib/inets/src/http_client/Makefile
@@ -1,19 +1,19 @@
#
# %CopyrightBegin%
-#
-# Copyright Ericsson AB 2005-2009. All Rights Reserved.
-#
+#
+# Copyright Ericsson AB 2005-2010. 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
# 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.
-#
+#
# %CopyrightEnd%
#
#
@@ -22,6 +22,7 @@ include $(ERL_TOP)/make/target.mk
EBIN = ../../ebin
include $(ERL_TOP)/make/$(TARGET)/otp.mk
+
# ----------------------------------------------------
# Application version
# ----------------------------------------------------
@@ -29,17 +30,20 @@ include ../../vsn.mk
VSN = $(INETS_VSN)
+
# ----------------------------------------------------
# Release directory specification
# ----------------------------------------------------
-RELSYSDIR = $(RELEASE_PATH)/lib/inets-$(VSN)
+RELSYSDIR = $(RELEASE_PATH)/lib/$(APPLICATION)-$(VSN)
+
# ----------------------------------------------------
# Target Specs
# ----------------------------------------------------
MODULES = \
http \
- http_cookie \
+ httpc \
+ httpc_cookie \
httpc_handler \
httpc_manager \
httpc_sup \
@@ -55,20 +59,24 @@ ERL_FILES = $(MODULES:%=%.erl)
TARGET_FILES= $(MODULES:%=$(EBIN)/%.$(EMULATOR))
+
# ----------------------------------------------------
# INETS FLAGS
# ----------------------------------------------------
-INETS_FLAGS = -D'SERVER_SOFTWARE="inets/$(VSN)"' \
+INETS_FLAGS = -D'SERVER_SOFTWARE="$(APPLICATION)/$(VSN)"'
+
# ----------------------------------------------------
# FLAGS
# ----------------------------------------------------
INETS_ERL_FLAGS += -I ../http_lib -I ../inets_app -pa ../../ebin
-ERL_COMPILE_FLAGS += $(INETS_ERL_FLAGS)\
+ERL_COMPILE_FLAGS += $(INETS_ERL_FLAGS) \
$(INETS_FLAGS) \
+'{parse_transform,sys_pre_attributes}' \
+'{attribute,insert,app_vsn,$(APP_VSN)}'
+
+
# ----------------------------------------------------
# Targets
# ----------------------------------------------------
@@ -94,6 +102,7 @@ release_spec: opt
release_docs_spec:
info:
+ @echo "APPLICATION = $(APPLICATION)"
@echo "INETS_DEBUG = $(INETS_DEBUG)"
@echo "INETS_FLAGS = $(INETS_FLAGS)"
@echo "ERL_COMPILE_FLAGS = $(ERL_COMPILE_FLAGS)"
diff --git a/lib/inets/src/http_client/http.erl b/lib/inets/src/http_client/http.erl
index ce5d7723f0..7e1e90b50e 100644
--- a/lib/inets/src/http_client/http.erl
+++ b/lib/inets/src/http_client/http.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2002-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2002-2010. 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
%% 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.
-%%
+%%
%% %CopyrightEnd%
%%
%%
@@ -24,7 +24,6 @@
%%% - RFC 2818 HTTP Over TLS
-module(http).
--behaviour(inets_service).
%% API
-export([request/1, request/2, request/4, request/5,
@@ -35,15 +34,6 @@
cookie_header/2, stream_next/1,
default_profile/0]).
-%% Behavior callbacks
--export([start_standalone/1, start_service/1,
- stop_service/1, services/0, service_info/1]).
-
--include("http_internal.hrl").
--include("httpc_internal.hrl").
-
--define(DEFAULT_PROFILE, default).
-
%%%=========================================================================
%%% API
@@ -51,751 +41,75 @@
%%--------------------------------------------------------------------------
%% request(Url [, Profile]) ->
-%% {ok, {StatusLine, Headers, Body}} | {error,Reason}
-%%
-%% Url - string()
-%% Description: Calls request/4 with default values.
+%% request(Method, Request, HTTPOptions, Options [, Profile])
%%--------------------------------------------------------------------------
-request(Url) ->
- request(Url, default_profile()).
-
-request(Url, Profile) ->
- request(get, {Url, []}, [], [], Profile).
-
-
-%%--------------------------------------------------------------------------
-%% request(Method, Request, HTTPOptions, Options [, Profile]) ->
-%% {ok, {StatusLine, Headers, Body}} | {ok, {Status, Body}} |
-%% {ok, RequestId} | {error,Reason} | {ok, {saved_as, FilePath}
-%%
-%% Method - atom() = head | get | put | post | trace | options| delete
-%% Request - {Url, Headers} | {Url, Headers, ContentType, Body}
-%% Url - string()
-%% HTTPOptions - [HttpOption]
-%% HTTPOption - {timeout, Time} | {connect_timeout, Time} |
-%% {ssl, SSLOptions} | {proxy_auth, {User, Password}}
-%% Ssloptions = [SSLOption]
-%% SSLOption = {verify, code()} | {depth, depth()} | {certfile, path()} |
-%% {keyfile, path()} | {password, string()} | {cacertfile, path()} |
-%% {ciphers, string()}
-%% Options - [Option]
-%% Option - {sync, Boolean} | {body_format, BodyFormat} |
-%% {full_result, Boolean} | {stream, To} |
-%% {headers_as_is, Boolean}
-%% StatusLine = {HTTPVersion, StatusCode, ReasonPhrase}</v>
-%% HTTPVersion = string()
-%% StatusCode = integer()
-%% ReasonPhrase = string()
-%% Headers = [Header]
-%% Header = {Field, Value}
-%% Field = string()
-%% Value = string()
-%% Body = string() | binary() - HTLM-code
-%%
-%% Description: Sends a HTTP-request. The function can be both
-%% syncronus and asynchronous in the later case the function will
-%% return {ok, RequestId} and later on a message will be sent to the
-%% calling process on the format {http, {RequestId, {StatusLine,
-%% Headers, Body}}} or {http, {RequestId, {error, Reason}}}
-%%--------------------------------------------------------------------------
+request(Url) -> httpc:request(Url).
+request(Url, Profile) -> httpc:request(Url, Profile).
request(Method, Request, HttpOptions, Options) ->
- request(Method, Request, HttpOptions, Options, default_profile()).
+ httpc:request(Method, Request, HttpOptions, Options).
+request(Method, Request, HttpOptions, Options, Profile) ->
+ httpc:request(Method, Request, HttpOptions, Options, Profile).
-request(Method, {Url, Headers}, HTTPOptions, Options, Profile)
- when (Method =:= options) orelse
- (Method =:= get) orelse
- (Method =:= head) orelse
- (Method =:= delete) orelse
- (Method =:= trace) ->
- case http_uri:parse(Url) of
- {error, Reason} ->
- {error, Reason};
- ParsedUrl ->
- handle_request(Method, Url, ParsedUrl, Headers, [], [],
- HTTPOptions, Options, Profile)
- end;
-
-request(Method, {Url,Headers,ContentType,Body}, HTTPOptions, Options, Profile)
- when (Method =:= post) orelse (Method =:= put) ->
- case http_uri:parse(Url) of
- {error, Reason} ->
- {error, Reason};
- ParsedUrl ->
- handle_request(Method, Url,
- ParsedUrl, Headers, ContentType, Body,
- HTTPOptions, Options, Profile)
- end.
%%--------------------------------------------------------------------------
-%% request(RequestId) -> ok
-%% RequestId - As returned by request/4
-%%
-%% Description: Cancels a HTTP-request.
+%% cancel_request(RequestId [, Profile])
%%-------------------------------------------------------------------------
-cancel_request(RequestId) ->
- cancel_request(RequestId, default_profile()).
+cancel_request(RequestId) ->
+ httpc:cancel_request(RequestId).
cancel_request(RequestId, Profile) ->
- ok = httpc_manager:cancel_request(RequestId, profile_name(Profile)),
- receive
- %% If the request was allready fullfilled throw away the
- %% answer as the request has been canceled.
- {http, {RequestId, _}} ->
- ok
- after 0 ->
- ok
- end.
-
-
-set_option(Key, Value) ->
- set_option(Key, Value, default_profile()).
-
-set_option(Key, Value, Profile) ->
- set_options([{Key, Value}], Profile).
+ httpc:cancel_request(RequestId, Profile).
%%--------------------------------------------------------------------------
-%% set_options(Options [, Profile]) -> ok | {error, Reason}
-%% Options - [Option]
-%% Profile - atom()
-%% Option - {proxy, {Proxy, NoProxy}} | {max_sessions, MaxSessions} |
-%% {max_pipeline_length, MaxPipeline} |
-%% {pipeline_timeout, PipelineTimeout} | {cookies, CookieMode} |
-%% {ipfamily, IpFamily}
-%% Proxy - {Host, Port}
-%% NoProxy - [Domain | HostName | IPAddress]
-%% MaxSessions, MaxPipeline, PipelineTimeout = integer()
-%% CookieMode - enabled | disabled | verify
-%% IpFamily - inet | inet6 | inet6fb4
-%% Description: Informs the httpc_manager of the new settings.
+%% set_options(Options [, Profile])
+%% set_option(Key, Value [, Profile])
%%-------------------------------------------------------------------------
+
set_options(Options) ->
- set_options(Options, default_profile()).
+ httpc:set_options(Options).
set_options(Options, Profile) ->
- case validate_options(Options) of
- {ok, Opts} ->
- try httpc_manager:set_options(Opts, profile_name(Profile)) of
- Result ->
- Result
- catch
- exit:{noproc, _} ->
- {error, inets_not_started}
- end;
- {error, Reason} ->
- {error, Reason}
- end.
+ httpc:set_options(Options, Profile).
+
+set_option(Key, Value) ->
+ httpc:set_option(Key, Value).
+set_option(Key, Value, Profile) ->
+ httpc:set_option(Key, Value, Profile).
%%--------------------------------------------------------------------------
-%% verify_cookies(SetCookieHeaders, Url [, Profile]) -> ok | {error, reason}
-%%
-%%
-%% Description: Store the cookies from <SetCookieHeaders>
-%% in the cookie database
-%% for the profile <Profile>. This function shall be used when the option
-%% cookie is set to verify.
+%% verify_cookies(SetCookieHeaders, Url [, Profile])
%%-------------------------------------------------------------------------
-verify_cookies(SetCookieHeaders, Url) ->
- verify_cookies(SetCookieHeaders, Url, default_profile()).
+verify_cookies(SetCookieHeaders, Url) ->
+ httpc:store_cookies(SetCookieHeaders, Url).
verify_cookies(SetCookieHeaders, Url, Profile) ->
- {_, _, Host, Port, Path, _} = http_uri:parse(Url),
- ProfileName = profile_name(Profile),
- Cookies = http_cookie:cookies(SetCookieHeaders, Path, Host),
- try httpc_manager:store_cookies(Cookies, {Host, Port}, ProfileName) of
- _ ->
- ok
- catch
- exit:{noproc, _} ->
- {error, {not_started, Profile}}
- end.
+ httpc:store_cookies(SetCookieHeaders, Url, Profile).
+
%%--------------------------------------------------------------------------
-%% cookie_header(Url [, Profile]) -> Header | {error, Reason}
-%%
-%% Description: Returns the cookie header that would be sent when making
-%% a request to <Url>.
+%% cookie_header(Url [, Profile])
%%-------------------------------------------------------------------------
-cookie_header(Url) ->
- cookie_header(Url, default_profile()).
+cookie_header(Url) ->
+ httpc:cookie_header(Url).
cookie_header(Url, Profile) ->
- try httpc_manager:cookies(Url, profile_name(Profile)) of
- Header ->
- Header
- catch
- exit:{noproc, _} ->
- {error, {not_started, Profile}}
- end.
-
-
-stream_next(Pid) ->
- httpc_handler:stream_next(Pid).
-
-%%%========================================================================
-%%% Behavior callbacks
-%%%========================================================================
-start_standalone(PropList) ->
- case proplists:get_value(profile, PropList) of
- undefined ->
- {error, no_profile};
- Profile ->
- Dir =
- proplists:get_value(data_dir, PropList, only_session_cookies),
- httpc_manager:start_link({Profile, Dir}, stand_alone)
- end.
-
-start_service(Config) ->
- httpc_profile_sup:start_child(Config).
-
-stop_service(Profile) when is_atom(Profile) ->
- httpc_profile_sup:stop_child(Profile);
-stop_service(Pid) when is_pid(Pid) ->
- case service_info(Pid) of
- {ok, [{profile, Profile}]} ->
- stop_service(Profile);
- Error ->
- Error
- end.
-
-services() ->
- [{httpc, Pid} || {_, Pid, _, _} <-
- supervisor:which_children(httpc_profile_sup)].
-service_info(Pid) ->
- try [{ChildName, ChildPid} ||
- {ChildName, ChildPid, _, _} <-
- supervisor:which_children(httpc_profile_sup)] of
- Children ->
- child_name2info(child_name(Pid, Children))
- catch
- exit:{noproc, _} ->
- {error, service_not_available}
- end.
-
-
-%%%========================================================================
-%%% Internal functions
-%%%========================================================================
-handle_request(Method, Url,
- {Scheme, UserInfo, Host, Port, Path, Query},
- Headers, ContentType, Body,
- HTTPOptions0, Options, Profile) ->
-
- HTTPOptions = http_options(HTTPOptions0),
- Sync = proplists:get_value(sync, Options, true),
- NewHeaders = lists:map(fun({Key, Val}) ->
- {http_util:to_lower(Key), Val} end,
- Headers),
- Stream = proplists:get_value(stream, Options, none),
- case {Sync, Stream} of
- {true, self} ->
- {error, streaming_error};
- _ ->
- RecordHeaders = header_record(NewHeaders,
- #http_request_h{},
- Host,
- HTTPOptions#http_options.version),
- Request = #request{from = self(),
- scheme = Scheme,
- address = {Host,Port},
- path = Path,
- pquery = Query,
- method = Method,
- headers = RecordHeaders,
- content = {ContentType,Body},
- settings = HTTPOptions,
- abs_uri = Url,
- userinfo = UserInfo,
- stream = Stream,
- headers_as_is = headers_as_is(Headers, Options)},
- try httpc_manager:request(Request, profile_name(Profile)) of
- {ok, RequestId} ->
- handle_answer(RequestId, Sync, Options);
- {error, Reason} ->
- {error, Reason}
- catch
- error:{noproc, _} ->
- {error, {not_started, Profile}}
- end
- end.
-
-
-handle_answer(RequestId, false, _) ->
- {ok, RequestId};
-handle_answer(RequestId, true, Options) ->
- receive
- {http, {RequestId, saved_to_file}} ->
- {ok, saved_to_file};
- {http, {RequestId, Result = {_,_,_}}} ->
- return_answer(Options, Result);
- {http, {RequestId, {error, Reason}}} ->
- {error, Reason}
- end.
-
-return_answer(Options, {{"HTTP/0.9",_,_}, _, BinBody}) ->
- Body = format_body(BinBody, Options),
- {ok, Body};
-
-return_answer(Options, {StatusLine, Headers, BinBody}) ->
-
- Body = format_body(BinBody, Options),
-
- case proplists:get_value(full_result, Options, true) of
- true ->
- {ok, {StatusLine, Headers, Body}};
- false ->
- {_, Status, _} = StatusLine,
- {ok, {Status, Body}}
- end.
-
-format_body(BinBody, Options) ->
- case proplists:get_value(body_format, Options, string) of
- string ->
- binary_to_list(BinBody);
- _ ->
- BinBody
- end.
+ httpc:cookie_header(Url, Profile).
-%% This options is a workaround for http servers that do not follow the
-%% http standard and have case sensative header parsing. Should only be
-%% used if there is no other way to communicate with the server or for
-%% testing purpose.
-headers_as_is(Headers, Options) ->
- case proplists:get_value(headers_as_is, Options, false) of
- false ->
- [];
- true ->
- Headers
- end.
+%%--------------------------------------------------------------------------
+%% stream_next(Pid)
+%%-------------------------------------------------------------------------
-http_options(HttpOptions) ->
- HttpOptionsDefault = http_options_default(),
- http_options(HttpOptionsDefault, HttpOptions, #http_options{}).
-
-http_options([], [], Acc) ->
- Acc;
-http_options([], HttpOptions, Acc) ->
- Fun = fun(BadOption) ->
- Report = io_lib:format("Invalid option ~p ignored ~n",
- [BadOption]),
- error_logger:info_report(Report)
- end,
- lists:foreach(Fun, HttpOptions),
- Acc;
-http_options([{Tag, Default, Idx, Post} | Defaults], HttpOptions, Acc) ->
- case lists:keysearch(Tag, 1, HttpOptions) of
- {value, {Tag, Val0}} ->
- case Post(Val0) of
- {ok, Val} ->
- Acc2 = setelement(Idx, Acc, Val),
- HttpOptions2 = lists:keydelete(Tag, 1, HttpOptions),
- http_options(Defaults, HttpOptions2, Acc2);
- error ->
- Report = io_lib:format("Invalid option ~p:~p ignored ~n",
- [Tag, Val0]),
- error_logger:info_report(Report),
- HttpOptions2 = lists:keydelete(Tag, 1, HttpOptions),
- http_options(Defaults, HttpOptions2, Acc)
- end;
- false ->
- DefaultVal =
- case Default of
- {value, Val} ->
- Val;
- {field, DefaultIdx} ->
- element(DefaultIdx, Acc)
- end,
- Acc2 = setelement(Idx, Acc, DefaultVal),
- http_options(Defaults, HttpOptions, Acc2)
- end.
-
-http_options_default() ->
- VersionPost =
- fun(Value) when is_atom(Value) ->
- {ok, http_util:to_upper(atom_to_list(Value))};
- (Value) when is_list(Value) ->
- {ok, http_util:to_upper(Value)};
- (_) ->
- error
- end,
- TimeoutPost = fun(Value) when is_integer(Value) andalso (Value >= 0) ->
- {ok, Value};
- (infinity = Value) ->
- {ok, Value};
- (_) ->
- error
- end,
- AutoRedirectPost = fun(Value) when (Value =:= true) orelse
- (Value =:= false) ->
- {ok, Value};
- (_) ->
- error
- end,
- SslPost = fun(Value) when is_list(Value) ->
- {ok, Value};
- (_) ->
- error
- end,
- ProxyAuthPost = fun({User, Passwd} = Value) when is_list(User) andalso
- is_list(Passwd) ->
- {ok, Value};
- (_) ->
- error
- end,
- RelaxedPost = fun(Value) when (Value =:= true) orelse
- (Value =:= false) ->
- {ok, Value};
- (_) ->
- error
- end,
- ConnTimeoutPost =
- fun(Value) when is_integer(Value) andalso (Value >= 0) ->
- {ok, Value};
- (infinity = Value) ->
- {ok, Value};
- (_) ->
- error
- end,
- [
- {version, {value, "HTTP/1.1"}, #http_options.version, VersionPost},
- {timeout, {value, ?HTTP_REQUEST_TIMEOUT}, #http_options.timeout, TimeoutPost},
- {autoredirect, {value, true}, #http_options.autoredirect, AutoRedirectPost},
- {ssl, {value, []}, #http_options.ssl, SslPost},
- {proxy_auth, {value, undefined}, #http_options.proxy_auth, ProxyAuthPost},
- {relaxed, {value, false}, #http_options.relaxed, RelaxedPost},
- %% this field has to be *after* the timeout field (as that field is used for the default value)
- {connect_timeout, {field, #http_options.timeout}, #http_options.connect_timeout, ConnTimeoutPost}
- ].
-
-validate_options(Options) ->
- (catch validate_options(Options, [])).
-
-validate_options([], ValidateOptions) ->
- {ok, lists:reverse(ValidateOptions)};
-
-validate_options([{proxy, Proxy} = Opt| Tail], Acc) ->
- validate_proxy(Proxy),
- validate_options(Tail, [Opt | Acc]);
-
-validate_options([{max_sessions, Value} = Opt| Tail], Acc) ->
- validate_max_sessions(Value),
- validate_options(Tail, [Opt | Acc]);
-
-validate_options([{keep_alive_timeout, Value} = Opt| Tail], Acc) ->
- validate_keep_alive_timeout(Value),
- validate_options(Tail, [Opt | Acc]);
-
-validate_options([{max_keep_alive_length, Value} = Opt| Tail], Acc) ->
- validate_max_keep_alive_length(Value),
- validate_options(Tail, [Opt | Acc]);
-
-validate_options([{pipeline_timeout, Value} = Opt| Tail], Acc) ->
- validate_pipeline_timeout(Value),
- validate_options(Tail, [Opt | Acc]);
-
-validate_options([{max_pipeline_length, Value} = Opt| Tail], Acc) ->
- validate_max_pipeline_length(Value),
- validate_options(Tail, [Opt | Acc]);
-
-validate_options([{cookies, Value} = Opt| Tail], Acc) ->
- validate_cookies(Value),
- validate_options(Tail, [Opt | Acc]);
-
-validate_options([{ipfamily, Value} = Opt| Tail], Acc) ->
- validate_ipfamily(Value),
- validate_options(Tail, [Opt | Acc]);
-
-%% For backward compatibillity
-validate_options([{ipv6, Value}| Tail], Acc) ->
- NewValue = validate_ipv6(Value),
- Opt = {ipfamily, NewValue},
- validate_options(Tail, [Opt | Acc]);
-
-validate_options([{ip, Value} = Opt| Tail], Acc) ->
- validate_ip(Value),
- validate_options(Tail, [Opt | Acc]);
-
-validate_options([{port, Value} = Opt| Tail], Acc) ->
- validate_port(Value),
- validate_options(Tail, [Opt | Acc]);
-
-validate_options([{verbose, Value} = Opt| Tail], Acc) ->
- validate_verbose(Value),
- validate_options(Tail, [Opt | Acc]);
-
-validate_options([{_, _} = Opt| _], _Acc) ->
- {error, {not_an_option, Opt}}.
-
-
-validate_proxy({{ProxyHost, ProxyPort}, NoProxy} = Proxy)
- when is_list(ProxyHost) andalso
- is_integer(ProxyPort) andalso
- is_list(NoProxy) ->
- Proxy;
-validate_proxy(BadProxy) ->
- bad_option(proxy, BadProxy).
-
-validate_max_sessions(Value) when is_integer(Value) andalso (Value >= 0) ->
- Value;
-validate_max_sessions(BadValue) ->
- bad_option(max_sessions, BadValue).
-
-validate_keep_alive_timeout(Value) when is_integer(Value) andalso (Value >= 0) ->
- Value;
-validate_keep_alive_timeout(infinity = Value) ->
- Value;
-validate_keep_alive_timeout(BadValue) ->
- bad_option(keep_alive_timeout, BadValue).
-
-validate_max_keep_alive_length(Value) when is_integer(Value) andalso (Value >= 0) ->
- Value;
-validate_max_keep_alive_length(BadValue) ->
- bad_option(max_keep_alive_length, BadValue).
-
-validate_pipeline_timeout(Value) when is_integer(Value) ->
- Value;
-validate_pipeline_timeout(infinity = Value) ->
- Value;
-validate_pipeline_timeout(BadValue) ->
- bad_option(pipeline_timeout, BadValue).
-
-validate_max_pipeline_length(Value) when is_integer(Value) ->
- Value;
-validate_max_pipeline_length(BadValue) ->
- bad_option(max_pipeline_length, BadValue).
-
-validate_cookies(Value)
- when ((Value =:= enabled) orelse
- (Value =:= disabled) orelse
- (Value =:= verify)) ->
- Value;
-validate_cookies(BadValue) ->
- bad_option(cookies, BadValue).
-
-validate_ipv6(Value) when (Value =:= enabled) orelse (Value =:= disabled) ->
- case Value of
- enabled ->
- inet6fb4;
- disabled ->
- inet
- end;
-validate_ipv6(BadValue) ->
- bad_option(ipv6, BadValue).
-
-validate_ipfamily(Value)
- when (Value =:= inet) orelse (Value =:= inet6) orelse (Value =:= inet6fb4) ->
- Value;
-validate_ipfamily(BadValue) ->
- bad_option(ipfamily, BadValue).
-
-validate_ip(Value)
- when is_tuple(Value) andalso ((size(Value) =:= 4) orelse (size(Value) =:= 8)) ->
- Value;
-validate_ip(BadValue) ->
- bad_option(ip, BadValue).
-
-validate_port(Value) when is_integer(Value) ->
- Value;
-validate_port(BadValue) ->
- bad_option(port, BadValue).
-
-validate_verbose(Value)
- when ((Value =:= false) orelse
- (Value =:= verbose) orelse
- (Value =:= debug) orelse
- (Value =:= trace)) ->
- ok;
-validate_verbose(BadValue) ->
- bad_option(verbose, BadValue).
-
-bad_option(Option, BadValue) ->
- throw({error, {bad_option, Option, BadValue}}).
-
-
-
-header_record([], RequestHeaders, Host, Version) ->
- validate_headers(RequestHeaders, Host, Version);
-header_record([{"cache-control", Val} | Rest], RequestHeaders, Host, Version) ->
- header_record(Rest, RequestHeaders#http_request_h{'cache-control' = Val},
- Host, Version);
-header_record([{"connection", Val} | Rest], RequestHeaders, Host, Version) ->
- header_record(Rest, RequestHeaders#http_request_h{connection = Val}, Host,
- Version);
-header_record([{"date", Val} | Rest], RequestHeaders, Host, Version) ->
- header_record(Rest, RequestHeaders#http_request_h{date = Val}, Host,
- Version);
-header_record([{"pragma", Val} | Rest], RequestHeaders, Host, Version) ->
- header_record(Rest, RequestHeaders#http_request_h{pragma = Val}, Host,
- Version);
-header_record([{"trailer", Val} | Rest], RequestHeaders, Host, Version) ->
- header_record(Rest, RequestHeaders#http_request_h{trailer = Val}, Host,
- Version);
-header_record([{"transfer-encoding", Val} | Rest], RequestHeaders, Host,
- Version) ->
- header_record(Rest,
- RequestHeaders#http_request_h{'transfer-encoding' = Val},
- Host, Version);
-header_record([{"upgrade", Val} | Rest], RequestHeaders, Host, Version) ->
- header_record(Rest, RequestHeaders#http_request_h{upgrade = Val}, Host,
- Version);
-header_record([{"via", Val} | Rest], RequestHeaders, Host, Version) ->
- header_record(Rest, RequestHeaders#http_request_h{via = Val}, Host,
- Version);
-header_record([{"warning", Val} | Rest], RequestHeaders, Host, Version) ->
- header_record(Rest, RequestHeaders#http_request_h{warning = Val}, Host,
- Version);
-header_record([{"accept", Val} | Rest], RequestHeaders, Host, Version) ->
- header_record(Rest, RequestHeaders#http_request_h{accept = Val}, Host,
- Version);
-header_record([{"accept-charset", Val} | Rest], RequestHeaders, Host, Version) ->
- header_record(Rest, RequestHeaders#http_request_h{'accept-charset' = Val},
- Host, Version);
-header_record([{"accept-encoding", Val} | Rest], RequestHeaders, Host,
- Version) ->
- header_record(Rest, RequestHeaders#http_request_h{'accept-encoding' = Val},
- Host, Version);
-header_record([{"accept-language", Val} | Rest], RequestHeaders, Host,
- Version) ->
- header_record(Rest, RequestHeaders#http_request_h{'accept-language' = Val},
- Host, Version);
-header_record([{"authorization", Val} | Rest], RequestHeaders, Host, Version) ->
- header_record(Rest, RequestHeaders#http_request_h{authorization = Val},
- Host, Version);
-header_record([{"expect", Val} | Rest], RequestHeaders, Host, Version) ->
- header_record(Rest, RequestHeaders#http_request_h{expect = Val}, Host,
- Version);
-header_record([{"from", Val} | Rest], RequestHeaders, Host, Version) ->
- header_record(Rest, RequestHeaders#http_request_h{from = Val}, Host,
- Version);
-header_record([{"host", Val} | Rest], RequestHeaders, Host, Version) ->
- header_record(Rest, RequestHeaders#http_request_h{host = Val}, Host,
- Version);
-header_record([{"if-match", Val} | Rest], RequestHeaders, Host, Version) ->
- header_record(Rest, RequestHeaders#http_request_h{'if-match' = Val},
- Host, Version);
-header_record([{"if-modified-since", Val} | Rest], RequestHeaders, Host,
- Version) ->
- header_record(Rest,
- RequestHeaders#http_request_h{'if-modified-since' = Val},
- Host, Version);
-header_record([{"if-none-match", Val} | Rest], RequestHeaders, Host, Version) ->
- header_record(Rest, RequestHeaders#http_request_h{'if-none-match' = Val},
- Host, Version);
-header_record([{"if-range", Val} | Rest], RequestHeaders, Host, Version) ->
- header_record(Rest, RequestHeaders#http_request_h{'if-range' = Val},
- Host, Version);
-
-header_record([{"if-unmodified-since", Val} | Rest], RequestHeaders, Host,
- Version) ->
- header_record(Rest, RequestHeaders#http_request_h{'if-unmodified-since'
- = Val}, Host, Version);
-header_record([{"max-forwards", Val} | Rest], RequestHeaders, Host, Version) ->
- header_record(Rest, RequestHeaders#http_request_h{'max-forwards' = Val},
- Host, Version);
-header_record([{"proxy-authorization", Val} | Rest], RequestHeaders, Host,
- Version) ->
- header_record(Rest, RequestHeaders#http_request_h{'proxy-authorization'
- = Val}, Host, Version);
-header_record([{"range", Val} | Rest], RequestHeaders, Host, Version) ->
- header_record(Rest, RequestHeaders#http_request_h{range = Val}, Host,
- Version);
-header_record([{"referer", Val} | Rest], RequestHeaders, Host, Version) ->
- header_record(Rest, RequestHeaders#http_request_h{referer = Val}, Host,
- Version);
-header_record([{"te", Val} | Rest], RequestHeaders, Host, Version) ->
- header_record(Rest, RequestHeaders#http_request_h{te = Val}, Host,
- Version);
-header_record([{"user-agent", Val} | Rest], RequestHeaders, Host, Version) ->
- header_record(Rest, RequestHeaders#http_request_h{'user-agent' = Val},
- Host, Version);
-header_record([{"allow", Val} | Rest], RequestHeaders, Host, Version) ->
- header_record(Rest, RequestHeaders#http_request_h{allow = Val}, Host,
- Version);
-header_record([{"content-encoding", Val} | Rest], RequestHeaders, Host,
- Version) ->
- header_record(Rest,
- RequestHeaders#http_request_h{'content-encoding' = Val},
- Host, Version);
-header_record([{"content-language", Val} | Rest], RequestHeaders,
- Host, Version) ->
- header_record(Rest,
- RequestHeaders#http_request_h{'content-language' = Val},
- Host, Version);
-header_record([{"content-length", Val} | Rest], RequestHeaders, Host, Version) ->
- header_record(Rest, RequestHeaders#http_request_h{'content-length' = Val},
- Host, Version);
-header_record([{"content-location", Val} | Rest], RequestHeaders,
- Host, Version) ->
- header_record(Rest,
- RequestHeaders#http_request_h{'content-location' = Val},
- Host, Version);
-header_record([{"content-md5", Val} | Rest], RequestHeaders, Host, Version) ->
- header_record(Rest, RequestHeaders#http_request_h{'content-md5' = Val},
- Host, Version);
-header_record([{"content-range", Val} | Rest], RequestHeaders, Host, Version) ->
- header_record(Rest, RequestHeaders#http_request_h{'content-range' = Val},
- Host, Version);
-header_record([{"content-type", Val} | Rest], RequestHeaders, Host, Version) ->
- header_record(Rest, RequestHeaders#http_request_h{'content-type' = Val},
- Host, Version);
-header_record([{"expires", Val} | Rest], RequestHeaders, Host, Version) ->
- header_record(Rest, RequestHeaders#http_request_h{expires = Val}, Host,
- Version);
-header_record([{"last-modified", Val} | Rest], RequestHeaders, Host, Version) ->
- header_record(Rest, RequestHeaders#http_request_h{'last-modified' = Val},
- Host, Version);
-header_record([{Key, Val} | Rest], RequestHeaders, Host, Version) ->
- header_record(Rest, RequestHeaders#http_request_h{
- other = [{Key, Val} |
- RequestHeaders#http_request_h.other]},
- Host, Version).
+stream_next(Pid) ->
+ httpc:stream_next(Pid).
-validate_headers(RequestHeaders = #http_request_h{te = undefined}, Host,
- "HTTP/1.1" = Version) ->
- validate_headers(RequestHeaders#http_request_h{te = ""}, Host,
- "HTTP/1.1" = Version);
-validate_headers(RequestHeaders = #http_request_h{host = undefined},
- Host, "HTTP/1.1" = Version) ->
- validate_headers(RequestHeaders#http_request_h{host = Host}, Host, Version);
-validate_headers(RequestHeaders, _, _) ->
- RequestHeaders.
+%%--------------------------------------------------------------------------
+%% default_profile()
+%%-------------------------------------------------------------------------
default_profile() ->
- ?DEFAULT_PROFILE.
-
-profile_name(?DEFAULT_PROFILE) ->
- httpc_manager;
-profile_name(Pid) when is_pid(Pid) ->
- Pid;
-profile_name(Profile) ->
- list_to_atom("httpc_manager_" ++ atom_to_list(Profile)).
-
-child_name2info(undefined) ->
- {error, no_such_service};
-child_name2info(httpc_manager) ->
- {ok, [{profile, default}]};
-child_name2info({http, Profile}) ->
- {ok, [{profile, Profile}]}.
-
-child_name(_, []) ->
- undefined;
-child_name(Pid, [{Name, Pid} | _]) ->
- Name;
-child_name(Pid, [_ | Children]) ->
- child_name(Pid, Children).
-
-%% d(F) ->
-%% d(F, []).
-
-%% d(F, A) ->
-%% d(get(dbg), F, A).
-
-%% d(true, F, A) ->
-%% io:format(user, "~w:~w:" ++ F ++ "~n", [self(), ?MODULE | A]);
-%% d(_, _, _) ->
-%% ok.
-
+ httpc:default_profile().
diff --git a/lib/inets/src/http_client/httpc_response.erl b/lib/inets/src/http_client/httpc_response.erl
index e2ba66f730..df7d40a33e 100644
--- a/lib/inets/src/http_client/httpc_response.erl
+++ b/lib/inets/src/http_client/httpc_response.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2004-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2004-2010. 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
%% 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.
-%%
+%%
%% %CopyrightEnd%
%%
@@ -132,8 +132,13 @@ result(Response = {{_,Code,_}, _, _}, Request) when (Code div 100) =:= 5 ->
result(Response, Request) ->
transparent(Response, Request).
-send(To, Msg) ->
- To ! {http, Msg}.
+send(Receiver, Msg) when is_pid(Receiver) ->
+ Receiver ! {http, Msg};
+send(Receiver, Msg) when is_function(Receiver) ->
+ (catch Receiver(Msg));
+send({Module, Function, Args}, Msg) ->
+ (catch apply(Module, Function, [Msg | Args])).
+
%%%========================================================================
%%% Internal functions
diff --git a/lib/inets/src/http_lib/Makefile b/lib/inets/src/http_lib/Makefile
index 27e7ee65c5..7f4c92861c 100644
--- a/lib/inets/src/http_lib/Makefile
+++ b/lib/inets/src/http_lib/Makefile
@@ -1,19 +1,19 @@
#
# %CopyrightBegin%
-#
-# Copyright Ericsson AB 2005-2009. All Rights Reserved.
-#
+#
+# Copyright Ericsson AB 2005-2010. 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
# 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.
-#
+#
# %CopyrightEnd%
#
#
@@ -22,6 +22,7 @@ include $(ERL_TOP)/make/target.mk
EBIN = ../../ebin
include $(ERL_TOP)/make/$(TARGET)/otp.mk
+
# ----------------------------------------------------
# Application version
# ----------------------------------------------------
@@ -29,10 +30,12 @@ include ../../vsn.mk
VSN = $(INETS_VSN)
+
# ----------------------------------------------------
# Release directory specification
# ----------------------------------------------------
-RELSYSDIR = $(RELEASE_PATH)/lib/inets-$(VSN)
+RELSYSDIR = $(RELEASE_PATH)/lib/$(APPLICATION)-$(VSN)
+
# ----------------------------------------------------
# Target Specs
@@ -50,10 +53,12 @@ ERL_FILES = $(MODULES:%=%.erl)
TARGET_FILES= $(MODULES:%=$(EBIN)/%.$(EMULATOR))
+
# ----------------------------------------------------
# INETS FLAGS
# ----------------------------------------------------
-INETS_FLAGS = -D'SERVER_SOFTWARE="inets/$(VSN)"' \
+INETS_FLAGS = -D'SERVER_SOFTWARE="$(APPLICATION)/$(VSN)"'
+
# ----------------------------------------------------
# FLAGS
@@ -82,6 +87,7 @@ clean:
docs:
+
# ----------------------------------------------------
# Release Target
# ----------------------------------------------------
@@ -96,6 +102,8 @@ release_spec: opt
release_docs_spec:
info:
+ @echo "APPLICATION = $(APPLICATION)"
@echo "INETS_DEBUG = $(INETS_DEBUG)"
@echo "INETS_FLAGS = $(INETS_FLAGS)"
@echo "ERL_COMPILE_FLAGS = $(ERL_COMPILE_FLAGS)"
+
diff --git a/lib/inets/src/http_lib/http_chunk.erl b/lib/inets/src/http_lib/http_chunk.erl
index cd20dce9d5..621bc68eae 100644
--- a/lib/inets/src/http_lib/http_chunk.erl
+++ b/lib/inets/src/http_lib/http_chunk.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2004-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2004-2010. 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
%% 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.
-%%
+%%
%% %CopyrightEnd%
%%
%% Description: Implements chunked transfer encoding see RFC2616 section
@@ -186,13 +186,6 @@ decode_data(ChunkSize, TotalChunk,
Info = {MaxBodySize, BodySoFar, AccLength, MaxHeaderSize, Stream})
when ChunkSize =< size(TotalChunk) ->
case TotalChunk of
- %% Potential last chunk
- <<_:ChunkSize/binary, ?CR, ?LF, "0">> ->
- {?MODULE, decode_data, [ChunkSize, TotalChunk, Info]};
- <<_:ChunkSize/binary, ?CR, ?LF, "0", ?CR>> ->
- {?MODULE, decode_data, [ChunkSize, TotalChunk, Info]};
- <<_:ChunkSize/binary, ?CR, ?LF>> ->
- {?MODULE, decode_data, [ChunkSize, TotalChunk, Info]};
%% Last chunk
<<Data:ChunkSize/binary, ?CR, ?LF, "0", ";">> ->
%% Note ignore_extensions will call decode_trailer/1
@@ -223,6 +216,10 @@ decode_data(ChunkSize, TotalChunk,
NewBody,
integer_to_list(AccLength));
%% There are more chunks, so here we go agin...
+ <<Data:ChunkSize/binary, ?CR, ?LF>> ->
+ {NewBody, NewStream} =
+ stream(<<BodySoFar/binary, Data/binary>>, Stream),
+ {?MODULE, decode_size, [<<>>, [], {MaxBodySize, NewBody, AccLength, MaxHeaderSize, NewStream}]};
<<Data:ChunkSize/binary, ?CR, ?LF, Rest/binary>>
when (AccLength < MaxBodySize) or (MaxBodySize == nolimit) ->
{NewBody, NewStream} =
diff --git a/lib/inets/src/http_lib/http_transport.erl b/lib/inets/src/http_lib/http_transport.erl
index 8100d7183a..27a950174f 100644
--- a/lib/inets/src/http_lib/http_transport.erl
+++ b/lib/inets/src/http_lib/http_transport.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2004-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2004-2010. 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
%% 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.
-%%
+%%
%% %CopyrightEnd%
%%
%
@@ -247,6 +247,7 @@ send(ip_comm, Socket, Message) ->
send({ssl, _}, Socket, Message) ->
ssl:send(Socket, Message).
+
%%-------------------------------------------------------------------------
%% close(SocketType, Socket) -> ok | {error, Reason}
%% SocketType = ip_comm | {ssl, _}
diff --git a/lib/inets/src/http_lib/http_util.erl b/lib/inets/src/http_lib/http_util.erl
index b03b780cf8..ddb58c7116 100644
--- a/lib/inets/src/http_lib/http_util.erl
+++ b/lib/inets/src/http_lib/http_util.erl
@@ -1,27 +1,33 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2005-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2005-2010. 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
%% 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.
-%%
+%%
%% %CopyrightEnd%
%%
%%
-module(http_util).
--export([to_upper/1, to_lower/1, convert_netscapecookie_date/1,
+-export([
+ to_upper/1, to_lower/1,
+ convert_netscapecookie_date/1,
hexlist_to_integer/1, integer_to_hexlist/1,
- convert_month/1, is_hostname/1]).
+ convert_month/1,
+ is_hostname/1,
+ timestamp/0, timeout/2
+ ]).
+
%%%=========================================================================
%%% Internal application API
@@ -100,6 +106,21 @@ convert_month("Dec") -> 12.
is_hostname(Dest) ->
inet_parse:domain(Dest).
+
+timestamp() ->
+ {A,B,C} = os:timestamp(),
+ A*1000000000+B*1000+(C div 1000).
+
+timeout(Timeout, Started) ->
+ %% NewTimeout = Timeout - (timestamp() - Started),
+ case Timeout - (timestamp() - Started) of
+ NewTimeout when Timeout > 0 ->
+ NewTimeout;
+ _ ->
+ 0
+ end.
+
+
%%%========================================================================
%%% Internal functions
%%%========================================================================
diff --git a/lib/inets/src/http_server/Makefile b/lib/inets/src/http_server/Makefile
index 4bbd23df3f..ce1405011e 100644
--- a/lib/inets/src/http_server/Makefile
+++ b/lib/inets/src/http_server/Makefile
@@ -1,19 +1,19 @@
#
# %CopyrightBegin%
-#
-# Copyright Ericsson AB 2005-2009. All Rights Reserved.
-#
+#
+# Copyright Ericsson AB 2005-2010. 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
# 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.
-#
+#
# %CopyrightEnd%
#
#
@@ -33,7 +33,7 @@ VSN = $(INETS_VSN)
# ----------------------------------------------------
# Release directory specification
# ----------------------------------------------------
-RELSYSDIR = $(RELEASE_PATH)/lib/inets-$(VSN)
+RELSYSDIR = $(RELEASE_PATH)/lib/$(APPLICATION)-$(VSN)
# ----------------------------------------------------
@@ -92,7 +92,7 @@ TARGET_FILES= $(MODULES:%=$(EBIN)/%.$(EMULATOR))
# ----------------------------------------------------
# INETS FLAGS
# ----------------------------------------------------
-INETS_FLAGS = -D'SERVER_SOFTWARE="inets/$(VSN)"'
+INETS_FLAGS = -D'SERVER_SOFTWARE="$(APPLICATION)/$(VSN)"'
# ----------------------------------------------------
@@ -133,6 +133,7 @@ release_spec: opt
release_docs_spec:
info:
+ @echo "APPLICATION = $(APPLICATION)"
@echo "INETS_DEBUG = $(INETS_DEBUG)"
@echo "INETS_FLAGS = $(INETS_FLAGS)"
@echo "ERL_COMPILE_FLAGS = $(ERL_COMPILE_FLAGS)"
diff --git a/lib/inets/src/http_server/httpd.erl b/lib/inets/src/http_server/httpd.erl
index 554f162fc5..8fe54ccef6 100644
--- a/lib/inets/src/http_server/httpd.erl
+++ b/lib/inets/src/http_server/httpd.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 1997-2010. 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
%% 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.
-%%
+%%
%% %CopyrightEnd%
%%
%%
@@ -358,7 +358,7 @@ foreach([KeyValue|Rest]) ->
get_addr_and_port(ConfigFile) ->
case httpd_conf:load(ConfigFile) of
{ok, ConfigList} ->
- case httpd_conf:validate_properties(ConfigList) of
+ case (catch httpd_conf:validate_properties(ConfigList)) of
{ok, Config} ->
Address = proplists:get_value(bind_address, Config, any),
Port = proplists:get_value(port, Config, 80),
@@ -506,7 +506,7 @@ get_status(Addr,Port,Timeout) when is_integer(Port) ->
end.
do_reload_config(ConfigList, Mode) ->
- case httpd_conf:validate_properties(ConfigList) of
+ case (catch httpd_conf:validate_properties(ConfigList)) of
{ok, Config} ->
Address = proplists:get_value(bind_address, Config, any),
Port = proplists:get_value(port, Config, 80),
diff --git a/lib/inets/src/http_server/httpd_conf.erl b/lib/inets/src/http_server/httpd_conf.erl
index 9c93e2c5fe..3e498d1db7 100644
--- a/lib/inets/src/http_server/httpd_conf.erl
+++ b/lib/inets/src/http_server/httpd_conf.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 1997-2010. 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
%% 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.
-%%
+%%
%% %CopyrightEnd%
%%
%%
@@ -864,17 +864,22 @@ load_traverse(Line, [Context|Contexts], [Module|Modules], NewContexts,
{'EXIT', {undef, _}} ->
?hdrt("does not implement load", []),
load_traverse(Line, Contexts, Modules,
- [Context|NewContexts], ConfigList,yes);
+ [Context|NewContexts], ConfigList, yes);
{'EXIT', Reason} ->
error_logger:error_report({'EXIT', Reason}),
load_traverse(Line, Contexts, Modules,
[Context|NewContexts], ConfigList, State);
+ ok ->
+ ?hdrt("line processed", []),
+ load_traverse(Line, Contexts, Modules,
+ [Context|NewContexts], ConfigList, yes);
+
{ok, NewContext} ->
?hdrt("line processed", [{new_context, NewContext}]),
load_traverse(Line, Contexts, Modules,
- [NewContext|NewContexts], ConfigList,yes);
+ [NewContext|NewContexts], ConfigList, yes);
{ok, NewContext, ConfigEntry} when is_tuple(ConfigEntry) ->
?hdrt("line processed",
diff --git a/lib/inets/src/http_server/httpd_instance_sup.erl b/lib/inets/src/http_server/httpd_instance_sup.erl
index 3b5464132c..0aaeb838c2 100644
--- a/lib/inets/src/http_server/httpd_instance_sup.erl
+++ b/lib/inets/src/http_server/httpd_instance_sup.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2001-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2001-2010. 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
%% 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.
-%%
+%%
%% %CopyrightEnd%
%%
%%
@@ -37,7 +37,7 @@
%%% Internal Application API
%%%=========================================================================
start_link([{_, _}| _] = Config, AcceptTimeout, Debug) ->
- case httpd_conf:validate_properties(Config) of
+ case (catch httpd_conf:validate_properties(Config)) of
{ok, Config2} ->
Address = proplists:get_value(bind_address, Config2),
Port = proplists:get_value(port, Config2),
@@ -66,7 +66,7 @@ start_link(ConfigFile, AcceptTimeout, Debug) ->
start_link([{_, _}| _] = Config, AcceptTimeout, ListenInfo, Debug) ->
- case httpd_conf:validate_properties(Config) of
+ case (catch httpd_conf:validate_properties(Config)) of
{ok, Config2} ->
Address = proplists:get_value(bind_address, Config2),
Port = proplists:get_value(port, Config2),
@@ -154,7 +154,7 @@ make_name(Address,Port) ->
file_2_config(ConfigFile) ->
case httpd_conf:load(ConfigFile) of
{ok, ConfigList} ->
- case httpd_conf:validate_properties(ConfigList) of
+ case (catch httpd_conf:validate_properties(ConfigList)) of
{ok, Config} ->
Address = proplists:get_value(bind_address, ConfigList),
Port = proplists:get_value(port, ConfigList),
diff --git a/lib/inets/src/http_server/httpd_request.erl b/lib/inets/src/http_server/httpd_request.erl
index ad2cc4bda3..8eee08e766 100644
--- a/lib/inets/src/http_server/httpd_request.erl
+++ b/lib/inets/src/http_server/httpd_request.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2005-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2005-2010. 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
%% 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.
-%%
+%%
%% %CopyrightEnd%
%%
@@ -68,10 +68,11 @@ body_data(Headers, Body) ->
{binary_to_list(BodyThisReq), Next}
end.
+
%%-------------------------------------------------------------------------
%% validate(Method, Uri, Version) -> ok | {error, {bad_request, Reason} |
%% {error, {not_supported, {Method, Uri, Version}}
-%% Method = "HEAD" | "GET" | "POST" | "TRACE"
+%% Method = "HEAD" | "GET" | "POST" | "TRACE" | "PUT" | "DELETE"
%% Uri = uri()
%% Version = "HTTP/N.M"
%% Description: Checks that HTTP-request-line is valid.
@@ -84,6 +85,10 @@ validate("GET", Uri, "HTTP/0.9") ->
validate_uri(Uri);
validate("GET", Uri, "HTTP/1." ++ _N) ->
validate_uri(Uri);
+validate("PUT", Uri, "HTTP/1." ++ _N) ->
+ validate_uri(Uri);
+validate("DELETE", Uri, "HTTP/1." ++ _N) ->
+ validate_uri(Uri);
validate("POST", Uri, "HTTP/1." ++ _N) ->
validate_uri(Uri);
validate("TRACE", Uri, "HTTP/1." ++ N) when hd(N) >= $1 ->
diff --git a/lib/inets/src/http_server/httpd_sup.erl b/lib/inets/src/http_server/httpd_sup.erl
index fc41994727..3399f78b53 100644
--- a/lib/inets/src/http_server/httpd_sup.erl
+++ b/lib/inets/src/http_server/httpd_sup.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2004-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2004-2010. 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
%% 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.
-%%
+%%
%% %CopyrightEnd%
%%
%%
@@ -169,7 +169,7 @@ httpd_child_spec([Value| _] = Config, AcceptTimeout, Debug)
httpd_child_spec(ConfigFile, AcceptTimeout, Debug) ->
case httpd_conf:load(ConfigFile) of
{ok, ConfigList} ->
- case httpd_conf:validate_properties(ConfigList) of
+ case (catch httpd_conf:validate_properties(ConfigList)) of
{ok, Config} ->
Address = proplists:get_value(bind_address, Config, any),
Port = proplists:get_value(port, Config, 80),
diff --git a/lib/inets/src/http_server/mod_alias.erl b/lib/inets/src/http_server/mod_alias.erl
index 7073f5405d..ec0a12242f 100644
--- a/lib/inets/src/http_server/mod_alias.erl
+++ b/lib/inets/src/http_server/mod_alias.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 1997-2010. 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
%% 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.
-%%
+%%
%% %CopyrightEnd%
%%
%%
@@ -28,44 +28,51 @@
path/3]).
-include("httpd.hrl").
+-include("httpd_internal.hrl").
-define(VMODULE,"ALIAS").
%% do
-do(Info) ->
- case proplists:get_value(status, Info#mod.data) of
+do(#mod{data = Data} = Info) ->
+ ?hdrt("do", []),
+ case proplists:get_value(status, Data) of
%% A status code has been generated!
{_StatusCode, _PhraseArgs, _Reason} ->
- {proceed,Info#mod.data};
+ {proceed, Data};
%% No status code has been generated!
undefined ->
- case proplists:get_value(response, Info#mod.data) of
+ case proplists:get_value(response, Data) of
%% No response has been generated!
undefined ->
do_alias(Info);
%% A response has been generated or sent!
_Response ->
- {proceed, Info#mod.data}
+ {proceed, Data}
end
end.
-do_alias(Info) ->
- {ShortPath, Path, AfterPath} =
- real_name(Info#mod.config_db,
- Info#mod.request_uri,
- httpd_util:multi_lookup(Info#mod.config_db,alias)),
+do_alias(#mod{config_db = ConfigDB,
+ request_uri = ReqURI,
+ data = Data}) ->
+ {ShortPath, Path, AfterPath} =
+ real_name(ConfigDB, ReqURI, which_alias(ConfigDB)),
+ ?hdrt("real name",
+ [{request_uri, ReqURI},
+ {short_path, ShortPath},
+ {path, Path},
+ {after_path, AfterPath}]),
%% Relocate if a trailing slash is missing else proceed!
LastChar = lists:last(ShortPath),
case file:read_file_info(ShortPath) of
- {ok, FileInfo} when FileInfo#file_info.type == directory,
- LastChar /= $/ ->
- ServerName = httpd_util:lookup(Info#mod.config_db, server_name),
- Port = port_string(httpd_util:lookup(Info#mod.config_db,port, 80)),
- URL = "http://" ++ ServerName ++ Port ++
- Info#mod.request_uri ++ "/",
+ {ok, FileInfo} when ((FileInfo#file_info.type =:= directory) andalso
+ (LastChar =/= $/)) ->
+ ?hdrt("directory and last-char is a /", []),
+ ServerName = which_server_name(ConfigDB),
+ Port = port_string( which_port(ConfigDB) ),
+ URL = "http://" ++ ServerName ++ Port ++ ReqURI ++ "/",
ReasonPhrase = httpd_util:reason_phrase(301),
- Message = httpd_util:message(301, URL, Info#mod.config_db),
+ Message = httpd_util:message(301, URL, ConfigDB),
{proceed,
[{response,
{301, ["Location: ", URL, "\r\n"
@@ -76,25 +83,26 @@ do_alias(Info) ->
"<BODY>\n<H1>",ReasonPhrase,
"</H1>\n", Message,
"\n</BODY>\n</HTML>\n"]}}|
- [{real_name, {Path, AfterPath}} | Info#mod.data]]};
+ [{real_name, {Path, AfterPath}} | Data]]};
_NoFile ->
- {proceed,[{real_name, {Path, AfterPath}} | Info#mod.data]}
+ {proceed, [{real_name, {Path, AfterPath}} | Data]}
end.
port_string(80) ->
"";
port_string(Port) ->
- ":"++integer_to_list(Port).
+ ":" ++ integer_to_list(Port).
%% real_name
real_name(ConfigDB, RequestURI, []) ->
- DocumentRoot = httpd_util:lookup(ConfigDB, document_root, ""),
+ DocumentRoot = which_document_root(ConfigDB),
RealName = DocumentRoot ++ RequestURI,
{ShortPath, _AfterPath} = httpd_util:split_path(RealName),
- {Path, AfterPath} = httpd_util:split_path(default_index(ConfigDB,
- RealName)),
+ {Path, AfterPath} =
+ httpd_util:split_path(default_index(ConfigDB, RealName)),
{ShortPath, Path, AfterPath};
+
real_name(ConfigDB, RequestURI, [{FakeName,RealName}|Rest]) ->
case inets_regexp:match(RequestURI, "^" ++ FakeName) of
{match, _, _} ->
@@ -105,7 +113,7 @@ real_name(ConfigDB, RequestURI, [{FakeName,RealName}|Rest]) ->
httpd_util:split_path(default_index(ConfigDB, ActualName)),
{ShortPath, Path, AfterPath};
nomatch ->
- real_name(ConfigDB,RequestURI,Rest)
+ real_name(ConfigDB, RequestURI, Rest)
end.
%% real_script_name
@@ -113,20 +121,21 @@ real_name(ConfigDB, RequestURI, [{FakeName,RealName}|Rest]) ->
real_script_name(_ConfigDB, _RequestURI, []) ->
not_a_script;
real_script_name(ConfigDB, RequestURI, [{FakeName,RealName} | Rest]) ->
- case inets_regexp:match(RequestURI,"^"++FakeName) of
+ case inets_regexp:match(RequestURI, "^" ++ FakeName) of
{match,_,_} ->
- {ok,ActualName,_}=inets_regexp:sub(RequestURI,"^"++FakeName,RealName),
- httpd_util:split_script_path(default_index(ConfigDB,ActualName));
+ {ok, ActualName, _} =
+ inets_regexp:sub(RequestURI, "^" ++ FakeName, RealName),
+ httpd_util:split_script_path(default_index(ConfigDB, ActualName));
nomatch ->
- real_script_name(ConfigDB,RequestURI,Rest)
+ real_script_name(ConfigDB, RequestURI, Rest)
end.
%% default_index
default_index(ConfigDB, Path) ->
case file:read_file_info(Path) of
- {ok, FileInfo} when FileInfo#file_info.type == directory ->
- DirectoryIndex = httpd_util:lookup(ConfigDB, directory_index, []),
+ {ok, FileInfo} when FileInfo#file_info.type =:= directory ->
+ DirectoryIndex = which_directory_index(ConfigDB),
append_index(Path, DirectoryIndex);
_ ->
Path
@@ -147,9 +156,9 @@ append_index(RealName, [Index | Rest]) ->
path(Data, ConfigDB, RequestURI) ->
case proplists:get_value(real_name, Data) of
undefined ->
- DocumentRoot = httpd_util:lookup(ConfigDB, document_root, ""),
+ DocumentRoot = which_document_root(ConfigDB),
{Path, _AfterPath} =
- httpd_util:split_path(DocumentRoot++RequestURI),
+ httpd_util:split_path(DocumentRoot ++ RequestURI),
Path;
{Path, _AfterPath} ->
Path
@@ -164,7 +173,7 @@ path(Data, ConfigDB, RequestURI) ->
load("DirectoryIndex " ++ DirectoryIndex, []) ->
{ok, DirectoryIndexes} = inets_regexp:split(DirectoryIndex," "),
{ok,[], {directory_index, DirectoryIndexes}};
-load("Alias " ++ Alias,[]) ->
+load("Alias " ++ Alias, []) ->
case inets_regexp:split(Alias," ") of
{ok, [FakeName, RealName]} ->
{ok,[],{alias,{FakeName,RealName}}};
@@ -191,13 +200,13 @@ store({directory_index, Value} = Conf, _) when is_list(Value) ->
end;
store({directory_index, Value}, _) ->
{error, {wrong_type, {directory_index, Value}}};
-store({alias, {Fake, Real}} = Conf, _) when is_list(Fake),
- is_list(Real) ->
+store({alias, {Fake, Real}} = Conf, _)
+ when is_list(Fake) andalso is_list(Real) ->
{ok, Conf};
store({alias, Value}, _) ->
{error, {wrong_type, {alias, Value}}};
-store({script_alias, {Fake, Real}} = Conf, _) when is_list(Fake),
- is_list(Real) ->
+store({script_alias, {Fake, Real}} = Conf, _)
+ when is_list(Fake) andalso is_list(Real) ->
{ok, Conf};
store({script_alias, Value}, _) ->
{error, {wrong_type, {script_alias, Value}}}.
@@ -208,3 +217,21 @@ is_directory_index_list([Head | Tail]) when is_list(Head) ->
is_directory_index_list(Tail);
is_directory_index_list(_) ->
false.
+
+
+%% ---------------------------------------------------------------------
+
+which_alias(ConfigDB) ->
+ httpd_util:multi_lookup(ConfigDB, alias).
+
+which_server_name(ConfigDB) ->
+ httpd_util:lookup(ConfigDB, server_name).
+
+which_port(ConfigDB) ->
+ httpd_util:lookup(ConfigDB, port, 80).
+
+which_document_root(ConfigDB) ->
+ httpd_util:lookup(ConfigDB, document_root, "").
+
+which_directory_index(ConfigDB) ->
+ httpd_util:lookup(ConfigDB, directory_index, []).
diff --git a/lib/inets/src/http_server/mod_cgi.erl b/lib/inets/src/http_server/mod_cgi.erl
index ab12a3b57b..33605b9698 100644
--- a/lib/inets/src/http_server/mod_cgi.erl
+++ b/lib/inets/src/http_server/mod_cgi.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 1997-2010. 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
%% 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.
-%%
+%%
%% %CopyrightEnd%
%%
%%
@@ -335,6 +335,8 @@ script_elements(#mod{method = "GET"}, {PathInfo, QueryString}) ->
[{query_string, QueryString}, {path_info, PathInfo}];
script_elements(#mod{method = "POST", entity_body = Body}, _) ->
[{entity_body, Body}];
+script_elements(#mod{method = "PUT", entity_body = Body}, _) ->
+ [{entity_body, Body}];
script_elements(_, _) ->
[].
diff --git a/lib/inets/src/http_server/mod_esi.erl b/lib/inets/src/http_server/mod_esi.erl
index dd6f62ae2d..484d4b3fb4 100644
--- a/lib/inets/src/http_server/mod_esi.erl
+++ b/lib/inets/src/http_server/mod_esi.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 1997-2010. 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
%% 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.
-%%
+%%
%% %CopyrightEnd%
%%
%%
@@ -249,7 +249,24 @@ erl(#mod{method = Method} = ModData, ESIBody, Modules)
{proceed, [{status,{400, none, BadRequest}} | ModData#mod.data]}
end;
-erl(#mod{method = "POST", entity_body = Body} = ModData, ESIBody, Modules) ->
+erl(#mod{request_uri = ReqUri,
+ method = "PUT",
+ http_version = Version,
+ data = Data}, _ESIBody, _Modules) ->
+ {proceed, [{status,{501,{"PUT", ReqUri, Version},
+ ?NICE("Erl mechanism doesn't support method PUT")}}|
+ Data]};
+
+erl(#mod{request_uri = ReqUri,
+ method = "DELETE",
+ http_version = Version,
+ data = Data}, _ESIBody, _Modules) ->
+ {proceed,[{status,{501,{"DELETE", ReqUri, Version},
+ ?NICE("Erl mechanism doesn't support method DELETE")}}|
+ Data]};
+
+erl(#mod{method = "POST",
+ entity_body = Body} = ModData, ESIBody, Modules) ->
case httpd_util:split(ESIBody,":|%3A|/",2) of
{ok,[ModuleName, Function]} ->
generate_webpage(ModData, ESIBody, Modules,
@@ -444,8 +461,26 @@ input_type([_First|Rest]) ->
%%------------------------ Eval mechanism --------------------------------
-eval(#mod{request_uri = ReqUri, method = "POST",
- http_version = Version, data = Data}, _ESIBody, _Modules) ->
+eval(#mod{request_uri = ReqUri,
+ method = "PUT",
+ http_version = Version,
+ data = Data}, _ESIBody, _Modules) ->
+ {proceed,[{status,{501,{"PUT", ReqUri, Version},
+ ?NICE("Eval mechanism doesn't support method PUT")}}|
+ Data]};
+
+eval(#mod{request_uri = ReqUri,
+ method = "DELETE",
+ http_version = Version,
+ data = Data}, _ESIBody, _Modules) ->
+ {proceed,[{status,{501,{"DELETE", ReqUri, Version},
+ ?NICE("Eval mechanism doesn't support method DELETE")}}|
+ Data]};
+
+eval(#mod{request_uri = ReqUri,
+ method = "POST",
+ http_version = Version,
+ data = Data}, _ESIBody, _Modules) ->
{proceed,[{status,{501,{"POST", ReqUri, Version},
?NICE("Eval mechanism doesn't support method POST")}}|
Data]};
diff --git a/lib/inets/src/inets_app/Makefile b/lib/inets/src/inets_app/Makefile
index 2dab99386a..33c9e34a3a 100644
--- a/lib/inets/src/inets_app/Makefile
+++ b/lib/inets/src/inets_app/Makefile
@@ -1,19 +1,19 @@
#
# %CopyrightBegin%
-#
-# Copyright Ericsson AB 2005-2009. All Rights Reserved.
-#
+#
+# Copyright Ericsson AB 2005-2010. 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
# 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.
-#
+#
# %CopyrightEnd%
#
#
@@ -22,6 +22,7 @@ include $(ERL_TOP)/make/target.mk
EBIN = ../../ebin
include $(ERL_TOP)/make/$(TARGET)/otp.mk
+
# ----------------------------------------------------
# Application version
# ----------------------------------------------------
@@ -32,12 +33,13 @@ VSN = $(INETS_VSN)
# ----------------------------------------------------
# Release directory specification
# ----------------------------------------------------
-RELSYSDIR = $(RELEASE_PATH)/lib/inets-$(VSN)
+RELSYSDIR = $(RELEASE_PATH)/lib/$(APPLICATION)-$(VSN)
# ----------------------------------------------------
# Target Specs
# ----------------------------------------------------
+
MODULES = \
inets_service \
inets \
@@ -49,7 +51,8 @@ HRL_FILES = inets_internal.hrl
ERL_FILES = $(MODULES:%=%.erl)
-TARGET_FILES= $(MODULES:%=$(EBIN)/%.$(EMULATOR)) \
+TARGET_FILES= \
+ $(MODULES:%=$(EBIN)/%.$(EMULATOR)) \
$(APP_TARGET) \
$(APPUP_TARGET)
@@ -66,7 +69,7 @@ APPUP_TARGET = $(EBIN)/$(APPUP_FILE)
# ----------------------------------------------------
# INETS FLAGS
# ----------------------------------------------------
-INETS_FLAGS = -D'SERVER_SOFTWARE="inets/$(VSN)"' \
+INETS_FLAGS = -D'SERVER_SOFTWARE="$(APPLICATION)/$(VSN)"'
# ----------------------------------------------------
@@ -108,14 +111,15 @@ $(APPUP_TARGET): $(APPUP_SRC) ../../vsn.mk
include $(ERL_TOP)/make/otp_release_targets.mk
release_spec: opt
- $(INSTALL_DIR) $(RELSYSDIR)/src
+ $(INSTALL_DIR) $(RELSYSDIR)/src
$(INSTALL_DATA) $(HRL_FILES) $(ERL_FILES) $(RELSYSDIR)/src
- $(INSTALL_DIR) $(RELSYSDIR)/ebin
+ $(INSTALL_DIR) $(RELSYSDIR)/ebin
$(INSTALL_DATA) $(TARGET_FILES) $(RELSYSDIR)/ebin
release_docs_spec:
info:
+ @echo "APPLICATION = $(APPLICATION)"
@echo "INETS_DEBUG = $(INETS_DEBUG)"
@echo "INETS_FLAGS = $(INETS_FLAGS)"
@echo "ERL_COMPILE_FLAGS = $(ERL_COMPILE_FLAGS)"
diff --git a/lib/inets/src/inets_app/inets.app.src b/lib/inets/src/inets_app/inets.app.src
index 6524c3b19b..04f6365b98 100644
--- a/lib/inets/src/inets_app/inets.app.src
+++ b/lib/inets/src/inets_app/inets.app.src
@@ -1,19 +1,19 @@
%% This is an -*- erlang -*- file.
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 1997-2010. 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
%% 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.
-%%
+%%
%% %CopyrightEnd%
%%
@@ -34,7 +34,8 @@
ftp_sup,
%% HTTP client:
- http,
+ http, %% Old client API module
+ httpc, %% New client API module
httpc_handler,
httpc_handler_sup,
httpc_manager,
@@ -42,7 +43,7 @@
httpc_request,
httpc_response,
httpc_sup,
- http_cookie,
+ httpc_cookie,
http_uri, %% Proably will by used by server also in the future
diff --git a/lib/inets/src/inets_app/inets.appup.src b/lib/inets/src/inets_app/inets.appup.src
index 0112a64239..2efa7ccb60 100644
--- a/lib/inets/src/inets_app/inets.appup.src
+++ b/lib/inets/src/inets_app/inets.appup.src
@@ -1,34 +1,31 @@
%% This is an -*- erlang -*- file.
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1999-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 1999-2010. 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
%% 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.
-%%
+%%
%% %CopyrightEnd%
{"%VSN%",
[
{"5.2",
[
- {load_module, inets, soft_purge, soft_purge, []}
+ {restart_application, inets}
]
},
{"5.1.3",
[
- {load_module, httpd_response, soft_purge, soft_purge, []},
- {update, ftp, {advanced, upgrade_from_pre_5_12},
- soft_purge, soft_purge, []},
- {update, httpc_handler, soft, soft_purge, soft_purge, []}
+ {restart_application, inets}
]
},
{"5.1.2",
@@ -40,15 +37,12 @@
[
{"5.2",
[
- {load_module, inets, soft_purge, soft_purge, []}
+ {restart_application, inets}
]
},
{"5.1.3",
[
- {load_module, httpd_response, soft_purge, soft_purge, []},
- {update, ftp, {advanced, downgrade_to_pre_5_12},
- soft_purge, soft_purge, []},
- {update, httpc_handler, soft, soft_purge, soft_purge, []}
+ {restart_application, inets}
]
},
{"5.1.2",
diff --git a/lib/inets/src/inets_app/inets.erl b/lib/inets/src/inets_app/inets.erl
index 77cb14cc20..7e3f862ee7 100644
--- a/lib/inets/src/inets_app/inets.erl
+++ b/lib/inets/src/inets_app/inets.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2006-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2006-2010. 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
%% 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.
-%%
+%%
%% %CopyrightEnd%
%%
%%
@@ -522,9 +522,7 @@ change_pattern({Mod, Service, Pattern})
catch
exit:{Where, Reason} ->
{error, {Where, Reason}}
- end;
- _ ->
- exit({bad_pattern, Pattern})
+ end
end,
ok.
@@ -728,7 +726,7 @@ call_service(Service, Call, Args) ->
service_module(tftpd) ->
tftp;
service_module(httpc) ->
- http;
+ httpc;
service_module(ftpc) ->
ftp;
service_module(Service) ->
diff --git a/lib/inets/src/tftp/Makefile b/lib/inets/src/tftp/Makefile
index 63f70f7943..b4339da1e2 100644
--- a/lib/inets/src/tftp/Makefile
+++ b/lib/inets/src/tftp/Makefile
@@ -1,19 +1,19 @@
#
# %CopyrightBegin%
-#
-# Copyright Ericsson AB 2005-2009. All Rights Reserved.
-#
+#
+# Copyright Ericsson AB 2005-2010. 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
# 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.
-#
+#
# %CopyrightEnd%
#
#
@@ -33,7 +33,8 @@ VSN = $(INETS_VSN)
# ----------------------------------------------------
# Release directory specification
# ----------------------------------------------------
-RELSYSDIR = $(RELEASE_PATH)/lib/inets-$(VSN)
+RELSYSDIR = $(RELEASE_PATH)/lib/$(APPLICATION)-$(VSN)
+
# ----------------------------------------------------
# Target Specs
@@ -53,10 +54,12 @@ ERL_FILES = $(MODULES:%=%.erl)
TARGET_FILES= $(MODULES:%=$(EBIN)/%.$(EMULATOR))
+
# ----------------------------------------------------
# INETS FLAGS
# ----------------------------------------------------
-INETS_FLAGS = -D'SERVER_SOFTWARE="inets/$(VSN)"' \
+INETS_FLAGS = -D'SERVER_SOFTWARE="$(APPLICATION)/$(VSN)"'
+
# ----------------------------------------------------
# FLAGS
@@ -64,6 +67,8 @@ INETS_FLAGS = -D'SERVER_SOFTWARE="inets/$(VSN)"' \
ERL_COMPILE_FLAGS += $(INETS_FLAGS) \
+'{parse_transform,sys_pre_attributes}' \
+'{attribute,insert,app_vsn,$(APP_VSN)}'
+
+
# ----------------------------------------------------
# Targets
# ----------------------------------------------------
@@ -90,6 +95,7 @@ release_spec: opt
release_docs_spec:
info:
+ @echo "APPLICATION = $(APPLICATION)"
@echo "INETS_DEBUG = $(INETS_DEBUG)"
@echo "INETS_FLAGS = $(INETS_FLAGS)"
@echo "ERL_COMPILE_FLAGS = $(ERL_COMPILE_FLAGS)"
diff --git a/lib/inets/test/Makefile b/lib/inets/test/Makefile
index d13ffea544..1dd7a51717 100644
--- a/lib/inets/test/Makefile
+++ b/lib/inets/test/Makefile
@@ -1,19 +1,19 @@
#
# %CopyrightBegin%
-#
-# Copyright Ericsson AB 1997-2009. All Rights Reserved.
-#
+#
+# Copyright Ericsson AB 1997-2010. 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
# 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.
-#
+#
# %CopyrightEnd%
#
#
@@ -32,6 +32,12 @@ VSN = $(INETS_VSN)
# ----------------------------------------------------
+# Release directory specification
+# ----------------------------------------------------
+RELSYSDIR = $(RELEASE_PATH)/lib/$(APPLICATION)-$(VSN)
+
+
+# ----------------------------------------------------
# Target Specs
# ----------------------------------------------------
INCLUDES = -I. \
@@ -188,22 +194,26 @@ HRL_FILES = inets_test_lib.hrl \
ERL_FILES = $(MODULES:%=%.erl)
-TARGET_FILES = $(MODULES:%=$(EBIN)/%.$(EMULATOR))
-
-INETS_FILES = Makefile.inets rules.mk suite_targets.mk \
- inets.config inets.spec inets.spec.vxworks
-
-
SOURCE = $(ERL_FILES) $(HRL_FILES)
+TARGET_FILES = $(MODULES:%=$(EBIN)/%.$(EMULATOR))
+
INETS_SPECS = inets.spec inets.spec.vxworks
+INETS_FILES = inets.config $(INETS_SPECS)
-INETS_DATADIR = inets_SUITE_data inets_sup_SUITE_data
-HTTPD_DATADIR = httpd_test_data httpd_SUITE_data
-HTTPC_DATADIR = httpc_SUITE_data
-FTP_DATADIR = ftp_SUITE_data
+# SUB_SUITES = \
+# inets_sup_suite \
+# inets_httpd_suite \
+# inets_httpc_suite \
+# inets_ftp_suite \
+# inets_tftp_suite
-DATADIRS = $(INETS_DATADIR) $(HTTPD_DATADIR) $(HTTPC_DATADIR) $(FTP_DATADIR)
+INETS_DATADIRS = inets_SUITE_data inets_sup_SUITE_data
+HTTPD_DATADIRS = httpd_test_data httpd_SUITE_data
+HTTPC_DATADIRS = httpc_SUITE_data
+FTP_DATADIRS = ftp_SUITE_data
+
+DATADIRS = $(INETS_DATADIRS) $(HTTPD_DATADIRS) $(HTTPC_DATADIRS) $(FTP_DATADIRS)
EMAKEFILE = Emakefile
MAKE_EMAKE = $(wildcard $(ERL_TOP)/make/make_emakefile)
@@ -216,10 +226,10 @@ BUILDTARGET = emakebuild
RELTEST_FILES = $(EMAKEFILE) $(INETS_SPECS) $(SOURCE)
endif
+
# ----------------------------------------------------
# Release directory specification
# ----------------------------------------------------
-RELSYSDIR = $(RELEASE_PATH)/lib/inets-$(VSN)
RELTESTSYSDIR = $(RELEASE_PATH)/inets_test
RELTESTSYSALLDATADIR = $(RELTESTSYSDIR)/all_SUITE_data
@@ -276,9 +286,19 @@ release_spec: opt
$(INSTALL_DIR) $(RELSYSDIR)/test
$(INSTALL_DATA) $(HRL_FILES) $(ERL_FILES) $(RELSYSDIR)/test
$(INSTALL_DATA) $(INETS_FILES) $(RELSYSDIR)/test
- $(INSTALL_DIR) $(RELSYSDIR)/test/$(HTTPD_DATADIR)
- tar chf - -C $(HTTPD_DATADIR) . | (cd $(RELSYSDIR)/test/$(HTTPD_DATADIR); tar xf -)
- (cd $(RELSYSDIR)/test; mv Makefile.inets Makefile)
+ @for d in $(DATADIRS); do \
+ echo "installing data dir $$d"; \
+ echo $$d/TAR.exclude2 > $$d/TAR.exclude2; \
+ cat $$d/TAR.exclude >> $$d/TAR.exclude2; \
+ find $$d -name '*.contrib*' >> $$d/TAR.exclude2; \
+ find $$d -name '*.keep*' >> $$d/TAR.exclude2; \
+ find $$d -name '*.mkelem*' >> $$d/TAR.exclude2; \
+ find $$d -name '*~' >> $$d/TAR.exclude2; \
+ find $$d -name 'erl_crash.dump' >> $$d/TAR.exclude2; \
+ find $$d -name 'core' >> $$d/TAR.exclude2; \
+ find $$d -name '.cmake.state' >> $$d/TAR.exclude2; \
+ tar cfX - $$d/TAR.exclude2 $$d | (cd $(RELSYSDIR)/test; tar xf -); \
+ done
release_tests_spec: opt
$(INSTALL_DIR) $(RELTESTSYSDIR)
@@ -287,7 +307,6 @@ release_tests_spec: opt
tar chf - $(DATADIRS) | (cd $(RELTESTSYSDIR); tar xf -)
$(INSTALL_DIR) $(RELTESTSYSALLDATADIR)
$(INSTALL_DATA) $(MAKEFILE_SRC) $(RELTESTSYSALLDATADIR)/Makefile.src
- $(INSTALL_DATA) copy_files.erl $(RELTESTSYSALLDATADIR)/copy_files.erl
$(INSTALL_DIR) $(RELTESTSYSBINDIR)
chmod -f -R +x $(RELTESTSYSBINDIR)
tar cf - -C $(INETS_SSL_LIB_DIR) . | (cd $(RELTESTSYSALLDATADIR); tar xf -)
@@ -301,7 +320,24 @@ info:
@echo "MAKE_EMAKE = $(MAKE_EMAKE)"
@echo "EMAKEFILE = $(EMAKEFILE)"
@echo "BUILDTARGET = $(BUILDTARGET)"
+ @echo ""
+ @echo "MODULES = $(MODULES)"
+ @echo "ERL_FILES = $(ERL_FILES)"
+ @echo "SOURCE = $(SOURCE)"
@echo "TARGET_FILES = $(TARGET_FILES)"
+ @echo ""
+ @echo "INETS_SPECS = $(INETS_SPECS)"
+ @echo "INETS_FILES = $(INETS_FILES)"
+ @echo ""
+ @echo "RELEASE_PATH = $(RELEASE_PATH)"
+ @echo "RELSYSDIR = $(RELSYSDIR)"
+ @echo "RELTESTSYSDIR = $(RELTESTSYSDIR)"
+ @echo "RELTESTSYSALLDATADIR = $(RELTESTSYSALLDATADIR)"
+ @echo "RELTESTSYSBINDIR = $(RELTESTSYSBINDIR)"
+ @echo ""
+ @echo "DATADIRS = $(DATADIRS)"
+ @echo "REL_DATADIRS = $(REL_DATADIRS)"
+ @echo ""
@echo "INETS_DATA_DIR = $(INETS_DATA_DIR)"
@echo "INETS_PRIV_DIR = $(INETS_PRIV_DIR)"
@echo "INETS_SSL_LIB_DIR = $(INETS_SSL_LIB_DIR)"
diff --git a/lib/inets/test/ftp_SUITE_data/TAR.exclude b/lib/inets/test/ftp_SUITE_data/TAR.exclude
new file mode 100644
index 0000000000..2078965740
--- /dev/null
+++ b/lib/inets/test/ftp_SUITE_data/TAR.exclude
@@ -0,0 +1,2 @@
+ftp_SUITE_data/TAR.exclude
+ftp_SUITE_data/ftpd_hosts
diff --git a/lib/inets/test/ftp_SUITE_data/ftpd_hosts.skel b/lib/inets/test/ftp_SUITE_data/ftpd_hosts.skel
new file mode 100644
index 0000000000..a820f8d014
--- /dev/null
+++ b/lib/inets/test/ftp_SUITE_data/ftpd_hosts.skel
@@ -0,0 +1,17 @@
+%% Add a host name in the appropriate list
+%% Each "platform" contains a list of hostnames (a string) that can
+%% be used for testing the ftp client.
+[{solaris8_sparc, []},
+ {solaris9_sparc, []},
+ {solaris10_sparc, []},
+ {solaris10_x86, []},
+ {linux_x86, []},
+ {linux_ppc, []},
+ {macosx_ppc, []},
+ {macosx_x86, []},
+ {openbsd_x86, []},
+ {freebsd_x86, []},
+ {netbsd_x86, []},
+ {windows_xp, []},
+ {windows_2003_server, []},
+ {ticket_test, []}].
diff --git a/lib/inets/test/ftp_SUITE_data/inets_test_hosts b/lib/inets/test/ftp_SUITE_data/inets_test_hosts
deleted file mode 100644
index 20623b9edc..0000000000
--- a/lib/inets/test/ftp_SUITE_data/inets_test_hosts
+++ /dev/null
@@ -1,15 +0,0 @@
-%% Add a host name in the appropriate list
-[{solaris8_sparc, ["fingon"]},
- {solaris9_sparc, []},
- {solaris10_sparc, []},
- {solaris10_x86, []},
- {linux_x86, []},
- {linux_ppc, []},
- {macosx_ppc, []},
- {macosx_x86, []},
- {openbsd_x86, []},
- {freebsd_x86, []},
- {netbsd_x86, []},
- {windows_xp, []},
- {windows_2003_server, ["fobi"]},
- {ticket_test,["fingon","finrod"]}].
diff --git a/lib/inets/test/ftp_suite_lib.erl b/lib/inets/test/ftp_suite_lib.erl
index 29339da6e5..75e1a5a7f9 100644
--- a/lib/inets/test/ftp_suite_lib.erl
+++ b/lib/inets/test/ftp_suite_lib.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2005-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2005-2010. 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
%% 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.
-%%
+%%
%% %CopyrightEnd%
%%
%%
@@ -23,6 +23,7 @@
-include("test_server.hrl").
-include("test_server_line.hrl").
+-include("inets_test_lib.hrl").
%% Test server specific exports
% -export([init_per_testcase/2, end_per_testcase/2]).
@@ -37,7 +38,6 @@
--define(FTP_HOSTS(X),ftp_hosts(X)).
-define(FTP_USER, "anonymous").
-define(FTP_PASS, passwd()).
-define(FTP_PORT, 21).
@@ -73,7 +73,7 @@ ftpd_init(FtpdTag, Config) ->
Hosts =
case ?config(ftpd_hosts, Config) of
undefined ->
- ?FTP_HOSTS(data_dir(Config));
+ ftpd_hosts(data_dir(Config));
H ->
H
end,
@@ -123,6 +123,59 @@ get_ftpd_host([Host|Hosts]) ->
get_ftpd_host(Hosts)
end.
+
+%%--------------------------------------------------------------------
+
+dirty_select_ftpd_host(Config) ->
+ Hosts =
+ case ?config(ftpd_hosts, Config) of
+ undefined ->
+ ftpd_hosts(data_dir(Config));
+ H ->
+ H
+ end,
+ dirty_select_ftpd_host2(Hosts).
+
+dirty_select_ftpd_host2([]) ->
+ throw({error, not_found});
+dirty_select_ftpd_host2([{PlatformTag, Hosts} | PlatformHosts]) ->
+ case dirty_select_ftpd_host3(Hosts) of
+ none ->
+ dirty_select_ftpd_host2(PlatformHosts);
+ {ok, Host} ->
+ {PlatformTag, Host}
+ end.
+
+dirty_select_ftpd_host3([]) ->
+ none;
+dirty_select_ftpd_host3([Host|Hosts]) when is_list(Host) ->
+ case dirty_select_ftpd_host4(Host) of
+ true ->
+ {ok, Host};
+ false ->
+ dirty_select_ftpd_host3(Hosts)
+ end;
+dirty_select_ftpd_host3([_|Hosts]) ->
+ dirty_select_ftpd_host3(Hosts).
+
+%% This is a very simple and dirty test that there is a
+%% (FTP) deamon on the other end.
+dirty_select_ftpd_host4(Host) ->
+ Port = 21,
+ IpFam = inet,
+ Opts = [IpFam, binary, {packet, 0}, {active, false}],
+ Timeout = ?SECS(5),
+ case gen_tcp:connect(Host, Port, Opts, Timeout) of
+ {ok, Sock} ->
+ gen_tcp:close(Sock),
+ true;
+ _Error ->
+ false
+ end.
+
+
+%%--------------------------------------------------------------------
+
test_filenames() ->
{ok, Host} = inet:gethostname(),
File = Host ++ "_ftp_test.txt",
@@ -1048,12 +1101,20 @@ ticket_6035(Config) ->
"~n Config: ~p", [Config]),
PrivDir = ?config(priv_dir, Config),
LogFile = filename:join([PrivDir,"ticket_6035.log"]),
- Pid = spawn(?MODULE,open_wait_6035,[self()]),
- error_logger:logfile({open,LogFile}),
- ok = kill_ftp_proc_6035(Pid,LogFile),
- error_logger:logfile(close),
- p("ticket_6035 -> done", []),
- ok.
+ try
+ begin
+ Host = dirty_select_ftpd_host(Config),
+ Pid = spawn(?MODULE, open_wait_6035, [Host, self()]),
+ error_logger:logfile({open, LogFile}),
+ ok = kill_ftp_proc_6035(Pid,LogFile),
+ error_logger:logfile(close),
+ p("ticket_6035 -> done", []),
+ ok
+ end
+ catch
+ throw:{error, not_found} ->
+ {skip, "No available FTP servers"}
+ end.
kill_ftp_proc_6035(Pid, LogFile) ->
p("kill_ftp_proc_6035 -> entry"),
@@ -1072,8 +1133,7 @@ kill_ftp_proc_6035(Pid, LogFile) ->
is_error_report_6035(LogFile)
end.
-open_wait_6035(From) ->
- FtpServer = "elrond",
+open_wait_6035(FtpServer, From) ->
p("open_wait_6035 -> try connect to ~s", [FtpServer]),
case ftp:open(FtpServer, [{timeout, timer:seconds(15)}]) of
{ok, Pid} ->
@@ -1491,14 +1551,15 @@ passwd() ->
end,
"ftp_SUITE@" ++ Host.
-ftp_hosts(Config) ->
- DataDir = ?config(data_dir,Config),
- FileName = filename:join([DataDir,"../ftp_SUITE_data/",inets_test_hosts]),
- io:format("FileName: ~p~n",[FileName]),
+ftpd_hosts(Config) ->
+ DataDir = ?config(data_dir, Config),
+ FileName = filename:join([DataDir, "../ftp_SUITE_data/", ftpd_hosts]),
+ io:format("FileName: ~p~n", [FileName]),
case file:consult(FileName) of
- {ok,[Hosts]} when is_list(Hosts) ->
+ {ok, [Hosts]} when is_list(Hosts) ->
Hosts;
- _ -> []
+ _ ->
+ []
end.
wrapper(Prefix,doc,Func) ->
@@ -1507,13 +1568,14 @@ wrapper(_,X,Func) ->
Func(X).
data_dir(Config) ->
- case ?config(data_dir,Config) of
+ case ?config(data_dir, Config) of
List when (length(List) > 0) ->
- PathList = filename:split(List),
- {NewPathList,_} = lists:split((length(PathList)-1),PathList),
- DataDir=filename:join(NewPathList++[ftp_SUITE_data]),
- _NewConfig = lists:keyreplace(data_dir,1,Config,
- {data_dir,DataDir});
+ PathList = filename:split(List),
+ {NewPathList,_} = lists:split((length(PathList)-1), PathList),
+ DataDir = filename:join(NewPathList ++ [ftp_SUITE_data]),
+ NewConfig =
+ lists:keyreplace(data_dir,1,Config, {data_dir,DataDir}),
+ NewConfig;
_ -> Config
end.
diff --git a/lib/inets/test/ftp_ticket_test.erl b/lib/inets/test/ftp_ticket_test.erl
index 96e443fab5..6748df03bb 100644
--- a/lib/inets/test/ftp_ticket_test.erl
+++ b/lib/inets/test/ftp_ticket_test.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2006-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2006-2010. 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
%% 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.
-%%
+%%
%% %CopyrightEnd%
%%
%%
@@ -39,8 +39,7 @@ all(suite) ->
{conf,init,tickets(),fin}.
init(Config) ->
- [{ftp_remote_host, "elrond"}|Config].
-% ?LIB_MOD:ftpd_init(ticket_test,Config).
+ ?LIB_MOD:ftpd_init(ticket_test, Config).
tickets() ->
[ticket_6035].
diff --git a/lib/inets/test/httpc_SUITE.erl b/lib/inets/test/httpc_SUITE.erl
index 3485966307..4914a16264 100644
--- a/lib/inets/test/httpc_SUITE.erl
+++ b/lib/inets/test/httpc_SUITE.erl
@@ -1,25 +1,28 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2004-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2004-2010. 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
%% 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.
-%%
+%%
%% %CopyrightEnd%
%%
%%
+%%
+%% ts:run(inets, httpc_SUITE, [batch]).
+%%
+
-module(httpc_SUITE).
--author('[email protected]').
-include("test_server.hrl").
-include("test_server_line.hrl").
@@ -55,6 +58,7 @@
%% Description: Returns documentation/test cases in this test suite
%% or a skip tuple if the platform is not supported.
%%--------------------------------------------------------------------
+
all(doc) ->
["Test the http client in the intes application."];
all(suite) ->
@@ -93,7 +97,7 @@ all(suite) ->
http_server_does_not_exist,
http_invalid_http,
http_emulate_lower_versions,
- http_relaxed,
+ http_relaxed,
page_does_not_exist,
proxy_page_does_not_exist,
proxy_https_not_supported,
@@ -138,12 +142,12 @@ init_per_suite(Config) ->
end,
{ok, FileInfo} = file:read_file_info(Cgi),
- ok = file:write_file_info(Cgi,
- FileInfo#file_info{mode = 8#00755}),
+ ok = file:write_file_info(Cgi, FileInfo#file_info{mode = 8#00755}),
- [{server_root, ServerRoot}, {doc_root, DocRoot},
- {local_port, ?IP_PORT}, {local_ssl_port, ?SSL_PORT}
- | Config].
+ [{server_root, ServerRoot},
+ {doc_root, DocRoot},
+ {local_port, ?IP_PORT},
+ {local_ssl_port, ?SSL_PORT} | Config].
%%--------------------------------------------------------------------
%% Function: end_per_suite(Config) -> _
@@ -170,11 +174,17 @@ end_per_suite(Config) ->
%% Note: This function is free to add any key/value pairs to the Config
%% variable, but should NOT alter/remove any existing entries.
%%--------------------------------------------------------------------
+init_per_testcase(otp_8154_1 = Case, Config) ->
+ init_per_testcase(Case, 5, Config);
init_per_testcase(Case, Config) ->
- io:format(user, "~n~n*** INIT ~w:~w ***~n~n", [?MODULE,Case]),
+ 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]),
PrivDir = ?config(priv_dir, Config),
application:stop(inets),
- Dog = test_server:timetrap(inets_test_lib:minutes(10)),
+ Dog = test_server:timetrap(inets_test_lib:minutes(Timeout)),
TmpConfig = lists:keydelete(watchdog, 1, Config),
IpConfFile = integer_to_list(?IP_PORT) ++ ".conf",
SslConfFile = integer_to_list(?SSL_PORT) ++ ".conf",
@@ -185,11 +195,10 @@ init_per_testcase(Case, Config) ->
application:stop(ssl),
TmpConfig2 =
lists:keydelete(local_ssl_server, 1, TmpConfig),
+ %% Will start inets
Server =
- %% Will start inets
- inets_test_lib:start_http_server(
- filename:join(PrivDir,
- SslConfFile)),
+ inets_test_lib:start_http_server(
+ filename:join(PrivDir, SslConfFile)),
[{watchdog, Dog}, {local_ssl_server, Server} | TmpConfig2];
"proxy" ++ Rest ->
case Rest of
@@ -224,7 +233,8 @@ init_per_testcase(Case, Config) ->
http:set_options([{proxy, {{?PROXY, ?PROXY_PORT},
["localhost", ?IPV6_LOCAL_HOST]}}]),
- inets:enable_trace(max, io),
+ inets:enable_trace(max, io, httpc),
+ %% snmp:set_trace([gen_tcp, inet_tcp, prim_inet]),
NewConfig.
%%--------------------------------------------------------------------
@@ -269,7 +279,10 @@ tickets(suite) ->
no_content_204_otp_6982,
missing_CR_otp_7304,
otp_7883,
- otp_8154
+ otp_8154,
+ otp_8106,
+ otp_8056,
+ otp_8371
].
@@ -295,9 +308,9 @@ http_head(Config) when is_list(Config) ->
{ok, {{_,200,_}, [_ | _], []}} ->
ok;
{ok, WrongReply} ->
- test_server:fail({wrong_reply, WrongReply});
+ tsf({wrong_reply, WrongReply});
Error ->
- test_server:fail({failed, Error})
+ tsf({failed, Error})
end;
_ ->
{skip, "Failed to start local http-server"}
@@ -308,28 +321,47 @@ http_get(doc) ->
http_get(suite) ->
[];
http_get(Config) when is_list(Config) ->
- case ?config(local_server, Config) of
+ tsp("http_get -> entry with"
+ "~n Config: ~p", [Config]),
+ case ?config(local_server, Config) of
ok ->
- Port = ?config(local_port, Config),
- URL = ?URL_START ++ integer_to_list(Port) ++ "/dummy.html",
- Timeout = timer:seconds(1),
- ConnTimeout = Timeout + timer:seconds(1),
- {ok, {{_,200,_}, [_ | _], Body = [_ | _]}} =
- http:request(get, {URL, []},
- [{timeout, Timeout}, {connect_timeout, ConnTimeout}], []),
- %% eqvivivalent to http:request(get, {URL, []}, [], []),
- inets_test_lib:check_body(Body),
- {ok, {{_,200,_}, [_ | _], Bin}} =
- http:request(get, {URL, []}, [], [{body_format, binary}]),
- case Bin of
- Bin when is_binary(Bin) ->
- ok;
- _ ->
- test_server:fail(body_format_not_binary)
- end;
- _ ->
- {skip, "Failed to start local http-server"}
- end.
+ tsp("local-server running"),
+ Method = get,
+ Port = ?config(local_port, Config),
+ URL = ?URL_START ++ integer_to_list(Port) ++ "/dummy.html",
+ Request = {URL, []},
+ Timeout = timer:seconds(1),
+ ConnTimeout = Timeout + timer:seconds(1),
+ HttpOptions1 = [{timeout, Timeout}, {connect_timeout, ConnTimeout}],
+ Options1 = [],
+ Body =
+ case http:request(Method, Request, HttpOptions1, Options1) of
+ {ok, {{_,200,_}, [_ | _], ReplyBody = [_ | _]}} ->
+ ReplyBody;
+ {ok, UnexpectedReply1} ->
+ tsf({unexpected_reply, UnexpectedReply1});
+ {error, _} = Error1 ->
+ tsf({bad_reply, Error1})
+ end,
+
+ %% eqvivivalent to http:request(get, {URL, []}, [], []),
+ inets_test_lib:check_body(Body),
+
+ HttpOptions2 = [],
+ Options2 = [{body_format, binary}],
+ case http:request(Method, Request, HttpOptions2, Options2) of
+ {ok, {{_,200,_}, [_ | _], Bin}} when is_binary(Bin) ->
+ ok;
+ {ok, {{_,200,_}, [_ | _], BadBin}} ->
+ tsf({body_format_not_binary, BadBin});
+ {ok, UnexpectedReply2} ->
+ tsf({unexpected_reply, UnexpectedReply2});
+ {error, _} = Error2 ->
+ tsf({bad_reply, Error2})
+ end;
+ _ ->
+ {skip, "Failed to start local http-server"}
+ end.
%%-------------------------------------------------------------------------
http_post(doc) ->
@@ -389,7 +421,9 @@ http_emulate_lower_versions(Config) when is_list(Config) ->
{skip, "Failed to start local http-server"}
end.
+
%%-------------------------------------------------------------------------
+
http_relaxed(doc) ->
["Test relaxed mode"];
http_relaxed(suite) ->
@@ -397,12 +431,7 @@ http_relaxed(suite) ->
http_relaxed(Config) when is_list(Config) ->
ok = http:set_options([{ipv6, disabled}]), % also test the old option
%% ok = http:set_options([{ipfamily, inet}]),
- DummyServerPid = dummy_server(self(), ipv4),
-
- Port = receive
- {port, ServerPort} ->
- ServerPort
- end,
+ {DummyServerPid, Port} = dummy_server(self(), ipv4),
URL = ?URL_START ++ integer_to_list(Port) ++
"/missing_reason_phrase.html",
@@ -428,13 +457,8 @@ http_dummy_pipe(suite) ->
[];
http_dummy_pipe(Config) when is_list(Config) ->
ok = http:set_options([{ipfamily, inet}]),
- DummyServerPid = dummy_server(self(), ipv4),
+ {DummyServerPid, Port} = dummy_server(self(), ipv4),
- Port = receive
- {port, ServerPort} ->
- ServerPort
- end,
-
URL = ?URL_START ++ integer_to_list(Port) ++ "/foobar.html",
test_pipeline(URL),
@@ -451,78 +475,126 @@ http_inets_pipe(Config) when is_list(Config) ->
case ?config(local_server, Config) of
ok ->
- Port = ?config(local_port, Config),
- URL = ?URL_START ++ integer_to_list(Port) ++ "/dummy.html",
+ Port = ?config(local_port, Config),
+ URL = ?URL_START ++ integer_to_list(Port) ++ "/dummy.html",
test_pipeline(URL);
_ ->
{skip, "Failed to start local http-server"}
end.
test_pipeline(URL) ->
-
+ p("test_pipeline -> entry with"
+ "~n URL: ~p", [URL]),
+
http:set_options([{pipeline_timeout, 50000}]),
+ p("test_pipeline -> issue (async) request 1"),
{ok, RequestId1} =
http: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} =
http:request(get, {URL, []}, [], [{sync, false}]),
- test_server:format("RequestId2: ~p~n", [RequestId2]),
+ tsp("RequestId2: ~p", [RequestId2]),
+ p("test_pipeline -> RequestId2: ~p", [RequestId2]),
- {ok, {{_,200,_}, [_ | _], [_ | _]}}
- = http:request(get, {URL, []}, [], []),
+ p("test_pipeline -> issue (sync) request 3"),
+ {ok, {{_,200,_}, [_ | _], [_ | _]}} =
+ http:request(get, {URL, []}, [], []),
+
+ p("test_pipeline -> expect reply for (async) request 1 or 2"),
receive
{http, {RequestId1, {{_, 200, _}, _, _}}} ->
+ p("test_pipeline -> received reply for (async) request 1 - now wait for 2"),
receive
{http, {RequestId2, {{_, 200, _}, _, _}}} ->
+ p("test_pipeline -> received reply for (async) request 2"),
ok;
{http, Msg1} ->
test_server:fail(Msg1)
end;
{http, {RequestId2, {{_, 200, _}, _, _}}} ->
+ io:format("test_pipeline -> received reply for (async) request 2 - now wait for 1"),
receive
{http, {RequestId1, {{_, 200, _}, _, _}}} ->
+ io:format("test_pipeline -> received reply for (async) request 1"),
ok;
{http, Msg2} ->
test_server:fail(Msg2)
end;
{http, Msg3} ->
- test_server:fail(Msg3)
+ test_server:fail(Msg3)
+ after 60000 ->
+ receive Any1 ->
+ tsp("received crap after timeout: ~n ~p", [Any1]),
+ test_server:fail({error, {timeout, Any1}})
+ end
end,
+ p("test_pipeline -> sleep some"),
+ test_server:sleep(4000),
+
+ p("test_pipeline -> issue (async) request 4"),
{ok, RequestId3} =
- http:request(get, {URL, []}, [], [{sync, false}]),
- test_server:format("RequestId3: ~p~n", [RequestId3]),
+ http:request(get, {URL, []}, [], [{sync, false}]),
+ tsp("RequestId3: ~p", [RequestId3]),
+ p("test_pipeline -> RequestId3: ~p", [RequestId3]),
+
+ p("test_pipeline -> issue (async) request 5"),
{ok, RequestId4} =
http:request(get, {URL, []}, [], [{sync, false}]),
- test_server:format("RequestId4: ~p~n", [RequestId4]),
+ tsp("RequestId4: ~p~n", [RequestId4]),
+ p("test_pipeline -> RequestId4: ~p", [RequestId4]),
+
+ p("test_pipeline -> cancel (async) request 4"),
ok = http:cancel_request(RequestId3),
+
+ p("test_pipeline -> expect *no* reply for cancelled (async) request 4 (for 3 secs)"),
receive
{http, {RequestId3, _}} ->
- test_server:fail(http_cancel_request_failed)
+ test_server:fail(http_cancel_request_failed)
after 3000 ->
ok
end,
+
+ p("test_pipeline -> expect reply for (async) request 4"),
Body =
receive
- Res = {http, {RequestId4, {{_, 200, _}, _, BinBody4}}} ->
- test_server:format(" Receive : ~p~n", [Res]),
+ {http, {RequestId4, {{_, 200, _}, _, BinBody4}}} = Res ->
+ p("test_pipeline -> received reply for (async) request 5"),
+ tsp("Receive : ~p", [Res]),
BinBody4;
{http, Msg4} ->
test_server:fail(Msg4)
+ after 60000 ->
+ receive Any2 ->
+ tsp("received crap after timeout: ~n ~p", [Any2]),
+ test_server:fail({error, {timeout, Any2}})
+ end
end,
+
+ p("test_pipeline -> check reply for (async) request 5"),
inets_test_lib:check_body(binary_to_list(Body)),
+ p("test_pipeline -> ensure no unexpected incomming"),
receive
{http, Any} ->
test_server:fail({unexpected_message, Any})
after 500 ->
ok
- end.
+ end,
+
+ p("test_pipeline -> done"),
+ ok.
+
+
+
%%-------------------------------------------------------------------------
http_trace(doc) ->
["Perform a TRACE request that goes through a proxy."];
@@ -700,12 +772,7 @@ http_headers_dummy(suite) ->
[];
http_headers_dummy(Config) when is_list(Config) ->
ok = http:set_options([{ipfamily, inet}]),
- DummyServerPid = dummy_server(self(), ipv4),
-
- Port = receive
- {port, ServerPort} ->
- ServerPort
- end,
+ {DummyServerPid, Port} = dummy_server(self(), ipv4),
URL = ?URL_START ++ integer_to_list(Port) ++ "/dummy_headers.html",
@@ -770,12 +837,7 @@ http_bad_response(suite) ->
[];
http_bad_response(Config) when is_list(Config) ->
ok = http:set_options([{ipfamily, inet}]),
- DummyServerPid = dummy_server(self(), ipv4),
-
- Port = receive
- {port, ServerPort} ->
- ServerPort
- end,
+ {DummyServerPid, Port} = dummy_server(self(), ipv4),
URL = ?URL_START ++ integer_to_list(Port) ++ "/missing_crlf.html",
@@ -868,64 +930,90 @@ http_redirect(doc) ->
http_redirect(suite) ->
[];
http_redirect(Config) when is_list(Config) ->
+ tsp("http_redirect -> entry with"
+ "~n Config: ~p", [Config]),
case ?config(local_server, Config) of
ok ->
+ tsp("http_redirect -> set ipfamily option to inet"),
ok = http:set_options([{ipfamily, inet}]),
- DummyServerPid = dummy_server(self(), ipv4),
-
- Port = receive
- {port, ServerPort} ->
- ServerPort
- end,
+
+ tsp("http_redirect -> start dummy server inet"),
+ {DummyServerPid, Port} = dummy_server(self(), ipv4),
+ tsp("http_redirect -> server port = ~p", [Port]),
URL300 = ?URL_START ++ integer_to_list(Port) ++ "/300.html",
+ tsp("http_redirect -> issue request 1: "
+ "~n ~p", [URL300]),
{ok, {{_,200,_}, [_ | _], [_|_]}}
= http:request(get, {URL300, []}, [], []),
- {ok, {{_,300,_}, [_ | _], _}}
- = http:request(get, {URL300, []}, [{autoredirect, false}],
- []),
+ tsp("http_redirect -> issue request 2: "
+ "~n ~p", [URL300]),
+ {ok, {{_,300,_}, [_ | _], _}} =
+ http:request(get, {URL300, []}, [{autoredirect, false}], []),
URL301 = ?URL_START ++ integer_to_list(Port) ++ "/301.html",
-
+ tsp("http_redirect -> issue request 3: "
+ "~n ~p", [URL301]),
{ok, {{_,200,_}, [_ | _], [_|_]}}
= http:request(get, {URL301, []}, [], []),
+ tsp("http_redirect -> issue request 4: "
+ "~n ~p", [URL301]),
{ok, {{_,200,_}, [_ | _], []}}
= http:request(head, {URL301, []}, [], []),
+ tsp("http_redirect -> issue request 5: "
+ "~n ~p", [URL301]),
{ok, {{_,301,_}, [_ | _], [_|_]}}
= http:request(post, {URL301, [],"text/plain", "foobar"},
[], []),
URL302 = ?URL_START ++ integer_to_list(Port) ++ "/302.html",
+ tsp("http_redirect -> issue request 6: "
+ "~n ~p", [URL302]),
{ok, {{_,200,_}, [_ | _], [_|_]}}
= http:request(get, {URL302, []}, [], []),
+ tsp("http_redirect -> issue request 7: "
+ "~n ~p", [URL302]),
{ok, {{_,200,_}, [_ | _], []}}
= http:request(head, {URL302, []}, [], []),
+ tsp("http_redirect -> issue request 8: "
+ "~n ~p", [URL302]),
{ok, {{_,302,_}, [_ | _], [_|_]}}
= http:request(post, {URL302, [],"text/plain", "foobar"},
[], []),
URL307 = ?URL_START ++ integer_to_list(Port) ++ "/307.html",
+ tsp("http_redirect -> issue request 9: "
+ "~n ~p", [URL307]),
{ok, {{_,200,_}, [_ | _], [_|_]}}
= http:request(get, {URL307, []}, [], []),
+ tsp("http_redirect -> issue request 10: "
+ "~n ~p", [URL307]),
{ok, {{_,200,_}, [_ | _], []}}
= http:request(head, {URL307, []}, [], []),
+ tsp("http_redirect -> issue request 11: "
+ "~n ~p", [URL307]),
{ok, {{_,307,_}, [_ | _], [_|_]}}
= http:request(post, {URL307, [],"text/plain", "foobar"},
[], []),
+ tsp("http_redirect -> stop dummy server"),
DummyServerPid ! stop,
- ok = http:set_options([{ipfamily, inet6fb4}]); % ********** ipfamily = inet6 *************
+ tsp("http_redirect -> reset ipfamily option (to inet6fb4)"),
+ ok = http:set_options([{ipfamily, inet6fb4}]), % ********** ipfamily = inet6 *************
+ tsp("http_redirect -> done"),
+ ok;
+
_ ->
{skip, "Failed to start local http-server"}
end.
@@ -938,12 +1026,7 @@ http_redirect_loop(suite) ->
[];
http_redirect_loop(Config) when is_list(Config) ->
ok = http:set_options([{ipfamily, inet}]),
- DummyServerPid = dummy_server(self(), ipv4),
-
- Port = receive
- {port, ServerPort} ->
- ServerPort
- end,
+ {DummyServerPid, Port} = dummy_server(self(), ipv4),
URL = ?URL_START ++ integer_to_list(Port) ++ "/redirectloop.html",
@@ -960,12 +1043,7 @@ http_internal_server_error(suite) ->
[];
http_internal_server_error(Config) when is_list(Config) ->
ok = http:set_options([{ipfamily, inet}]),
- DummyServerPid = dummy_server(self(), ipv4),
-
- Port = receive
- {port, ServerPort} ->
- ServerPort
- end,
+ {DummyServerPid, Port} = dummy_server(self(), ipv4),
URL500 = ?URL_START ++ integer_to_list(Port) ++ "/500.html",
@@ -1001,12 +1079,7 @@ http_userinfo(suite) ->
http_userinfo(Config) when is_list(Config) ->
ok = http:set_options([{ipfamily, inet}]),
- DummyServerPid = dummy_server(self(), ipv4),
-
- Port = receive
- {port, ServerPort} ->
- ServerPort
- end,
+ {DummyServerPid, Port} = dummy_server(self(), ipv4),
URLAuth = "http://alladin:sesame@localhost:"
++ integer_to_list(Port) ++ "/userinfo.html",
@@ -1032,12 +1105,7 @@ http_cookie(suite) ->
[];
http_cookie(Config) when is_list(Config) ->
ok = http:set_options([{cookies, enabled}, {ipfamily, inet}]),
- DummyServerPid = dummy_server(self(), ipv4),
-
- Port = receive
- {port, ServerPort} ->
- ServerPort
- end,
+ {DummyServerPid, Port} = dummy_server(self(), ipv4),
URLStart = ?URL_START
++ integer_to_list(Port),
@@ -1335,8 +1403,8 @@ proxy_https_not_supported(doc) ->
proxy_https_not_supported(suite) ->
[];
proxy_https_not_supported(Config) when is_list(Config) ->
- {error, https_through_proxy_is_not_currently_supported}
- = http:request(get, {"https://login.yahoo.com", []}, [], []),
+ {error, {failed_connecting, https_through_proxy_is_not_currently_supported}} =
+ http:request(get, {"https://login.yahoo.com", []}, [], []),
ok.
@@ -1374,51 +1442,68 @@ http_stream_once(doc) ->
http_stream_once(suite) ->
[];
http_stream_once(Config) when is_list(Config) ->
+ p("http_stream_once -> entry with"
+ "~n Config: ~p", [Config]),
+
+ p("http_stream_once -> set ipfamily to inet", []),
ok = http:set_options([{ipfamily, inet}]),
- DummyServerPid = dummy_server(self(), ipv4),
- Port = receive
- {port, ServerPort} ->
- ServerPort
- end,
+ p("http_stream_once -> start dummy server", []),
+ {DummyServerPid, Port} = dummy_server(self(), ipv4),
PortStr = integer_to_list(Port),
+ p("http_stream_once -> once", []),
once(?URL_START ++ PortStr ++ "/once.html"),
+ p("http_stream_once -> once_chunked", []),
once(?URL_START ++ PortStr ++ "/once_chunked.html"),
+ p("http_stream_once -> dummy", []),
once(?URL_START ++ PortStr ++ "/dummy.html"),
+ p("http_stream_once -> stop dummy server", []),
DummyServerPid ! stop,
+ p("http_stream_once -> set ipfamily to inet6fb4", []),
ok = http:set_options([{ipfamily, inet6fb4}]), % ********** ipfamily = inet6 *************
+ p("http_stream_once -> done", []),
ok.
once(URL) ->
+ p("once -> issue sync request for ~p", [URL]),
{ok, {{_,200,_}, [_ | _], Body}} =
http:request(get, {URL, []}, [], []),
+ p("once -> issue async (self stream) request for ~p", [URL]),
{ok, RequestId} =
http:request(get, {URL, []}, [], [{sync, false},
{stream, {self, once}}]),
- NewPid = receive
- {http, {RequestId, stream_start, _Headers, Pid}} ->
- Pid;
- {http, Msg} ->
- test_server:fail(Msg)
- end,
+ p("once -> await stream_start reply for (async) request ~p", [RequestId]),
+ NewPid =
+ receive
+ {http, {RequestId, stream_start, _Headers, Pid}} ->
+ p("once -> received stream_start reply for (async) request ~p: ~p",
+ [RequestId, Pid]),
+ Pid;
+ {http, Msg} ->
+ test_server:fail(Msg)
+ end,
- test_server:format("Request handler: ~p~n", [NewPid]),
+ tsp("once -> request handler: ~p", [NewPid]),
+ p("once -> await stream reply for (async) request ~p", [RequestId]),
BodyPart =
receive
{http, {RequestId, stream, BinBodyPart}} ->
+ p("once -> received stream reply for (async) request ~p: "
+ "~n~p", [RequestId, binary_to_list(BinBodyPart)]),
BinBodyPart
end,
- test_server:format("First body part: ~p~n",
- [binary_to_list(BodyPart)]),
+ tsp("once -> first body part '~p' received", [binary_to_list(BodyPart)]),
StreamedBody = receive_streamed_body(RequestId, BinBodyPart, NewPid),
Body = binary_to_list(StreamedBody),
+
+ p("once -> done when Bode: ~p", [Body]),
ok.
@@ -1509,12 +1594,7 @@ ipv6(Config) when is_list(Config) ->
case lists:member(list_to_atom(Hostname),
?config(ipv6_hosts, Config)) of
true ->
- DummyServerPid = dummy_server(self(), ipv6),
-
- Port = receive
- {port, ServerPort} ->
- ServerPort
- end,
+ {DummyServerPid, Port} = dummy_server(self(), ipv6),
URL = "http://[" ++ ?IPV6_LOCAL_HOST ++ "]:" ++
integer_to_list(Port) ++ "/foobar.html",
@@ -1576,12 +1656,7 @@ http_invalid_http(suite) ->
[];
http_invalid_http(Config) when is_list(Config) ->
ok = http:set_options([{ipfamily, inet}]),
- DummyServerPid = dummy_server(self(), ipv4),
-
- Port = receive
- {port, ServerPort} ->
- ServerPort
- end,
+ {DummyServerPid, Port} = dummy_server(self(), ipv4),
URL = ?URL_START ++ integer_to_list(Port) ++ "/invalid_http.html",
@@ -1638,12 +1713,7 @@ transfer_encoding_otp_6807(suite) ->
[];
transfer_encoding_otp_6807(Config) when is_list(Config) ->
ok = http:set_options([{ipfamily, inet}]),
- DummyServerPid = dummy_server(self(), ipv4),
-
- Port = receive
- {port, ServerPort} ->
- ServerPort
- end,
+ {DummyServerPid, Port} = dummy_server(self(), ipv4),
URL = ?URL_START ++ integer_to_list(Port) ++
"/capital_transfer_encoding.html",
@@ -1676,12 +1746,7 @@ empty_response_header_otp_6830(suite) ->
[];
empty_response_header_otp_6830(Config) when is_list(Config) ->
ok = http:set_options([{ipfamily, inet}]),
- DummyServerPid = dummy_server(self(), ipv4),
-
- Port = receive
- {port, ServerPort} ->
- ServerPort
- end,
+ {DummyServerPid, Port} = dummy_server(self(), ipv4),
URL = ?URL_START ++ integer_to_list(Port) ++ "/no_headers.html",
{ok, {{_,200,_}, [], [_ | _]}} = http:request(URL),
@@ -1698,12 +1763,7 @@ no_content_204_otp_6982(suite) ->
[];
no_content_204_otp_6982(Config) when is_list(Config) ->
ok = http:set_options([{ipfamily, inet}]),
- DummyServerPid = dummy_server(self(), ipv4),
-
- Port = receive
- {port, ServerPort} ->
- ServerPort
- end,
+ {DummyServerPid, Port} = dummy_server(self(), ipv4),
URL = ?URL_START ++ integer_to_list(Port) ++ "/no_content.html",
{ok, {{_,204,_}, [], []}} = http:request(URL),
@@ -1721,12 +1781,7 @@ missing_CR_otp_7304(suite) ->
[];
missing_CR_otp_7304(Config) when is_list(Config) ->
ok = http:set_options([{ipfamily, inet}]),
- DummyServerPid = dummy_server(self(), ipv4),
-
- Port = receive
- {port, ServerPort} ->
- ServerPort
- end,
+ {DummyServerPid, Port} = dummy_server(self(), ipv4),
URL = ?URL_START ++ integer_to_list(Port) ++ "/missing_CR.html",
{ok, {{_,200,_}, _, [_ | _]}} = http:request(URL),
@@ -1747,13 +1802,8 @@ otp_7883_1(suite) ->
otp_7883_1(Config) when is_list(Config) ->
ok = http:set_options([{ipfamily, inet}]),
- DummyServerPid = dummy_server(self(), ipv4),
+ {DummyServerPid, Port} = dummy_server(self(), ipv4),
- Port = receive
- {port, ServerPort} ->
- ServerPort
- end,
-
URL = ?URL_START ++ integer_to_list(Port) ++ "/just_close.html",
{error, socket_closed_remotely} = http:request(URL),
DummyServerPid ! stop,
@@ -1768,13 +1818,8 @@ otp_7883_2(suite) ->
otp_7883_2(Config) when is_list(Config) ->
ok = http:set_options([{ipfamily, inet}]),
- DummyServerPid = dummy_server(self(), ipv4),
+ {DummyServerPid, Port} = dummy_server(self(), ipv4),
- Port = receive
- {port, ServerPort} ->
- ServerPort
- end,
-
URL = ?URL_START ++ integer_to_list(Port) ++ "/just_close.html",
Method = get,
Request = {URL, []},
@@ -1810,7 +1855,7 @@ otp_8154_1(Config) when is_list(Config) ->
{ok, Server, Port} = start_slow_server(RespSeqNumServer),
Clients = run_clients(105, Port, ReqSeqNumServer),
%% ok = wait_for_clients(Clients),
- ok = wait4clients(Clients, timer:minutes(2)),
+ ok = wait4clients(Clients, timer:minutes(3)),
Server ! shutdown,
RespSeqNumServer ! shutdown,
ReqSeqNumServer ! shutdown,
@@ -1820,6 +1865,7 @@ start_inets() ->
inets:start(),
ok.
+
%% -----------------------------------------------------
%% A sequence number handler
%% The purpose is to be able to pair requests with responses.
@@ -1886,25 +1932,25 @@ run_clients(NumClients, ServerPort, SeqNumServer) ->
end,
lists:seq(1, NumClients)).
-wait_for_clients(Clients) ->
- lists:foreach(
- fun({Id, Pid, MRef}) ->
- io:format("waiting for client ~w termination~n", [Id]),
- receive
- {'DOWN', MRef, process, Pid, normal} ->
- io:format("waiting for clients: "
- "normal exit from ~w (~p)~n",
- [Id, Pid]),
- ok;
- {'DOWN', MRef, process, Pid, Reason} ->
- io:format("waiting for clients: "
- "unexpected exit from ~w (~p):"
- "~n Reason: ~p"
- "~n", [Id, Pid, Reason]),
- erlang:error(Reason)
- end
- end,
- Clients).
+%% wait_for_clients(Clients) ->
+%% lists:foreach(
+%% fun({Id, Pid, MRef}) ->
+%% io:format("waiting for client ~w termination~n", [Id]),
+%% receive
+%% {'DOWN', MRef, process, Pid, normal} ->
+%% io:format("waiting for clients: "
+%% "normal exit from ~w (~p)~n",
+%% [Id, Pid]),
+%% ok;
+%% {'DOWN', MRef, process, Pid, Reason} ->
+%% io:format("waiting for clients: "
+%% "unexpected exit from ~w (~p):"
+%% "~n Reason: ~p"
+%% "~n", [Id, Pid, Reason]),
+%% erlang:error(Reason)
+%% end
+%% end,
+%% Clients).
wait4clients([], _Timeout) ->
@@ -2074,6 +2120,201 @@ f(F, A) -> lists:flatten(io_lib:format(F,A)).
+%%-------------------------------------------------------------------------
+
+otp_8106(suite) ->
+ [
+ otp_8106_pid,
+ otp_8106_fun,
+ otp_8106_mfa
+ ].
+
+
+otp_8106_pid(doc) ->
+ ["OTP-8106 - deliver reply info using \"other\" pid"];
+otp_8106_pid(suite) ->
+ [];
+otp_8106_pid(Config) when is_list(Config) ->
+ case ?config(local_server, Config) of
+ ok ->
+ ReceiverPid = create_receiver(pid),
+ Receiver = ReceiverPid,
+
+ otp8106(ReceiverPid, Receiver, Config),
+
+ stop_receiver(ReceiverPid),
+
+ ok;
+ _ ->
+ {skip, "Failed to start local http-server"}
+ end.
+
+
+otp_8106_fun(doc) ->
+ ["OTP-8106 - deliver reply info using fun"];
+otp_8106_fun(suite) ->
+ [];
+otp_8106_fun(Config) when is_list(Config) ->
+ case ?config(local_server, Config) of
+ ok ->
+ ReceiverPid = create_receiver(function),
+ Receiver = otp_8106_deliver_fun(ReceiverPid),
+
+ otp8106(ReceiverPid, Receiver, Config),
+
+ stop_receiver(ReceiverPid),
+
+ ok;
+ _ ->
+ {skip, "Failed to start local http-server"}
+ end.
+
+
+otp_8106_mfa(doc) ->
+ ["OTP-8106 - deliver reply info using mfa callback"];
+otp_8106_mfa(suite) ->
+ [];
+otp_8106_mfa(Config) when is_list(Config) ->
+ case ?config(local_server, Config) of
+ ok ->
+ ReceiverPid = create_receiver(mfa),
+ Receiver = {?MODULE, otp_8106_deliver, [mfa, ReceiverPid]},
+
+ otp8106(ReceiverPid, Receiver, Config),
+
+ stop_receiver(ReceiverPid),
+
+ ok;
+ _ ->
+ {skip, "Failed to start local http-server"}
+ end.
+
+
+ otp8106(ReceiverPid, Receiver, Config) ->
+ Port = ?config(local_port, Config),
+ URL = ?URL_START ++ integer_to_list(Port) ++ "/dummy.html",
+ Request = {URL, []},
+ HTTPOptions = [],
+ Options = [{sync, false}, {receiver, Receiver}],
+
+ {ok, RequestId} =
+ httpc:request(get, Request, HTTPOptions, Options),
+
+ Body =
+ receive
+ {reply, ReceiverPid, {RequestId, {{_, 200, _}, _, B}}} ->
+ B;
+ {reply, ReceiverPid, Msg} ->
+ tsf(Msg);
+ {bad_reply, ReceiverPid, Msg} ->
+ tsf(Msg)
+ end,
+
+ inets_test_lib:check_body(binary_to_list(Body)),
+ ok.
+
+
+create_receiver(Type) ->
+ Parent = self(),
+ Receiver = fun() -> receiver(Type, Parent) end,
+ spawn_link(Receiver).
+
+stop_receiver(Pid) ->
+ Pid ! {stop, self()}.
+
+receiver(Type, Parent) ->
+ receive
+ {stop, Parent} ->
+ exit(normal);
+
+ {http, ReplyInfo} when (Type =:= pid) ->
+ Parent ! {reply, self(), ReplyInfo},
+ receiver(Type, Parent);
+
+ {Type, ReplyInfo} ->
+ Parent ! {reply, self(), ReplyInfo},
+ receiver(Type, Parent);
+
+ Crap ->
+ Parent ! {reply, self(), {bad_reply, Crap}},
+ receiver(Type, Parent)
+ end.
+
+
+otp_8106_deliver_fun(ReceiverPid) ->
+ fun(ReplyInfo) -> otp_8106_deliver(ReplyInfo, function, ReceiverPid) end.
+
+otp_8106_deliver(ReplyInfo, Type, ReceiverPid) ->
+ ReceiverPid ! {Type, ReplyInfo},
+ ok.
+
+
+
+%%-------------------------------------------------------------------------
+
+otp_8056(doc) ->
+ "OTP-8056";
+otp_8056(suite) ->
+ [];
+otp_8056(Config) when is_list(Config) ->
+ Method = get,
+ Port = ?config(local_port, Config),
+ URL = ?URL_START ++ integer_to_list(Port) ++ "/dummy.html",
+ Request = {URL, []},
+ HTTPOptions = [],
+ Options1 = [{sync, true}, {stream, {self, once}}],
+ Options2 = [{sync, true}, {stream, self}],
+ {error, streaming_error} = httpc:request(Method, Request,
+ HTTPOptions, Options1),
+ tsp("request 1 failed as expected"),
+ {error, streaming_error} = httpc:request(Method, Request,
+ HTTPOptions, Options2),
+ tsp("request 2 failed as expected"),
+ ok.
+
+
+%%-------------------------------------------------------------------------
+
+otp_8371(doc) ->
+ ["OTP-8371"];
+otp_8371(suite) ->
+ [];
+otp_8371(Config) when is_list(Config) ->
+ ok = http:set_options([{ipv6, disabled}]), % also test the old option
+ {DummyServerPid, Port} = dummy_server(self(), ipv4),
+
+ URL = ?URL_START ++ integer_to_list(Port) ++
+ "/ensure_host_header_with_port.html",
+
+ case http:request(get, {URL, []}, [], []) of
+ {ok, Result} ->
+ case Result of
+ {{_, 200, _}, _Headers, Body} ->
+ tsp("expected response with"
+ "~n Body: ~p", [Body]),
+ ok;
+ {StatusLine, Headers, Body} ->
+ tsp("expected response with"
+ "~n StatusLine: ~p"
+ "~n Headers: ~p"
+ "~n Body: ~p", [StatusLine, Headers, Body]),
+ tsf({unexpected_result,
+ [{status_line, StatusLine},
+ {headers, Headers},
+ {body, Body}]});
+ _ ->
+ tsf({unexpected_result, Result})
+ end;
+ Error ->
+ tsf({request_failed, Error})
+ end,
+
+ DummyServerPid ! stop,
+ ok = http:set_options([{ipv6, enabled}]),
+ ok.
+
+
+
%%--------------------------------------------------------------------
%% Internal functions
%%--------------------------------------------------------------------
@@ -2171,7 +2412,7 @@ receive_streamed_body(RequestId, Body) ->
receive_streamed_body(RequestId, Body, Pid) ->
http:stream_next(Pid),
- test_server:format("Requested next stream ~n", []),
+ test_server:format("~p:receive_streamed_body -> requested next stream ~n", [?MODULE]),
receive
{http, {RequestId, stream, BinBodyPart}} ->
receive_streamed_body(RequestId,
@@ -2186,7 +2427,11 @@ receive_streamed_body(RequestId, Body, Pid) ->
dummy_server(Caller, IpV) ->
- spawn(httpc_SUITE, dummy_server_init, [Caller, IpV]).
+ Pid = spawn(httpc_SUITE, dummy_server_init, [Caller, IpV]),
+ receive
+ {port, Port} ->
+ {Pid, Port}
+ end.
dummy_server_init(Caller, IpV) ->
{ok, ListenSocket} =
@@ -2201,7 +2446,7 @@ dummy_server_init(Caller, IpV) ->
{active, false}])
end,
{ok, Port} = inet:port(ListenSocket),
- test_server:format("Port: ~p~n", [Port]),
+ tsp("dummy_server_init -> Port: ~p", [Port]),
Caller ! {port, Port},
dummy_server_loop({httpd_request, parse, [?HTTP_MAX_HEADER_SIZE]},
[], ListenSocket).
@@ -2209,8 +2454,7 @@ dummy_server_init(Caller, IpV) ->
dummy_server_loop(MFA, Handlers, ListenSocket) ->
receive
stop ->
- lists:foreach(fun(Handler) -> Handler ! stop end,
- Handlers)
+ lists:foreach(fun(Handler) -> Handler ! stop end, Handlers)
after 0 ->
{ok, Socket} = gen_tcp:accept(ListenSocket),
HandlerPid = dummy_request_handler(MFA, Socket),
@@ -2231,9 +2475,13 @@ dummy_request_handler_init(MFA, Socket) ->
dummy_request_handler_loop(MFA, Socket).
dummy_request_handler_loop({Module, Function, Args}, Socket) ->
+ tsp("dummy_request_handler_loop -> entry with"
+ "~n Module: ~p"
+ "~n Function: ~p"
+ "~n Args: ~p", [Module, Function, Args]),
receive
{tcp, _, Data} ->
- test_server:format("dummy_request_handler_loop -> Data ~p~n", [Data]),
+ tsp("dummy_request_handler_loop -> Data ~p", [Data]),
case handle_request(Module, Function, [Data | Args], Socket) of
stop ->
gen_tcp:close(Socket);
@@ -2245,48 +2493,59 @@ dummy_request_handler_loop({Module, Function, Args}, Socket) ->
end.
handle_request(Module, Function, Args, Socket) ->
+ tsp("handle_request -> entry with"
+ "~n Module: ~p"
+ "~n Function: ~p"
+ "~n Args: ~p", [Module, Function, Args]),
case Module:Function(Args) of
{ok, Result} ->
- case handle_http_msg(Result, Socket) of
+ tsp("handle_request -> ok"
+ "~n Result: ~p", [Result]),
+ case (catch handle_http_msg(Result, Socket)) of
stop ->
stop;
<<>> ->
- {httpd_request, parse, [?HTTP_MAX_HEADER_SIZE]};
+ tsp("handle_request -> empty data"),
+ {httpd_request, parse, [[<<>>, ?HTTP_MAX_HEADER_SIZE]]};
Data ->
handle_request(httpd_request, parse,
- [Data |[?HTTP_MAX_HEADER_SIZE]],
- Socket)
+ [Data |[?HTTP_MAX_HEADER_SIZE]], Socket)
end;
NewMFA ->
+ tsp("handle_request -> "
+ "~n NewMFA: ~p", [NewMFA]),
NewMFA
end.
handle_http_msg({_, RelUri, _, {_, Headers}, Body}, Socket) ->
-
- NextRequest = case RelUri of
- "/dummy_headers.html" ->
- <<>>;
- "/no_headers.html" ->
- stop;
- "/just_close.html" ->
- stop;
- _ ->
- ContentLength = content_length(Headers),
- case size(Body) - ContentLength of
- 0 ->
- <<>>;
- _ ->
- <<_BodyThisReq:ContentLength/binary,
- Next/binary>> = Body,
- Next
- end
- end,
+ tsp("handle_http_msg -> entry with: "
+ "~n RelUri: ~p"
+ "~n Headers: ~p"
+ "~n Body: ~p", [RelUri, Headers, Body]),
+ NextRequest =
+ case RelUri of
+ "/dummy_headers.html" ->
+ <<>>;
+ "/no_headers.html" ->
+ stop;
+ "/just_close.html" ->
+ stop;
+ _ ->
+ ContentLength = content_length(Headers),
+ case size(Body) - ContentLength of
+ 0 ->
+ <<>>;
+ _ ->
+ <<_BodyThisReq:ContentLength/binary,
+ Next/binary>> = Body,
+ Next
+ end
+ end,
- test_server:format("NextRequest: ~p~n", [NextRequest]),
-
+ tsp("handle_http_msg -> NextRequest: ~p", [NextRequest]),
case (catch ets:lookup(cookie, cookies)) of
[{cookies, true}]->
- test_server:format("Headers ~p~n", [Headers]),
+ tsp("handle_http_msg -> check cookies ~p", []),
check_cookie(Headers);
_ ->
ok
@@ -2304,6 +2563,26 @@ handle_http_msg({_, RelUri, _, {_, Headers}, Body}, Socket) ->
"HTTP/1.0 204 No Content\r\n\r\n";
"/no_headers.html" ->
"HTTP/1.0 200 OK\r\n\r\nTEST";
+ "/ensure_host_header_with_port.html" ->
+ %% tsp("handle_http_msg -> validate host with port"),
+ case ensure_host_header_with_port(Headers) of
+ true ->
+ B =
+ "<HTML><BODY>" ++
+ "host with port" ++
+ "</BODY></HTML>",
+ Len = integer_to_list(length(B)),
+ "HTTP/1.1 200 ok\r\n" ++
+ "Content-Length:" ++ Len ++ "\r\n\r\n" ++ B;
+ false ->
+ B =
+ "<HTML><BODY>" ++
+ "Internal Server Error - host without port" ++
+ "</BODY></HTML>",
+ Len = integer_to_list(length(B)),
+ "HTTP/1.1 500 Internal Server Error\r\n" ++
+ "Content-Length:" ++ Len ++ "\r\n\r\n" ++ B
+ end;
"/300.html" ->
NewUri = ?URL_START ++
integer_to_list(?IP_PORT) ++ "/dummy.html",
@@ -2337,7 +2616,7 @@ handle_http_msg({_, RelUri, _, {_, Headers}, Body}, Socket) ->
"/500.html" ->
"HTTP/1.1 500 Internal Server Error\r\n" ++
"Content-Length:47\r\n\r\n" ++
- "<HTML><BODY>Internal Server Error</BODY<</HTML>";
+ "<HTML><BODY>Internal Server Error</BODY></HTML>";
"/503.html" ->
case ets:lookup(unavailable, 503) of
[{503, unavailable}] ->
@@ -2452,16 +2731,35 @@ handle_http_msg({_, RelUri, _, {_, Headers}, Body}, Socket) ->
DefaultResponse
end,
- test_server:format("Msg: ~p~n", [Msg]),
+ tsp("handle_http_msg -> Msg: ~p", [Msg]),
case Msg of
+ ok ->
+ %% Previously, this resulted in an {error, einval}. Now what?
+ ok;
close ->
%% Nothing to send, just close
gen_tcp:close(Socket);
- _ ->
+ _ when is_list(Msg) orelse is_binary(Msg) ->
gen_tcp:send(Socket, Msg)
end,
+ tsp("handle_http_msg -> done"),
NextRequest.
+ensure_host_header_with_port([]) ->
+ false;
+ensure_host_header_with_port(["host: " ++ Host| _]) ->
+ case string:tokens(Host, [$:]) of
+ [ActualHost, Port] ->
+ tsp("ensure_host_header_with_port -> "
+ "~n ActualHost: ~p"
+ "~n Port: ~p", [ActualHost, Port]),
+ true;
+ _ ->
+ false
+ end;
+ensure_host_header_with_port([_|T]) ->
+ ensure_host_header_with_port(T).
+
auth_header([]) ->
auth_header_not_found;
auth_header(["authorization:" ++ Value | _]) ->
@@ -2507,9 +2805,10 @@ provocate_not_modified_bug(Url) ->
[]) of
{ok, {{_, 304, _}, _, _}} -> %% The expected reply
page_unchanged;
- {ok, {{_, 200, _}, _, _}} -> %% If the page has changed since the
- %% last request we retry to
- %% trigger the bug
+ {ok, {{_, 200, _}, _, _}} ->
+ %% If the page has changed since the
+ %% last request we retry to
+ %% trigger the bug
provocate_not_modified_bug(Url);
{error, timeout} ->
%% Not what we expected. Tcpdump can be used to
@@ -2528,5 +2827,20 @@ pick_header(Headers, Name) ->
end.
-%% p(F, A) ->
-%% io:format("~p ~w:" ++ F ++ "~n", [self(), ?MODULE | A]).
+not_implemented_yet() ->
+ exit(not_implemented_yet).
+
+
+p(F) ->
+ p(F, []).
+
+p(F, A) ->
+ io:format("~p ~w:" ++ F ++ "~n", [self(), ?MODULE | A]).
+
+tsp(F) ->
+ tsp(F, []).
+tsp(F, A) ->
+ test_server:format("~p ~p:" ++ F ++ "~n", [self(), ?MODULE | A]).
+
+tsf(Reason) ->
+ test_server:fail(Reason).
diff --git a/lib/inets/test/httpc_cookie_SUITE.erl b/lib/inets/test/httpc_cookie_SUITE.erl
index 7d91631934..ad5df656c6 100644
--- a/lib/inets/test/httpc_cookie_SUITE.erl
+++ b/lib/inets/test/httpc_cookie_SUITE.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2005-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2005-2010. 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
%% 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.
-%%
+%%
%% %CopyrightEnd%
%%
%%
@@ -31,7 +31,7 @@
domain_cookie/1, secure_cookie/1, update_cookie/1,
update_cookie_session/1, cookie_attributes/1]).
--define(URL, "http://myhost.cookie.test.org").
+-define(URL, "http://myhost.cookie.test.org").
-define(URL_DOMAIN, "http://myhost2.cookie.test.org").
-define(URL_SECURE, "https://myhost.cookie.test.org").
@@ -50,15 +50,21 @@
%% variable, but should NOT alter/remove any existing entries.
%% Description: Initiation before each test case
%%--------------------------------------------------------------------
-init_per_testcase(session_cookies_only, Config) ->
+init_per_testcase(session_cookies_only = Case, Config0) ->
+ tsp("init_per_testcase(~p) -> entry with"
+ "~n Config0: ~p", [Case, Config0]),
+ Config = init_workdir(Case, Config0),
application:start(inets),
http:set_options([{cookies, verify}]),
watch_dog(Config);
-init_per_testcase(_, Config) ->
- PrivDir = ?config(priv_dir, Config),
+init_per_testcase(Case, Config0) ->
+ tsp("init_per_testcase(~p) -> entry with"
+ "~n Config0: ~p", [Case, Config0]),
+ Config = init_workdir(Case, Config0),
+ CaseDir = ?config(case_top_dir, Config),
application:load(inets),
- application:set_env(inets, services, [{httpc,{default, PrivDir}}]),
+ application:set_env(inets, services, [{httpc, {default, CaseDir}}]),
application:start(inets),
http:set_options([{cookies, verify}]),
watch_dog(Config).
@@ -68,6 +74,24 @@ watch_dog(Config) ->
NewConfig = lists:keydelete(watchdog, 1, Config),
[{watchdog, Dog} | NewConfig].
+init_workdir(Case, Config) ->
+ PrivDir = ?config(priv_dir, Config),
+ SuiteTopDir = filename:join(PrivDir, ?MODULE),
+ case file:make_dir(SuiteTopDir) of
+ ok ->
+ ok;
+ {error, eexist} ->
+ ok;
+ Error ->
+ tsf({failed_creating_subsuite_top_dir, Error})
+ end,
+
+ CaseTopDir = filename:join(SuiteTopDir, Case),
+ ?line ok = file:make_dir(CaseTopDir),
+ [{suite_top_dir, SuiteTopDir},
+ {case_top_dir, CaseTopDir} | Config].
+
+
%%--------------------------------------------------------------------
%% Function: end_per_testcase(TestCase, Config) -> _
%% Case - atom()
@@ -76,10 +100,10 @@ watch_dog(Config) ->
%% A list of key/value pairs, holding the test case configuration.
%% Description: Cleanup after each test case
%%--------------------------------------------------------------------
-end_per_testcase(_TestCase, Config) ->
+end_per_testcase(Case, Config) ->
+ tsp("end_per_testcase(~p) -> entry with"
+ "~n Config: ~p", [Case, Config]),
application:stop(inets),
- File = filename:join(?config(priv_dir, Config), "http_default_cookie_db"),
- file:delete(File),
Dog = ?config(watchdog, Config),
test_server:timetrap_cancel(Dog),
ok.
@@ -96,9 +120,18 @@ all(doc) ->
["Describe the main purpose of this suite"];
all(suite) ->
- [session_cookies_only, netscape_cookies, cookie_cancel,
- cookie_expires, persistent_cookie, domain_cookie, secure_cookie,
- update_cookie, update_cookie_session, cookie_attributes].
+ [
+ session_cookies_only,
+ netscape_cookies,
+ cookie_cancel,
+ cookie_expires,
+ persistent_cookie,
+ domain_cookie,
+ secure_cookie,
+ update_cookie,
+ update_cookie_session,
+ cookie_attributes
+ ].
%% Test cases starts here.
%%--------------------------------------------------------------------
@@ -108,6 +141,8 @@ session_cookies_only(doc) ->
session_cookies_only(suite) ->
[];
session_cookies_only(Config) when is_list(Config) ->
+ tsp("session_cookies_only -> Cookies 1: ~p", [httpc:which_cookies()]),
+
SetCookieHeaders = [{"set-cookie", "test_cookie=true; path=/;"
";max-age=60000"}],
http:verify_cookies(SetCookieHeaders, ?URL),
@@ -115,8 +150,9 @@ session_cookies_only(Config) when is_list(Config) ->
= http:cookie_header(?URL),
application:stop(inets),
application:start(inets),
- {"cookie",""}
- = http:cookie_header(?URL),
+ {"cookie",""} = http:cookie_header(?URL),
+
+ tsp("session_cookies_only -> Cookies 2: ~p", [httpc:which_cookies()]),
ok.
netscape_cookies(doc) ->
@@ -124,12 +160,16 @@ netscape_cookies(doc) ->
netscape_cookies(suite) ->
[];
netscape_cookies(Config) when is_list(Config) ->
+ tsp("netscape_cookies -> Cookies 1: ~p", [httpc:which_cookies()]),
+
Expires = future_netscape_date(),
SetCookieHeaders = [{"set-cookie", "test_cookie=true; path=/; "
"expires=" ++ Expires}],
http:verify_cookies(SetCookieHeaders, ?URL),
- {"cookie","$Version=0; test_cookie=true; $Path=/"}
- = http:cookie_header(?URL),
+ {"cookie","$Version=0; test_cookie=true; $Path=/"} =
+ http:cookie_header(?URL),
+
+ tsp("netscape_cookies -> Cookies 2: ~p", [httpc:which_cookies()]),
ok.
cookie_cancel(doc) ->
@@ -138,6 +178,8 @@ cookie_cancel(doc) ->
cookie_cancel(suite) ->
[];
cookie_cancel(Config) when is_list(Config) ->
+ tsp("cookie_cancel -> Cookies 1: ~p", [httpc:which_cookies()]),
+
SetCookieHeaders = [{"set-cookie", "test_cookie=true; path=/;"
"max-age=60000"}],
http:verify_cookies(SetCookieHeaders, ?URL),
@@ -147,6 +189,8 @@ cookie_cancel(Config) when is_list(Config) ->
"max-age=0"}],
http:verify_cookies(NewSetCookieHeaders, ?URL),
{"cookie", ""} = http:cookie_header(?URL),
+
+ tsp("cookie_cancel -> Cookies 2: ~p", [httpc:which_cookies()]),
ok.
cookie_expires(doc) ->
@@ -154,6 +198,8 @@ cookie_expires(doc) ->
cookie_expires(suite) ->
[];
cookie_expires(Config) when is_list(Config) ->
+ tsp("cookie_expires -> Cookies 1: ~p", [httpc:which_cookies()]),
+
SetCookieHeaders = [{"set-cookie", "test_cookie=true; path=/;"
"max-age=5"}],
http:verify_cookies(SetCookieHeaders, ?URL),
@@ -161,56 +207,95 @@ cookie_expires(Config) when is_list(Config) ->
= http:cookie_header(?URL),
test_server:sleep(10000),
{"cookie", ""} = http:cookie_header(?URL),
+
+ tsp("cookie_expires -> Cookies 2: ~p", [httpc:which_cookies()]),
ok.
-persistent_cookie(doc)->
+persistent_cookie(doc) ->
["Test domian cookie attribute"];
persistent_cookie(suite) ->
[];
persistent_cookie(Config) when is_list(Config)->
+ tsp("persistent_cookie -> Cookies 1: ~p", [httpc:which_cookies()]),
+
SetCookieHeaders = [{"set-cookie", "test_cookie=true; path=/;"
"max-age=60000"}],
http:verify_cookies(SetCookieHeaders, ?URL),
- {"cookie","$Version=0; test_cookie=true; $Path=/"}
- = http:cookie_header(?URL),
- PrivDir = ?config(priv_dir, Config),
+ {"cookie","$Version=0; test_cookie=true; $Path=/"} =
+ http:cookie_header(?URL),
+ CaseDir = ?config(case_top_dir, Config),
application:stop(inets),
application:load(inets),
- application:set_env(inets, services, [{httpc,{default, PrivDir}}]),
+ application:set_env(inets, services, [{httpc, {default, CaseDir}}]),
application:start(inets),
- http:set_options([{cookies, enabled}]),
- {"cookie","$Version=0; test_cookie=true; $Path=/"}
- = http:cookie_header(?URL),
+ http:set_options([{cookies, enabled}]),
+ {"cookie","$Version=0; test_cookie=true; $Path=/"} = http:cookie_header(?URL),
+
+ tsp("persistent_cookie -> Cookies 2: ~p", [httpc:which_cookies()]),
ok.
-domain_cookie(doc)->
+
+domain_cookie(doc) ->
["Test the domian cookie attribute"];
domain_cookie(suite) ->
[];
-domain_cookie(Config) when is_list(Config)->
+domain_cookie(Config) when is_list(Config) ->
+ tsp("domain_cookie -> Cookies 1: ~p", [httpc:which_cookies()]),
+
SetCookieHeaders = [{"set-cookie", "test_cookie=true; path=/;"
"domain=.cookie.test.org"}],
http:verify_cookies(SetCookieHeaders, ?URL),
{"cookie","$Version=0; test_cookie=true; $Path=/; "
- "$Domain=.cookie.test.org"}
- = http:cookie_header(?URL_DOMAIN),
+ "$Domain=.cookie.test.org"} =
+ http:cookie_header(?URL_DOMAIN),
+
+ tsp("domain_cookie -> Cookies 2: ~p", [httpc:which_cookies()]),
ok.
-secure_cookie(doc)->
+
+secure_cookie(doc) ->
["Test the secure cookie attribute"];
secure_cookie(suite) ->
[];
-secure_cookie(Config) when is_list(Config)->
+secure_cookie(Config) when is_list(Config) ->
+ tsp("secure_cookie -> entry with"
+ "~n Config: ~p", [Config]),
+
+ inets:enable_trace(max, io, httpc),
+
+ %% httpc:reset_cookies(),
+
+ tsp("secure_cookie -> Cookies 1: ~p", [httpc:which_cookies()]),
+
SetCookieHeaders = [{"set-cookie", "test_cookie=true; path=/; secure"}],
- http:verify_cookies(SetCookieHeaders, ?URL),
- {"cookie","$Version=0; test_cookie=true; $Path=/"}
- = http:cookie_header(?URL_SECURE),
- {"cookie",""}
- = http:cookie_header(?URL),
+ tsp("secure_cookie -> verify cookies (1)"),
+ ok = http:verify_cookies(SetCookieHeaders, ?URL),
+
+ tsp("secure_cookie -> Cookies 2: ~p", [httpc:which_cookies()]),
+
+ tsp("secure_cookie -> check cookie (secure)"),
+ check_cookie("$Version=0; test_cookie=true; $Path=/", ?URL_SECURE),
+
+ tsp("secure_cookie -> check cookie (plain)"),
+ check_cookie("", ?URL),
+
+ tsp("secure_cookie -> verify cookies (2)"),
SetCookieHeaders1 = [{"set-cookie", "test1_cookie=true; path=/; secure"}],
- http:verify_cookies(SetCookieHeaders1, ?URL),
- {"cookie","$Version=0; test_cookie=true; $Path=/; "
- "test1_cookie=true; $Path=/"} = http:cookie_header(?URL_SECURE),
+ ok = http:verify_cookies(SetCookieHeaders1, ?URL),
+
+ tsp("secure_cookie -> Cookies 3: ~p", [httpc:which_cookies()]),
+
+ tsp("secure_cookie -> cookie header (3)"),
+ check_cookie("$Version=0; test_cookie=true; $Path=/; "
+ "test1_cookie=true; $Path=/",
+ ?URL_SECURE),
+%% {"cookie","$Version=0; test_cookie=true; $Path=/; "
+%% "test1_cookie=true; $Path=/"} = http:cookie_header(?URL_SECURE),
+
+ tsp("secure_cookie -> Cookies 4: ~p", [httpc:which_cookies()]),
+
+ inets:disable_trace(),
+ tsp("secure_cookie -> done"),
ok.
update_cookie(doc)->
@@ -257,13 +342,31 @@ cookie_attributes(Config) when is_list(Config) ->
"foo=bar;" %% Nonsense should be ignored
"max-age=60000"}],
http:verify_cookies(SetCookieHeaders, ?URL),
- {"cookie","$Version=1; test_cookie=true"}
- = http:cookie_header(?URL),
+ {"cookie","$Version=1; test_cookie=true"} = http:cookie_header(?URL),
ok.
+
%%--------------------------------------------------------------------
%%% Internal functions
%%--------------------------------------------------------------------
+
+check_cookie(Expect, URL) ->
+ case http:cookie_header(URL) of
+ {"cookie", Expect} ->
+ ok;
+ {"cookie", Unexpected} ->
+ case lists:prefix(Expect, Unexpected) of
+ true ->
+ Extra = Unexpected -- Expect,
+ tsf({extra_cookie_info, Extra});
+ false ->
+ tsf({unknown_cookie, Expect, Unexpected})
+ end;
+ Bad ->
+ tsf({bad_cookies, Bad})
+ end.
+
+
future_netscape_date() ->
[Day, DD, Mon, YYYY] = netscape_date(date()),
lists:flatten(io_lib:format("~s, ~s ~s ~s 12:30:00 GMT",
@@ -336,3 +439,13 @@ month_str(9) ->"Sep";
month_str(10) ->"Oct";
month_str(11) ->"Nov";
month_str(12) ->"Dec".
+
+
+tsp(F) ->
+ tsp(F, []).
+tsp(F, A) ->
+ test_server:format("~p ~p:" ++ F ++ "~n", [self(), ?MODULE | A]).
+
+tsf(Reason) ->
+ test_server:fail(Reason).
+
diff --git a/lib/inets/test/httpd_SUITE.erl b/lib/inets/test/httpd_SUITE.erl
index b7e97aa3ec..7403d4a643 100644
--- a/lib/inets/test/httpd_SUITE.erl
+++ b/lib/inets/test/httpd_SUITE.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2005-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2005-2010. 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
%% 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.
-%%
+%%
%% %CopyrightEnd%
%%
%%
@@ -444,35 +444,35 @@ ip(doc) ->
["HTTP tests using TCP/IP"];
ip(suite) ->
[
-%% ip_mod_alias,
-%% ip_mod_actions,
-%% ip_mod_security,
-%% ip_mod_auth,
-%% ip_mod_auth_api,
-%% ip_mod_auth_mnesia_api,
-%% ip_mod_htaccess,
-%% ip_mod_cgi,
-%% ip_mod_esi,
-%% ip_mod_get,
-%% ip_mod_head,
-%% ip_mod_all,
-%% ip_load_light,
-%% ip_load_medium,
-%% ip_load_heavy,
-%% ip_dos_hostname,
-%% ip_time_test,
-%% ip_block_disturbing_idle,
-%% ip_block_non_disturbing_idle,
-%% ip_block_503,
-%% ip_block_disturbing_active,
-%% ip_block_non_disturbing_active,
-%% ip_block_disturbing_active_timeout_not_released,
-%% ip_block_disturbing_active_timeout_released,
-%% ip_block_non_disturbing_active_timeout_not_released,
-%% ip_block_non_disturbing_active_timeout_released,
-%% ip_block_disturbing_blocker_dies,
-%% ip_block_non_disturbing_blocker_dies,
-%% ip_restart_no_block,
+ ip_mod_alias,
+ ip_mod_actions,
+ ip_mod_security,
+ ip_mod_auth,
+ ip_mod_auth_api,
+ ip_mod_auth_mnesia_api,
+ ip_mod_htaccess,
+ ip_mod_cgi,
+ ip_mod_esi,
+ ip_mod_get,
+ ip_mod_head,
+ ip_mod_all,
+ ip_load_light,
+ ip_load_medium,
+ ip_load_heavy,
+ ip_dos_hostname,
+ ip_time_test,
+ ip_block_disturbing_idle,
+ ip_block_non_disturbing_idle,
+ ip_block_503,
+ ip_block_disturbing_active,
+ ip_block_non_disturbing_active,
+ ip_block_disturbing_active_timeout_not_released,
+ ip_block_disturbing_active_timeout_released,
+ ip_block_non_disturbing_active_timeout_not_released,
+ ip_block_non_disturbing_active_timeout_released,
+ ip_block_disturbing_blocker_dies,
+ ip_block_non_disturbing_blocker_dies,
+ ip_restart_no_block,
ip_restart_disturbing_block,
ip_restart_non_disturbing_block
].
@@ -482,37 +482,37 @@ ssl(doc) ->
["HTTP test using SSL"];
ssl(suite) ->
[
-%% ssl_mod_alias,
-%% ssl_mod_actions,
-%% ssl_mod_security,
-%% ssl_mod_auth,
-%% ssl_mod_auth_api,
-%% ssl_mod_auth_mnesia_api,
-%% ssl_mod_htaccess,
-%% ssl_mod_cgi,
-%% ssl_mod_esi,
-%% ssl_mod_get,
-%% ssl_mod_head,
-%% ssl_mod_all,
-%% ssl_load_light,
-%% ssl_load_medium,
-%% ssl_load_heavy,
-%% ssl_dos_hostname,
-%% ssl_time_test,
-%% ssl_restart_no_block,
+ ssl_mod_alias,
+ ssl_mod_actions,
+ ssl_mod_security,
+ ssl_mod_auth,
+ ssl_mod_auth_api,
+ ssl_mod_auth_mnesia_api,
+ ssl_mod_htaccess,
+ ssl_mod_cgi,
+ ssl_mod_esi,
+ ssl_mod_get,
+ ssl_mod_head,
+ ssl_mod_all,
+ ssl_load_light,
+ ssl_load_medium,
+ ssl_load_heavy,
+ ssl_dos_hostname,
+ ssl_time_test,
+ ssl_restart_no_block,
ssl_restart_disturbing_block,
- ssl_restart_non_disturbing_block%% ,
-%% ssl_block_disturbing_idle,
-%% ssl_block_non_disturbing_idle,
-%% ssl_block_503,
-%% ssl_block_disturbing_active,
-%% ssl_block_non_disturbing_active,
-%% ssl_block_disturbing_active_timeout_not_released,
-%% ssl_block_disturbing_active_timeout_released,
-%% ssl_block_non_disturbing_active_timeout_not_released,
-%% ssl_block_non_disturbing_active_timeout_released,
-%% ssl_block_disturbing_blocker_dies,
-%% ssl_block_non_disturbing_blocker_dies
+ ssl_restart_non_disturbing_block,
+ ssl_block_disturbing_idle,
+ ssl_block_non_disturbing_idle,
+ ssl_block_503,
+ ssl_block_disturbing_active,
+ ssl_block_non_disturbing_active,
+ ssl_block_disturbing_active_timeout_not_released,
+ ssl_block_disturbing_active_timeout_released,
+ ssl_block_non_disturbing_active_timeout_not_released,
+ ssl_block_non_disturbing_active_timeout_released,
+ ssl_block_disturbing_blocker_dies,
+ ssl_block_non_disturbing_blocker_dies
].
%%-------------------------------------------------------------------------
diff --git a/lib/inets/test/inets_SUITE.erl b/lib/inets/test/inets_SUITE.erl
index c249bdf81b..56983caace 100644
--- a/lib/inets/test/inets_SUITE.erl
+++ b/lib/inets/test/inets_SUITE.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 1997-2010. 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
%% 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.
-%%
+%%
%% %CopyrightEnd%
%%
%%
@@ -21,12 +21,12 @@
-include("test_server.hrl").
-include("test_server_line.hrl").
+-include("inets_test_lib.hrl").
%% Note: This directive should only be used in test suites.
-compile(export_all).
-define(NUM_DEFAULT_SERVICES, 1).
--define(FTP_HOST,"tuor").
all(doc) ->
["Test suites for the inets application."];
@@ -35,14 +35,20 @@ all(suite) ->
[
app_test,
appup_test,
+ services_test,
+ httpd_reload
+ ].
+
+services_test(suite) ->
+ [
start_inets,
start_httpc,
start_httpd,
start_ftpc,
- start_tftpd,
- httpd_reload
+ start_tftpd
].
+
%%--------------------------------------------------------------------
%% Function: init_per_suite(Config) -> Config
%% Config - [tuple()]
@@ -139,40 +145,88 @@ start_httpc(suite) ->
[];
start_httpc(Config) when is_list(Config) ->
process_flag(trap_exit, true),
+ tsp("start_httpc -> entry with"
+ "~n Config: ~p", [Config]),
+
PrivDir = ?config(priv_dir, Config),
+
+ tsp("start_httpc -> start (empty) inets"),
ok = inets:start(),
+
+ tsp("start_httpc -> start httpc (as inets service) with profile foo"),
{ok, Pid0} = inets:start(httpc, [{profile, foo}]),
+
+ tsp("start_httpc -> check running services"),
Pids0 = [ServicePid || {_, ServicePid} <- inets:services()],
true = lists:member(Pid0, Pids0),
[_|_] = inets:services_info(),
+
+ tsp("start_httpc -> stop httpc"),
inets:stop(httpc, Pid0),
+
+ tsp("start_httpc -> sleep some"),
test_server:sleep(100),
+
+ tsp("start_httpc -> check running services"),
Pids1 = [ServicePid || {_, ServicePid} <- inets:services()],
false = lists:member(Pid0, Pids1),
+
+ tsp("start_httpc -> start httpc (stand-alone) with profile bar"),
{ok, Pid1} = inets:start(httpc, [{profile, bar}], stand_alone),
+
+ tsp("start_httpc -> check running services"),
Pids2 = [ServicePid || {_, ServicePid} <- inets:services()],
false = lists:member(Pid1, Pids2),
+
+ tsp("start_httpc -> stop httpc"),
ok = inets:stop(stand_alone, Pid1),
receive
{'EXIT', Pid1, shutdown} ->
ok
after 100 ->
- test_server:fail(stand_alone_not_shutdown)
+ tsf(stand_alone_not_shutdown)
end,
+
+ tsp("start_httpc -> stop inets"),
ok = inets:stop(),
+
+ tsp("start_httpc -> unload inets"),
application:load(inets),
+
+ tsp("start_httpc -> set inets environment (httpc profile foo)"),
application:set_env(inets, services, [{httpc,[{profile, foo},
{data_dir, PrivDir}]}]),
+
+ tsp("start_httpc -> start inets"),
ok = inets:start(),
+
+ tsp("start_httpc -> check running services"),
(?NUM_DEFAULT_SERVICES + 1) = length(inets:services()),
+
+ tsp("start_httpc -> unset inets env"),
application:unset_env(inets, services),
+
+ tsp("start_httpc -> stop inets"),
ok = inets:stop(),
+
+ tsp("start_httpc -> start (empty) inets"),
ok = inets:start(),
+
+ tsp("start_httpc -> start inets httpc service with profile foo"),
{ok, Pid3} = inets:start(httpc, [{profile, foo}]),
+
+ tsp("start_httpc -> stop inets service httpc with profile foo"),
ok = inets:stop(httpc, foo),
+
+ tsp("start_httpc -> check running services"),
Pids3 = [ServicePid || {_, ServicePid} <- inets:services()],
false = lists:member(Pid3, Pids3),
- ok = inets:stop().
+
+ tsp("start_httpc -> stop inets"),
+ ok = inets:stop(),
+
+ tsp("start_httpc -> done"),
+ ok.
%%-------------------------------------------------------------------------
@@ -191,11 +245,13 @@ start_httpd(Config) when is_list(Config) ->
i("start_httpd -> start inets"),
ok = inets:start(),
+
i("start_httpd -> start httpd service"),
{ok, Pid0} = inets:start(httpd, [{port, 0}, {ipfamily, inet} | HttpdConf]),
Pids0 = [ServicePid || {_, ServicePid} <- inets:services()],
true = lists:member(Pid0, Pids0),
[_|_] = inets:services_info(),
+
i("start_httpd -> stop httpd service"),
inets:stop(httpd, Pid0),
test_server:sleep(500),
@@ -310,30 +366,49 @@ start_ftpc(suite) ->
[];
start_ftpc(Config) when is_list(Config) ->
process_flag(trap_exit, true),
+ inets:disable_trace(),
+ inets:enable_trace(max, io, ftpc),
ok = inets:start(),
- case inets:start(ftpc, [{host, ?FTP_HOST}]) of
- {ok, Pid0} ->
- Pids0 = [ServicePid || {_, ServicePid} <- inets:services()],
- true = lists:member(Pid0, Pids0),
- [_|_] = inets:services_info(),
- inets:stop(ftpc, Pid0),
- test_server:sleep(100),
- Pids1 = [ServicePid || {_, ServicePid} <- inets:services()],
- false = lists:member(Pid0, Pids1),
- {ok, Pid1} = inets:start(ftpc, [{host, ?FTP_HOST}], stand_alone),
- Pids2 = [ServicePid || {_, ServicePid} <- inets:services()],
- false = lists:member(Pid1, Pids2),
- ok = inets:stop(stand_alone, Pid1),
- receive
- {'EXIT', Pid1, shutdown} ->
- ok
- after 100 ->
- test_server:fail(stand_alone_not_shutdown)
- end,
- ok = inets:stop();
- _ ->
- {skip, "Unable to reach test FTP server " ++ ?FTP_HOST}
+ try
+ begin
+ {_Tag, FtpdHost} = ftp_suite_lib:dirty_select_ftpd_host(Config),
+ case inets:start(ftpc, [{host, FtpdHost}]) of
+ {ok, Pid0} ->
+ Pids0 = [ServicePid || {_, ServicePid} <-
+ inets:services()],
+ true = lists:member(Pid0, Pids0),
+ [_|_] = inets:services_info(),
+ inets:stop(ftpc, Pid0),
+ test_server:sleep(100),
+ Pids1 = [ServicePid || {_, ServicePid} <-
+ inets:services()],
+ false = lists:member(Pid0, Pids1),
+ {ok, Pid1} =
+ inets:start(ftpc, [{host, FtpdHost}], stand_alone),
+ Pids2 = [ServicePid || {_, ServicePid} <-
+ inets:services()],
+ false = lists:member(Pid1, Pids2),
+ ok = inets:stop(stand_alone, Pid1),
+ receive
+ {'EXIT', Pid1, shutdown} ->
+ ok
+ after 100 ->
+ tsf(stand_alone_not_shutdown)
+ end,
+ ok = inets:stop(),
+ inets:disable_trace(),
+ ok;
+ _ ->
+ inets:disable_trace(),
+ {skip, "Unable to reach selected FTP server " ++ FtpdHost}
+ end
+ end
+ catch
+ throw:{error, not_found} ->
+ inets:disable_trace(),
+ {skip, "No available FTP servers"}
end.
+
%%-------------------------------------------------------------------------
@@ -478,15 +553,24 @@ httpd_reload(Config) when is_list(Config) ->
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]).
+
i(F) ->
i(F, []).
i(F, A) ->
Timestamp = formated_timestamp(),
- io:format("*** ~s ~w:~w:" ++ F ++ "~n", [Timestamp, ?MODULE, ?LINE | A]).
+ io:format("*** ~s ~w:" ++ F ++ "~n", [Timestamp, ?MODULE | A]).
formated_timestamp() ->
- format_timestamp( now() ).
+ format_timestamp( os:timestamp() ).
format_timestamp({_N1, _N2, N3} = Now) ->
{Date, Time} = calendar:now_to_datetime(Now),
@@ -496,3 +580,4 @@ format_timestamp({_N1, _N2, N3} = Now) ->
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/test/inets_sup_SUITE.erl b/lib/inets/test/inets_sup_SUITE.erl
index 755ab594ed..ba41e0960c 100644
--- a/lib/inets/test/inets_sup_SUITE.erl
+++ b/lib/inets/test/inets_sup_SUITE.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2004-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2004-2010. 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
%% 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.
-%%
+%%
%% %CopyrightEnd%
%%
%%
@@ -26,8 +26,6 @@
%% Note: This directive should only be used in test suites.
-compile(export_all).
--define(FTP_HOST, "tuor").
-
all(doc) ->
["Test that the inets supervisorstructur is the expected one."];
all(suite) ->
@@ -223,20 +221,34 @@ ftpc_worker(doc) ->
ftpc_worker(suite) ->
[];
ftpc_worker(Config) when is_list(Config) ->
+ inets:disable_trace(),
+ inets:enable_trace(max, io, ftpc),
[] = supervisor:which_children(ftp_sup),
- case inets:start(ftpc, [{host, ?FTP_HOST}]) of
- {ok, Pid} ->
- case supervisor:which_children(ftp_sup) of
- [{_,_, worker, [ftp]}] ->
- inets:stop(ftpc, Pid),
- test_server:sleep(5000),
- [] = supervisor:which_children(ftp_sup),
- ok;
- Children ->
- exit({unexpected_children, Children})
- end;
- _ ->
- {skip, "Unable to reach test FTP server"}
+ try
+ begin
+ {_Tag, FtpdHost} = ftp_suite_lib:dirty_select_ftpd_host(Config),
+ case inets:start(ftpc, [{host, FtpdHost}]) of
+ {ok, Pid} ->
+ case supervisor:which_children(ftp_sup) of
+ [{_,_, worker, [ftp]}] ->
+ inets:stop(ftpc, Pid),
+ test_server:sleep(5000),
+ [] = supervisor:which_children(ftp_sup),
+ inets:disable_trace(),
+ ok;
+ Children ->
+ inets:disable_trace(),
+ exit({unexpected_children, Children})
+ end;
+ _ ->
+ inets:disable_trace(),
+ {skip, "Unable to reach test FTP server"}
+ end
+ end
+ catch
+ throw:{error, not_found} ->
+ inets:disable_trace(),
+ {skip, "No available FTP servers"}
end.
@@ -252,7 +264,7 @@ tftpd_worker(Config) when is_list(Config) ->
{ok, Pid0} = inets:start(tftpd, [{host, "localhost"},
{port, inet_port()}]),
{ok, _Pid1} = inets:start(tftpd, [{host, "localhost"},
- {port, inet_port()}], stand_alone),
+ {port, inet_port()}], stand_alone),
[{_,Pid0, worker, _}] = supervisor:which_children(tftp_sup),
inets:stop(tftpd, Pid0),
@@ -356,25 +368,33 @@ httpc_subtree(doc) ->
httpc_subtree(suite) ->
[];
httpc_subtree(Config) when is_list(Config) ->
- io:format("httpd_subtree -> entry with"
- "~n Config: ~p"
- "~n", [Config]),
+ tsp("httpc_subtree -> entry with"
+ "~n Config: ~p", [Config]),
+ tsp("httpc_subtree -> start inets service httpc with profile foo"),
{ok, Foo} = inets:start(httpc, [{profile, foo}]),
- io:format("httpc_subtree -> foo started~n", []),
+
+ tsp("httpc_subtree -> "
+ "start stand-alone inets service httpc with profile bar"),
{ok, Bar} = inets:start(httpc, [{profile, bar}], stand_alone),
- io:format("httpc_subtree -> bar started~n", []),
-
+
+ tsp("httpc_subtree -> retreive list of httpc instances"),
HttpcChildren = supervisor:which_children(httpc_profile_sup),
- io:format("httpc_subtree -> HttpcChildren: ~p~n", [HttpcChildren]),
+ tsp("httpc_subtree -> HttpcChildren: ~n~p", [HttpcChildren]),
- {value, {httpc_manager, _, worker,[httpc_manager]}} =
+ tsp("httpc_subtree -> verify httpc stand-alone instances"),
+ {value, {httpc_manager, _, worker, [httpc_manager]}} =
lists:keysearch(httpc_manager, 1, HttpcChildren),
- {value,{{http,foo}, Pid, worker,[httpc_manager]}} =
- lists:keysearch({http, foo}, 1, HttpcChildren),
- false = lists:keysearch({http, bar}, 1, HttpcChildren),
+
+ tsp("httpc_subtree -> verify httpc (named) instances"),
+ {value,{{httpc,foo}, Pid, worker, [httpc_manager]}} =
+ lists:keysearch({httpc, foo}, 1, HttpcChildren),
+ false = lists:keysearch({httpc, bar}, 1, HttpcChildren),
+ tsp("httpc_subtree -> stop inets"),
inets:stop(httpc, Pid),
+
+ tsp("httpc_subtree -> done"),
ok.
inet_port() ->
@@ -384,3 +404,11 @@ inet_port() ->
Port.
+tsp(F) ->
+ tsp(F, []).
+tsp(F, A) ->
+ test_server:format("~p ~p:" ++ F ++ "~n", [self(), ?MODULE | A]).
+
+tsf(Reason) ->
+ test_server:fail(Reason).
+