From d36857bfd25711b5b8438440146a34916b35bddc Mon Sep 17 00:00:00 2001 From: Micael Karlberg Date: Fri, 13 Sep 2013 12:50:45 +0200 Subject: [inets/httpd] Fixed mod_head handling of "new" response --- lib/inets/src/http_server/httpd_response.erl | 33 ++++++++++++++++------------ lib/inets/src/http_server/mod_head.erl | 4 ++++ lib/inets/src/inets_app/inets_internal.hrl | 2 ++ 3 files changed, 25 insertions(+), 14 deletions(-) (limited to 'lib/inets') diff --git a/lib/inets/src/http_server/httpd_response.erl b/lib/inets/src/http_server/httpd_response.erl index a45b04f275..0895729d05 100644 --- a/lib/inets/src/http_server/httpd_response.erl +++ b/lib/inets/src/http_server/httpd_response.erl @@ -23,9 +23,10 @@ is_disable_chunked_send/1, cache_headers/2]). -export([map_status_code/2]). --include("httpd.hrl"). --include("http_internal.hrl"). --include("httpd_internal.hrl"). +-include_lib("inets/src/inets_app/inets_internal.hrl"). +-include_lib("inets/include/httpd.hrl"). +-include_lib("inets/src/http_lib/http_internal.hrl"). +-include_lib("inets/src/http_server/httpd_internal.hrl"). -define(VMODULE,"RESPONSE"). @@ -35,7 +36,7 @@ generate_and_send_response(#mod{init_data = #init_data{peername = {_,"unknown"}}}) -> ok; generate_and_send_response(#mod{config_db = ConfigDB} = ModData) -> - Modules = httpd_util:lookup(ConfigDB,modules, ?DEFAULT_MODS), + Modules = httpd_util:lookup(ConfigDB, modules, ?DEFAULT_MODS), case traverse_modules(ModData, Modules) of done -> ok; @@ -68,16 +69,7 @@ traverse_modules(ModData,[]) -> {proceed,ModData#mod.data}; traverse_modules(ModData,[Module|Rest]) -> ?hdrd("traverse modules", [{callback_module, Module}]), - case (catch apply(Module, do, [ModData])) of - {'EXIT', Reason} -> - String = - lists:flatten( - io_lib:format("traverse exit from apply: ~p:do => ~n~p", - [Module, Reason])), - report_error(mod_log, ModData#mod.config_db, String), - report_error(mod_disk_log, ModData#mod.config_db, String), - send_status(ModData, 500, none), - done; + try apply(Module, do, [ModData]) of done -> ?hdrt("traverse modules - done", []), done; @@ -87,6 +79,19 @@ traverse_modules(ModData,[Module|Rest]) -> {proceed, NewData} -> ?hdrt("traverse modules - proceed", [{new_data, NewData}]), traverse_modules(ModData#mod{data = NewData}, Rest) + catch + T:E -> + String = + lists:flatten( + io_lib:format("module traverse failed: ~p:do => " + "~n Error Type: ~p" + "~n Error: ~p" + "~n Stack trace: ~p", + [Module, T, E, ?STACK()])), + report_error(mod_log, ModData#mod.config_db, String), + report_error(mod_disk_log, ModData#mod.config_db, String), + send_status(ModData, 500, none), + done end. %% send_status %% diff --git a/lib/inets/src/http_server/mod_head.erl b/lib/inets/src/http_server/mod_head.erl index c346fd4d23..02b8485b25 100644 --- a/lib/inets/src/http_server/mod_head.erl +++ b/lib/inets/src/http_server/mod_head.erl @@ -42,6 +42,10 @@ do(Info) -> %% A response has been sent! Nothing to do about it! {already_sent, _StatusCode, _Size} -> {proceed,Info#mod.data}; + {response, Header, _Body} -> %% New way + {proceed, + lists:keyreplace(response, 1, Info#mod.data, + {response, Header, nobody})}; %% A response has been generated! {_StatusCode, _Response} -> {proceed,Info#mod.data} diff --git a/lib/inets/src/inets_app/inets_internal.hrl b/lib/inets/src/inets_app/inets_internal.hrl index e56af3b59d..06843f2275 100644 --- a/lib/inets/src/inets_app/inets_internal.hrl +++ b/lib/inets/src/inets_app/inets_internal.hrl @@ -21,6 +21,8 @@ -ifndef(inets_internal_hrl). -define(inets_internal_hrl, true). +-define(STACK(), erlang:get_stacktrace()). + %% Various trace macros -define(report(Severity, Label, Service, Content), -- cgit v1.2.3 From b6447a51da5e601ce24b20b9059143e7db5f981d Mon Sep 17 00:00:00 2001 From: Micael Karlberg Date: Mon, 16 Sep 2013 11:47:06 +0200 Subject: [inets/httpd] Logging cleanup Remove logging when fo keep-alive connection timeout. This is a normal event (feature) not an error. --- lib/inets/src/http_server/httpd_request_handler.erl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'lib/inets') diff --git a/lib/inets/src/http_server/httpd_request_handler.erl b/lib/inets/src/http_server/httpd_request_handler.erl index cb20159794..57beb1e403 100644 --- a/lib/inets/src/http_server/httpd_request_handler.erl +++ b/lib/inets/src/http_server/httpd_request_handler.erl @@ -268,8 +268,8 @@ 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 " - "before server side timeout", ModData), + %% 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) -> -- cgit v1.2.3 From 1b39c3289665b82d0dd8d3d232bc9de1d7fb5237 Mon Sep 17 00:00:00 2001 From: Micael Karlberg Date: Mon, 16 Sep 2013 12:44:50 +0200 Subject: [inets/httpd] Improved access log entry Sometimes the size of a response could be as a string. --- lib/inets/src/http_server/httpd_log.erl | 15 +++++++++++---- lib/inets/src/http_server/httpd_request_handler.erl | 2 +- 2 files changed, 12 insertions(+), 5 deletions(-) (limited to 'lib/inets') diff --git a/lib/inets/src/http_server/httpd_log.erl b/lib/inets/src/http_server/httpd_log.erl index a34435e0e8..7ff73669f9 100644 --- a/lib/inets/src/http_server/httpd_log.erl +++ b/lib/inets/src/http_server/httpd_log.erl @@ -39,14 +39,21 @@ Size :: 0 | pos_integer() | string()) -> {Log :: atom() | pid(), Entry :: string()} | term() . -access_entry(Log, NoLog, Info, RFC931, AuthUser, Date, StatusCode, SizeStr) - when is_list(SizeStr) -> +%% Somethime the size in the form of the content_length is put here, which +%% is actually in the form of a string +%% So it can either be the size as an integer, the size as a string +%% or, worst case scenario, bytes. +access_entry(Log, NoLog, Info, RFC931, AuthUser, Date, StatusCode, + SizeStrOrBytes) + when is_list(SizeStrOrBytes) -> Size = - case (catch list_to_integer(SizeStr)) of + case (catch list_to_integer(SizeStrOrBytes)) of I when is_integer(I) -> + %% This is from using the content_length (which is a string) I; _ -> - SizeStr % This is better then nothing + %% This is better than nothing + httpd_util:flatlength(SizeStrOrBytes) end, access_entry(Log, NoLog, Info, RFC931, AuthUser, Date, StatusCode, Size); access_entry(Log, NoLog, diff --git a/lib/inets/src/http_server/httpd_request_handler.erl b/lib/inets/src/http_server/httpd_request_handler.erl index 57beb1e403..2e4a35d031 100644 --- a/lib/inets/src/http_server/httpd_request_handler.erl +++ b/lib/inets/src/http_server/httpd_request_handler.erl @@ -267,7 +267,7 @@ handle_info({ssl_error, _, _} = Reason, State) -> {stop, Reason, State}; %% Timeouts -handle_info(timeout, #state{mod = ModData, mfa = {_, parse, _}} = State) -> +handle_info(timeout, #state{mfa = {_, parse, _}} = State) -> %% error_log("No request received on keep-alive connection " %% "before server side timeout", ModData), %% No response should be sent! -- cgit v1.2.3 From a589518053c2893dead28fd159ef3d9e48585cf4 Mon Sep 17 00:00:00 2001 From: Micael Karlberg Date: Mon, 16 Sep 2013 17:52:27 +0200 Subject: [inets/httpd] Improved request handler terminate error-log entry If a request handler terminates abnormally (terminate reason not normal), the error-log entry was a bit obtuse ("Internal Server Error"). This has been improved so that the log entry now also include the actual terminate reason. --- lib/inets/src/http_server/httpd_request_handler.erl | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'lib/inets') diff --git a/lib/inets/src/http_server/httpd_request_handler.erl b/lib/inets/src/http_server/httpd_request_handler.erl index 2e4a35d031..ea7a17e40d 100644 --- a/lib/inets/src/http_server/httpd_request_handler.erl +++ b/lib/inets/src/http_server/httpd_request_handler.erl @@ -316,7 +316,10 @@ terminate(normal, State) -> do_terminate(State); terminate(Reason, #state{response_sent = false, mod = ModData} = State) -> httpd_response:send_status(ModData, 500, none), - error_log(httpd_util:reason_phrase(500), ModData), + ReasonStr = + lists:flatten(io_lib:format("~s - ~p", + [httpd_util:reason_phrase(500), Reason])), + error_log(ReasonStr, ModData), terminate(Reason, State#state{response_sent = true, mod = ModData}); terminate(_Reason, State) -> do_terminate(State). -- cgit v1.2.3