aboutsummaryrefslogtreecommitdiffstats
path: root/lib/inets
diff options
context:
space:
mode:
Diffstat (limited to 'lib/inets')
-rw-r--r--lib/inets/doc/src/http_server.xml188
-rw-r--r--lib/inets/examples/httpd_load_test/hdlt_random_html.erl7
-rw-r--r--lib/inets/src/ftp/ftp.erl12
-rw-r--r--lib/inets/src/http_client/httpc_handler.erl32
-rw-r--r--lib/inets/src/http_server/Makefile1
-rw-r--r--lib/inets/src/http_server/httpd_conf.erl11
-rw-r--r--lib/inets/src/http_server/mod_include.erl598
-rw-r--r--lib/inets/src/inets_app/Makefile6
-rw-r--r--lib/inets/src/inets_app/inets.app.src7
-rw-r--r--lib/inets/src/inets_app/inets_lib.erl49
-rw-r--r--lib/inets/src/inets_app/inets_time_compat.erl71
-rw-r--r--lib/inets/src/inets_app/inets_trace.erl32
-rw-r--r--lib/inets/src/tftp/tftp_logger.erl6
-rw-r--r--lib/inets/src/tftp/tftp_sup.erl4
-rw-r--r--lib/inets/test/erl_make_certs.erl10
-rw-r--r--lib/inets/test/ftp_suite_lib.erl8
-rw-r--r--lib/inets/test/httpc_SUITE.erl44
-rw-r--r--lib/inets/test/httpd_SUITE.erl58
-rw-r--r--lib/inets/test/httpd_SUITE_data/server_root/config/mime.types4
-rw-r--r--lib/inets/test/httpd_time_test.erl49
-rw-r--r--lib/inets/test/inets_SUITE.erl19
-rw-r--r--lib/inets/test/inets_app_test.erl67
-rw-r--r--lib/inets/test/inets_test_lib.erl23
-rw-r--r--lib/inets/test/old_httpd_SUITE.erl6
-rw-r--r--lib/inets/vsn.mk4
25 files changed, 280 insertions, 1036 deletions
diff --git a/lib/inets/doc/src/http_server.xml b/lib/inets/doc/src/http_server.xml
index e3b763b4f3..65e89db391 100644
--- a/lib/inets/doc/src/http_server.xml
+++ b/lib/inets/doc/src/http_server.xml
@@ -46,8 +46,7 @@
Layer), ESI (Erlang Scripting Interface), CGI (Common Gateway
Interface), User Authentication(using Mnesia, dets or plain text
database), Common Logfile Format (with or without disk_log(3)
- support), URL Aliasing, Action Mappings, Directory Listings and SSI
- (Server-Side Includes).</p>
+ support), URL Aliasing, Action Mappings, and Directory Listings</p>
<p>The configuration of the server is provided as an erlang
property list, and for backwards compatibility also a configuration
@@ -478,170 +477,9 @@ http://your.server.org/eval?httpd_example:print(atom_to_list(apply(erlang,halt,[
</p>
<p><em>[date]</em> access to <em>path</em> failed for
<em>remotehost</em>, reason: <em>reason</em></p>
-
- <marker id="ssi"></marker>
</section>
-
+
<section>
- <title>Server Side Includes</title>
- <p>Server Side Includes enables the server to run code embedded
- in HTML pages to generate the response to the client.</p>
- <note>
- <p>Having the server parse HTML pages is a double edged sword!
- It can be costly for a heavily loaded server to perform
- parsing of HTML pages while sending them. Furthermore, it can
- be considered a security risk to have average users executing
- commands in the name of the Erlang node user. Carefully
- consider these items before activating server-side includes.</p>
- </note>
-
- <section>
- <marker id="ssi_setup"></marker>
- <title>SERVER-SIDE INCLUDES (SSI) SETUP</title>
- <p>The server must be told which filename extensions to be used
- for the parsed files. These files, while very similar to HTML,
- are not HTML and are thus not treated the same. Internally, the
- server uses the magic MIME type <c>text/x-server-parsed-html</c>
- to identify parsed documents. It will then perform a format
- conversion to change these files into HTML for the
- client. Update the <c>mime.types</c> file, as described in the
- Mime Type Settings, to tell the server which extension to use
- for parsed files, for example:
- </p>
- <pre>
- text/x-server-parsed-html shtml shtm
- </pre>
- <p>This makes files ending with <c>.shtml</c> and <c>.shtm</c>
- into parsed files. Alternatively, if the performance hit is not a
- problem, <em>all</em> HTML pages can be marked as parsed:
- </p>
- <pre>
- text/x-server-parsed-html html htm
- </pre>
- </section>
-
- <section>
- <marker id="ssi_format"></marker>
- <title>Server-Side Includes (SSI) Format</title>
- <p>All server-side include directives to the server are formatted
- as SGML comments within the HTML page. This is in case the
- document should ever find itself in the client's hands
- unparsed. Each directive has the following format:
- </p>
- <pre>
- &lt;!--#command tag1="value1" tag2="value2" --&gt;
- </pre>
- <p>Each command takes different arguments, most only accept one
- tag at a time. Here is a breakdown of the commands and their
- associated tags:
- </p>
- <p>The config directive controls various aspects of the
- file parsing. There are two valid tags:
- </p>
- <taglist>
- <tag><c>errmsg</c></tag>
- <item>
- <p>controls the message sent back to the client if an
- error occurred while parsing the document. All errors are
- logged in the server's error log.</p>
- </item>
- <tag><c>sizefmt</c></tag>
- <item>
- <p>determines the format used to display the size of
- a file. Valid choices are <c>bytes</c> or
- <c>abbrev</c>. <c>bytes</c> for a formatted byte count
- or <c>abbrev</c> for an abbreviated version displaying
- the number of kilobytes.</p>
- </item>
- </taglist>
- <p>The include directory
- will insert the text of a document into the parsed
- document. This command accepts two tags:</p>
- <taglist>
- <tag><c>virtual</c></tag>
- <item>
- <p>gives a virtual path to a document on the
- server. Only normal files and other parsed documents can
- be accessed in this way.</p>
- </item>
- <tag><c>file</c></tag>
- <item>
- <p>gives a pathname relative to the current
- directory. <c>../</c> cannot be used in this pathname, nor
- can absolute paths. As above, you can send other parsed
- documents, but you cannot send CGI scripts.</p>
- </item>
- </taglist>
- <p>The echo directive prints the value of one of the include
- variables (defined below). The only valid tag to this
- command is <c>var</c>, whose value is the name of the
- variable you wish to echo.</p>
- <p>The fsize directive prints the size of the specified
- file. Valid tags are the same as with the <c>include</c>
- command. The resulting format of this command is subject
- to the <c>sizefmt</c> parameter to the <c>config</c>
- command.</p>
- <p>The lastmod directive prints the last modification date of
- the specified file. Valid tags are the same as with the
- <c>include</c> command.</p>
- <p>The exec directive executes a given shell command or CGI
- script. Valid tags are:</p>
- <taglist>
- <tag><c>cmd</c></tag>
- <item>
- <p>executes the given string using <c>/bin/sh</c>. All
- of the variables defined below are defined, and can be
- used in the command.</p>
- </item>
- <tag><c>cgi</c></tag>
- <item>
- <p>executes the given virtual path to a CGI script and
- includes its output. The server does not perform error
- checking on the script output.</p>
- </item>
- </taglist>
- </section>
-
- <section>
- <marker id="ssi_environment_variables"></marker>
- <title>Server-Side Includes (SSI) Environment Variables</title>
- <p>A number of variables are made available to parsed
- documents. In addition to the CGI variable set, the following
- variables are made available:
- </p>
- <taglist>
- <tag><c>DOCUMENT_NAME</c></tag>
- <item>
- <p>The current filename.</p>
- </item>
- <tag><c>DOCUMENT_URI</c></tag>
- <item>
- <p>The virtual path to this document (such as
- <c>/docs/tutorials/foo.shtml</c>).</p>
- </item>
- <tag><c>QUERY_STRING_UNESCAPED</c></tag>
- <item>
- <p>The unescaped version of any search query the client
- sent, with all shell-special characters escaped with
- <c>\</c>.</p>
- </item>
- <tag><c>DATE_LOCAL</c></tag>
- <item>
- <p>The current date, local time zone.</p>
- </item>
- <tag><c>DATE_GMT</c></tag>
- <item>
- <p>Same as DATE_LOCAL but in Greenwich mean time.</p>
- </item>
- <tag><c>LAST_MODIFIED</c></tag>
- <item>
- <p>The last modification date of the current document.</p>
- </item>
- </taglist>
- </section>
- </section>
-
- <section>
<title>The Erlang Web Server API</title>
<p>The process of handling a HTTP request involves several steps
such as:</p>
@@ -907,28 +745,6 @@ start() ->
</taglist>
</section>
- <section>
- <title>mod_include - SSI</title>
- <p>This module makes it possible to expand "macros" embedded in
- HTML pages before they are delivered to the client, that is
- Server-Side Includes (SSI).
- </p>
- <p>Uses the following Erlang Webserver API interaction data:
- </p>
- <list type="bulleted">
- <item>real_name - from mod_alias</item>
- <item>remote_user - from mod_auth</item>
- </list>
- <p>Exports the following Erlang Webserver API interaction data:
- </p>
- <taglist>
- <tag><c>{mime_type, MimeType}</c></tag>
- <item>The file suffix of the incoming URL mapped into a
- <c>MimeType</c> as defined in the Mime Type Settings
- section.</item>
- </taglist>
- </section>
-
<section>
<title>mod_log - Logging Using Text Files.</title>
<p>Standard logging using the "Common Logfile Format" and text
diff --git a/lib/inets/examples/httpd_load_test/hdlt_random_html.erl b/lib/inets/examples/httpd_load_test/hdlt_random_html.erl
index e3a572c61f..59073a3d23 100644
--- a/lib/inets/examples/httpd_load_test/hdlt_random_html.erl
+++ b/lib/inets/examples/httpd_load_test/hdlt_random_html.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2010. All Rights Reserved.
+%% Copyright Ericsson AB 2010-2015. 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
@@ -48,7 +48,10 @@ stop() ->
".
content(WorkSim, SzSim) ->
- {A, B, C} = now(),
+ {A, B, C} = {erlang:phash2([node()]),
+ inets_time_compat:monotonic_time(),
+ inets_time_compat:unique_integer()},
+
random:seed(A, B, C),
lists:sort([random:uniform(X) || X <- lists:seq(1, WorkSim)]),
lists:flatten(lists:duplicate(SzSim, "Dummy data ")).
diff --git a/lib/inets/src/ftp/ftp.erl b/lib/inets/src/ftp/ftp.erl
index 8e51b1be5a..7eebe8d5bf 100644
--- a/lib/inets/src/ftp/ftp.erl
+++ b/lib/inets/src/ftp/ftp.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2013. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2015. 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
@@ -2176,16 +2176,16 @@ handle_caller(#state{caller = {transfer_data, {Cmd, Bin, RemoteFile}}} =
%% Connect to FTP server at Host (default is TCP port 21)
%% in order to establish a control connection.
setup_ctrl_connection(Host, Port, Timeout, State) ->
- MsTime = millisec_time(),
+ MsTime = inets_time_compat:monotonic_time(),
case connect(Host, Port, Timeout, State) of
{ok, IpFam, CSock} ->
NewState = State#state{csock = {tcp, CSock}, ipfamily = IpFam},
activate_ctrl_connection(NewState),
- case Timeout - (millisec_time() - MsTime) of
+ case Timeout - inets_lib:millisec_passed(MsTime) of
Timeout2 when (Timeout2 >= 0) ->
{ok, NewState#state{caller = open}, Timeout2};
_ ->
- %% Oups: Simulate timeout
+ %% Oups: Simulate timeout
{ok, NewState#state{caller = open}, 0}
end;
Error ->
@@ -2501,10 +2501,6 @@ progress_report(Report, #state{progress = ProgressPid}) ->
ftp_progress:report(ProgressPid, Report).
-millisec_time() ->
- {A,B,C} = erlang:now(),
- A*1000000000+B*1000+(C div 1000).
-
peername({tcp, Socket}) -> inet:peername(Socket);
peername({ssl, Socket}) -> ssl:peername(Socket).
diff --git a/lib/inets/src/http_client/httpc_handler.erl b/lib/inets/src/http_client/httpc_handler.erl
index 0bbd40d656..f4f0c37570 100644
--- a/lib/inets/src/http_client/httpc_handler.erl
+++ b/lib/inets/src/http_client/httpc_handler.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2002-2014. All Rights Reserved.
+%% Copyright Ericsson AB 2002-2015. 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
@@ -87,7 +87,7 @@
%% block the httpc manager process in odd cases such as trying to call
%% a server that does not exist. (See OTP-6735) The only API function
%% sending messages to the handler process that can be called before
-%% init has compleated is cancel and that is not a problem! (Send and
+%% init has completed is cancel and that is not a problem! (Send and
%% stream will not be called before the first request has been sent and
%% the reply or part of it has arrived.)
%%--------------------------------------------------------------------
@@ -316,8 +316,9 @@ handle_call(#request{address = Addr} = Request, _,
{reply, ok, State}
end;
{error, Reason} ->
- ?hcri("failed sending request", [{reason, Reason}]),
- {reply, {pipeline_failed, Reason}, State0}
+ ?hcri("failed sending request", [{reason, Reason}]),
+ NewPipeline = queue:in(Request, State0#state.pipeline),
+ {stop, shutdown, {pipeline_failed, Reason}, State0#state{pipeline = NewPipeline}}
end;
handle_call(#request{address = Addr} = Request, _,
@@ -355,25 +356,25 @@ handle_call(#request{address = Addr} = Request, _,
?hcrd("no current request", []),
cancel_timer(Timers#timers.queue_timer,
timeout_queue),
+ NewTimers = Timers#timers{queue_timer = undefined},
+ State1 = State0#state{timers = NewTimers},
Address = handle_proxy(Addr, Proxy),
case httpc_request:send(Address, Session, Request) of
ok ->
?hcrd("request sent", []),
%% Activate the request time out for the new request
- State1 =
- activate_request_timeout(State0#state{request = Request}),
- NewTimers = State1#state.timers,
+ State2 =
+ activate_request_timeout(State1#state{request = Request}),
NewSession =
Session#session{queue_length = 1,
client_close = ClientClose},
insert_session(NewSession, ProfileName),
- State = init_wait_for_response_state(Request, State1#state{session = NewSession,
- timers = NewTimers}),
+ State = init_wait_for_response_state(Request, State2#state{session = NewSession}),
{reply, ok, State};
{error, Reason} ->
?hcri("failed sending request", [{reason, Reason}]),
- {reply, {request_failed, Reason}, State0}
+ {stop, shutdown, {keepalive_failed, Reason}, State1}
end
end;
@@ -391,7 +392,7 @@ handle_call(info, _, State) ->
%% When the request in process has been canceled the handler process is
%% stopped and the pipelined requests will be reissued or remaining
%% requests will be sent on a new connection. This is is
-%% based on the assumption that it is proably cheaper to reissue the
+%% based on the assumption that it is probably cheaper to reissue the
%% requests than to wait for a potentiall large response that we then
%% only throw away. This of course is not always true maybe we could
%% do something smarter here?! If the request canceled is not
@@ -1121,7 +1122,7 @@ handle_http_body(Body, #state{headers = Headers,
handle_response(State#state{headers = NewHeaders,
body = NewBody});
_ ->
- {NewBody2, NewRequest} =
+ {NewBody2, _NewRequest} =
stream(NewBody, Request, Code),
handle_response(State#state{headers = NewHeaders,
body = NewBody2})
@@ -1329,7 +1330,7 @@ handle_keep_alive_queue(#state{status = keep_alive,
Session, <<>>,
State#state{keep_alive = KeepAlive});
{error, Reason} ->
- {reply, {keep_alive_failed, Reason}, State}
+ {stop, shutdown, {keepalive_failed, Reason}, State}
end
end
end.
@@ -1344,7 +1345,7 @@ handle_empty_queue(Session, ProfileName, TimeOut, State) ->
%% closed by the server, the client may want to close it.
NewState = activate_queue_timeout(TimeOut, State),
update_session(ProfileName, Session, #session.queue_length, 0),
- %% Note mfa will be initilized when a new request
+ %% Note mfa will be initialized when a new request
%% arrives.
{noreply,
NewState#state{request = undefined,
@@ -1850,6 +1851,7 @@ update_session(ProfileName, #session{id = SessionId} = Session, Pos, Value) ->
Session2 = erlang:setelement(Pos, Session, Value),
insert_session(Session2, ProfileName);
T:E ->
+ Stacktrace = erlang:get_stacktrace(),
error_logger:error_msg("Failed updating session: "
"~n ProfileName: ~p"
"~n SessionId: ~p"
@@ -1873,7 +1875,7 @@ update_session(ProfileName, #session{id = SessionId} = Session, Pos, Value) ->
{value, Value},
{etype, T},
{error, E},
- {stacktrace, erlang:get_stacktrace()}]})
+ {stacktrace, Stacktrace}]})
end.
diff --git a/lib/inets/src/http_server/Makefile b/lib/inets/src/http_server/Makefile
index 2660d04d16..51e3dd9212 100644
--- a/lib/inets/src/http_server/Makefile
+++ b/lib/inets/src/http_server/Makefile
@@ -75,7 +75,6 @@ MODULES = \
mod_get \
mod_head \
mod_htaccess \
- mod_include \
mod_log \
mod_range \
mod_responsecontrol \
diff --git a/lib/inets/src/http_server/httpd_conf.erl b/lib/inets/src/http_server/httpd_conf.erl
index dbdc1be272..a21eb915d4 100644
--- a/lib/inets/src/http_server/httpd_conf.erl
+++ b/lib/inets/src/http_server/httpd_conf.erl
@@ -785,8 +785,15 @@ fix_mime_types(ConfigList0) ->
[{"html","text/html"},{"htm","text/html"}]}
| ConfigList0]
end;
- _ ->
- ConfigList0
+ MimeTypes ->
+ case filelib:is_file(MimeTypes) of
+ true ->
+ {ok, MimeTypesList} = load_mime_types(MimeTypes),
+ ConfigList = proplists:delete(mime_types, ConfigList0),
+ [{mime_types, MimeTypesList} | ConfigList];
+ false ->
+ ConfigList0
+ end
end.
store({mime_types,MimeTypesList},ConfigList) ->
diff --git a/lib/inets/src/http_server/mod_include.erl b/lib/inets/src/http_server/mod_include.erl
deleted file mode 100644
index 35f45bdd33..0000000000
--- a/lib/inets/src/http_server/mod_include.erl
+++ /dev/null
@@ -1,598 +0,0 @@
-%%
-%% %CopyrightBegin%
-%%
-%% 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%
-%%
-%%
--module(mod_include).
--export([do/1,parse/2,config/6,include/6,echo/6,fsize/6,flastmod/6,exec/6]).
-
--include("httpd.hrl").
--include("httpd_internal.hrl").
-
--define(VMODULE,"INCLUDE").
-
-%% do
-
-do(Info) ->
- case Info#mod.method of
- "GET" ->
- case proplists:get_value(status, Info#mod.data) of
- %% A status code has been generated!
- {_StatusCode, _PhraseArgs, _Reason} ->
- {proceed,Info#mod.data};
- %% No status code has been generated!
- undefined ->
- case proplists:get_value(response, Info#mod.data) of
- %% No response has been generated!
- undefined ->
- do_include(Info);
- %% A response has been generated or sent!
- _Response ->
- {proceed,Info#mod.data}
- end
- end;
- %% Not a GET method!
- _ ->
- {proceed,Info#mod.data}
- end.
-
-do_include(Info) ->
- Path = mod_alias:path(Info#mod.data,Info#mod.config_db,
- Info#mod.request_uri),
- Suffix = httpd_util:suffix(Path),
- case httpd_util:lookup_mime_default(Info#mod.config_db,Suffix) of
- "text/x-server-parsed-html" ->
- HeaderStart = [{content_type, "text/html"}],
- case send_in(Info, Path, HeaderStart, file:read_file_info(Path)) of
- {ok, ErrorLog, Size} ->
- {proceed, [{response, {already_sent, 200, Size}},
- {mime_type, "text/html"} |
- lists:append(ErrorLog, Info#mod.data)]};
- {error, Reason} ->
- {proceed,
- [{status,send_error(Reason,Info,Path)}|Info#mod.data]}
- end;
- _ -> %% Unknown mime type, ignore
- {proceed,Info#mod.data}
- end.
-
-
-%%
-%% config directive
-%%
-
-config(_Info, Context, ErrorLog, TagList, ValueList, R) ->
- case verify_tags("config",[errmsg,timefmt,sizefmt],
- TagList,ValueList) of
- ok ->
- {ok,update_context(TagList,ValueList,Context),ErrorLog,"",R};
- {error,Reason} ->
- {ok,Context,[{internal_info,Reason}|ErrorLog],
- proplists:get_value(errmsg,Context,""),R}
- end.
-
-update_context([],[],Context) ->
- Context;
-update_context([Tag|R1],[Value|R2],Context) ->
- update_context(R1,R2,[{Tag,Value}|Context]).
-
-verify_tags(Command,ValidTags,TagList,ValueList)
- when length(TagList) =:= length(ValueList) ->
- verify_tags(Command, ValidTags, TagList);
-verify_tags(Command, _ValidTags, _TagList, _ValueList) ->
- {error, ?NICE(Command ++ " directive has spurious tags")}.
-
-verify_tags(_Command, _ValidTags, []) ->
- ok;
-verify_tags(Command, ValidTags, [Tag|Rest]) ->
- case lists:member(Tag, ValidTags) of
- true ->
- verify_tags(Command, ValidTags, Rest);
- false ->
- {error, ?NICE(Command++" directive has a spurious tag ("++
- atom_to_list(Tag)++")")}
- end.
-
-%%
-%% include directive
-%%
-
-include(Info,Context,ErrorLog,[virtual],[VirtualPath],R) ->
- Aliases = httpd_util:multi_lookup(Info#mod.config_db,alias),
- {_, Path, _AfterPath} =
- mod_alias:real_name(Info#mod.config_db, VirtualPath, Aliases),
- include(Info,Context,ErrorLog,R,Path);
-include(Info, Context, ErrorLog, [file], [FileName], R) ->
- Path = file(Info#mod.config_db, Info#mod.request_uri, FileName),
- include(Info, Context, ErrorLog, R, Path);
-include(_Info, Context, ErrorLog, _TagList, _ValueList, R) ->
- {ok, Context,
- [{internal_info,?NICE("include directive has a spurious tag")}|
- ErrorLog], proplists:get_value(errmsg, Context, ""), R}.
-
-include(Info, Context, ErrorLog, R, Path) ->
- case file:read_file(Path) of
- {ok, Body} ->
- {ok, NewContext, NewErrorLog, Result} =
- parse(Info, binary_to_list(Body), Context, ErrorLog, []),
- {ok, NewContext, NewErrorLog, Result, R};
- {error, _Reason} ->
- {ok, Context,
- [{internal_info, ?NICE("Can't open "++Path)}|ErrorLog],
- proplists:get_value(errmsg, Context, ""), R}
- end.
-
-file(ConfigDB, RequestURI, FileName) ->
- Aliases = httpd_util:multi_lookup(ConfigDB, alias),
- {_, Path, _AfterPath}
- = mod_alias:real_name(ConfigDB, RequestURI, Aliases),
- Pwd = filename:dirname(Path),
- filename:join(Pwd, FileName).
-
-%%
-%% echo directive
-%%
-
-echo(Info,Context,ErrorLog,[var],["DOCUMENT_NAME"],R) ->
- {ok,Context,ErrorLog,document_name(Info#mod.data,Info#mod.config_db,
- Info#mod.request_uri),R};
-echo(Info,Context,ErrorLog,[var],["DOCUMENT_URI"],R) ->
- {ok,Context,ErrorLog,document_uri(Info#mod.config_db,
- Info#mod.request_uri),R};
-echo(Info,Context,ErrorLog,[var],["QUERY_STRING_UNESCAPED"],R) ->
- {ok,Context,ErrorLog,query_string_unescaped(Info#mod.request_uri),R};
-echo(_Info,Context,ErrorLog,[var],["DATE_LOCAL"],R) ->
- {ok,Context,ErrorLog,date_local(),R};
-echo(_Info,Context,ErrorLog,[var],["DATE_GMT"],R) ->
- {ok,Context,ErrorLog,date_gmt(),R};
-echo(Info,Context,ErrorLog,[var],["LAST_MODIFIED"],R) ->
- {ok,Context,ErrorLog,last_modified(Info#mod.data,Info#mod.config_db,
- Info#mod.request_uri),R};
-echo(_Info, Context, ErrorLog, _TagList, _ValueList, R) ->
- {ok,Context,
- [{internal_info,?NICE("echo directive has a spurious tag")}|
- ErrorLog],"(none)",R}.
-
-document_name(Data,ConfigDB,RequestURI) ->
- Path = mod_alias:path(Data,ConfigDB,RequestURI),
- case inets_regexp:match(Path,"[^/]*\$") of
- {match,Start,Length} ->
- string:substr(Path,Start,Length);
- nomatch ->
- "(none)"
- end.
-
-document_uri(ConfigDB, RequestURI) ->
- Aliases = httpd_util:multi_lookup(ConfigDB, alias),
-
- {_, Path, AfterPath} = mod_alias:real_name(ConfigDB, RequestURI, Aliases),
-
- VirtualPath = string:substr(RequestURI, 1,
- length(RequestURI)-length(AfterPath)),
- {match, Start, Length} = inets_regexp:match(Path,"[^/]*\$"),
- FileName = string:substr(Path,Start,Length),
- case inets_regexp:match(VirtualPath, FileName++"\$") of
- {match, _, _} ->
- http_uri:decode(VirtualPath)++AfterPath;
- nomatch ->
- string:strip(http_uri:decode(VirtualPath),right,$/)++
- "/"++FileName++AfterPath
- end.
-
-query_string_unescaped(RequestURI) ->
- case inets_regexp:match(RequestURI,"[\?].*\$") of
- {match,Start,Length} ->
- %% Escape all shell-special variables with \
- escape(string:substr(RequestURI,Start+1,Length-1));
- nomatch ->
- "(none)"
- end.
-
-escape([]) -> [];
-escape([$;|R]) -> [$\\,$;|escape(R)];
-escape([$&|R]) -> [$\\,$&|escape(R)];
-escape([$(|R]) -> [$\\,$(|escape(R)];
-escape([$)|R]) -> [$\\,$)|escape(R)];
-escape([$||R]) -> [$\\,$||escape(R)];
-escape([$^|R]) -> [$\\,$^|escape(R)];
-escape([$<|R]) -> [$\\,$<|escape(R)];
-escape([$>|R]) -> [$\\,$>|escape(R)];
-escape([$\n|R]) -> [$\\,$\n|escape(R)];
-escape([$ |R]) -> [$\\,$ |escape(R)];
-escape([$\t|R]) -> [$\\,$\t|escape(R)];
-escape([C|R]) -> [C|escape(R)].
-
-date_local() ->
- {{Year,Month,Day},{Hour,Minute,Second}}=calendar:local_time(),
- %% Time format hard-wired to: "%a %b %e %T %Y" according to strftime(3)
- io_lib:format("~s ~s ~2w ~2.2.0w:~2.2.0w:~2.2.0w ~w",
- [httpd_util:day(calendar:day_of_the_week(Year,Month,Day)),
- httpd_util:month(Month),Day,Hour,Minute,Second,Year]).
-
-date_gmt() ->
- {{Year,Month,Day},{Hour,Minute,Second}}=calendar:universal_time(),
- %% Time format hard-wired to: "%a %b %e %T %Z %Y" according to strftime(3)
- io_lib:format("~s ~s ~2w ~2.2.0w:~2.2.0w:~2.2.0w GMT ~w",
- [httpd_util:day(calendar:day_of_the_week(Year,Month,Day)),
- httpd_util:month(Month),Day,Hour,Minute,Second,Year]).
-
-last_modified(Data,ConfigDB,RequestURI) ->
- {ok,FileInfo}=file:read_file_info(mod_alias:path(Data,ConfigDB,RequestURI)),
- {{Year,Month,Day},{Hour,Minute,Second}}=FileInfo#file_info.mtime,
- io_lib:format("~s ~s ~2w ~2.2.0w:~2.2.0w:~2.2.0w ~w",
- [httpd_util:day(calendar:day_of_the_week(Year,Month,Day)),
- httpd_util:month(Month),Day,Hour,Minute,Second,Year]).
-
-%%
-%% fsize directive
-%%
-
-fsize(Info,Context,ErrorLog,[virtual],[VirtualPath],R) ->
- Aliases = httpd_util:multi_lookup(Info#mod.config_db,alias),
- {_,Path, _AfterPath}=
- mod_alias:real_name(Info#mod.config_db,VirtualPath,Aliases),
- fsize(Info, Context, ErrorLog, R, Path);
-fsize(Info,Context,ErrorLog,[file],[FileName],R) ->
- Path = file(Info#mod.config_db,Info#mod.request_uri,FileName),
- fsize(Info,Context,ErrorLog,R,Path);
-fsize(_Info, Context, ErrorLog, _TagList, _ValueList, R) ->
- {ok,Context,[{internal_info,?NICE("fsize directive has a spurious tag")}|
- ErrorLog],proplists:get_value(errmsg,Context,""),R}.
-
-fsize(_Info, Context, ErrorLog, R, Path) ->
- case file:read_file_info(Path) of
- {ok,FileInfo} ->
- case proplists:get_value(sizefmt,Context) of
- "bytes" ->
- {ok,Context,ErrorLog,
- integer_to_list(FileInfo#file_info.size),R};
- "abbrev" ->
- Size = integer_to_list(trunc(FileInfo#file_info.size/1024+1))++"k",
- {ok,Context,ErrorLog,Size,R};
- Value->
- {ok,Context,
- [{internal_info,
- ?NICE("fsize directive has a spurious tag value ("++
- Value++")")}|
- ErrorLog],
- proplists:get_value(errmsg, Context, ""), R}
- end;
- {error, _Reason} ->
- {ok,Context,[{internal_info,?NICE("Can't open "++Path)}|ErrorLog],
- proplists:get_value(errmsg,Context,""),R}
- end.
-
-%%
-%% flastmod directive
-%%
-
-flastmod(#mod{config_db = Db} = Info,
- Context, ErrorLog, [virtual], [VirtualPath],R) ->
- Aliases = httpd_util:multi_lookup(Db,alias),
- {_,Path, _AfterPath} = mod_alias:real_name(Db, VirtualPath, Aliases),
- flastmod(Info,Context,ErrorLog,R,Path);
-flastmod(#mod{config_db = Db, request_uri = RequestUri} = Info,
- Context, ErrorLog, [file], [FileName], R) ->
- Path = file(Db, RequestUri, FileName),
- flastmod(Info, Context, ErrorLog, R, Path);
-flastmod(_Info, Context, ErrorLog, _TagList, _ValueList, R) ->
- {ok,Context,
- [{internal_info,?NICE("flastmod directive has a spurious tag")}|
- ErrorLog],proplists:get_value(errmsg,Context,""),R}.
-
-flastmod(_Info, Context, ErrorLog, R, File) ->
- case file:read_file_info(File) of
- {ok, FileInfo} ->
- {{Yr,Mon,Day},{Hour,Minute,Second}}=FileInfo#file_info.mtime,
- Result =
- io_lib:format("~s ~s ~2w ~w:~w:~w ~w",
- [httpd_util:day(
- calendar:day_of_the_week(Yr,Mon, Day)),
- httpd_util:month(Mon),Day,Hour,Minute,Second, Yr]),
- {ok, Context, ErrorLog, Result, R};
- {error, _Reason} ->
- {ok,Context,[{internal_info,?NICE("Can't open "++File)}|ErrorLog],
- proplists:get_value(errmsg,Context,""),R}
- end.
-
-%%
-%% exec directive
-%%
-
-exec(Info,Context,ErrorLog,[cmd],[Command],R) ->
- cmd(Info,Context,ErrorLog,R,Command);
-exec(Info,Context,ErrorLog,[cgi],[RequestURI],R) ->
- cgi(Info,Context,ErrorLog,R,RequestURI);
-exec(_Info, Context, ErrorLog, _TagList, _ValueList, R) ->
- {ok, Context,
- [{internal_info,?NICE("exec directive has a spurious tag")}|
- ErrorLog], proplists:get_value(errmsg,Context,""),R}.
-
-%% cmd
-
-cmd(Info, Context, ErrorLog, R, Command) ->
- process_flag(trap_exit,true),
- Env = env(Info),
- Dir = filename:dirname(Command),
- Port = (catch open_port({spawn,Command},[stream,{cd,Dir},{env,Env}])),
- case Port of
- P when is_port(P) ->
- {NewErrorLog, Result} = proxy(Port, ErrorLog),
- {ok, Context, NewErrorLog, Result, R};
- {'EXIT', Reason} ->
- exit({open_port_failed,Reason,
- [{uri,Info#mod.request_uri},{script,Command},
- {env,Env},{dir,Dir}]});
- O ->
- exit({open_port_failed,O,
- [{uri,Info#mod.request_uri},{script,Command},
- {env,Env},{dir,Dir}]})
- end.
-
-env(Info) ->
- [{"DOCUMENT_NAME",document_name(Info#mod.data,Info#mod.config_db,
- Info#mod.request_uri)},
- {"DOCUMENT_URI", document_uri(Info#mod.config_db, Info#mod.request_uri)},
- {"QUERY_STRING_UNESCAPED", query_string_unescaped(Info#mod.request_uri)},
- {"DATE_LOCAL", date_local()},
- {"DATE_GMT", date_gmt()},
- {"LAST_MODIFIED", last_modified(Info#mod.data, Info#mod.config_db,
- Info#mod.request_uri)}
- ].
-
-%% cgi
-
-cgi(Info, Context, ErrorLog, R, RequestURI) ->
- ScriptAliases = httpd_util:multi_lookup(Info#mod.config_db, script_alias),
- case mod_alias:real_script_name(Info#mod.config_db, RequestURI,
- ScriptAliases) of
- {Script, AfterScript} ->
- exec_script(Info,Script,AfterScript,ErrorLog,Context,R);
- not_a_script ->
- {ok, Context,
- [{internal_info, ?NICE(RequestURI++" is not a script")}|
- ErrorLog], proplists:get_value(errmsg, Context, ""),R}
- end.
-
-remove_header([]) ->
- [];
-remove_header([$\n,$\n|Rest]) ->
- Rest;
-remove_header([_C|Rest]) ->
- remove_header(Rest).
-
-
-exec_script(#mod{config_db = Db, request_uri = RequestUri} = Info,
- Script, _AfterScript, ErrorLog, Context, R) ->
- process_flag(trap_exit,true),
- Aliases = httpd_util:multi_lookup(Db, alias),
- {_, Path, AfterPath} = mod_alias:real_name(Db, RequestUri, Aliases),
- Env = env(Info) ++ mod_cgi:env(Info, Path, AfterPath),
- Dir = filename:dirname(Path),
- Port = (catch open_port({spawn,Script},[stream,{env, Env},{cd, Dir}])),
- case Port of
- P when is_port(P) ->
- %% Send entity body to port.
- Res = case Info#mod.entity_body of
- [] ->
- true;
- EntityBody ->
- (catch port_command(Port, EntityBody))
- end,
- case Res of
- {'EXIT', Reason} ->
- exit({open_cmd_failed,Reason,
- [{mod,?MODULE},{port,Port},
- {uri,RequestUri},
- {script,Script},{env,Env},{dir,Dir},
- {ebody_size,sz(Info#mod.entity_body)}]});
- true ->
- {NewErrorLog, Result} = proxy(Port, ErrorLog),
- {ok, Context, NewErrorLog, remove_header(Result), R}
- end;
- {'EXIT', Reason} ->
- exit({open_port_failed,Reason,
- [{mod,?MODULE},{uri,RequestUri},{script,Script},
- {env,Env},{dir,Dir}]});
- O ->
- exit({open_port_failed,O,
- [{mod,?MODULE},{uri,RequestUri},{script,Script},
- {env,Env},{dir,Dir}]})
- end.
-
-
-%%
-%% Port communication
-%%
-
-proxy(Port, ErrorLog) ->
- process_flag(trap_exit, true),
- proxy(Port, ErrorLog, []).
-
-proxy(Port, ErrorLog, Result) ->
- receive
- {Port, {data, Response}} ->
- proxy(Port, ErrorLog, lists:append(Result,Response));
- {'EXIT', Port, normal} when is_port(Port) ->
- process_flag(trap_exit, false),
- {ErrorLog, Result};
- {'EXIT', Port, _Reason} when is_port(Port) ->
- process_flag(trap_exit, false),
- {[{internal_info,
- ?NICE("Scrambled output from CGI-script")}|ErrorLog],
- Result};
- {'EXIT', Pid, Reason} when is_pid(Pid) ->
- process_flag(trap_exit, false),
- {'EXIT', Pid, Reason};
- %% This should not happen!
- _WhatEver ->
- process_flag(trap_exit, false),
- {ErrorLog, Result}
- end.
-
-
-%% ------
-%% Temporary until I figure out a way to fix send_in_chunks
-%% (comments and directives that start in one chunk but end
-%% in another is not handled).
-%%
-
-send_in(Info, Path, Head, {ok,FileInfo}) ->
- case file:read_file(Path) of
- {ok, Bin} ->
- send_in1(Info, binary_to_list(Bin), Head, FileInfo);
- {error, Reason} ->
- {error, {read,Reason}}
- end;
-send_in(_Info , _Path, _Head,{error,Reason}) ->
- {error, {open,Reason}}.
-
-send_in1(Info, Data, Head, FileInfo) ->
- {ok, _Context, Err, ParsedBody} = parse(Info,Data,?DEFAULT_CONTEXT,[],[]),
- Size = length(ParsedBody),
- LastModified = case catch httpd_util:rfc1123_date(FileInfo#file_info.mtime) of
- Date when is_list(Date) -> [{last_modified,Date}];
- _ -> []
- end,
- Head1 = case Info#mod.http_version of
- "HTTP/1.1"->
- Head ++ [{content_length, integer_to_list(Size)},
- {etag, httpd_util:create_etag(FileInfo,Size)}|
- LastModified];
- _->
- %% i.e http/1.0 and http/0.9
- Head ++ [{content_length, integer_to_list(Size)}|
- LastModified]
- end,
- httpd_response:send_header(Info, 200, Head1),
- httpd_socket:deliver(Info#mod.socket_type,Info#mod.socket, ParsedBody),
- {ok, Err, Size}.
-
-
-parse(Info,Body) ->
- parse(Info, Body, ?DEFAULT_CONTEXT, [], []).
-
-parse(_Info, [], Context, ErrorLog, Result) ->
- {ok, Context, lists:reverse(ErrorLog), lists:reverse(Result)};
-parse(Info,[$<,$!,$-,$-,$#|R1],Context,ErrorLog,Result) ->
- case catch parse0(R1,Context) of
- {parse_error,Reason} ->
- parse(Info,R1,Context,[{internal_info,?NICE(Reason)}|ErrorLog],
- [$#,$-,$-,$!,$<|Result]);
- {ok,Context,Command,TagList,ValueList,R2} ->
- {ok,NewContext,NewErrorLog,MoreResult,R3}=
- handle(Info,Context,ErrorLog,Command,TagList,ValueList,R2),
- parse(Info,R3,NewContext,NewErrorLog,
- lists:reverse(MoreResult)++Result)
- end;
-parse(Info,[$<,$!,$-,$-|R1],Context,ErrorLog,Result) ->
- case catch parse5(R1,[],0) of
- {parse_error,Reason} ->
- parse(Info,R1,Context,
- [{internal_info,?NICE(Reason)}|ErrorLog],Result);
- {Comment,R2} ->
- parse(Info,R2,Context,ErrorLog,Comment++Result)
- end;
-parse(Info,[C|R],Context,ErrorLog,Result) ->
- parse(Info,R,Context,ErrorLog,[C|Result]).
-
-handle(Info,Context,ErrorLog,Command,TagList,ValueList,R) ->
- case catch apply(?MODULE,Command,[Info,Context,ErrorLog,TagList,ValueList,
- R]) of
- {'EXIT',{undef,_}} ->
- throw({parse_error,"Unknown command "++atom_to_list(Command)++
- " in parsed doc"});
- Result ->
- Result
- end.
-
-parse0([], _Context) ->
- throw({parse_error,"Premature EOF in parsed file"});
-parse0([$-,$-,$>|_R], _Context) ->
- throw({parse_error,"Premature EOF in parsed file"});
-parse0([$ |R], Context) ->
- parse0(R,Context);
-parse0(String, Context) ->
- parse1(String, Context,"").
-
-parse1([], _Context, _Command) ->
- throw({parse_error,"Premature EOF in parsed file"});
-parse1([$-,$-,$>|_R], _Context, _Command) ->
- throw({parse_error,"Premature EOF in parsed file"});
-parse1([$ |R], Context, Command) ->
- parse2(R,Context,list_to_atom(lists:reverse(Command)),[],[],"");
-parse1([C|R], Context, Command) ->
- parse1(R,Context,[C|Command]).
-
-parse2([], _Context, _Command, _TagList, _ValueList, _Tag) ->
- throw({parse_error,"Premature EOF in parsed file"});
-parse2([$-,$-,$>|R], Context, Command, TagList, ValueList, _Tag) ->
- {ok,Context,Command,TagList,ValueList,R};
-parse2([$ |R],Context,Command,TagList,ValueList,Tag) ->
- parse2(R,Context,Command,TagList,ValueList,Tag);
-parse2([$=|R],Context,Command,TagList,ValueList,Tag) ->
- parse3(R,Context,Command,[list_to_atom(lists:reverse(Tag))|TagList],
- ValueList);
-parse2([C|R],Context,Command,TagList,ValueList,Tag) ->
- parse2(R,Context,Command,TagList,ValueList,[C|Tag]).
-
-parse3([], _Context, _Command, _TagList, _ValueList) ->
- throw({parse_error,"Premature EOF in parsed file"});
-parse3([$-,$-,$>|_R], _Context, _Command, _TagList, _ValueList) ->
- throw({parse_error,"Premature EOF in parsed file"});
-parse3([$ |R], Context, Command, TagList, ValueList) ->
- parse3(R, Context, Command, TagList, ValueList);
-parse3([$"|R], Context, Command, TagList, ValueList) ->
- parse4(R,Context,Command,TagList,ValueList,"");
-parse3(_String, _Context, _Command, _TagList, _ValueList) ->
- throw({parse_error,"Premature EOF in parsed file"}).
-
-parse4([], _Context, _Command, _TagList, _ValueList, _Value) ->
- throw({parse_error,"Premature EOF in parsed file"});
-parse4([$-,$-,$>|_R], _Context, _Command, _TagList, _ValueList, _Value) ->
- throw({parse_error,"Premature EOF in parsed file"});
-parse4([$"|R],Context,Command,TagList,ValueList,Value) ->
- parse2(R,Context,Command,TagList,[lists:reverse(Value)|ValueList],"");
-parse4([C|R],Context,Command,TagList,ValueList,Value) ->
- parse4(R,Context,Command,TagList,ValueList,[C|Value]).
-
-parse5([], _Comment, _Depth) ->
- throw({parse_error,"Premature EOF in parsed file"});
-parse5([$<,$!,$-,$-|R],Comment,Depth) ->
- parse5(R,[$-,$-,$!,$<|Comment],Depth+1);
-parse5([$-,$-,$>|R],Comment,0) ->
- {">--"++Comment++"--!<",R};
-parse5([$-,$-,$>|R],Comment,Depth) ->
- parse5(R,[$>,$-,$-|Comment],Depth-1);
-parse5([C|R],Comment,Depth) ->
- parse5(R,[C|Comment],Depth).
-
-
-sz(B) when is_binary(B) -> {binary,size(B)};
-sz(L) when is_list(L) -> {list,length(L)};
-sz(_) -> undefined.
-
-%% send_error - Handle failure to send the file
-%%
-send_error({open,Reason},Info,Path) ->
- httpd_file:handle_error(Reason, "open", Info, Path);
-send_error({read,Reason},Info,Path) ->
- httpd_file:handle_error(Reason, "read", Info, Path).
-
-
-
-
diff --git a/lib/inets/src/inets_app/Makefile b/lib/inets/src/inets_app/Makefile
index 22426eee79..926585f198 100644
--- a/lib/inets/src/inets_app/Makefile
+++ b/lib/inets/src/inets_app/Makefile
@@ -1,7 +1,7 @@
#
# %CopyrightBegin%
#
-# Copyright Ericsson AB 2005-2012. All Rights Reserved.
+# Copyright Ericsson AB 2005-2015. 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
@@ -47,7 +47,9 @@ MODULES = \
inets_app \
inets_sup \
inets_regexp \
- inets_trace
+ inets_trace \
+ inets_lib \
+ inets_time_compat
INTERNAL_HRL_FILES = inets_internal.hrl
EXTERNAL_HRL_FILES = ../../include/httpd.hrl \
diff --git a/lib/inets/src/inets_app/inets.app.src b/lib/inets/src/inets_app/inets.app.src
index 9eae962d03..b7c3e341e8 100644
--- a/lib/inets/src/inets_app/inets.app.src
+++ b/lib/inets/src/inets_app/inets.app.src
@@ -1,7 +1,7 @@
%% This is an -*- erlang -*- file.
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2014. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2015. 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
@@ -26,7 +26,9 @@
inets_app,
inets_service,
inets_regexp,
- inets_trace,
+ inets_trace,
+ inets_lib,
+ inets_time_compat,
%% FTP
ftp,
@@ -90,7 +92,6 @@
mod_get,
mod_head,
mod_htaccess,
- mod_include,
mod_log,
mod_range,
mod_responsecontrol,
diff --git a/lib/inets/src/inets_app/inets_lib.erl b/lib/inets/src/inets_app/inets_lib.erl
new file mode 100644
index 0000000000..fa6adaebd0
--- /dev/null
+++ b/lib/inets/src/inets_app/inets_lib.erl
@@ -0,0 +1,49 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2015-2015. 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(inets_lib).
+
+-export([millisec_passed/1, formated_timestamp/0, format_timestamp/1]).
+
+
+
+%% Help function, elapsed milliseconds since T0
+millisec_passed({_,_,_} = T0 ) ->
+ %% OTP 17 and earlier
+ timer:now_diff(inets_time_compat:timestamp(), T0) div 1000;
+
+millisec_passed(T0) ->
+ %% OTP 18
+ erlang:convert_time_unit(erlang:monotonic_time() - T0,
+ native,
+ micro_seconds) div 1000.
+
+%% Return formated time stamp (e.g. 2015:03:16 10:05:23 1234)
+formated_timestamp() ->
+ format_timestamp( os:timestamp() ).
+
+%% Return formated time stamp (e.g. 2015:03:16 10:05:23 1234)
+format_timestamp({_N1, _N2, N3} = Tme) ->
+ {Date, Time} = calendar:now_to_datetime(Tme),
+ {YYYY,MM,DD} = Date,
+ {Hour,Min,Sec} = Time,
+ FormatDate =
+ io_lib:format("~.4w:~.2.0w:~.2.0w ~.2.0w:~.2.0w:~.2.0w 4~w",
+ [YYYY,MM,DD,Hour,Min,Sec,round(N3/1000)]),
+ lists:flatten(FormatDate).
diff --git a/lib/inets/src/inets_app/inets_time_compat.erl b/lib/inets/src/inets_app/inets_time_compat.erl
new file mode 100644
index 0000000000..d6297d9caf
--- /dev/null
+++ b/lib/inets/src/inets_app/inets_time_compat.erl
@@ -0,0 +1,71 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2015-2015. 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%
+%%
+
+%% This module is created to be able to execute on ERTS versions both
+%% earlier and later than 7.0.
+
+-module(inets_time_compat).
+
+%% We don't want warnings about the use of erlang:now/0 in
+%% this module.
+-compile(nowarn_deprecated_function).
+
+-export([monotonic_time/0,
+ timestamp/0,
+ unique_integer/0,
+ unique_integer/1]).
+
+monotonic_time() ->
+ try
+ erlang:monotonic_time()
+ catch
+ error:undef ->
+ %% Use Erlang system time as monotonic time
+ erlang_system_time_fallback()
+ end.
+
+timestamp() ->
+ try
+ erlang:timestamp()
+ catch
+ error:undef ->
+ erlang:now()
+ end.
+
+unique_integer() ->
+ try
+ erlang:unique_integer()
+ catch
+ error:undef ->
+ erlang_system_time_fallback()
+ end.
+
+unique_integer(Modifiers) ->
+ try
+ erlang:unique_integer(Modifiers)
+ catch
+ error:badarg ->
+ erlang:error(badarg, [Modifiers]);
+ error:undef ->
+ erlang_system_time_fallback()
+ end.
+
+erlang_system_time_fallback() ->
+ {MS, S, US} = erlang:now(),
+ (MS*1000000+S)*1000000+US.
diff --git a/lib/inets/src/inets_app/inets_trace.erl b/lib/inets/src/inets_app/inets_trace.erl
index 8911f65897..cb6d6d8bdb 100644
--- a/lib/inets/src/inets_app/inets_trace.erl
+++ b/lib/inets/src/inets_app/inets_trace.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2011-2012. All Rights Reserved.
+%% Copyright Ericsson AB 2011-2015. 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
@@ -228,21 +228,24 @@ handle_trace({trace_ts, _Who, call,
[_Sev, "stop trace", stop_trace, [stop_trace]]},
Timestamp},
{_, standard_io} = Fd) ->
- (catch io:format(standard_io, "stop trace at ~s~n", [format_timestamp(Timestamp)])),
+ (catch io:format(standard_io, "stop trace at ~s~n",
+ [inets_lib:format_timestamp(Timestamp)])),
Fd;
handle_trace({trace_ts, _Who, call,
{?MODULE, report_event,
[_Sev, "stop trace", stop_trace, [stop_trace]]},
Timestamp},
standard_io = Fd) ->
- (catch io:format(Fd, "stop trace at ~s~n", [format_timestamp(Timestamp)])),
+ (catch io:format(Fd, "stop trace at ~s~n",
+ [inets_lib:format_timestamp(Timestamp)])),
Fd;
handle_trace({trace_ts, _Who, call,
{?MODULE, report_event,
[_Sev, "stop trace", stop_trace, [stop_trace]]},
Timestamp},
{_Service, Fd}) ->
- (catch io:format(Fd, "stop trace at ~s~n", [format_timestamp(Timestamp)])),
+ (catch io:format(Fd, "stop trace at ~s~n",
+ [inets_lib:format_timestamp(Timestamp)])),
(catch file:close(Fd)),
closed_file;
handle_trace({trace_ts, _Who, call,
@@ -250,7 +253,8 @@ handle_trace({trace_ts, _Who, call,
[_Sev, "stop trace", stop_trace, [stop_trace]]},
Timestamp},
Fd) ->
- (catch io:format(Fd, "stop trace at ~s~n", [format_timestamp(Timestamp)])),
+ (catch io:format(Fd, "stop trace at ~s~n",
+ [inets_lib:format_timestamp(Timestamp)])),
(catch file:close(Fd)),
closed_file;
handle_trace({trace_ts, Who, call,
@@ -280,7 +284,7 @@ print_inets_trace(Fd, Sev, Timestamp, Who, Label, Service, Content) ->
do_print_inets_trace(Fd, Sev, Timestamp, Who, Label, Service, Content).
do_print_inets_trace(Fd, Sev, Timestamp, Who, Label, Service, Content) ->
- Ts = format_timestamp(Timestamp),
+ Ts = inets_lib:format_timestamp(Timestamp),
io:format(Fd, "[inets ~w trace ~w ~w ~s] ~s "
"~n Content: ~p"
"~n",
@@ -307,7 +311,7 @@ do_print_trace(Fd, {trace, Who, What, Where, Extra}) ->
"~n", [Who, What, Where, Extra]);
do_print_trace(Fd, {trace_ts, Who, What, Where, When}) ->
- Ts = format_timestamp(When),
+ Ts = inets_lib:format_timestamp(When),
io:format(Fd, "[trace ~s]"
"~n Who: ~p"
"~n What: ~p"
@@ -315,7 +319,7 @@ do_print_trace(Fd, {trace_ts, Who, What, Where, When}) ->
"~n", [Ts, Who, What, Where]);
do_print_trace(Fd, {trace_ts, Who, What, Where, Extra, When}) ->
- Ts = format_timestamp(When),
+ Ts = inets_lib:format_timestamp(When),
io:format(Fd, "[trace ~s]"
"~n Who: ~p"
"~n What: ~p"
@@ -330,7 +334,7 @@ do_print_trace(Fd, {seq_trace, What, Where}) ->
"~n", [What, Where]);
do_print_trace(Fd, {seq_trace, What, Where, When}) ->
- Ts = format_timestamp(When),
+ Ts = inets_lib:format_timestamp(When),
io:format(Fd, "[seq trace ~s]"
"~n What: ~p"
"~n Where: ~p"
@@ -345,13 +349,3 @@ do_print_trace(Fd, Trace) ->
"~n", [Trace]).
-format_timestamp({_N1, _N2, N3} = Now) ->
- {Date, Time} = calendar:now_to_datetime(Now),
- {YYYY,MM,DD} = Date,
- {Hour,Min,Sec} = Time,
- FormatDate =
- io_lib:format("~.4w:~.2.0w:~.2.0w ~.2.0w:~.2.0w:~.2.0w 4~w",
- [YYYY,MM,DD,Hour,Min,Sec,round(N3/1000)]),
- lists:flatten(FormatDate).
-
-
diff --git a/lib/inets/src/tftp/tftp_logger.erl b/lib/inets/src/tftp/tftp_logger.erl
index 0c3620e665..231a705371 100644
--- a/lib/inets/src/tftp/tftp_logger.erl
+++ b/lib/inets/src/tftp/tftp_logger.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
+%% Copyright Ericsson AB 2008-2015. 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
@@ -84,8 +84,8 @@ info_msg(Format, Data) ->
%%-------------------------------------------------------------------
add_timestamp(Format, Data) ->
- Now = {_MegaSecs, _Secs, _MicroSecs} = erlang:now(),
- {{_Y, _Mo, _D}, {H, Mi, S}} = calendar:now_to_universal_time(Now),
+ Time = inets_time_compat:timestamp(),
+ {{_Y, _Mo, _D}, {H, Mi, S}} = calendar:now_to_universal_time(Time),
%% {"~p-~s-~sT~s:~s:~sZ,~6.6.0w tftp: " ++ Format ++ "\n",
%% [Y, t(Mo), t(D), t(H), t(Mi), t(S), MicroSecs | Data]}.
{"~s:~s:~s tftp: " ++ Format, [t(H), t(Mi), t(S) | Data]}.
diff --git a/lib/inets/src/tftp/tftp_sup.erl b/lib/inets/src/tftp/tftp_sup.erl
index 1cafcc1069..7a0dcffc90 100644
--- a/lib/inets/src/tftp/tftp_sup.erl
+++ b/lib/inets/src/tftp/tftp_sup.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2005-2009. All Rights Reserved.
+%% Copyright Ericsson AB 2005-2015. 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
@@ -93,7 +93,7 @@ unique_name(Options) ->
{value, {_, Port}} when is_integer(Port), Port > 0 ->
{tftpd, Port};
_ ->
- {tftpd, erlang:now()}
+ {tftpd, inets_time_compat:unique_integer([positive])}
end.
default_kill_after() ->
diff --git a/lib/inets/test/erl_make_certs.erl b/lib/inets/test/erl_make_certs.erl
index 22dc951ac1..6c168a5704 100644
--- a/lib/inets/test/erl_make_certs.erl
+++ b/lib/inets/test/erl_make_certs.erl
@@ -204,7 +204,7 @@ issuer_der(Issuer) ->
Subject.
subject(undefined, IsRootCA) ->
- User = if IsRootCA -> "RootCA"; true -> user() end,
+ User = if IsRootCA -> "RootCA"; true -> os:getenv("USER", "test_user") end,
Opts = [{email, User ++ "@erlang.org"},
{name, User},
{city, "Stockholm"},
@@ -215,14 +215,6 @@ subject(undefined, IsRootCA) ->
subject(Opts, _) ->
subject(Opts).
-user() ->
- case os:getenv("USER") of
- false ->
- "test_user";
- User ->
- User
- end.
-
subject(SubjectOpts) when is_list(SubjectOpts) ->
Encode = fun(Opt) ->
{Type,Value} = subject_enc(Opt),
diff --git a/lib/inets/test/ftp_suite_lib.erl b/lib/inets/test/ftp_suite_lib.erl
index daee1bdcdc..b637832101 100644
--- a/lib/inets/test/ftp_suite_lib.erl
+++ b/lib/inets/test/ftp_suite_lib.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2005-2013. All Rights Reserved.
+%% Copyright Ericsson AB 2005-2015. 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
@@ -1352,9 +1352,9 @@ do_delete(Pid, Config) ->
ok.
do_mkdir(Pid) ->
- {A, B, C} = erlang:now(),
- NewDir = "nisse_" ++ integer_to_list(A) ++ "_" ++
- integer_to_list(B) ++ "_" ++ integer_to_list(C),
+ NewDir = "earl_" ++
+ integer_to_list(inets_time_compat:unique_integer([positive])),
+
ok = ftp:cd(Pid, "incoming"),
{ok, CurrDir} = ftp:pwd(Pid),
{error, efnamena} = ftp:mkdir(Pid, NewDir++"\r\nCWD ."),
diff --git a/lib/inets/test/httpc_SUITE.erl b/lib/inets/test/httpc_SUITE.erl
index 21be7862cb..0dfc65e8f7 100644
--- a/lib/inets/test/httpc_SUITE.erl
+++ b/lib/inets/test/httpc_SUITE.erl
@@ -28,6 +28,7 @@
-include_lib("common_test/include/ct.hrl").
-include("inets_test_lib.hrl").
-include("http_internal.hrl").
+-include("httpc_internal.hrl").
%% Note: This directive should only be used in test suites.
-compile(export_all).
@@ -106,6 +107,7 @@ only_simulated() ->
empty_response_header,
remote_socket_close,
remote_socket_close_async,
+ process_leak_on_keepalive,
transfer_encoding,
transfer_encoding_identity,
redirect_loop,
@@ -913,6 +915,33 @@ remote_socket_close_async(Config) when is_list(Config) ->
%%-------------------------------------------------------------------------
+process_leak_on_keepalive(Config) ->
+ {ok, ClosedSocket} = gen_tcp:listen(6666, [{active, false}]),
+ ok = gen_tcp:close(ClosedSocket),
+ Request = {url(group_name(Config), "/dummy.html", Config), []},
+ HttpcHandlers0 = supervisor:which_children(httpc_handler_sup),
+ {ok, {{_, 200, _}, _, Body}} = httpc:request(get, Request, [], []),
+ HttpcHandlers1 = supervisor:which_children(httpc_handler_sup),
+ ChildrenCount = supervisor:count_children(httpc_handler_sup),
+ %% Assuming that the new handler will be selected for keep_alive
+ %% which could not be the case if other handlers existed
+ [{undefined, Pid, worker, [httpc_handler]}] =
+ ordsets:to_list(
+ ordsets:subtract(ordsets:from_list(HttpcHandlers1),
+ ordsets:from_list(HttpcHandlers0))),
+ sys:replace_state(
+ Pid, fun (State) ->
+ Session = element(3, State),
+ setelement(3, State, Session#session{socket=ClosedSocket})
+ end),
+ {ok, {{_, 200, _}, _, Body}} = httpc:request(get, Request, [], []),
+ %% bad handler with the closed socket should get replaced by
+ %% the new one, so children count should stay the same
+ ChildrenCount = supervisor:count_children(httpc_handler_sup),
+ ok.
+
+%%-------------------------------------------------------------------------
+
stream_to_pid(Config) when is_list(Config) ->
ReceiverPid = create_receiver(pid),
Receiver = ReceiverPid,
@@ -1904,12 +1933,13 @@ run_clients(NumClients, ServerPort, SeqNumServer) ->
wait4clients([], _Timeout) ->
ok;
wait4clients(Clients, Timeout) when Timeout > 0 ->
- Time = now_ms(),
+ Time = inets_time_compat:monotonic_time(),
+
receive
{'DOWN', _MRef, process, Pid, normal} ->
{value, {Id, _, _}} = lists:keysearch(Pid, 2, Clients),
NewClients = lists:keydelete(Id, 1, Clients),
- wait4clients(NewClients, Timeout - (now_ms() - Time));
+ wait4clients(NewClients, Timeout - inets_lib:millisec_passed(Time));
{'DOWN', _MRef, process, Pid, Reason} ->
{value, {Id, _, _}} = lists:keysearch(Pid, 2, Clients),
ct:fail({bad_client_termination, Id, Reason})
@@ -2002,14 +2032,10 @@ parse_connection_type(Request) ->
"keep-alive" -> keep_alive
end.
-%% Time in milli seconds
-now_ms() ->
- {A,B,C} = erlang:now(),
- A*1000000000+B*1000+(C div 1000).
-
set_random_seed() ->
- {_, _, Micros} = now(),
- A = erlang:phash2([make_ref(), self(), Micros]),
+ Unique = inets_time_compat:unique_integer(),
+
+ A = erlang:phash2([make_ref(), self(), Unique]),
random:seed(A, A, A).
diff --git a/lib/inets/test/httpd_SUITE.erl b/lib/inets/test/httpd_SUITE.erl
index 342004f19b..7670c2cc60 100644
--- a/lib/inets/test/httpd_SUITE.erl
+++ b/lib/inets/test/httpd_SUITE.erl
@@ -66,7 +66,8 @@ all() ->
{group, http_security},
{group, https_security},
{group, http_reload},
- {group, https_reload}
+ {group, https_reload},
+ {group, http_mime_types}
].
groups() ->
@@ -89,6 +90,7 @@ groups() ->
{https_security, [], [{group, security}]},
{http_reload, [], [{group, reload}]},
{https_reload, [], [{group, reload}]},
+ {http_mime_types, [], [alias_1_1, alias_1_0, alias_0_9]},
{limit, [], [max_clients_1_1, max_clients_1_0, max_clients_0_9]},
{reload, [], [non_disturbing_reconfiger_dies,
disturbing_reconfiger_dies,
@@ -127,7 +129,6 @@ http_get() ->
get,
%%actions, Add configuration so that this test mod_action
esi,
- ssi,
content_length,
bad_hex,
missing_CR,
@@ -192,7 +193,8 @@ init_per_group(Group, Config0) when Group == http_basic;
Group == http_auth_api_dets;
Group == http_auth_api_mnesia;
Group == http_security;
- Group == http_reload
+ Group == http_reload;
+ Group == http_mime_types
->
ok = start_apps(Group),
init_httpd(Group, [{type, ip_comm} | Config0]);
@@ -236,7 +238,8 @@ end_per_group(Group, _Config) when Group == http_basic;
Group == http_auth_api_mnesia;
Group == http_htaccess;
Group == http_security;
- Group == http_reload
+ Group == http_reload;
+ Group == http_mime_types
->
inets:stop();
end_per_group(Group, _Config) when Group == https_basic;
@@ -552,22 +555,6 @@ ipv6(Config) when is_list(Config) ->
end.
%%-------------------------------------------------------------------------
-ssi() ->
- [{doc, "HTTP GET server side include test"}].
-ssi(Config) when is_list(Config) ->
- Version = ?config(http_version, Config),
- Host = ?config(host, Config),
- Type = ?config(type, Config),
- ok = httpd_test_lib:verify_request(?config(type, Config), Host, ?config(port, Config),
- transport_opts(Type, Config),
- ?config(node, Config),
- http_request("GET /fsize.shtml ", Version, Host),
- [{statuscode, 200},
- {header, "Content-Type", "text/html"},
- {header, "Date"},
- {header, "Server"},
- {version, Version}]).
-%%-------------------------------------------------------------------------
htaccess_1_1(Config) when is_list(Config) ->
htaccess([{http_version, "HTTP/1.1"} | Config]).
@@ -857,6 +844,24 @@ cgi_chunked_encoding_test(Config) when is_list(Config) ->
?config(node, Config),
Requests).
%%-------------------------------------------------------------------------
+alias_1_1() ->
+ [{doc, "Test mod_alias"}].
+
+alias_1_1(Config) when is_list(Config) ->
+ alias([{http_version, "HTTP/1.1"} | Config]).
+
+alias_1_0() ->
+ [{doc, "Test mod_alias"}].
+
+alias_1_0(Config) when is_list(Config) ->
+ alias([{http_version, "HTTP/1.0"} | Config]).
+
+alias_0_9() ->
+ [{doc, "Test mod_alias"}].
+
+alias_0_9(Config) when is_list(Config) ->
+ alias([{http_version, "HTTP/0.9"} | Config]).
+
alias() ->
[{doc, "Test mod_alias"}].
@@ -915,7 +920,6 @@ trace(Config) when is_list(Config) ->
Cb = ?config(version_cb, Config),
Cb:trace(?config(type, Config), ?config(port, Config),
?config(host, Config), ?config(node, Config)).
-
%%-------------------------------------------------------------------------
light() ->
["Test light load"].
@@ -1276,22 +1280,26 @@ setup_server_dirs(ServerRoot, DocRoot, DataDir) ->
CgiDir = filename:join(ServerRoot, "cgi-bin"),
AuthDir = filename:join(ServerRoot, "auth"),
PicsDir = filename:join(ServerRoot, "icons"),
+ ConfigDir = filename:join(ServerRoot, "config"),
ok = file:make_dir(ServerRoot),
ok = file:make_dir(DocRoot),
ok = file:make_dir(CgiDir),
ok = file:make_dir(AuthDir),
ok = file:make_dir(PicsDir),
+ ok = file:make_dir(ConfigDir),
DocSrc = filename:join(DataDir, "server_root/htdocs"),
AuthSrc = filename:join(DataDir, "server_root/auth"),
CgiSrc = filename:join(DataDir, "server_root/cgi-bin"),
PicsSrc = filename:join(DataDir, "server_root/icons"),
+ ConfigSrc = filename:join(DataDir, "server_root/config"),
inets_test_lib:copy_dirs(DocSrc, DocRoot),
inets_test_lib:copy_dirs(AuthSrc, AuthDir),
inets_test_lib:copy_dirs(CgiSrc, CgiDir),
inets_test_lib:copy_dirs(PicsSrc, PicsDir),
+ inets_test_lib:copy_dirs(ConfigSrc, ConfigDir),
Cgi = case test_server:os_type() of
{win32, _} ->
@@ -1329,7 +1337,8 @@ start_apps(Group) when Group == http_basic;
Group == http_auth_api_mnesia;
Group == https_htaccess;
Group == https_security;
- Group == https_reload->
+ Group == https_reload;
+ Group == http_mime_types->
inets_test_lib:start_apps([inets]).
server_start(_, HttpdConfig) ->
@@ -1417,6 +1426,11 @@ server_config(http_security, Config) ->
server_config(https_security, Config) ->
ServerRoot = ?config(server_root, Config),
tl(auth_conf(ServerRoot)) ++ security_conf(ServerRoot) ++ server_config(https, Config);
+server_config(http_mime_types, Config0) ->
+ Config1 = basic_conf() ++ server_config(http, Config0),
+ ServerRoot = ?config(server_root, Config0),
+ MimeTypesFile = filename:join([ServerRoot,"config", "mime.types"]),
+ [{mime_types, MimeTypesFile} | proplists:delete(mime_types, Config1)];
server_config(http, Config) ->
ServerRoot = ?config(server_root, Config),
diff --git a/lib/inets/test/httpd_SUITE_data/server_root/config/mime.types b/lib/inets/test/httpd_SUITE_data/server_root/config/mime.types
new file mode 100644
index 0000000000..b68cff21a6
--- /dev/null
+++ b/lib/inets/test/httpd_SUITE_data/server_root/config/mime.types
@@ -0,0 +1,4 @@
+text/html html
+text/html htm
+text/html shtml
+image/gif gif
diff --git a/lib/inets/test/httpd_time_test.erl b/lib/inets/test/httpd_time_test.erl
index 0bb457f9b9..7dd61a5517 100644
--- a/lib/inets/test/httpd_time_test.erl
+++ b/lib/inets/test/httpd_time_test.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2001-2011. All Rights Reserved.
+%% Copyright Ericsson AB 2001-2015. 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
@@ -116,13 +116,14 @@ main(N, SocketType, Host, Port, Time)
loop(Pollers, Timeout) ->
d("loop -> entry when"
"~n Timeout: ~p", [Timeout]),
- Start = t(),
+ Start = inets_time_compat:monotonic_time(),
+
receive
{'EXIT', Pid, {poller_stat_failure, SocketType, Host, Port, Time, Reason}} ->
case is_poller(Pid, Pollers) of
true ->
error_msg("received unexpected exit from poller ~p~n"
- "befor completion of test "
+ "before completion of test "
"after ~p micro sec"
"~n SocketType: ~p"
"~n Host: ~p"
@@ -133,7 +134,7 @@ loop(Pollers, Timeout) ->
false ->
error_msg("received unexpected ~p from ~p"
"befor completion of test", [Reason, Pid]),
- loop(Pollers, to(Timeout, Start))
+ loop(Pollers, Timeout - inets_lib:millisec_passed(Start))
end;
{poller_stat_failure, Pid, {SocketType, Host, Port, Time, Reason}} ->
@@ -412,35 +413,6 @@ validate(ExpStatusCode, _SocketType, _Socket, Response) ->
end.
-trash_the_rest(Socket, N) ->
- receive
- {ssl, Socket, Trash} ->
- trash_the_rest(Socket, add(N,sz(Trash)));
- {ssl_closed, Socket} ->
- N;
- {ssl_error, Socket, Error} ->
- exit({connection_error, Error});
-
- {tcp, Socket, Trash} ->
- trash_the_rest(Socket, add(N,sz(Trash)));
- {tcp_closed, Socket} ->
- N;
- {tcp_error, Socket, Error} ->
- exit({connection_error, Error})
-
- after 10000 ->
- exit({connection_timed_out, N})
- end.
-
-
-add(N1,N2) when is_integer(N1) andalso is_integer(N2) ->
- N1 + N2;
-add(N1,_) when is_integer(N1) ->
- N1;
-add(_,N2) when is_integer(N2) ->
- N2.
-
-
sz(L) when is_list(L) ->
length(lists:flatten(L));
sz(B) when is_binary(B) ->
@@ -505,17 +477,6 @@ status_to_message(Code) -> io_lib:format("Unknown status code: ~p",[Code]).
%% ----------------------------------------------------------------
-to(To, Start) ->
- To - (t() - Start).
-
-%% Time in milli seconds
-t() ->
- {A,B,C} = erlang:now(),
- A*1000000000+B*1000+(C div 1000).
-
-
-%% ----------------------------------------------------------------
-
% close(Socket) ->
diff --git a/lib/inets/test/inets_SUITE.erl b/lib/inets/test/inets_SUITE.erl
index 6510c70d08..a07dc79c02 100644
--- a/lib/inets/test/inets_SUITE.erl
+++ b/lib/inets/test/inets_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2013. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2015. 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
@@ -549,25 +549,12 @@ tsf(Reason) ->
tsp(F) ->
tsp(F, []).
tsp(F, A) ->
- Timestamp = formated_timestamp(),
+ Timestamp = inets_lib:formated_timestamp(),
test_server:format("** ~s ** ~p ~p:" ++ F ++ "~n", [Timestamp, self(), ?MODULE | A]).
i(F) ->
i(F, []).
i(F, A) ->
- Timestamp = formated_timestamp(),
+ Timestamp = inets_lib:formated_timestamp(),
io:format("*** ~s ~w:" ++ F ++ "~n", [Timestamp, ?MODULE | A]).
-
-formated_timestamp() ->
- format_timestamp( os:timestamp() ).
-
-format_timestamp({_N1, _N2, N3} = Now) ->
- {Date, Time} = calendar:now_to_datetime(Now),
- {YYYY,MM,DD} = Date,
- {Hour,Min,Sec} = Time,
- FormatDate =
- io_lib:format("~.4w:~.2.0w:~.2.0w ~.2.0w:~.2.0w:~.2.0w 4~w",
- [YYYY,MM,DD,Hour,Min,Sec,round(N3/1000)]),
- lists:flatten(FormatDate).
-
diff --git a/lib/inets/test/inets_app_test.erl b/lib/inets/test/inets_app_test.erl
index eabfa69f7c..22d6e25c87 100644
--- a/lib/inets/test/inets_app_test.erl
+++ b/lib/inets/test/inets_app_test.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2002-2012. All Rights Reserved.
+%% Copyright Ericsson AB 2002-2015. 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
@@ -32,19 +32,6 @@
%% Test server callbacks
-init_per_testcase(undef_funcs, Config) ->
- NewConfig = lists:keydelete(watchdog, 1, Config),
- Dog = test_server:timetrap(inets_test_lib:minutes(10)),
-
- %% We need to check if there is a point to run this test.
- %% On some platforms, crypto will not build, which in turn
- %% causes ssl to not build (at this time, this will
- %% change in the future).
- %% So, we first check if we can start crypto, and if not,
- %% we skip this test case!
- ?ENSURE_STARTED(crypto),
-
- [{watchdog, Dog}| NewConfig];
init_per_testcase(_, Config) ->
Config.
@@ -54,7 +41,7 @@ end_per_testcase(_Case, Config) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
all() ->
- [fields, modules, exportall, app_depend, undef_funcs].
+ [fields, modules, exportall, app_depend].
groups() ->
[].
@@ -244,56 +231,6 @@ check_apps([App|Apps]) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-undef_funcs(suite) ->
- [];
-undef_funcs(doc) ->
- [];
-undef_funcs(Config) when is_list(Config) ->
- App = inets,
- AppFile = key1search(app_file, Config),
- Mods = key1search(modules, AppFile),
- Root = code:root_dir(),
- LibDir = code:lib_dir(App),
- EbinDir = filename:join([LibDir,"ebin"]),
- XRefTestName = undef_funcs_make_name(App, xref_test_name),
- {ok, XRef} = xref:start(XRefTestName),
- ok = xref:set_default(XRef,
- [{verbose,false},{warnings,false}]),
- XRefName = undef_funcs_make_name(App, xref_name),
- {ok, XRefName} = xref:add_release(XRef, Root, {name, XRefName}),
- {ok, App} = xref:replace_application(XRef, App, EbinDir),
- {ok, Undefs} = xref:analyze(XRef, undefined_function_calls),
- xref:stop(XRef),
- analyze_undefined_function_calls(Undefs, Mods, []).
-
-analyze_undefined_function_calls([], _, []) ->
- ok;
-analyze_undefined_function_calls([], _, AppUndefs) ->
- exit({suite_failed, {undefined_function_calls, AppUndefs}});
-analyze_undefined_function_calls([{{Mod, _F, _A}, _C} = AppUndef|Undefs],
- AppModules, AppUndefs) ->
- %% Check that this module is our's
- case lists:member(Mod,AppModules) of
- true ->
- {Calling,Called} = AppUndef,
- {Mod1,Func1,Ar1} = Calling,
- {Mod2,Func2,Ar2} = Called,
- io:format("undefined function call: "
- "~n ~w:~w/~w calls ~w:~w/~w~n",
- [Mod1,Func1,Ar1,Mod2,Func2,Ar2]),
- analyze_undefined_function_calls(Undefs, AppModules,
- [AppUndef|AppUndefs]);
- false ->
- io:format("dropping ~p~n", [Mod]),
- analyze_undefined_function_calls(Undefs, AppModules, AppUndefs)
- end.
-
-%% This function is used simply to avoid cut-and-paste errors later...
-undef_funcs_make_name(App, PostFix) ->
- list_to_atom(atom_to_list(App) ++ "_" ++ atom_to_list(PostFix)).
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
fail(Reason) ->
exit({suite_failed, Reason}).
diff --git a/lib/inets/test/inets_test_lib.erl b/lib/inets/test/inets_test_lib.erl
index 4be9d9c8b3..7485971d3e 100644
--- a/lib/inets/test/inets_test_lib.erl
+++ b/lib/inets/test/inets_test_lib.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2001-2013. All Rights Reserved.
+%% Copyright Ericsson AB 2001-2015. 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
@@ -498,13 +498,6 @@ close(essl,Socket) ->
close(ip_comm,Socket) ->
catch gen_tcp:close(Socket).
-millis() ->
- erlang:now().
-
-millis_diff(A,B) ->
- T1 = (element(1,A)*1000000) + element(2,A) + (element(3,A)/1000000),
- T2 = (element(1,B)*1000000) + element(2,B) + (element(3,B)/1000000),
- T1 - T2.
hours(N) -> trunc(N * 1000 * 60 * 60).
minutes(N) -> trunc(N * 1000 * 60).
@@ -546,7 +539,7 @@ flush() ->
tsp(F) ->
tsp(F, []).
tsp(F, A) ->
- Timestamp = formated_timestamp(),
+ Timestamp = inets_lib:formated_timestamp(),
ct:pal("*** ~s ~p ~p " ++ F ++ "~n",
[Timestamp, node(), self() | A]).
@@ -559,18 +552,6 @@ tss(Time) ->
timestamp() ->
http_util:timestamp().
-formated_timestamp() ->
- format_timestamp( os:timestamp() ).
-
-format_timestamp({_N1, _N2, N3} = Now) ->
- {Date, Time} = calendar:now_to_datetime(Now),
- {YYYY,MM,DD} = Date,
- {Hour,Min,Sec} = Time,
- FormatDate =
- io_lib:format("~.4w:~.2.0w:~.2.0w ~.2.0w:~.2.0w:~.2.0w 4~w",
- [YYYY,MM,DD,Hour,Min,Sec,round(N3/1000)]),
- lists:flatten(FormatDate).
-
start_apps(Apps) ->
lists:foreach(fun(App) ->
application:stop(App),
diff --git a/lib/inets/test/old_httpd_SUITE.erl b/lib/inets/test/old_httpd_SUITE.erl
index 74c11f71ba..39b0b08645 100644
--- a/lib/inets/test/old_httpd_SUITE.erl
+++ b/lib/inets/test/old_httpd_SUITE.erl
@@ -2072,13 +2072,13 @@ create_config(Config, Access, FileName) ->
"Modules mod_alias mod_htaccess mod_auth "
"mod_security "
"mod_responsecontrol mod_trace mod_esi "
- "mod_actions mod_cgi mod_include mod_dir "
+ "mod_actions mod_cgi mod_dir "
"mod_range mod_get "
"mod_head mod_log mod_disk_log";
_ ->
"Modules mod_alias mod_auth mod_security "
"mod_responsecontrol mod_trace mod_esi "
- "mod_actions mod_cgi mod_include mod_dir "
+ "mod_actions mod_cgi mod_dir "
"mod_range mod_get "
"mod_head mod_log mod_disk_log"
end,
@@ -2436,7 +2436,7 @@ create_ipv6_config(Config, FileName, Ipv6Address) ->
MaxHdrAct = io_lib:format("~p", [close]),
Mod_order = "Modules mod_alias mod_auth mod_esi mod_actions mod_cgi"
- " mod_include mod_dir mod_get mod_head"
+ " mod_dir mod_get mod_head"
" mod_log mod_disk_log mod_trace",
SSL =
diff --git a/lib/inets/vsn.mk b/lib/inets/vsn.mk
index ecb84e447c..f52347e39e 100644
--- a/lib/inets/vsn.mk
+++ b/lib/inets/vsn.mk
@@ -2,7 +2,7 @@
# %CopyrightBegin%
#
-# Copyright Ericsson AB 2001-2014. All Rights Reserved.
+# Copyright Ericsson AB 2001-2015. 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
@@ -18,6 +18,6 @@
# %CopyrightEnd%
APPLICATION = inets
-INETS_VSN = 5.10.8
+INETS_VSN = 6.0
PRE_VSN =
APP_VSN = "$(APPLICATION)-$(INETS_VSN)$(PRE_VSN)"