make router more easy to inherit from and specialized
This commit is contained in:
@@ -140,7 +140,7 @@ feature -- Execution
|
|||||||
msg := "Hello anonymous visitor !%N"
|
msg := "Hello anonymous visitor !%N"
|
||||||
end
|
end
|
||||||
content_type_supported := <<{HTTP_CONSTANTS}.json_app, {HTTP_CONSTANTS}.html_text, {HTTP_CONSTANTS}.xml_text, {HTTP_CONSTANTS}.plain_text>>
|
content_type_supported := <<{HTTP_CONSTANTS}.json_app, {HTTP_CONSTANTS}.html_text, {HTTP_CONSTANTS}.xml_text, {HTTP_CONSTANTS}.plain_text>>
|
||||||
inspect request_format_id (ctx, "format", content_type_supported)
|
inspect ctx.request_format_id ("format", content_type_supported)
|
||||||
when {HTTP_FORMAT_CONSTANTS}.json then
|
when {HTTP_FORMAT_CONSTANTS}.json then
|
||||||
l_response_content_type := {HTTP_CONSTANTS}.json_app
|
l_response_content_type := {HTTP_CONSTANTS}.json_app
|
||||||
msg := "{%N%"application%": %"/hello%",%N %"message%": %"" + msg + "%" %N}"
|
msg := "{%N%"application%": %"/hello%",%N %"message%": %"" + msg + "%" %N}"
|
||||||
|
|||||||
@@ -7,15 +7,15 @@
|
|||||||
<exclude>/EIFGENs$</exclude>
|
<exclude>/EIFGENs$</exclude>
|
||||||
<exclude>/.svn$</exclude>
|
<exclude>/.svn$</exclude>
|
||||||
</file_rule>
|
</file_rule>
|
||||||
<option warning="true" full_class_checking="true" is_attached_by_default="true" void_safety="all">
|
<option warning="true" full_class_checking="true" is_attached_by_default="true" void_safety="all" syntax="provisional">
|
||||||
<assertions precondition="true"/>
|
<assertions precondition="true"/>
|
||||||
</option>
|
</option>
|
||||||
<library name="base" location="$ISE_LIBRARY\library\base\base-safe.ecf"/>
|
<library name="base" location="$ISE_LIBRARY\library\base\base-safe.ecf"/>
|
||||||
<library name="base_extension" location="$ISE_LIBRARY\library\base_extension\base_extension-safe.ecf"/>
|
<library name="base_extension" location="$ISE_LIBRARY\library\base_extension\base_extension-safe.ecf"/>
|
||||||
<library name="ewsgi" location="..\..\ewsgi\ewsgi-safe.ecf" readonly="false"/>
|
<library name="ewsgi" location="..\..\ewsgi\ewsgi-safe.ecf" readonly="false"/>
|
||||||
<library name="http" location="..\..\..\protocol\http\http-safe.ecf"/>
|
<library name="http" location="..\..\..\protocol\http\http-safe.ecf"/>
|
||||||
<library name="uri_template" location="..\..\..\protocol\uri_template\uri_template-safe.ecf" readonly="false"/>
|
|
||||||
<library name="time" location="$ISE_LIBRARY\library\time\time-safe.ecf"/>
|
<library name="time" location="$ISE_LIBRARY\library\time\time-safe.ecf"/>
|
||||||
|
<library name="uri_template" location="..\..\..\protocol\uri_template\uri_template-safe.ecf" readonly="false"/>
|
||||||
<cluster name="src" location="src\" recursive="true"/>
|
<cluster name="src" location="src\" recursive="true"/>
|
||||||
</target>
|
</target>
|
||||||
<target name="ewsgi_compliant_router">
|
<target name="ewsgi_compliant_router">
|
||||||
@@ -32,8 +32,8 @@
|
|||||||
<library name="base_extension" location="$ISE_LIBRARY\library\base_extension\base_extension-safe.ecf"/>
|
<library name="base_extension" location="$ISE_LIBRARY\library\base_extension\base_extension-safe.ecf"/>
|
||||||
<library name="ewsgi" location="..\..\ewsgi\ewsgi_spec-safe.ecf" readonly="false"/>
|
<library name="ewsgi" location="..\..\ewsgi\ewsgi_spec-safe.ecf" readonly="false"/>
|
||||||
<library name="http" location="..\..\..\protocol\http\http-safe.ecf"/>
|
<library name="http" location="..\..\..\protocol\http\http-safe.ecf"/>
|
||||||
<library name="uri_template" location="..\..\..\protocol\uri_template\uri_template-safe.ecf" readonly="false"/>
|
|
||||||
<library name="time" location="$ISE_LIBRARY\library\time\time-safe.ecf"/>
|
<library name="time" location="$ISE_LIBRARY\library\time\time-safe.ecf"/>
|
||||||
|
<library name="uri_template" location="..\..\..\protocol\uri_template\uri_template-safe.ecf" readonly="false"/>
|
||||||
<cluster name="src" location="src\" recursive="true"/>
|
<cluster name="src" location="src\" recursive="true"/>
|
||||||
</target>
|
</target>
|
||||||
</system>
|
</system>
|
||||||
|
|||||||
@@ -36,10 +36,11 @@ feature -- Setup
|
|||||||
feature -- Execution
|
feature -- Execution
|
||||||
|
|
||||||
execute (req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER)
|
execute (req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER)
|
||||||
|
local
|
||||||
|
l_handled: BOOLEAN
|
||||||
do
|
do
|
||||||
if attached router.dispatch (req, res) as r then
|
l_handled := router.dispatch (req, res)
|
||||||
--| done
|
if not l_handled then
|
||||||
else
|
|
||||||
execute_default (req, res)
|
execute_default (req, res)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -15,14 +15,59 @@ inherit
|
|||||||
{NONE} all
|
{NONE} all
|
||||||
end
|
end
|
||||||
|
|
||||||
|
HTTP_FORMAT_CONSTANTS
|
||||||
|
export
|
||||||
|
{NONE} all
|
||||||
|
end
|
||||||
|
|
||||||
feature -- Access
|
feature -- Access
|
||||||
|
|
||||||
request: WGI_REQUEST
|
request: WGI_REQUEST
|
||||||
-- Associated request
|
-- Associated request
|
||||||
|
|
||||||
path: READABLE_STRING_GENERAL
|
path: READABLE_STRING_8
|
||||||
-- Associated path
|
-- Associated path
|
||||||
|
|
||||||
|
request_format (a_format_variable_name: detachable STRING; content_type_supported: detachable ARRAY [STRING]): detachable READABLE_STRING_8
|
||||||
|
-- Format id for the request based on {HTTP_FORMAT_CONSTANTS}
|
||||||
|
local
|
||||||
|
do
|
||||||
|
if a_format_variable_name /= Void and then attached parameter (a_format_variable_name) as ctx_format then
|
||||||
|
Result := ctx_format.as_string_8
|
||||||
|
else
|
||||||
|
Result := content_type_to_request_format (request_content_type (content_type_supported))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
request_format_id (a_format_variable_name: detachable STRING; content_type_supported: detachable ARRAY [STRING]): INTEGER
|
||||||
|
-- Format id for the request based on {HTTP_FORMAT_CONSTANTS}
|
||||||
|
do
|
||||||
|
if attached request_format (a_format_variable_name, content_type_supported) as l_format then
|
||||||
|
Result := format_id (l_format)
|
||||||
|
else
|
||||||
|
Result := 0
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
content_type_to_request_format (a_content_type: detachable READABLE_STRING_8): detachable READABLE_STRING_8
|
||||||
|
-- `a_content_type' converted into a request format name
|
||||||
|
do
|
||||||
|
if a_content_type /= Void then
|
||||||
|
if a_content_type.same_string ({HTTP_CONSTANTS}.json_text) then
|
||||||
|
Result := {HTTP_FORMAT_CONSTANTS}.json_name
|
||||||
|
elseif a_content_type.same_string ({HTTP_CONSTANTS}.json_app) then
|
||||||
|
Result := {HTTP_FORMAT_CONSTANTS}.json_name
|
||||||
|
elseif a_content_type.same_string ({HTTP_CONSTANTS}.xml_text) then
|
||||||
|
Result := {HTTP_FORMAT_CONSTANTS}.xml_name
|
||||||
|
elseif a_content_type.same_string ({HTTP_CONSTANTS}.html_text) then
|
||||||
|
Result := {HTTP_FORMAT_CONSTANTS}.html_name
|
||||||
|
elseif a_content_type.same_string ({HTTP_CONSTANTS}.plain_text) then
|
||||||
|
Result := {HTTP_FORMAT_CONSTANTS}.text_name
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
request_content_type (content_type_supported: detachable ARRAY [STRING]): detachable READABLE_STRING_8
|
request_content_type (content_type_supported: detachable ARRAY [STRING]): detachable READABLE_STRING_8
|
||||||
local
|
local
|
||||||
s: detachable READABLE_STRING_32
|
s: detachable READABLE_STRING_32
|
||||||
|
|||||||
@@ -7,6 +7,14 @@ note
|
|||||||
deferred class
|
deferred class
|
||||||
REQUEST_HANDLER
|
REQUEST_HANDLER
|
||||||
|
|
||||||
|
inherit
|
||||||
|
ANY
|
||||||
|
|
||||||
|
ROUTED_APPLICATION_HELPER
|
||||||
|
export
|
||||||
|
{NONE} all
|
||||||
|
end
|
||||||
|
|
||||||
feature {NONE} -- Initialization
|
feature {NONE} -- Initialization
|
||||||
|
|
||||||
initialize
|
initialize
|
||||||
@@ -42,7 +50,7 @@ feature -- Execution
|
|||||||
execute_application (a_hdl_context, req, res)
|
execute_application (a_hdl_context, req, res)
|
||||||
post_execute (req, res)
|
post_execute (req, res)
|
||||||
else
|
else
|
||||||
execute_method_not_allowed (a_hdl_context, req, res)
|
execute_request_method_not_allowed (req, res, supported_request_method_names)
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
rescue_execute (req, res)
|
rescue_execute (req, res)
|
||||||
@@ -52,29 +60,6 @@ feature -- Execution
|
|||||||
retry
|
retry
|
||||||
end
|
end
|
||||||
|
|
||||||
execute_method_not_allowed (a_hdl_context: REQUEST_HANDLER_CONTEXT; req: WGI_REQUEST; res: WGI_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: WGI_REQUEST; res: WGI_RESPONSE_BUFFER)
|
execute_application (a_hdl_context: REQUEST_HANDLER_CONTEXT; req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER)
|
||||||
-- Execute request handler
|
-- Execute request handler
|
||||||
deferred
|
deferred
|
||||||
@@ -101,76 +86,27 @@ feature -- Execution
|
|||||||
|
|
||||||
feature -- Execution: report
|
feature -- Execution: report
|
||||||
|
|
||||||
-- execution_information (req: WGI_REQUEST): detachable REQUEST_HANDLER_CONTEXT
|
url (req: WGI_REQUEST; a_base: detachable READABLE_STRING_8; args: detachable STRING; abs: BOOLEAN): STRING
|
||||||
-- -- Execution information related to the request
|
-- Associated url based on `a_base' and `args'
|
||||||
-- 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: WGI_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: WGI_REQUEST; args: detachable STRING; abs: BOOLEAN): STRING
|
|
||||||
-- Associated url based on `path' and `args'
|
|
||||||
-- if `abs' then return absolute url
|
-- if `abs' then return absolute url
|
||||||
local
|
local
|
||||||
s: detachable STRING
|
s: detachable STRING
|
||||||
|
l_base: STRING
|
||||||
do
|
do
|
||||||
|
if a_base /= Void then
|
||||||
|
l_base := a_base
|
||||||
|
else
|
||||||
|
l_base := req.request_uri
|
||||||
|
end
|
||||||
s := args
|
s := args
|
||||||
if s /= Void and then s.count > 0 then
|
if s /= Void and then s.count > 0 then
|
||||||
if s[1] /= '/' then
|
if s[1] /= '/' then
|
||||||
s := req.request_uri + "/" + s
|
s := l_base + "/" + s
|
||||||
else
|
else
|
||||||
s := req.request_uri + s
|
s := l_base + s
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
s := req.request_uri
|
s := l_base
|
||||||
end
|
end
|
||||||
if abs then
|
if abs then
|
||||||
Result := req.absolute_script_url (s)
|
Result := req.absolute_script_url (s)
|
||||||
|
|||||||
@@ -10,11 +10,6 @@ class
|
|||||||
inherit
|
inherit
|
||||||
ANY
|
ANY
|
||||||
|
|
||||||
HTTP_FORMAT_CONSTANTS
|
|
||||||
export
|
|
||||||
{NONE} all
|
|
||||||
end
|
|
||||||
|
|
||||||
feature -- Helper
|
feature -- Helper
|
||||||
|
|
||||||
execute_content_type_not_allowed (req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER; a_content_types: detachable ARRAY [STRING]; a_uri_formats: detachable ARRAY [STRING])
|
execute_content_type_not_allowed (req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER; a_content_types: detachable ARRAY [STRING]; a_uri_formats: detachable ARRAY [STRING])
|
||||||
@@ -70,26 +65,22 @@ feature -- Helper
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
execute_method_not_allowed (req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER; a_methods: ARRAY [STRING])
|
execute_request_method_not_allowed (req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER; a_methods: ITERABLE [STRING])
|
||||||
local
|
local
|
||||||
s: STRING
|
s: STRING
|
||||||
i, n: INTEGER
|
|
||||||
do
|
do
|
||||||
create s.make (10)
|
res.set_status_code ({HTTP_STATUS_CODE}.method_not_allowed)
|
||||||
from
|
create s.make (25)
|
||||||
i := a_methods.lower
|
across
|
||||||
n := a_methods.upper
|
a_methods as c
|
||||||
until
|
|
||||||
i > n
|
|
||||||
loop
|
loop
|
||||||
s.append_string (a_methods[i])
|
if not s.is_empty then
|
||||||
if i < n then
|
|
||||||
s.append_character (',')
|
s.append_character (',')
|
||||||
s.append_character (' ')
|
s.append_character (' ')
|
||||||
end
|
end
|
||||||
i := i + 1
|
s.append_string (c.item)
|
||||||
end
|
end
|
||||||
|
res.set_status_code ({HTTP_STATUS_CODE}.method_not_allowed)
|
||||||
res.write_header ({HTTP_STATUS_CODE}.method_not_allowed, <<
|
res.write_header ({HTTP_STATUS_CODE}.method_not_allowed, <<
|
||||||
["Content-Type", {HTTP_CONSTANTS}.plain_text],
|
["Content-Type", {HTTP_CONSTANTS}.plain_text],
|
||||||
["Allow", s]
|
["Allow", s]
|
||||||
@@ -97,43 +88,6 @@ feature -- Helper
|
|||||||
res.write_string ("Unsupported request method, Allow: " + s + "%N")
|
res.write_string ("Unsupported request method, Allow: " + s + "%N")
|
||||||
end
|
end
|
||||||
|
|
||||||
feature -- Context helper
|
|
||||||
|
|
||||||
request_format_id (ctx: REQUEST_HANDLER_CONTEXT; a_format_variable_name: detachable STRING; content_type_supported: detachable ARRAY [STRING]): INTEGER
|
|
||||||
-- Format id for the request based on {HTTP_FORMAT_CONSTANTS}
|
|
||||||
local
|
|
||||||
l_format: detachable STRING_8
|
|
||||||
do
|
|
||||||
if a_format_variable_name /= Void and then attached ctx.parameter (a_format_variable_name) as ctx_format then
|
|
||||||
l_format := ctx_format.as_string_8
|
|
||||||
else
|
|
||||||
l_format := content_type_to_request_format (ctx.request_content_type (content_type_supported))
|
|
||||||
end
|
|
||||||
if l_format /= Void then
|
|
||||||
Result := format_id (l_format)
|
|
||||||
else
|
|
||||||
Result := 0
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
content_type_to_request_format (a_content_type: detachable READABLE_STRING_8): detachable STRING
|
|
||||||
-- `a_content_type' converted into a request format name
|
|
||||||
do
|
|
||||||
if a_content_type /= Void then
|
|
||||||
if a_content_type.same_string ({HTTP_CONSTANTS}.json_text) then
|
|
||||||
Result := {HTTP_FORMAT_CONSTANTS}.json_name
|
|
||||||
elseif a_content_type.same_string ({HTTP_CONSTANTS}.json_app) then
|
|
||||||
Result := {HTTP_FORMAT_CONSTANTS}.json_name
|
|
||||||
elseif a_content_type.same_string ({HTTP_CONSTANTS}.xml_text) then
|
|
||||||
Result := {HTTP_FORMAT_CONSTANTS}.xml_name
|
|
||||||
elseif a_content_type.same_string ({HTTP_CONSTANTS}.html_text) then
|
|
||||||
Result := {HTTP_FORMAT_CONSTANTS}.html_name
|
|
||||||
elseif a_content_type.same_string ({HTTP_CONSTANTS}.plain_text) then
|
|
||||||
Result := {HTTP_FORMAT_CONSTANTS}.text_name
|
|
||||||
end
|
|
||||||
end
|
|
||||||
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)"
|
||||||
@@ -7,9 +7,6 @@ note
|
|||||||
deferred class
|
deferred class
|
||||||
REQUEST_ROUTER
|
REQUEST_ROUTER
|
||||||
|
|
||||||
inherit
|
|
||||||
ITERABLE [TUPLE [handler: REQUEST_HANDLER; resource: READABLE_STRING_8; request_methods: detachable ARRAY [READABLE_STRING_8]]]
|
|
||||||
|
|
||||||
feature -- Registration
|
feature -- Registration
|
||||||
|
|
||||||
map_default (r: like default_handler)
|
map_default (r: like default_handler)
|
||||||
@@ -17,7 +14,7 @@ feature -- Registration
|
|||||||
-- If no route/handler is found,
|
-- If no route/handler is found,
|
||||||
-- then use `default_handler' as default if not Void
|
-- then use `default_handler' as default if not Void
|
||||||
do
|
do
|
||||||
default_handler := r
|
set_default_handler (r)
|
||||||
end
|
end
|
||||||
|
|
||||||
map (a_id: READABLE_STRING_8; h: REQUEST_HANDLER)
|
map (a_id: READABLE_STRING_8; h: REQUEST_HANDLER)
|
||||||
@@ -46,13 +43,20 @@ feature -- Registration
|
|||||||
|
|
||||||
feature -- Execution
|
feature -- Execution
|
||||||
|
|
||||||
dispatch (req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER): detachable REQUEST_HANDLER
|
dispatch (req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER): BOOLEAN
|
||||||
|
-- Dispatch `req, res' to the associated handler
|
||||||
|
-- And return True is handled, otherwise False
|
||||||
|
do
|
||||||
|
Result := dispatch_and_return_handler (req, res) /= Void
|
||||||
|
end
|
||||||
|
|
||||||
|
dispatch_and_return_handler (req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER): like default_handler
|
||||||
-- Dispatch `req, res' to the associated handler
|
-- Dispatch `req, res' to the associated handler
|
||||||
-- And return this handler
|
-- And return this handler
|
||||||
-- If Result is Void, this means no handler was found.
|
-- If Result is Void, this means no handler was found.
|
||||||
local
|
local
|
||||||
d: like handler
|
d: like handler
|
||||||
ctx: detachable REQUEST_HANDLER_CONTEXT
|
ctx: detachable like default_handler_context
|
||||||
do
|
do
|
||||||
d := handler (req)
|
d := handler (req)
|
||||||
if d /= Void then
|
if d /= Void then
|
||||||
@@ -60,21 +64,29 @@ feature -- Execution
|
|||||||
ctx := d.context
|
ctx := d.context
|
||||||
else
|
else
|
||||||
Result := default_handler
|
Result := default_handler
|
||||||
end
|
if Result /= Void then
|
||||||
if Result /= Void then
|
ctx := default_handler_context (req)
|
||||||
if ctx = Void then
|
|
||||||
check is_default_handler: Result = default_handler end
|
|
||||||
create {REQUEST_URI_HANDLER_CONTEXT} ctx.make (req, "/")
|
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
if Result /= Void and ctx /= Void then
|
||||||
Result.execute (ctx, req, res)
|
Result.execute (ctx, req, res)
|
||||||
end
|
end
|
||||||
ensure
|
ensure
|
||||||
result_void_implie_no_default: Result = Void implies default_handler = Void
|
result_void_implie_no_default: Result = Void implies default_handler = Void
|
||||||
end
|
end
|
||||||
|
|
||||||
|
feature -- Traversing
|
||||||
|
|
||||||
|
new_cursor: ITERATION_CURSOR [TUPLE [handler: REQUEST_HANDLER; resource: READABLE_STRING_8; request_methods: detachable ARRAY [READABLE_STRING_8]]]
|
||||||
|
-- Fresh cursor associated with current structure
|
||||||
|
deferred
|
||||||
|
ensure
|
||||||
|
result_attached: Result /= Void
|
||||||
|
end
|
||||||
|
|
||||||
feature {NONE} -- Access: Implementation
|
feature {NONE} -- Access: Implementation
|
||||||
|
|
||||||
handler (req: WGI_REQUEST): detachable TUPLE [handler: REQUEST_HANDLER; context: REQUEST_HANDLER_CONTEXT]
|
handler (req: WGI_REQUEST): detachable TUPLE [handler: attached like default_handler; context: like default_handler_context]
|
||||||
-- Handler whose map matched with `req'
|
-- Handler whose map matched with `req'
|
||||||
require
|
require
|
||||||
req_valid: req /= Void and then req.path_info /= Void
|
req_valid: req /= Void and then req.path_info /= Void
|
||||||
@@ -127,8 +139,24 @@ feature {NONE} -- Access: Implementation
|
|||||||
|
|
||||||
feature {NONE} -- Implementation
|
feature {NONE} -- Implementation
|
||||||
|
|
||||||
|
set_default_handler (h: like default_handler)
|
||||||
|
-- Set `default_handler' to `h'
|
||||||
|
deferred
|
||||||
|
ensure
|
||||||
|
default_handler_set: h = default_handler
|
||||||
|
end
|
||||||
|
|
||||||
default_handler: detachable REQUEST_HANDLER
|
default_handler: detachable REQUEST_HANDLER
|
||||||
-- Default handler
|
-- Default handler
|
||||||
|
deferred
|
||||||
|
end
|
||||||
|
|
||||||
|
default_handler_context (req: WGI_REQUEST): REQUEST_HANDLER_CONTEXT
|
||||||
|
-- Default handler context associated with `default_handler'
|
||||||
|
require
|
||||||
|
has_default_handler: default_handler /= Void
|
||||||
|
deferred
|
||||||
|
end
|
||||||
|
|
||||||
;note
|
;note
|
||||||
copyright: "2011-2011, Eiffel Software and others"
|
copyright: "2011-2011, Eiffel Software and others"
|
||||||
|
|||||||
@@ -30,10 +30,10 @@ feature -- Registration
|
|||||||
|
|
||||||
feature {NONE} -- Access: Implementation
|
feature {NONE} -- Access: Implementation
|
||||||
|
|
||||||
handler (req: WGI_REQUEST): detachable TUPLE [handler: REQUEST_HANDLER; context: REQUEST_HANDLER_CONTEXT]
|
handler (req: WGI_REQUEST): detachable TUPLE [handler: REQUEST_HANDLER; context: like default_handler_context]
|
||||||
local
|
local
|
||||||
h: detachable REQUEST_HANDLER
|
h: detachable REQUEST_HANDLER
|
||||||
ctx: detachable REQUEST_HANDLER_CONTEXT
|
ctx: detachable like default_handler_context
|
||||||
do
|
do
|
||||||
h := handler_by_path (req.path_info, req.request_method)
|
h := handler_by_path (req.path_info, req.request_method)
|
||||||
if h = Void then
|
if h = Void then
|
||||||
@@ -82,7 +82,6 @@ feature {NONE} -- Access: Implementation
|
|||||||
end
|
end
|
||||||
l_handlers.forth
|
l_handlers.forth
|
||||||
end
|
end
|
||||||
-- Result := handlers.item (context_path (a_path))
|
|
||||||
ensure
|
ensure
|
||||||
a_path_unchanged: a_path.same_string (old a_path)
|
a_path_unchanged: a_path.same_string (old a_path)
|
||||||
end
|
end
|
||||||
@@ -115,14 +114,14 @@ feature {NONE} -- Access: Implementation
|
|||||||
a_path_unchanged: a_path.same_string (old a_path)
|
a_path_unchanged: a_path.same_string (old a_path)
|
||||||
end
|
end
|
||||||
|
|
||||||
feature -- Context factory
|
feature {NONE} -- Context factory
|
||||||
|
|
||||||
handler_context (p: detachable STRING; req: WGI_REQUEST): REQUEST_URI_HANDLER_CONTEXT
|
handler_context (p: detachable STRING; req: WGI_REQUEST): like default_handler_context
|
||||||
do
|
do
|
||||||
if p /= Void then
|
if p /= Void then
|
||||||
create Result.make (req, p)
|
create {REQUEST_URI_HANDLER_CONTEXT} Result.make (req, p)
|
||||||
else
|
else
|
||||||
create Result.make (req, req.path_info)
|
create {REQUEST_URI_HANDLER_CONTEXT} Result.make (req, req.path_info)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -165,7 +164,21 @@ feature {NONE} -- Implementation
|
|||||||
result_not_empty: not Result.is_empty
|
result_not_empty: not Result.is_empty
|
||||||
end
|
end
|
||||||
|
|
||||||
;note
|
feature {NONE} -- Default: implementation
|
||||||
|
|
||||||
|
default_handler: detachable REQUEST_HANDLER
|
||||||
|
|
||||||
|
set_default_handler (h: like default_handler)
|
||||||
|
do
|
||||||
|
default_handler := h
|
||||||
|
end
|
||||||
|
|
||||||
|
default_handler_context (req: WGI_REQUEST): REQUEST_HANDLER_CONTEXT
|
||||||
|
do
|
||||||
|
Result := handler_context (Void, req)
|
||||||
|
end
|
||||||
|
|
||||||
|
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)"
|
||||||
source: "[
|
source: "[
|
||||||
|
|||||||
@@ -45,9 +45,8 @@ feature -- Registration
|
|||||||
|
|
||||||
feature {NONE} -- Access: Implementation
|
feature {NONE} -- Access: Implementation
|
||||||
|
|
||||||
handler (req: WGI_REQUEST): detachable TUPLE [handler: REQUEST_HANDLER; context: REQUEST_HANDLER_CONTEXT]
|
handler (req: WGI_REQUEST): detachable TUPLE [handler: attached like default_handler; context: like default_handler_context]
|
||||||
local
|
local
|
||||||
ctx: detachable REQUEST_URI_TEMPLATE_HANDLER_CONTEXT
|
|
||||||
l_handlers: like handlers
|
l_handlers: like handlers
|
||||||
t: STRING
|
t: STRING
|
||||||
p: STRING
|
p: STRING
|
||||||
@@ -67,8 +66,7 @@ feature {NONE} -- Access: Implementation
|
|||||||
if attached templates.item (t) as tpl and then
|
if attached templates.item (t) as tpl and then
|
||||||
attached tpl.match (p) as res
|
attached tpl.match (p) as res
|
||||||
then
|
then
|
||||||
ctx := handler_context (p, req, tpl, res)
|
Result := [l_info.handler, handler_context (p, req, tpl, res)]
|
||||||
Result := [l_info.handler, ctx]
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -76,14 +74,14 @@ feature {NONE} -- Access: Implementation
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
feature -- Context factory
|
feature {NONE} -- Context factory
|
||||||
|
|
||||||
handler_context (p: detachable STRING; req: WGI_REQUEST; tpl: URI_TEMPLATE; tpl_res: URI_TEMPLATE_MATCH_RESULT): REQUEST_URI_TEMPLATE_HANDLER_CONTEXT
|
handler_context (p: detachable STRING; req: WGI_REQUEST; tpl: URI_TEMPLATE; tpl_res: URI_TEMPLATE_MATCH_RESULT): like default_handler_context
|
||||||
do
|
do
|
||||||
if p /= Void then
|
if p /= Void then
|
||||||
create Result.make (req, tpl, tpl_res, p)
|
create {REQUEST_URI_TEMPLATE_HANDLER_CONTEXT} Result.make (req, tpl, tpl_res, p)
|
||||||
else
|
else
|
||||||
create Result.make (req, tpl, tpl_res, req.path_info)
|
create {REQUEST_URI_TEMPLATE_HANDLER_CONTEXT} Result.make (req, tpl, tpl_res, req.path_info)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -126,6 +124,20 @@ feature {NONE} -- Implementation
|
|||||||
result_not_empty: not Result.is_empty
|
result_not_empty: not Result.is_empty
|
||||||
end
|
end
|
||||||
|
|
||||||
|
feature {NONE} -- Default: implementation
|
||||||
|
|
||||||
|
default_handler: detachable REQUEST_HANDLER
|
||||||
|
|
||||||
|
set_default_handler (h: like default_handler)
|
||||||
|
do
|
||||||
|
default_handler := h
|
||||||
|
end
|
||||||
|
|
||||||
|
default_handler_context (req: WGI_REQUEST): REQUEST_HANDLER_CONTEXT
|
||||||
|
do
|
||||||
|
create {REQUEST_URI_HANDLER_CONTEXT} Result.make (req, "/")
|
||||||
|
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)"
|
||||||
|
|||||||
Reference in New Issue
Block a user