summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMicael Karlberg <bmk@erlang.org>2012-01-03 11:42:58 +0100
committerMicael Karlberg <bmk@erlang.org>2012-01-03 11:42:58 +0100
commit10014b400da456869449c2affe683ddd2e252d0c (patch)
tree4fbeb0185735235e1df019bbba7b3f021f3b0257
parent021d5c2e49e623d4f43c0cc88a097bc99f3564e6 (diff)
downloaderlang-10014b400da456869449c2affe683ddd2e252d0c.tar.gz
[inets/httpc] Fix the selection of session for keep-alive mode
When selecting a session, the "state" of the session (specifically if the server has responded) was not taken into account. Attempting to fix this, a "state" field (actually available) has been added to the session record. OTP-9847
-rw-r--r--lib/inets/src/http_client/httpc_handler.erl24
-rw-r--r--lib/inets/src/http_client/httpc_internal.hrl36
-rw-r--r--lib/inets/src/http_client/httpc_manager.erl29
-rw-r--r--lib/inets/src/inets_app/inets.appup.src30
-rw-r--r--lib/inets/vsn.mk2
5 files changed, 99 insertions, 22 deletions
diff --git a/lib/inets/src/http_client/httpc_handler.erl b/lib/inets/src/http_client/httpc_handler.erl
index 587e24cc8d..8874304bd6 100644
--- a/lib/inets/src/http_client/httpc_handler.erl
+++ b/lib/inets/src/http_client/httpc_handler.erl
@@ -1403,7 +1403,9 @@ try_to_enable_pipeline_or_keep_alive(
end.
answer_request(#request{id = RequestId, from = From} = Request, Msg,
- #state{timers = Timers, profile_name = ProfileName} = State) ->
+ #state{session = Session,
+ timers = Timers,
+ profile_name = ProfileName} = State) ->
?hcrt("answer request", [{request, Request}, {msg, Msg}]),
httpc_response:send(From, Msg),
RequestTimers = Timers#timers.request_timers,
@@ -1412,12 +1414,22 @@ answer_request(#request{id = RequestId, from = From} = Request, Msg,
Timer = {RequestId, TimerRef},
cancel_timer(TimerRef, {timeout, Request#request.id}),
httpc_manager:request_done(RequestId, ProfileName),
-
+ NewSession = maybe_make_session_available(ProfileName, Session),
+ Timers2 = Timers#timers{request_timers = lists:delete(Timer,
+ RequestTimers)},
State#state{request = Request#request{from = answer_sent},
- timers =
- Timers#timers{request_timers =
- lists:delete(Timer, RequestTimers)}}.
-
+ session = NewSession,
+ timers = Timers2}.
+
+maybe_make_session_available(ProfileName,
+ #session{id = SessionId,
+ available = false} = Session) ->
+ httpc_manager:update_session(ProfileName, SessionId,
+ #session.available, true),
+ Session#session{available = true};
+maybe_make_session_available(_ProfileName, Session) ->
+ Session.
+
cancel_timers(#timers{request_timers = ReqTmrs, queue_timer = QTmr}) ->
cancel_timer(QTmr, timeout_queue),
CancelTimer = fun({_, Timer}) -> cancel_timer(Timer, timeout) end,
diff --git a/lib/inets/src/http_client/httpc_internal.hrl b/lib/inets/src/http_client/httpc_internal.hrl
index 1d8a5b6a92..3261061d61 100644
--- a/lib/inets/src/http_client/httpc_internal.hrl
+++ b/lib/inets/src/http_client/httpc_internal.hrl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2005-2010. All Rights Reserved.
+%% Copyright Ericsson AB 2005-2012. 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
@@ -112,17 +112,37 @@
}
).
+
-record(session,
{
- id, % {{Host, Port}, HandlerPid}
- client_close, % true | false
- scheme, % http (HTTP/TCP) | https (HTTP/SSL/TCP)
- socket, % Open socket, used by connection
- socket_type, % socket-type, used by connection
- queue_length = 1, % Current length of pipeline or keep-alive queue
- type % pipeline | keep_alive (wait for response before sending new request)
+ %% {{Host, Port}, HandlerPid}
+ id,
+
+ %% true | false
+ client_close,
+
+ %% http (HTTP/TCP) | https (HTTP/SSL/TCP)
+ scheme,
+
+ %% Open socket, used by connection
+ socket,
+
+ %% socket-type, used by connection
+ socket_type,
+
+ %% Current length of pipeline or keep-alive queue
+ queue_length = 1,
+
+ %% pipeline | keep_alive (wait for response before sending new request)
+ type,
+
+ %% true | false
+ %% This will be true, when a response has been received for
+ %% the first request. See type above.
+ available = false
}).
+
-record(http_cookie,
{
domain,
diff --git a/lib/inets/src/http_client/httpc_manager.erl b/lib/inets/src/http_client/httpc_manager.erl
index 9015bf1ce2..d699f1e7d8 100644
--- a/lib/inets/src/http_client/httpc_manager.erl
+++ b/lib/inets/src/http_client/httpc_manager.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2002-2011. All Rights Reserved.
+%% Copyright Ericsson AB 2002-2012. 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
@@ -34,6 +34,7 @@
retry_request/2,
redirect_request/2,
insert_session/2,
+ update_session/4,
delete_session/2,
set_options/2,
store_cookies/3,
@@ -193,6 +194,29 @@ insert_session(Session, ProfileName) ->
%%--------------------------------------------------------------------
+%% Function: update_session(ProfileName, SessionId, Pos, Value) -> _
+%% Session - #session{}
+%% ProfileName - atom()
+%%
+%% Description: Update, only one field (Pos) of the session record
+%% identified by the SessionId, the session information
+%% of the httpc manager table <ProfileName>_session_db.
+%% Intended to be called by the httpc request handler process.
+%%--------------------------------------------------------------------
+
+update_session(ProfileName, SessionId, Pos, Value) ->
+ SessionDbName = session_db_name(ProfileName),
+ ?hcrt("insert session",
+ [{id, SessionId},
+ {pos, Pos},
+ {value, Value},
+ {profile, ProfileName}]),
+ ets:update_element(SessionDbName, SessionId, {Pos, Value}).
+
+
+
+
+%%--------------------------------------------------------------------
%% Function: delete_session(SessionId, ProfileName) -> _
%% SessionId - {{Host, Port}, HandlerPid}
%% ProfileName - atom()
@@ -679,6 +703,7 @@ select_session(Method, HostPort, Scheme, SessionType,
scheme = Scheme,
queue_length = '$2',
type = SessionType,
+ available = true,
_ = '_'},
%% {'_', {HostPort, '$1'}, false, Scheme, '_', '$2', SessionTyp},
Candidates = ets:match(SessionDb, Pattern),
@@ -716,7 +741,7 @@ pipeline_or_keep_alive(Request, HandlerPid, State) ->
ets:insert(State#state.handler_db, {Request#request.id,
HandlerPid,
Request#request.from});
- _ -> %timeout pipelining failed
+ _ -> % timeout pipelining failed
start_handler(Request, State)
end.
diff --git a/lib/inets/src/inets_app/inets.appup.src b/lib/inets/src/inets_app/inets.appup.src
index fb605351b4..9108faf197 100644
--- a/lib/inets/src/inets_app/inets.appup.src
+++ b/lib/inets/src/inets_app/inets.appup.src
@@ -1,7 +1,7 @@
%% This is an -*- erlang -*- file.
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1999-2011. All Rights Reserved.
+%% Copyright Ericsson AB 1999-2012. 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,12 @@
{"%VSN%",
[
+ {"5.7.2",
+ [
+ {update, httpc_handler, soft, soft_purge, soft_purge, []},
+ {update, httpc_manager, soft, soft_purge, soft_purge, [httpc_handler]}
+ ]
+ },
{"5.7.1",
[
{load_module, http_uri, soft_purge, soft_purge, []},
@@ -26,7 +32,9 @@
{load_module, httpd_file, soft_purge, soft_purge, []},
{load_module, httpd_request, soft_purge, soft_purge, []},
{load_module, mod_responsecontrol, soft_purge, soft_purge, []},
- {load_module, httpd_response, soft_purge, soft_purge, [mod_responsecontrol]}
+ {load_module, httpd_response, soft_purge, soft_purge, [mod_responsecontrol]},
+ {update, httpc_handler, soft, soft_purge, soft_purge, []},
+ {update, httpc_manager, soft, soft_purge, soft_purge, [httpc_handler]}
]
},
{"5.7",
@@ -38,7 +46,9 @@
{load_module, httpc_cookie, soft_purge, soft_purge, [http_util]},
{load_module, http_util, soft_purge, soft_purge, []},
{load_module, mod_responsecontrol, soft_purge, soft_purge, []},
- {load_module, httpd_response, soft_purge, soft_purge, [mod_responsecontrol]}
+ {load_module, httpd_response, soft_purge, soft_purge, [mod_responsecontrol]},
+ {update, httpc_handler, soft, soft_purge, soft_purge, []},
+ {update, httpc_manager, soft, soft_purge, soft_purge, [httpc_handler]}
]
},
{"5.6",
@@ -80,6 +90,12 @@
}
],
[
+ {"5.7.2",
+ [
+ {update, httpc_handler, soft, soft_purge, soft_purge, []},
+ {update, httpc_manager, soft, soft_purge, soft_purge, [httpc_handler]}
+ ]
+ },
{"5.7.1",
[
{load_module, http_uri, soft_purge, soft_purge, []},
@@ -88,7 +104,9 @@
{load_module, httpd_file, soft_purge, soft_purge, []},
{load_module, httpd_request, soft_purge, soft_purge, []},
{load_module, mod_responsecontrol, soft_purge, soft_purge, []},
- {load_module, httpd_response, soft_purge, soft_purge, [mod_responsecontrol]}
+ {load_module, httpd_response, soft_purge, soft_purge, [mod_responsecontrol]},
+ {update, httpc_handler, soft, soft_purge, soft_purge, []},
+ {update, httpc_manager, soft, soft_purge, soft_purge, [httpc_handler]}
]
},
{"5.7",
@@ -100,7 +118,9 @@
{load_module, httpc_cookie, soft_purge, soft_purge, [http_util]},
{load_module, http_util, soft_purge, soft_purge, []},
{load_module, mod_responsecontrol, soft_purge, soft_purge, []},
- {load_module, httpd_response, soft_purge, soft_purge, [mod_responsecontrol]}
+ {load_module, httpd_response, soft_purge, soft_purge, [mod_responsecontrol]},
+ {update, httpc_handler, soft, soft_purge, soft_purge, []},
+ {update, httpc_manager, soft, soft_purge, soft_purge, [httpc_handler]}
]
},
{"5.6",
diff --git a/lib/inets/vsn.mk b/lib/inets/vsn.mk
index d294d0006e..e34500b3ab 100644
--- a/lib/inets/vsn.mk
+++ b/lib/inets/vsn.mk
@@ -18,7 +18,7 @@
# %CopyrightEnd%
APPLICATION = inets
-INETS_VSN = 5.7.2
+INETS_VSN = 5.7.3
PRE_VSN =
APP_VSN = "$(APPLICATION)-$(INETS_VSN)$(PRE_VSN)"