Removed most of the "retry" in rescue clauses, since it was hidding critical issue.

This should be the choice of the application to "retry" on exception, otherwise let the framework handle this in the lower part.

Better handling of response termination (alias commit)
Added the notion of "status_committed"
This commit is contained in:
Jocelyn Fiat
2012-01-23 15:31:34 +01:00
parent 80d68699b1
commit 6dc1c0d2b0
8 changed files with 54 additions and 63 deletions

View File

@@ -34,27 +34,20 @@ feature -- Execution
execute (ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE) execute (ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE)
-- Execute request handler -- Execute request handler
local
rescued: BOOLEAN
do do
if not rescued then if request_method_name_supported (req.request_method) then
if request_method_name_supported (req.request_method) then if authentication_required (req) and then not authenticated (ctx) then
if authentication_required (req) and then not authenticated (ctx) then execute_unauthorized (ctx, req, res)
execute_unauthorized (ctx, req, res)
else
pre_execute (ctx, req, res)
execute_application (ctx, req, res)
post_execute (ctx, req, res)
end
else else
execute_request_method_not_allowed (req, res, supported_request_method_names) pre_execute (ctx, req, res)
execute_application (ctx, req, res)
post_execute (ctx, req, res)
end end
else else
rescue_execute (ctx, req, res) execute_request_method_not_allowed (req, res, supported_request_method_names)
end end
rescue rescue
rescued := True execute_rescue (ctx, req, res)
retry
end end
execute_application (ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE) execute_application (ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE)
@@ -69,9 +62,11 @@ feature -- Execution
do do
end end
rescue_execute (ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE) execute_rescue (ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE)
do do
post_execute (ctx, req, res) post_execute (ctx, req, res)
rescue
--| Just in case, the rescue is raising other exceptions ...
end end
execute_unauthorized (ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE) execute_unauthorized (ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE)

View File

@@ -118,32 +118,16 @@ feature -- Server
local local
req: WGI_REQUEST_FROM_TABLE req: WGI_REQUEST_FROM_TABLE
res: detachable WGI_RESPONSE_STREAM res: detachable WGI_RESPONSE_STREAM
rescued: INTEGER
do do
if rescued = 0 then create req.make (env, create {WGI_NINO_INPUT_STREAM}.make (a_socket), Current)
create req.make (env, create {WGI_NINO_INPUT_STREAM}.make (a_socket), Current) create res.make (create {WGI_NINO_OUTPUT_STREAM}.make (a_socket))
create res.make (create {WGI_NINO_OUTPUT_STREAM}.make (a_socket)) req.set_meta_string_variable ("RAW_HEADER_DATA", a_headers_text)
req.set_meta_string_variable ("RAW_HEADER_DATA", a_headers_text) service.execute (req, res)
service.execute (req, res) res.commit
elseif rescued = 1 then
if attached (create {EXCEPTION_MANAGER}).last_exception as e and then attached e.exception_trace as l_trace then
if res /= Void then
if not res.status_is_set then
res.set_status_code ({HTTP_STATUS_CODE}.internal_server_error)
end
if res.message_writable then
res.put_string ("<pre>" + l_trace + "</pre>")
end
end
end
end
rescue
rescued := rescued + 1
retry
end end
note note
copyright: "2011-2011, Eiffel Software and others" copyright: "2011-2012, Eiffel Software and others"
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)" license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
source: "[ source: "[
Eiffel Software Eiffel Software

View File

@@ -6,7 +6,7 @@ note
deferred class deferred class
WGI_RESPONSE WGI_RESPONSE
feature {WGI_RESPONSE, WGI_SERVICE} -- Commit feature {WGI_CONNECTOR, WGI_SERVICE} -- Commit
commit commit
-- Commit the current response -- Commit the current response
@@ -49,6 +49,14 @@ feature -- Status setting
deferred deferred
end end
status_committed: BOOLEAN
-- Is status code set and committed?
-- i.e: sent to the client and could not be changed anymore
deferred
ensure
committed_implies_set: Result implies status_is_set
end
set_status_code (a_code: INTEGER) set_status_code (a_code: INTEGER)
-- Set response status code -- Set response status code
-- Should be done before sending any data back to the client -- Should be done before sending any data back to the client
@@ -116,7 +124,7 @@ feature -- Output operation
end end
note note
copyright: "2011-2011, Eiffel Software and others" copyright: "2011-2012, Eiffel Software and others"
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)" license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
source: "[ source: "[
Eiffel Software Eiffel Software

View File

@@ -22,7 +22,7 @@ feature {NONE} -- Initialization
output := a_output output := a_output
end end
feature {WGI_SERVICE} -- Commit feature {WGI_CONNECTOR, WGI_SERVICE} -- Commit
commit commit
-- Commit the current response -- Commit the current response
@@ -33,6 +33,9 @@ feature {WGI_SERVICE} -- Commit
feature -- Status report feature -- Status report
status_committed: BOOLEAN
-- Status code set and committed?
header_committed: BOOLEAN header_committed: BOOLEAN
-- Header committed? -- Header committed?
@@ -68,6 +71,7 @@ feature -- Status setting
do do
status_code := a_code status_code := a_code
output.put_status_line (a_code) output.put_status_line (a_code)
status_committed := True
end end
status_code: INTEGER status_code: INTEGER
@@ -129,7 +133,7 @@ feature {NONE} -- Implementation: Access
-- Server output channel -- Server output channel
;note ;note
copyright: "2011-2011, Eiffel Software and others" copyright: "2011-2012, Eiffel Software and others"
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)" license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
source: "[ source: "[
Eiffel Software Eiffel Software

View File

@@ -11,7 +11,7 @@ note
deferred class deferred class
WGI_SERVICE WGI_SERVICE
feature -- Execution feature {WGI_CONNECTOR} -- Execution
execute (req: WGI_REQUEST; res: WGI_RESPONSE) execute (req: WGI_REQUEST; res: WGI_RESPONSE)
-- Execute the request -- Execute the request
@@ -26,7 +26,7 @@ feature -- Execution
end end
note note
copyright: "2011-2011, Eiffel Software and others" copyright: "2011-2012, Eiffel Software and others"
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)" license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
source: "[ source: "[
Eiffel Software Eiffel Software

View File

@@ -38,15 +38,10 @@ feature -- Execution
execute (req: WSF_REQUEST; res: WSF_RESPONSE) execute (req: WSF_REQUEST; res: WSF_RESPONSE)
local local
l_handled: BOOLEAN l_handled: BOOLEAN
rescued: BOOLEAN
do do
if not rescued then l_handled := router.dispatch (req, res)
l_handled := router.dispatch (req, res) if not l_handled then
if not l_handled then execute_default (req, res)
execute_default (req, res)
end
else
execute_rescue (req, res)
end end
end end
@@ -54,14 +49,6 @@ feature -- Execution
deferred deferred
end end
execute_rescue (req: WSF_REQUEST; res: WSF_RESPONSE)
do
if not res.header_committed then
res.put_header ({HTTP_STATUS_CODE}.internal_server_error, Void)
end
res.flush
end
note note
copyright: "2011-2011, Eiffel Software and others" copyright: "2011-2011, Eiffel Software and others"
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)" license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"

View File

@@ -26,6 +26,12 @@ feature {NONE} -- Initialization
feature -- Status report feature -- Status report
status_committed: BOOLEAN
-- Status line committed?
do
Result := wgi_response.status_committed
end
header_committed: BOOLEAN header_committed: BOOLEAN
-- Header committed? -- Header committed?
do do
@@ -56,7 +62,7 @@ feature -- Status setting
-- Set response status code -- Set response status code
-- Should be done before sending any data back to the client -- Should be done before sending any data back to the client
require require
status_not_set: not status_is_set status_not_set: not status_committed
header_not_committed: not header_committed header_not_committed: not header_committed
do do
wgi_response.set_status_code (a_code) wgi_response.set_status_code (a_code)

View File

@@ -26,11 +26,18 @@ feature -- Execution
deferred deferred
end end
feature -- WGI Execution feature {WGI_CONNECTOR} -- WGI Execution
wgi_execute (req: WGI_REQUEST; res: WGI_RESPONSE) wgi_execute (req: WGI_REQUEST; res: WGI_RESPONSE)
local
w_res: detachable WSF_RESPONSE
do do
execute (create {WSF_REQUEST}.make_from_wgi (req), create {WSF_RESPONSE}.make_from_wgi (res)) create w_res.make_from_wgi (res)
execute (create {WSF_REQUEST}.make_from_wgi (req), w_res)
rescue
if w_res /= Void then
w_res.flush
end
end end
end end