summaryrefslogtreecommitdiff
path: root/lib/inets/src/http_client/httpc_handler.erl
diff options
context:
space:
mode:
Diffstat (limited to 'lib/inets/src/http_client/httpc_handler.erl')
-rw-r--r--lib/inets/src/http_client/httpc_handler.erl44
1 files changed, 26 insertions, 18 deletions
diff --git a/lib/inets/src/http_client/httpc_handler.erl b/lib/inets/src/http_client/httpc_handler.erl
index 3f91ae062c..9135935567 100644
--- a/lib/inets/src/http_client/httpc_handler.erl
+++ b/lib/inets/src/http_client/httpc_handler.erl
@@ -602,12 +602,18 @@ do_handle_info({Proto, Socket, Data},
{noreply, State};
%% The Server may close the connection to indicate that the
-%% whole body is now sent instead of sending an length
-%% indicator.
-do_handle_info({tcp_closed, _}, State = #state{mfa = {_, whole_body, Args}}) ->
- handle_response(State#state{body = hd(Args)});
-do_handle_info({ssl_closed, _}, State = #state{mfa = {_, whole_body, Args}}) ->
- handle_response(State#state{body = hd(Args)});
+%% whole body is now sent instead of sending a lengh
+%% indicator. In this case the lengh indicator will be
+%% -1.
+do_handle_info({Info, _}, State = #state{mfa = {_, whole_body, Args}})
+ when Info =:= tcp_closed orelse
+ Info =:= ssl_closed ->
+ case lists:last(Args) of
+ Length when Length =< 0 ->
+ handle_response(State#state{body = hd(Args)});
+ _Else ->
+ {stop, {shutdown, server_closed}, State}
+ end;
%%% Server closes idle pipeline
do_handle_info({tcp_closed, _}, State = #state{request = undefined}) ->
@@ -831,8 +837,7 @@ connect_and_send_first_request(Address, Request, #state{options = Options0} = St
headers = undefined,
body = undefined,
status = new},
- http_transport:setopts(SocketType,
- Socket, [{active, once}]),
+ activate_once(Session),
NewState = activate_request_timeout(TmpState),
{ok, NewState};
{error, Reason} ->
@@ -966,16 +971,16 @@ handle_http_body(_, #state{status = {ssl_tunnel, Request},
%% terminated by the first empty line after the header fields.
%% This implies that chunked encoding MUST NOT be used for these
%% status codes.
-handle_http_body(<<>>, #state{headers = Headers,
+handle_http_body(Body, #state{headers = Headers,
status_line = {_,StatusCode, _}} = State)
when Headers#http_response_h.'transfer-encoding' =/= "chunked" andalso
(StatusCode =:= 204 orelse %% No Content
StatusCode =:= 304 orelse %% Not Modified
100 =< StatusCode andalso StatusCode =< 199) -> %% Informational
- handle_response(State#state{body = <<>>});
+ handle_response(State#state{body = Body});
-
-handle_http_body(<<>>, #state{request = #request{method = head}} = State) ->
+%% Ignore the body of response to a HEAD method
+handle_http_body(_Body, #state{request = #request{method = head}} = State) ->
handle_response(State#state{body = <<>>});
handle_http_body(Body, #state{headers = Headers,
@@ -1238,7 +1243,12 @@ case_insensitive_header(Str) ->
Str.
activate_once(#session{socket = Socket, socket_type = SocketType}) ->
- http_transport:setopts(SocketType, Socket, [{active, once}]).
+ case http_transport:setopts(SocketType, Socket, [{active, once}]) of
+ ok ->
+ ok;
+ {error, _} -> %% inet can return einval instead of closed
+ self() ! {http_transport:close_tag(SocketType), Socket}
+ end.
close_socket(#session{socket = {remote_close,_}}) ->
ok;
@@ -1581,8 +1591,7 @@ send_raw(SocketType, Socket, ProcessBody, Acc) ->
end
end.
-tls_tunnel(Address, Request, #state{session = #session{socket = Socket,
- socket_type = SocketType} = Session} = State,
+tls_tunnel(Address, Request, #state{session = #session{} = Session} = State,
ErrorHandler) ->
UpgradeRequest = tls_tunnel_request(Request),
case httpc_request:send(Address, Session, UpgradeRequest) of
@@ -1594,8 +1603,7 @@ tls_tunnel(Address, Request, #state{session = #session{socket = Socket,
init_status_line(UpgradeRequest),
headers = undefined,
body = undefined},
- http_transport:setopts(SocketType,
- Socket, [{active, once}]),
+ activate_once(Session),
NewState = activate_request_timeout(TmpState),
{ok, NewState#state{status = {ssl_tunnel, Request}}};
{error, Reason} ->
@@ -1661,7 +1669,7 @@ tls_upgrade(#state{status =
type = SessionType,
client_close = ClientClose},
httpc_request:send(Address, Session, Request),
- http_transport:setopts(SocketType, TLSSocket, [{active, once}]),
+ activate_once(Session),
NewState = State#state{session = Session,
request = Request,
mfa = init_mfa(Request, State),