aboutsummaryrefslogtreecommitdiffstats
path: root/lib/inets/src/http_server/httpd_request_handler.erl
diff options
context:
space:
mode:
Diffstat (limited to 'lib/inets/src/http_server/httpd_request_handler.erl')
-rw-r--r--lib/inets/src/http_server/httpd_request_handler.erl102
1 files changed, 65 insertions, 37 deletions
diff --git a/lib/inets/src/http_server/httpd_request_handler.erl b/lib/inets/src/http_server/httpd_request_handler.erl
index 1bf1b20b5b..d2f22fce93 100644
--- a/lib/inets/src/http_server/httpd_request_handler.erl
+++ b/lib/inets/src/http_server/httpd_request_handler.erl
@@ -8,12 +8,12 @@
%% 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%
%%
%%
@@ -101,11 +101,13 @@ init([Manager, ConfigDB, AcceptTimeout]) ->
Then = erlang:now(),
+ ?hdrd("negotiate", []),
case http_transport:negotiate(SocketType, Socket, TimeOut) of
{error, Error} ->
+ ?hdrd("negotiation failed", [{error, Error}]),
exit(Error); %% Can be 'normal'.
ok ->
- ?hdrt("negotiated", []),
+ ?hdrt("negotiation successfull", []),
NewTimeout = TimeOut - timer:now_diff(now(),Then) div 1000,
continue_init(Manager, ConfigDB, SocketType, Socket, NewTimeout)
end.
@@ -121,12 +123,9 @@ continue_init(Manager, ConfigDB, SocketType, Socket, TimeOut) ->
socket = Socket,
init_data = InitData},
- MaxHeaderSize = httpd_util:lookup(ConfigDB, max_header_size,
- ?HTTP_MAX_HEADER_SIZE),
- MaxURISize = httpd_util:lookup(ConfigDB, max_uri_size,
- ?HTTP_MAX_URI_SIZE),
- NrOfRequest = httpd_util:lookup(ConfigDB,
- max_keep_alive_request, infinity),
+ MaxHeaderSize = max_header_size(ConfigDB),
+ MaxURISize = max_uri_size(ConfigDB),
+ NrOfRequest = max_keep_alive_request(ConfigDB),
{_, Status} = httpd_manager:new_connection(Manager),
@@ -142,9 +141,10 @@ continue_init(Manager, ConfigDB, SocketType, Socket, TimeOut) ->
?hdrt("activate request timeout", []),
NewState = activate_request_timeout(State),
- ?hdrt("update socket options", []),
- http_transport:setopts(SocketType, Socket, [binary,{packet, 0},
- {active, once}]),
+ ?hdrt("set socket options (binary, packet & active)", []),
+ http_transport:setopts(SocketType, Socket,
+ [binary, {packet, 0}, {active, once}]),
+
?hdrt("init done", []),
gen_server:enter_loop(?MODULE, [], NewState).
@@ -180,21 +180,29 @@ handle_cast(Msg, State) ->
%% {stop, Reason, State}
%% Description: Handling all non call/cast messages
%%--------------------------------------------------------------------
-handle_info({Proto, Socket, Data}, State =
+handle_info({Proto, Socket, Data},
#state{mfa = {Module, Function, Args} = MFA,
mod = #mod{socket_type = SockType,
socket = Socket} = ModData} = State)
when (((Proto =:= tcp) orelse
(Proto =:= ssl) orelse
(Proto =:= dummy)) andalso is_binary(Data)) ->
+
?hdrd("received data",
[{data, Data}, {proto, Proto},
{socket, Socket}, {socket_type, SockType}, {mfa, MFA}]),
- case Module:Function([Data | Args]) of
+
+%% case (catch Module:Function([Data | Args])) of
+ PROCESSED = (catch Module:Function([Data | Args])),
+
+ ?hdrt("data processed", [{processing_result, PROCESSED}]),
+
+ case PROCESSED of
{ok, Result} ->
?hdrd("data processed", [{result, Result}]),
NewState = cancel_request_timeout(State),
handle_http_msg(Result, NewState);
+
{error, {uri_too_long, MaxSize}, Version} ->
?hdrv("uri too long", [{max_size, MaxSize}, {version, Version}]),
NewModData = ModData#mod{http_version = Version},
@@ -205,7 +213,8 @@ handle_info({Proto, Socket, Data}, State =
{stop, normal, State#state{response_sent = true,
mod = NewModData}};
{error, {header_too_long, MaxSize}, Version} ->
- ?hdrv("header too long", [{max_size, MaxSize}, {version, Version}]),
+ ?hdrv("header too long",
+ [{max_size, MaxSize}, {version, Version}]),
NewModData = ModData#mod{http_version = Version},
httpd_response:send_status(NewModData, 413, "Header too long"),
Reason = io_lib:format("Header too long, max size is ~p~n",
@@ -231,13 +240,13 @@ handle_info({ssl_error, _, _} = Reason, State) ->
%% Timeouts
handle_info(timeout, #state{mod = ModData, mfa = {_, parse, _}} = State) ->
- error_log("No request received on keep-alive connection"
+ error_log("No request received on keep-alive connection "
"before server side timeout", ModData),
%% No response should be sent!
{stop, normal, State#state{response_sent = true}};
handle_info(timeout, #state{mod = ModData} = State) ->
httpd_response:send_status(ModData, 408, "Request timeout"),
- error_log("The client did not send the whole request before the"
+ error_log("The client did not send the whole request before the "
"server side timeout", ModData),
{stop, normal, State#state{response_sent = true}};
@@ -263,14 +272,16 @@ terminate(Reason, #state{response_sent = false, mod = ModData} = State) ->
httpd_response:send_status(ModData, 500, none),
error_log(httpd_util:reason_phrase(500), ModData),
terminate(Reason, State#state{response_sent = true, mod = ModData});
-terminate(_, State) ->
+terminate(_Reason, State) ->
do_terminate(State).
do_terminate(#state{mod = ModData, manager = Manager} = State) ->
catch httpd_manager:done_connection(Manager),
cancel_request_timeout(State),
+ %% receive after 5000 -> ok end,
httpd_socket:close(ModData#mod.socket_type, ModData#mod.socket).
+
%%--------------------------------------------------------------------
%% code_change(OldVsn, State, Extra) -> {ok, NewState}
%%
@@ -279,6 +290,7 @@ do_terminate(#state{mod = ModData, manager = Manager} = State) ->
code_change(_OldVsn, State, _Extra) ->
{ok, State}.
+
%%--------------------------------------------------------------------
%%% Internal functions
%%--------------------------------------------------------------------
@@ -383,9 +395,8 @@ is_host_specified_if_required(_, _, _) ->
handle_body(#state{mod = #mod{config_db = ConfigDB}} = State) ->
?hdrt("handle body", []),
- MaxHeaderSize =
- httpd_util:lookup(ConfigDB, max_header_size, ?HTTP_MAX_HEADER_SIZE),
- MaxBodySize = httpd_util:lookup(ConfigDB, max_body_size, nolimit),
+ MaxHeaderSize = max_header_size(ConfigDB),
+ MaxBodySize = max_body_size(ConfigDB),
case handle_expect(State, MaxBodySize) of
ok ->
@@ -538,24 +549,23 @@ handle_response(#state{body = Body,
{stop, normal, State#state{response_sent = true}}.
handle_next_request(#state{mod = #mod{connection = true} = ModData,
- max_keep_alive_request = Max} = State, Data) ->
+ max_keep_alive_request = Max} = State, Data) ->
?hdrt("handle next request", [{max, Max}]),
+
NewModData = #mod{socket_type = ModData#mod.socket_type,
- socket = ModData#mod.socket,
- config_db = ModData#mod.config_db,
- init_data = ModData#mod.init_data},
- MaxHeaderSize =
- httpd_util:lookup(ModData#mod.config_db,
- max_header_size, ?HTTP_MAX_HEADER_SIZE),
- MaxURISize = httpd_util:lookup(ModData#mod.config_db, max_uri_size,
- ?HTTP_MAX_URI_SIZE),
- TmpState = State#state{mod = NewModData,
- mfa = {httpd_request, parse, [{MaxURISize,
- MaxHeaderSize}]},
+ socket = ModData#mod.socket,
+ config_db = ModData#mod.config_db,
+ init_data = ModData#mod.init_data},
+ MaxHeaderSize = max_header_size(ModData#mod.config_db),
+ MaxURISize = max_uri_size(ModData#mod.config_db),
+
+ MFA = {httpd_request, parse, [{MaxURISize, MaxHeaderSize}]},
+ TmpState = State#state{mod = NewModData,
+ mfa = MFA,
max_keep_alive_request = decrease(Max),
- headers = undefined,
- body = undefined,
- response_sent = false},
+ headers = undefined,
+ body = undefined,
+ response_sent = false},
NewState = activate_request_timeout(TmpState),
@@ -596,7 +606,7 @@ decrease(N) ->
error_log(ReasonString, Info) ->
Error = lists:flatten(
- io_lib:format("Error reading request:~s",[ReasonString])),
+ io_lib:format("Error reading request: ~s", [ReasonString])),
error_log(mod_log, Info, Error),
error_log(mod_disk_log, Info, Error).
@@ -609,3 +619,21 @@ error_log(Mod, #mod{config_db = ConfigDB} = Info, String) ->
_ ->
ok
end.
+
+
+%%--------------------------------------------------------------------
+%% Config access wrapper functions
+%%--------------------------------------------------------------------
+
+max_header_size(ConfigDB) ->
+ httpd_util:lookup(ConfigDB, max_header_size, ?HTTP_MAX_HEADER_SIZE).
+
+max_uri_size(ConfigDB) ->
+ httpd_util:lookup(ConfigDB, max_uri_size, ?HTTP_MAX_URI_SIZE).
+
+max_body_size(ConfigDB) ->
+ httpd_util:lookup(ConfigDB, max_body_size, nolimit).
+
+max_keep_alive_request(ConfigDB) ->
+ httpd_util:lookup(ConfigDB, max_keep_alive_request, infinity).
+