Commit d6e058fb authored by Philipp Huebner's avatar Philipp Huebner

Merge tag 'upstream/1.0.7'

Upstream version 1.0.7
parents 2b85efd0 ea56ffe4
# Version 1.0.7
* Fix coverall invocation (Paweł Chmielowski)
* Fix p1_server timeout handling, R18 compatibility (Alexey Shchepin)
# Version 1.0.6
* Add p1_http
# Version 1.0.5
* Erlang R19 compliance (Paweł Chmielowski)
# Version 1.0.4
* Adds p1_time_compat:unique_timestamp() that returns value resembling what now() was returning
......
......@@ -10,5 +10,7 @@ p1_utils is an application containing ProcessOne modules and tools that are leve
* `treap` is a treap algorithm implementation. It is a randomized binary search tree. See: https://en.wikipedia.org/wiki/Treap
* `p1_time_compat` is a module to ease support and migration of Erlang
time management function from Erlang R16/R17 to Erlang R18.
* `p1_http` is an http client which provides a common API for inets / lhttpc / ibrowse
If you have `rebar` binary, you can generate `p1_utils` documentation by running `rebar3 edoc`.
......@@ -8,7 +8,7 @@
<body bgcolor="white" class="mainpane">
<div class="navbar"><a name="#navbar_top"></a><table width="100%" border="0" cellspacing="0" cellpadding="2" summary="navigation bar"><tr><td><a href="overview-summary.html" target="overviewFrame">Overview</a></td><td><a href="http://www.process-one.net" target="_top"><img src="logo_p1.png" align="right" border="0" alt="Logo"></a></td></tr></table></div>
<h1>P1 Erlang Utils</h1>
<p>Copyright © 2002-2015 ProcessOne</p>
<p>Copyright © 2002-2017 ProcessOne</p>
<p><b>Version:</b> 1.0.0</p>
<p><b>Authors:</b> ProcessOne [<em>web site:</em> <tt><a href="http://www.process-one.net" target="_top">http://www.process-one.net</a></tt>].</p>
<p>
......
@author ProcessOne [http://www.process-one.net]
@copyright 2002-2015 ProcessOne
@copyright 2002-2017 ProcessOne
@version 1.0.0
@title P1 Erlang Utils
@doc
......
......@@ -4,7 +4,7 @@
%%% Purpose : Rebar build script. Compliant with rebar and rebar3.
%%% Created : 24 Nov 2015 by Mickael Remond <mremond@process-one.net>
%%%
%%% Copyright (C) 2002-2015 ProcessOne, SARL. All Rights Reserved.
%%% Copyright (C) 2002-2017 ProcessOne, SARL. All Rights Reserved.
%%%
%%% Licensed under the Apache License, Version 2.0 (the "License");
%%% you may not use this file except in compliance with the License.
......@@ -67,7 +67,7 @@ Config = case os:getenv("TRAVIS") of
"true" ->
JobId = os:getenv("TRAVIS_JOB_ID"),
Cfg3 = ModCfg(Cfg2, [deps], fun(V) -> [{coveralls, ".*", {git, "https://github.com/markusn/coveralls-erl.git", "master"}}|V] end, []),
ModCfg(Cfg3, [post_hooks], fun(V) -> V ++ [{eunit, "echo '\n%%! -pa .eunit/ deps/coveralls/ebin\nmain(_)->{ok,F}=file:open(\"erlang.json\",[write]),io:fwrite(F,\"~s\",[coveralls:convert_file(\".eunit/cover.coverdata\", \""++JobId++"\", \"travis-ci\")]).' > getcover.erl"},
ModCfg(Cfg3, [post_hooks], fun(V) -> V ++ [{eunit, "echo '\n%%! -pa .eunit/ deps/coveralls/ebin\nmain(_)->{ok,F}=file:open(\"erlang.json\",[write]),io:fwrite(F,\"~s\",[coveralls:convert_file(\".eunit/cover.coverdata\", \""++JobId++"\", \"travis-ci\",\"\")]).' > getcover.erl"},
{eunit, "escript ./getcover.erl"}] end, []);
_ ->
Cfg2
......
......@@ -15,7 +15,7 @@
%%
%% The code has been modified and improved by ProcessOne.
%%
%% Copyright 2007-2015 ProcessOne
%% Copyright 2007-2017 ProcessOne
%%
%% The change adds the following features:
%% - You can send exit(priority_shutdown) to the p1_fsm process to
......
%%%-------------------------------------------------------------------
%%% File : p1_http.erl
%%% Author : Emilio Bustos <ebustos@process-one.net>
%%% Purpose : Provide a common API for inets / lhttpc / ibrowse
%%% Created : 29 Jul 2010 by Emilio Bustos <ebustos@process-one.net>
%%%
%%%
%%% Copyright (C) 2002-2017 ProcessOne, SARL. All Rights Reserved.
%%%
%%% Licensed under the Apache License, Version 2.0 (the "License");
%%% you may not use this file except in compliance with the License.
%%% You may obtain a copy of the License at
%%%
%%% http://www.apache.org/licenses/LICENSE-2.0
%%%
%%% Unless required by applicable law or agreed to in writing, software
%%% distributed under the License is distributed on an "AS IS" BASIS,
%%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%%% See the License for the specific language governing permissions and
%%% limitations under the License.
%%%
%%%-------------------------------------------------------------------
-module(p1_http).
-author('ebustos@process-one.net').
-export([start/0, stop/0, get/1, get/2, post/2, post/3,
request/3, request/4, request/5,
get_pool_size/0, set_pool_size/1]).
-type header() :: {string() | atom(), string()}.
-type headers() :: [header()].
-type option() :: {connect_timeout, timeout()} |
{timeout, timeout()} | {send_retry, non_neg_integer()} |
{partial_upload, non_neg_integer() | infinity} |
{partial_download, pid(), non_neg_integer() | infinity}.
-type options() :: [option()].
-type result() :: {ok,
{{pos_integer(), string()}, headers(), string()}} |
{error, atom()}.
-ifdef(USE_IBROWSE).
start() ->
application:start(ibrowse).
stop() ->
application:stop(ibrowse).
%% @spec (Method, URL, Hdrs, RequestBody, Options) -> Result
%% Method = atom()
%% URL = string()
%% Hdrs = [{Header, Value}]
%% Header = string()
%% Value = string()
%% RequestBody = string()
%% Options = [Option]
%% Option = {timeout, Milliseconds | infinity} |
%% {connect_timeout, Milliseconds | infinity} |
%% {socket_options, [term()]}
%% Milliseconds = integer()
%% Result = {ok, StatusCode, Hdrs, ResponseBody}
%% | {error, Reason}
%% StatusCode = integer()
%% ResponseBody = string()
%% Reason = connection_closed | connect_timeout | timeout
%% @doc Sends a request with a body.
%% Would be the same as calling
%% `request(Method, URL, Hdrs, Body, [])', that is {@link request/5}
%% with no options.
%% @end
%% @see request/5
-spec request(atom(), string(), headers(), string(), options()) -> result().
request(Method, URL, Hdrs, Body, Opts) ->
TimeOut = proplists:get_value(timeout, Opts, infinity),
Options = [{inactivity_timeout, TimeOut}
| proplists:delete(timeout, Opts)],
case ibrowse:send_req(URL, Hdrs, Method, Body, Options)
of
{ok, Status, Headers, Response} ->
{ok, jlib:binary_to_integer(Status), Headers,
Response};
{error, Reason} -> {error, Reason}
end.
get_pool_size() ->
application:get_env(ibrowse, default_max_sessions, 10).
set_pool_size(Size) ->
application:set_env(ibrowse, default_max_sessions, Size).
-else.
-ifdef(USE_LHTTPC).
start() ->
application:start(lhttpc).
stop() ->
application:stop(lhttpc).
%% @spec (Method, URL, Hdrs, RequestBody, Options) -> Result
%% Method = atom()
%% URL = string()
%% Hdrs = [{Header, Value}]
%% Header = string()
%% Value = string()
%% RequestBody = string()
%% Options = [Option]
%% Option = {timeout, Milliseconds | infinity} |
%% {connect_timeout, Milliseconds | infinity} |
%% {socket_options, [term()]}
%% Milliseconds = integer()
%% Result = {ok, StatusCode, Hdrs, ResponseBody}
%% | {error, Reason}
%% StatusCode = integer()
%% ResponseBody = string()
%% Reason = connection_closed | connect_timeout | timeout
%% @doc Sends a request with a body.
%% Would be the same as calling
%% `request(Method, URL, Hdrs, Body, [])', that is {@link request/5}
%% with no options.
%% @end
%% @see request/5
-spec request(atom(), string(), headers(), string(), options()) -> result().
request(Method, URL, Hdrs, Body, Opts) ->
{[TO, SO], Rest} = proplists:split(Opts, [timeout, socket_options]),
TimeOut = proplists:get_value(timeout, TO, infinity),
SockOpt = proplists:get_value(socket_options, SO, []),
Options = [{connect_options, SockOpt} | Rest],
Result = lhttpc:request(URL, Method, Hdrs, Body, TimeOut, Options),
case Result of
{ok, {{Status, _Reason}, Headers, Response}} ->
{ok, Status, Headers, (Response)};
{error, Reason} -> {error, Reason}
end.
get_pool_size() ->
Opts = proplists:get_value(lhttpc_manager, lhttpc_manager:list_pools()),
proplists:get_value(max_pool_size,Opts).
set_pool_size(Size) ->
lhttpc_manager:set_max_pool_size(lhttpc_manager, Size).
-else.
start() ->
application:start(inets).
stop() ->
application:stop(inets).
to_list(Str) when is_binary(Str) ->
binary_to_list(Str);
to_list(Str) ->
Str.
%% @spec (Method, URL, Hdrs, RequestBody, Options) -> Result
%% Method = atom()
%% URL = string()
%% Hdrs = [{Header, Value}]
%% Header = string()
%% Value = string()
%% RequestBody = string()
%% Options = [Option]
%% Option = {timeout, Milliseconds | infinity} |
%% {connect_timeout, Milliseconds | infinity} |
%% {socket_options, [term()]}
%% Milliseconds = integer()
%% Result = {ok, StatusCode, Hdrs, ResponseBody}
%% | {error, Reason}
%% StatusCode = integer()
%% ResponseBody = string()
%% Reason = connection_closed | connect_timeout | timeout
%% @doc Sends a request with a body.
%% Would be the same as calling
%% `request(Method, URL, Hdrs, Body, [])', that is {@link request/5}
%% with no options.
%% @end
%% @see request/5
-spec request(atom(), string(), headers(), string(), options()) -> result().
request(Method, URLRaw, HdrsRaw, Body, Opts) ->
Hdrs = lists:map(fun({N, V}) ->
{to_list(N), to_list(V)}
end, HdrsRaw),
URL = to_list(URLRaw),
Request = case Method of
get -> {URL, Hdrs};
head -> {URL, Hdrs};
delete -> {URL, Hdrs};
_ -> % post, etc.
{URL, Hdrs,
to_list(proplists:get_value(<<"content-type">>, HdrsRaw, [])),
Body}
end,
Options = case proplists:get_value(timeout, Opts,
infinity)
of
infinity -> proplists:delete(timeout, Opts);
_ -> Opts
end,
case httpc:request(Method, Request, Options, []) of
{ok, {{_, Status, _}, Headers, Response}} ->
{ok, Status, Headers, Response};
{error, Reason} -> {error, Reason}
end.
get_pool_size() ->
{ok, Size} = httpc:get_option(max_sessions),
Size.
set_pool_size(Size) ->
httpc:set_option(max_sessions, Size).
-endif.
-endif.
%% @spec (URL) -> Result
%% URL = string()
%% Result = {ok, StatusCode, Hdrs, ResponseBody}
%% | {error, Reason}
%% StatusCode = integer()
%% ResponseBody = string()
%% Reason = connection_closed | connect_timeout | timeout
%% @doc Sends a GET request.
%% Would be the same as calling `request(get, URL, [])',
%% that is {@link request/3} with an empty header list.
%% @end
%% @see request/3
-spec get(string()) -> result().
get(URL) -> request(get, URL, []).
%% @spec (URL, Hdrs) -> Result
%% URL = string()
%% Hdrs = [{Header, Value}]
%% Header = string()
%% Value = string()
%% Result = {ok, StatusCode, Hdrs, ResponseBody}
%% | {error, Reason}
%% StatusCode = integer()
%% ResponseBody = string()
%% Reason = connection_closed | connect_timeout | timeout
%% @doc Sends a GET request.
%% Would be the same as calling `request(get, URL, Hdrs)'.
%% @end
%% @see request/3
-spec get(string(), headers()) -> result().
get(URL, Hdrs) -> request(get, URL, Hdrs).
%% @spec (URL, RequestBody) -> Result
%% URL = string()
%% RequestBody = string()
%% Result = {ok, StatusCode, Hdrs, ResponseBody}
%% | {error, Reason}
%% StatusCode = integer()
%% ResponseBody = string()
%% Reason = connection_closed | connect_timeout | timeout
%% @doc Sends a POST request with form data.
%% Would be the same as calling
%% `request(post, URL, [{"content-type", "x-www-form-urlencoded"}], Body)'.
%% @end
%% @see request/4
-spec post(string(), string()) -> result().
post(URL, Body) ->
request(post, URL,
[{<<"content-type">>, <<"x-www-form-urlencoded">>}],
Body).
%% @spec (URL, Hdrs, RequestBody) -> Result
%% URL = string()
%% Hdrs = [{Header, Value}]
%% Header = string()
%% Value = string()
%% RequestBody = string()
%% Result = {ok, StatusCode, Hdrs, ResponseBody}
%% | {error, Reason}
%% StatusCode = integer()
%% ResponseBody = string()
%% Reason = connection_closed | connect_timeout | timeout
%% @doc Sends a POST request.
%% Would be the same as calling
%% `request(post, URL, Hdrs, Body)'.
%% @end
%% @see request/4
-spec post(string(), headers(), string()) -> result().
post(URL, Hdrs, Body) ->
NewHdrs = case [X
|| {X, _} <- Hdrs,
str:to_lower(X) == <<"content-type">>]
of
[] ->
[{<<"content-type">>, <<"x-www-form-urlencoded">>}
| Hdrs];
_ -> Hdrs
end,
request(post, URL, NewHdrs, Body).
%% @spec (Method, URL, Hdrs) -> Result
%% Method = atom()
%% URL = string()
%% Hdrs = [{Header, Value}]
%% Header = string()
%% Value = string()
%% Result = {ok, StatusCode, Hdrs, ResponseBody}
%% | {error, Reason}
%% StatusCode = integer()
%% ResponseBody = string()
%% Reason = connection_closed | connect_timeout | timeout
%% @doc Sends a request without a body.
%% Would be the same as calling `request(Method, URL, Hdrs, [], [])',
%% that is {@link request/5} with an empty body.
%% @end
%% @see request/5
-spec request(atom(), string(), headers()) -> result().
request(Method, URL, Hdrs) ->
request(Method, URL, Hdrs, [], []).
%% @spec (Method, URL, Hdrs, RequestBody) -> Result
%% Method = atom()
%% URL = string()
%% Hdrs = [{Header, Value}]
%% Header = string()
%% Value = string()
%% RequestBody = string()
%% Result = {ok, StatusCode, Hdrs, ResponseBody}
%% | {error, Reason}
%% StatusCode = integer()
%% ResponseBody = string()
%% Reason = connection_closed | connect_timeout | timeout
%% @doc Sends a request with a body.
%% Would be the same as calling
%% `request(Method, URL, Hdrs, Body, [])', that is {@link request/5}
%% with no options.
%% @end
%% @see request/5
-spec request(atom(), string(), headers(), string()) -> result().
request(Method, URL, Hdrs, Body) ->
request(Method, URL, Hdrs, Body, []).
% ibrowse {response_format, response_format()} |
% Options - [option()]
% Option - {sync, boolean()} | {stream, StreamTo} | {body_format, body_format()} | {full_result,
% boolean()} | {headers_as_is, boolean()}
%body_format() = string() | binary()
% The body_format option is only valid for the synchronous request and the default is string.
% When making an asynchronous request the body will always be received as a binary.
% lhttpc: always binary
......@@ -6,7 +6,7 @@
%%% Created : 7 Oct 2015 by Paweł Chmielowski <pawel@process-one.net>
%%%
%%%
%%% Copyright (C) 2002-2015 ProcessOne, SARL. All Rights Reserved.
%%% Copyright (C) 2002-2017 ProcessOne, SARL. All Rights Reserved.
%%%
%%% Licensed under the Apache License, Version 2.0 (the "License");
%%% you may not use this file except in compliance with the License.
......
......@@ -18,7 +18,7 @@
%%
%% The code has been modified and improved by ProcessOne.
%%
%% Copyright 2007-2015 ProcessOne
%% Copyright 2007-2017 ProcessOne
%%
%% The change adds the following features:
%% - You can send exit(priority_shutdown) to the p1_fsm process to
......@@ -114,6 +114,8 @@
-export([system_continue/3,
system_terminate/4,
system_code_change/4,
system_get_state/1,
system_replace_state/2,
format_status/2]).
%% Internal exports
......@@ -439,7 +441,7 @@ collect_messages(Queue, QueueLen, Time) ->
Input ->
{Input, Queue, QueueLen}
after Time ->
{{'$gen_event', timeout}, Queue, QueueLen}
{timeout, Queue, QueueLen}
end
end
end.
......@@ -459,15 +461,6 @@ decode_msg(Msg, Parent, Name, State, Mod, Time, Debug,
Limits, Queue, QueueLen, Hib) ->
put('$internal_queue_len', QueueLen),
case Msg of
{system, From, get_state} ->
sys:handle_system_msg(get_state, From, Parent, ?MODULE, Debug,
{State, [Name, State, Mod, Time,
Limits, Queue, QueueLen]}, Hib);
{system, From, {replace_state, StateFun}} ->
NState = try StateFun(State) catch _:_ -> State end,
sys:handle_system_msg(replace_state, From, Parent, ?MODULE, Debug,
{NState, [Name, NState, Mod, Time,
Limits, Queue, QueueLen]}, Hib);
{system, From, Req} ->
sys:handle_system_msg(Req, From, Parent, ?MODULE, Debug,
[Name, State, Mod, Time,
......@@ -808,6 +801,17 @@ system_code_change([Name, State, Mod, Time,
Else -> Else
end.
system_get_state([_Name, State, _Mod, _Time,
_Limits, _Queue, _QueueLen]) ->
{ok, State}.
system_replace_state(StateFun,
[Name, State, Mod, Time,
Limits, Queue, QueueLen]) ->
NState = StateFun(State),
{ok, NState, [Name, NState, Mod, Time,
Limits, Queue, QueueLen]}.
%%-----------------------------------------------------------------
%% Format debug messages. Print them as the call-back module sees
%% them, not as the real erlang messages. Use trace for that.
......
{application, p1_utils,
[
{description, "Erlang utility modules from ProcessOne"},
{vsn, "1.0.5"},
{vsn, "1.0.7"},
{modules, []},
{registered, []},
{applications, [
......
......@@ -5,7 +5,7 @@
%%% Created : 22 Apr 2008 by Alexey Shchepin <alexey@process-one.net>
%%%
%%%
%%% Copyright (C) 2002-2015 ProcessOne, SARL. All Rights Reserved.
%%% Copyright (C) 2002-2017 ProcessOne, SARL. All Rights Reserved.
%%%
%%% Licensed under the Apache License, Version 2.0 (the "License");
%%% you may not use this file except in compliance with the License.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment