Files
EWF/library/server/request/router/src/handler/request_handler.e
Jocelyn Fiat 4eb22d0272 Tried to reduce gap between both EWSGI proposals
Re-adapt the Spec-compliant solution (instead of Lib-compliant solution).
  Thus no more 100% deferred interface.
Rename EWSGI_RESPONSE into EWSGI_RESPONSE_BUFFER
Added in extra/response-as-result/  an copy/paste from the implementation of Paul's proposal (not up to date with Paul's spec). But this is mainly for information and tests.
Removed part of the ewsgi/specification interfaces ... to be able to test EWSGI compliant library against the pure specification (experimental).
Renamed most of the GW_... into EWSGI_...
2011-08-01 16:41:16 +02:00

311 lines
7.7 KiB
Plaintext

note
description: "Summary description for {REQUEST_HANDLER}."
author: ""
date: "$Date$"
revision: "$Revision$"
deferred class
REQUEST_HANDLER
feature {NONE} -- Initialization
initialize
-- Initialize various attributes
do
end
feature -- Access
description: detachable STRING
-- Optional descriptiong
feature -- Status report
is_valid_context (req: EWSGI_REQUEST): BOOLEAN
-- Is `req' valid context for current handler?
do
Result := request_method_name_supported (req.environment.request_method)
end
feature -- Execution
execute (a_hdl_context: REQUEST_HANDLER_CONTEXT; req: EWSGI_REQUEST; res: EWSGI_RESPONSE_BUFFER)
-- Execute request handler
require
is_valid_context: is_valid_context (req)
local
rescued: BOOLEAN
do
if not rescued then
if request_method_name_supported (req.environment.request_method) then
pre_execute (req)
execute_application (a_hdl_context, req, res)
post_execute (req, res)
else
execute_method_not_allowed (a_hdl_context, req, res)
end
else
rescue_execute (req, res)
end
rescue
rescued := True
retry
end
execute_method_not_allowed (a_hdl_context: REQUEST_HANDLER_CONTEXT; req: EWSGI_REQUEST; res: EWSGI_RESPONSE_BUFFER)
local
s: STRING
lst: LIST [STRING]
do
res.set_status_code ({HTTP_STATUS_CODE}.method_not_allowed)
create s.make (25)
from
lst := supported_request_method_names
lst.start
until
lst.after
loop
s.append_string (lst.item)
if not lst.islast then
s.append_character (',')
s.append_character (' ')
end
lst.forth
end
res.write_header ({HTTP_STATUS_CODE}.method_not_allowed, <<["Allow", s]>>)
end
execute_application (a_hdl_context: REQUEST_HANDLER_CONTEXT; req: EWSGI_REQUEST; res: EWSGI_RESPONSE_BUFFER)
-- Execute request handler
deferred
end
pre_execute (req: EWSGI_REQUEST)
-- Operation processed before `execute'
do
--| To be redefined if needed
end
post_execute (req: EWSGI_REQUEST; res: EWSGI_RESPONSE_BUFFER)
-- Operation processed after `execute'
do
--| To be redefined if needed
end
rescue_execute (req: EWSGI_REQUEST; res: EWSGI_RESPONSE_BUFFER)
-- Operation processed after a rescue
do
--| To be redefined if needed
post_execute (req, res)
end
feature -- Execution: report
-- execution_information (req: EWSGI_REQUEST): detachable REQUEST_HANDLER_CONTEXT
-- -- Execution information related to the request
-- do
-- if attached path_information (req, req.environment.path_info) as info then
-- create Result.make (req.environment.path_info)
-- end
-- end
-- path_information (req: EWSGI_REQUEST; a_rq_path: STRING): detachable TUPLE [format: detachable STRING; arguments: detachable STRING]
-- -- Information related to `a_path'
-- local
-- l_rq_path: STRING
-- i,p,n: INTEGER
-- l_format, l_args: detachable STRING
-- do
-- l_rq_path := a_rq_path
-- if l_rq_path.count > 0 and then l_rq_path[1] /= '/' then
-- l_rq_path := "/" + l_rq_path
-- end
-- n := l_rq_path.count
-- i := req.environment.path_info.count + 1
-- if format_located_before_parameters then
-- --| path = app-path{.format}/parameters
-- if l_rq_path.valid_index (i) and then l_rq_path[i] = '.' then
-- p := l_rq_path.index_of ('/', i + 1)
-- if p = 0 then
-- p := n + 1
-- else
-- l_args := l_rq_path.substring (p + 1, n)
-- end
-- l_format := l_rq_path.substring (i + 1, p - 1)
-- elseif n > i then
-- check l_rq_path[i] = '/' end
-- l_args := l_rq_path.substring (i + 1, n)
-- end
-- elseif format_located_after_parameters then
-- --| path = app-path/parameters{.format}
-- p := l_rq_path.last_index_of ('.', n)
-- if p > i then
-- l_format := l_rq_path.substring (p + 1, n)
-- l_args := l_rq_path.substring (i + 1, p - 1)
-- elseif n > i then
-- check l_rq_path[i] = '/' end
-- l_format := Void
-- l_args := l_rq_path.substring (i + 1, n)
-- end
-- end
-- if l_format /= Void or l_args /= Void then
-- Result := [l_format, l_args]
-- end
-- end
url (req: EWSGI_REQUEST; args: detachable STRING; abs: BOOLEAN): STRING
-- Associated url based on `path' and `args'
-- if `abs' then return absolute url
local
s: detachable STRING
do
s := args
if s /= Void and then s.count > 0 then
if s[1] /= '/' then
s := req.environment.request_uri + "/" + s
else
s := req.environment.request_uri + s
end
else
s := req.environment.request_uri
end
if abs then
Result := req.absolute_script_url (s)
else
Result := req.script_url (s)
end
ensure
result_attached: Result /= Void
end
feature -- Element change
set_description (s: like description)
-- Set `description' to `s'
do
description := s
end
feature {NONE} -- Implementation
supported_request_methods: INTEGER
-- Support request method such as GET, POST, ...
feature {NONE} -- Status report
request_method_id_supported (a_id: INTEGER): BOOLEAN
do
Result := (supported_request_methods & a_id) = a_id
end
request_method_name_supported (n: STRING): BOOLEAN
-- Is request method `n' supported?
do
Result := request_method_id_supported (request_method_constants.method_id (n))
end
request_method_constants: HTTP_REQUEST_METHOD_CONSTANTS
once
create Result
end
feature -- Status report
supported_request_method_names: LIST [STRING]
-- Support request method such as GET, POST, ...
do
create {LINKED_LIST [STRING]} Result.make
if method_get_supported then
Result.extend (request_method_constants.method_get_name)
end
if method_post_supported then
Result.extend (request_method_constants.method_post_name)
end
if method_put_supported then
Result.extend (request_method_constants.method_put_name)
end
if method_delete_supported then
Result.extend (request_method_constants.method_delete_name)
end
if method_head_supported then
Result.extend (request_method_constants.method_head_name)
end
end
method_get_supported: BOOLEAN
do
Result := request_method_id_supported ({HTTP_REQUEST_METHOD_CONSTANTS}.method_get)
end
method_post_supported: BOOLEAN
do
Result := request_method_id_supported ({HTTP_REQUEST_METHOD_CONSTANTS}.method_post)
end
method_put_supported: BOOLEAN
do
Result := request_method_id_supported ({HTTP_REQUEST_METHOD_CONSTANTS}.method_put)
end
method_delete_supported: BOOLEAN
do
Result := request_method_id_supported ({HTTP_REQUEST_METHOD_CONSTANTS}.method_delete)
end
method_head_supported: BOOLEAN
do
Result := request_method_id_supported ({HTTP_REQUEST_METHOD_CONSTANTS}.method_head)
end
feature -- Element change: request methods
reset_supported_request_methods
do
supported_request_methods := 0
end
enable_request_method_get
do
enable_request_method ({HTTP_REQUEST_METHOD_CONSTANTS}.method_get)
end
enable_request_method_post
do
enable_request_method ({HTTP_REQUEST_METHOD_CONSTANTS}.method_post)
end
enable_request_method_put
do
enable_request_method ({HTTP_REQUEST_METHOD_CONSTANTS}.method_put)
end
enable_request_method_delete
do
enable_request_method ({HTTP_REQUEST_METHOD_CONSTANTS}.method_delete)
end
enable_request_method_head
do
enable_request_method ({HTTP_REQUEST_METHOD_CONSTANTS}.method_head)
end
enable_request_method (m: INTEGER)
do
supported_request_methods := supported_request_methods | m
end
note
copyright: "2011-2011, Eiffel Software and others"
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
source: "[
Eiffel Software
5949 Hollister Ave., Goleta, CA 93117 USA
Telephone 805-685-1006, Fax 805-685-6869
Website http://www.eiffel.com
Customer support http://support.eiffel.com
]"
end