From ace897ea2b56bab740c9761bf412076a529eca21 Mon Sep 17 00:00:00 2001 From: Jocelyn Fiat Date: Mon, 10 Sep 2012 20:45:19 +0200 Subject: [PATCH 1/7] New ROUTER design, much simpler, less generic, easier to extend, and now one can mix uri map, uri_template map and so on. Update the "tutorial" example. --- .../step_4/hello/src/hello_application.e | 39 ++- .../step_4/hello/src/user_message_handler.e | 2 +- library/server/wsf/router/README.md | 2 +- .../wsf/router/default/wsf_routed_service.e | 23 -- .../wsf_routed_service.e} | 21 +- .../starts_with/wsf_starts_with_handler.e | 19 ++ .../starts_with/wsf_starts_with_mapping.e | 62 +++++ .../wsf/router/uri/default/wsf_uri_router.e | 50 ---- .../uri/default/wsf_uri_routing_handler.e | 35 --- ...ng_handler_i.e => wsf_agent_uri_handler.e} | 24 +- ...wsf_agent_uri_template_response_handler.e} | 11 +- .../server/wsf/router/uri/wsf_uri_handler.e | 19 ++ .../wsf/router/uri/wsf_uri_handler_context.e | 60 ---- .../server/wsf/router/uri/wsf_uri_mapping.e | 80 ++++++ .../wsf/router/uri/wsf_uri_response_handler.e | 41 +++ .../server/wsf/router/uri/wsf_uri_router_i.e | 251 ----------------- .../wsf_uri_template_response_handler.e} | 19 +- .../default/wsf_uri_template_routed_service.e | 39 --- .../default/wsf_uri_template_router.e | 52 ---- .../wsf_uri_template_routing_handler.e | 35 --- .../wsf_agent_uri_template_handler.e} | 19 +- .../uri_template/wsf_uri_template_handler.e | 19 ++ .../uri_template/wsf_uri_template_mapping.e | 81 ++++++ .../uri_template/wsf_uri_template_router_i.e | 228 --------------- .../wsf_uri_template_routing_handler_i.e | 47 ---- .../wsf/router/wsf_file_system_handler.e | 227 ++++++++++----- library/server/wsf/router/wsf_handler.e | 71 +---- library/server/wsf/router/wsf_route.e | 45 --- library/server/wsf/router/wsf_router.e | 261 ++++++------------ ..._routed_service.e => wsf_router_mapping.e} | 32 ++- .../server/wsf/router/wsf_routing_handler.e | 113 -------- 31 files changed, 668 insertions(+), 1359 deletions(-) delete mode 100644 library/server/wsf/router/default/wsf_routed_service.e rename library/server/wsf/router/{wsf_routed_service_i.e => service/wsf_routed_service.e} (78%) create mode 100644 library/server/wsf/router/starts_with/wsf_starts_with_handler.e create mode 100644 library/server/wsf/router/starts_with/wsf_starts_with_mapping.e delete mode 100644 library/server/wsf/router/uri/default/wsf_uri_router.e delete mode 100644 library/server/wsf/router/uri/default/wsf_uri_routing_handler.e rename library/server/wsf/router/uri/{wsf_uri_routing_handler_i.e => wsf_agent_uri_handler.e} (59%) rename library/server/wsf/router/{wsf_agent_response_handler.e => uri/wsf_agent_uri_template_response_handler.e} (62%) create mode 100644 library/server/wsf/router/uri/wsf_uri_handler.e delete mode 100644 library/server/wsf/router/uri/wsf_uri_handler_context.e create mode 100644 library/server/wsf/router/uri/wsf_uri_mapping.e create mode 100644 library/server/wsf/router/uri/wsf_uri_response_handler.e delete mode 100644 library/server/wsf/router/uri/wsf_uri_router_i.e rename library/server/wsf/router/{wsf_response_handler.e => uri/wsf_uri_template_response_handler.e} (59%) delete mode 100644 library/server/wsf/router/uri_template/default/wsf_uri_template_routed_service.e delete mode 100644 library/server/wsf/router/uri_template/default/wsf_uri_template_router.e delete mode 100644 library/server/wsf/router/uri_template/default/wsf_uri_template_routing_handler.e rename library/server/wsf/router/{wsf_agent_handler.e => uri_template/wsf_agent_uri_template_handler.e} (55%) create mode 100644 library/server/wsf/router/uri_template/wsf_uri_template_handler.e create mode 100644 library/server/wsf/router/uri_template/wsf_uri_template_mapping.e delete mode 100644 library/server/wsf/router/uri_template/wsf_uri_template_router_i.e delete mode 100644 library/server/wsf/router/uri_template/wsf_uri_template_routing_handler_i.e delete mode 100644 library/server/wsf/router/wsf_route.e rename library/server/wsf/router/{uri/default/wsf_uri_routed_service.e => wsf_router_mapping.e} (53%) delete mode 100644 library/server/wsf/router/wsf_routing_handler.e diff --git a/examples/tutorial/step_4/hello/src/hello_application.e b/examples/tutorial/step_4/hello/src/hello_application.e index 83dbc7bc..38d09ced 100644 --- a/examples/tutorial/step_4/hello/src/hello_application.e +++ b/examples/tutorial/step_4/hello/src/hello_application.e @@ -13,7 +13,7 @@ class HELLO_APPLICATION inherit - WSF_URI_TEMPLATE_ROUTED_SERVICE + WSF_ROUTED_SERVICE WSF_DEFAULT_SERVICE redefine @@ -27,12 +27,34 @@ feature {NONE} -- Initialization setup_router do - router.map_agent ("/hello", agent execute_hello) +-- router.map (create {WSF_URI_MAPPING}.make ("/hello", create {WSF_AGENT_URI_HANDLER}.make (agent execute_hello))) + map_agent_uri ("/hello", agent execute_hello, Void) - router.map_with_request_methods ("/users/{user}/message/{mesgid}", create {USER_MESSAGE_HANDLER}, router.methods_HEAD_GET_POST) - router.map_with_request_methods ("/users/{user}/message/", create {USER_MESSAGE_HANDLER}, router.methods_GET_POST) +-- router.map_with_request_methods (create {WSF_URI_TEMPLATE_MAPPING}.make ("/users/{user}/message/{mesgid}", create {USER_MESSAGE_HANDLER}), router.methods_HEAD_GET_POST) + map_uri_template ("/users/{user}/message/{mesgid}", create {USER_MESSAGE_HANDLER}, router.methods_HEAD_GET_POST) - router.map_agent_response_with_request_methods ("/users/{user}/{?op}", agent response_user, router.methods_GET) +-- router.map_with_request_methods (create {WSF_URI_TEMPLATE_MAPPING}.make ("/users/{user}/message/", create {USER_MESSAGE_HANDLER}), router.methods_GET_POST) + map_uri_template ("/users/{user}/message/", create {USER_MESSAGE_HANDLER}, router.methods_GET_POST) + +-- router.map_with_request_methods (create {WSF_URI_TEMPLATE_MAPPING}.make ("/users/{user}/{?op}", create {WSF_AGENT_URI_TEMPLATE_RESPONSE_HANDLER}.make (agent response_user)), router.methods_GET) + map_agent_uri_template_response ("/users/{user}/{?op}", agent response_user, router.methods_GET) + end + +feature -- Helper: mapping + + map_agent_uri (a_uri: READABLE_STRING_8; a_action: like {WSF_AGENT_URI_HANDLER}.action; rqst_methods: detachable WSF_ROUTER_METHODS) + do + router.map_with_request_methods (create {WSF_URI_MAPPING}.make (a_uri, create {WSF_AGENT_URI_HANDLER}.make (a_action)), rqst_methods) + end + + map_uri_template (a_tpl: READABLE_STRING_8; a_handler: WSF_URI_TEMPLATE_HANDLER; rqst_methods: detachable WSF_ROUTER_METHODS) + do + router.map_with_request_methods (create {WSF_URI_TEMPLATE_MAPPING}.make (a_tpl, a_handler), rqst_methods) + end + + map_agent_uri_template_response (a_tpl: READABLE_STRING_8; a_action: like {WSF_AGENT_URI_TEMPLATE_RESPONSE_HANDLER}.action; rqst_methods: detachable WSF_ROUTER_METHODS) + do + router.map_with_request_methods (create {WSF_URI_TEMPLATE_MAPPING}.make (a_tpl, create {WSF_AGENT_URI_TEMPLATE_RESPONSE_HANDLER}.make (a_action)), rqst_methods) end feature -- Execution @@ -43,7 +65,7 @@ feature -- Execution res.redirect_now_with_content (req.script_url ("/hello"), "Redirection to " + req.script_url ("/hello"), "text/html") end - execute_hello (ctx: WSF_URI_TEMPLATE_HANDLER_CONTEXT; req: WSF_REQUEST; res: WSF_RESPONSE) + execute_hello (req: WSF_REQUEST; res: WSF_RESPONSE) -- Computed response message. local mesg: WSF_HTML_PAGE_RESPONSE @@ -107,8 +129,9 @@ feature -- Execution then if l_op.is_case_insensitive_equal ("quit") then create redir.make (req.script_url ("/hello"), 3) - redir.set_title ("Bye " + u.url_encoded_value) - redir.set_body ("Bye " + u.url_encoded_value + ",
see you soon.

You will be redirected to " + + create html.make + redir.set_title ("Bye " + html.html_encoded_string (l_username)) + redir.set_body ("Bye " + html.html_encoded_string (l_username) + ",
see you soon.

You will be redirected to " + redir.url_location + " in " + redir.delay.out + " second(s) ...

" ) Result := redir diff --git a/examples/tutorial/step_4/hello/src/user_message_handler.e b/examples/tutorial/step_4/hello/src/user_message_handler.e index 616cd337..cbc95f17 100644 --- a/examples/tutorial/step_4/hello/src/user_message_handler.e +++ b/examples/tutorial/step_4/hello/src/user_message_handler.e @@ -9,7 +9,7 @@ class USER_MESSAGE_HANDLER inherit - WSF_RESPONSE_HANDLER [WSF_URI_TEMPLATE_HANDLER_CONTEXT] + WSF_URI_TEMPLATE_RESPONSE_HANDLER feature -- Access diff --git a/library/server/wsf/router/README.md b/library/server/wsf/router/README.md index 80233fc4..abd12c96 100644 --- a/library/server/wsf/router/README.md +++ b/library/server/wsf/router/README.md @@ -1,7 +1,7 @@ # Router ## Requirements -* [URI Template](../../../protocol/rui_template) +* [URI Template](../../../protocol/uri_template) ## Overview diff --git a/library/server/wsf/router/default/wsf_routed_service.e b/library/server/wsf/router/default/wsf_routed_service.e deleted file mode 100644 index b2634211..00000000 --- a/library/server/wsf/router/default/wsf_routed_service.e +++ /dev/null @@ -1,23 +0,0 @@ -note - description: "Summary description for {DEFAULT_ROUTED_SERVICE}." - author: "" - date: "$Date$" - revision: "$Revision$" - -deferred class - WSF_ROUTED_SERVICE - -inherit - WSF_ROUTED_SERVICE_I [WSF_HANDLER [WSF_HANDLER_CONTEXT], WSF_HANDLER_CONTEXT] - -note - copyright: "2011-2012, Jocelyn Fiat, Javier Velilla, 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 diff --git a/library/server/wsf/router/wsf_routed_service_i.e b/library/server/wsf/router/service/wsf_routed_service.e similarity index 78% rename from library/server/wsf/router/wsf_routed_service_i.e rename to library/server/wsf/router/service/wsf_routed_service.e index fa82da2a..11c09ba1 100644 --- a/library/server/wsf/router/wsf_routed_service_i.e +++ b/library/server/wsf/router/service/wsf_routed_service.e @@ -5,12 +5,11 @@ note revision: "$Revision$" deferred class - WSF_ROUTED_SERVICE_I [H -> WSF_HANDLER [C], C -> WSF_HANDLER_CONTEXT] + WSF_ROUTED_SERVICE -feature -- Setup +feature -- Initialization initialize_router - -- Initialize `router' do create_router setup_router @@ -18,7 +17,8 @@ feature -- Setup create_router -- Create `router' - deferred + do + create router.make (10) ensure router_created: router /= Void end @@ -30,15 +30,12 @@ feature -- Setup deferred end - router: WSF_ROUTER [H, C] - -- Request router - feature -- Execution execute (req: WSF_REQUEST; res: WSF_RESPONSE) do - if attached router.route (req) as r then - router.execute_route (r, req, res) + if attached router.dispatch_and_return_handler (req, res) as p then + -- executed else execute_default (req, res) end @@ -48,7 +45,11 @@ feature -- Execution deferred end -note +feature -- Access + + router: WSF_ROUTER + +;note copyright: "2011-2012, Jocelyn Fiat, Javier Velilla, Eiffel Software and others" license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)" source: "[ diff --git a/library/server/wsf/router/starts_with/wsf_starts_with_handler.e b/library/server/wsf/router/starts_with/wsf_starts_with_handler.e new file mode 100644 index 00000000..19c3a037 --- /dev/null +++ b/library/server/wsf/router/starts_with/wsf_starts_with_handler.e @@ -0,0 +1,19 @@ +note + description: "Summary description for {WSF_STARTS_WITH_HANDLER}." + author: "" + date: "$Date$" + revision: "$Revision$" + +deferred class + WSF_STARTS_WITH_HANDLER + +inherit + WSF_HANDLER + +feature -- Execution + + execute (a_start_path: READABLE_STRING_8; req: WSF_REQUEST; res: WSF_RESPONSE) + deferred + end + +end diff --git a/library/server/wsf/router/starts_with/wsf_starts_with_mapping.e b/library/server/wsf/router/starts_with/wsf_starts_with_mapping.e new file mode 100644 index 00000000..fed15b87 --- /dev/null +++ b/library/server/wsf/router/starts_with/wsf_starts_with_mapping.e @@ -0,0 +1,62 @@ +note + description: "Summary description for EWF_URI_PATH." + author: "" + date: "$Date$" + revision: "$Revision$" + +class + WSF_STARTS_WITH_MAPPING + +inherit + WSF_ROUTER_MAPPING + +create + make + +feature {NONE} -- Initialization + + make (a_uri: READABLE_STRING_8; h: like handler) + do + handler := h + uri := a_uri + end + +feature -- Access + + handler: WSF_STARTS_WITH_HANDLER + + uri: READABLE_STRING_8 + +feature -- Status + + routed_handler (req: WSF_REQUEST; res: WSF_RESPONSE; a_router: WSF_ROUTER): detachable WSF_HANDLER + local + p: READABLE_STRING_8 + s: like based_uri + do + p := source_uri (req) + s := based_uri (uri, a_router) + if p.starts_with (s) then + Result := handler + a_router.execute_before (Current) + handler.execute (s, req, res) + a_router.execute_after (Current) + end + end + +feature {NONE} -- Implementation + + based_uri (a_uri: like uri; a_router: WSF_ROUTER): like uri + local + s: STRING_8 + do + if attached a_router.base_url as l_base_url then + create s.make_from_string (l_base_url) + s.append_string (a_uri) + Result := s + else + Result := a_uri + end + end + +end diff --git a/library/server/wsf/router/uri/default/wsf_uri_router.e b/library/server/wsf/router/uri/default/wsf_uri_router.e deleted file mode 100644 index b4305757..00000000 --- a/library/server/wsf/router/uri/default/wsf_uri_router.e +++ /dev/null @@ -1,50 +0,0 @@ -note - description: "[ - Default router based on URI map - ]" - date: "$Date$" - revision: "$Revision$" - -class - WSF_URI_ROUTER - -inherit - WSF_URI_ROUTER_I [WSF_HANDLER [WSF_URI_HANDLER_CONTEXT], WSF_URI_HANDLER_CONTEXT] - redefine - map_agent_with_request_methods, map_agent_response_with_request_methods - end - -create - make - -feature -- Mapping agent - - map_agent_with_request_methods (a_id: READABLE_STRING_8; a_action: PROCEDURE [ANY, TUPLE [ctx: WSF_URI_HANDLER_CONTEXT; req: WSF_REQUEST; res: WSF_RESPONSE]]; - rqst_methods: detachable WSF_ROUTER_METHODS) - local - h: WSF_AGENT_HANDLER [WSF_URI_HANDLER_CONTEXT] - do - create h.make (a_action) - map_with_request_methods (a_id, h, rqst_methods) - end - - map_agent_response_with_request_methods (a_id: READABLE_STRING_8; a_action: FUNCTION [ANY, TUPLE [ctx: WSF_URI_HANDLER_CONTEXT; req: WSF_REQUEST], WSF_RESPONSE_MESSAGE]; - rqst_methods: detachable WSF_ROUTER_METHODS) - local - h: WSF_AGENT_RESPONSE_HANDLER [WSF_URI_HANDLER_CONTEXT] - do - create h.make (a_action) - map_with_request_methods (a_id, h, rqst_methods) - end - -note - copyright: "2011-2012, Jocelyn Fiat, Javier Velilla, 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 diff --git a/library/server/wsf/router/uri/default/wsf_uri_routing_handler.e b/library/server/wsf/router/uri/default/wsf_uri_routing_handler.e deleted file mode 100644 index 0d06d477..00000000 --- a/library/server/wsf/router/uri/default/wsf_uri_routing_handler.e +++ /dev/null @@ -1,35 +0,0 @@ -note - description: "[ - WSF_URI_ROUTING_HANDLER is a default descendant of WSF_URI_ROUTING_HANDLER_I - for WSF_URI_ROUTER - ]" - date: "$Date$" - revision: "$Revision$" - -class - WSF_URI_ROUTING_HANDLER - -inherit - WSF_URI_ROUTING_HANDLER_I [WSF_HANDLER [WSF_URI_HANDLER_CONTEXT], WSF_URI_HANDLER_CONTEXT] - redefine - router - end - -create - make - -feature {NONE} -- Routing - - router: WSF_URI_ROUTER - -;note - copyright: "2011-2012, Jocelyn Fiat, Javier Velilla, 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 diff --git a/library/server/wsf/router/uri/wsf_uri_routing_handler_i.e b/library/server/wsf/router/uri/wsf_agent_uri_handler.e similarity index 59% rename from library/server/wsf/router/uri/wsf_uri_routing_handler_i.e rename to library/server/wsf/router/uri/wsf_agent_uri_handler.e index 81a048ae..8fda84fa 100644 --- a/library/server/wsf/router/uri/wsf_uri_routing_handler_i.e +++ b/library/server/wsf/router/uri/wsf_agent_uri_handler.e @@ -1,33 +1,35 @@ note - description: "[ - This class helps to build Routing handler based for WSF_URI_ROUTER - ]" + description: "Summary description for {WSF_AGENT_HANDLER}." author: "" date: "$Date$" revision: "$Revision$" class - WSF_URI_ROUTING_HANDLER_I [H -> WSF_HANDLER [C], - C -> WSF_URI_HANDLER_CONTEXT create make end] + WSF_AGENT_URI_HANDLER inherit - WSF_ROUTING_HANDLER [H, C] + WSF_URI_HANDLER create make feature {NONE} -- Initialization - make (n: INTEGER) + make (a_action: like action) do - create router.make (n) + action := a_action end -feature {NONE} -- Routing + action: PROCEDURE [ANY, TUPLE [request: WSF_REQUEST; response: WSF_RESPONSE]] - router: WSF_URI_ROUTER_I [H, C] +feature -- Execution -;note + execute (req: WSF_REQUEST; res: WSF_RESPONSE) + do + action.call ([req, res]) + end + +note copyright: "2011-2012, Jocelyn Fiat, Javier Velilla, Eiffel Software and others" license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)" source: "[ diff --git a/library/server/wsf/router/wsf_agent_response_handler.e b/library/server/wsf/router/uri/wsf_agent_uri_template_response_handler.e similarity index 62% rename from library/server/wsf/router/wsf_agent_response_handler.e rename to library/server/wsf/router/uri/wsf_agent_uri_template_response_handler.e index 56277e51..e178ccf4 100644 --- a/library/server/wsf/router/wsf_agent_response_handler.e +++ b/library/server/wsf/router/uri/wsf_agent_uri_template_response_handler.e @@ -1,13 +1,14 @@ note - description: "Summary description for WSF_AGENT_RESPONSE_HANDLER." + description: "Summary description for {WSF_AGENT_URI_TEMPLATE_RESPONSE_HANDLER}." + author: "" date: "$Date$" revision: "$Revision$" class - WSF_AGENT_RESPONSE_HANDLER [C -> WSF_HANDLER_CONTEXT] + WSF_AGENT_URI_TEMPLATE_RESPONSE_HANDLER inherit - WSF_RESPONSE_HANDLER [C] + WSF_URI_TEMPLATE_RESPONSE_HANDLER create make @@ -21,11 +22,11 @@ feature -- Initialization feature -- Access - action: FUNCTION [ANY, TUPLE [ctx: C; req: WSF_REQUEST], WSF_RESPONSE_MESSAGE] + action: FUNCTION [ANY, TUPLE [ctx: WSF_URI_TEMPLATE_HANDLER_CONTEXT; req: WSF_REQUEST], WSF_RESPONSE_MESSAGE] feature -- Execution - response (ctx: C; req: WSF_REQUEST): WSF_RESPONSE_MESSAGE + response (ctx: WSF_URI_TEMPLATE_HANDLER_CONTEXT; req: WSF_REQUEST): WSF_RESPONSE_MESSAGE do Result := action.item ([ctx, req]) end diff --git a/library/server/wsf/router/uri/wsf_uri_handler.e b/library/server/wsf/router/uri/wsf_uri_handler.e new file mode 100644 index 00000000..74e63523 --- /dev/null +++ b/library/server/wsf/router/uri/wsf_uri_handler.e @@ -0,0 +1,19 @@ +note + description: "Summary description for {EWF_ROUTER_URI_PATH_HANDLER}." + author: "" + date: "$Date$" + revision: "$Revision$" + +deferred class + WSF_URI_HANDLER + +inherit + WSF_HANDLER + +feature -- Execution + + execute (req: WSF_REQUEST; res: WSF_RESPONSE) + deferred + end + +end diff --git a/library/server/wsf/router/uri/wsf_uri_handler_context.e b/library/server/wsf/router/uri/wsf_uri_handler_context.e deleted file mode 100644 index dfd880ca..00000000 --- a/library/server/wsf/router/uri/wsf_uri_handler_context.e +++ /dev/null @@ -1,60 +0,0 @@ -note - description: "[ - Context for the handler execution - - It does not provide additional information compared to {WSF_HANDLER_CONTEXT} - - request: WSF_REQUEST -- Associated request - - path: READABLE_STRING_8 -- Associated path - ]" - date: "$Date$" - revision: "$Revision$" - -class - WSF_URI_HANDLER_CONTEXT - -inherit - WSF_HANDLER_CONTEXT - -create - make - -feature {NONE} -- Initialization - - make (req: WSF_REQUEST; p: like path) - do - request := req - path := p - end - -feature -- Request data - - apply (req: WSF_REQUEST) - -- - do - end - - revert (req: WSF_REQUEST) - -- - do - end - -feature -- Item - - item (a_name: READABLE_STRING_GENERAL): detachable WSF_VALUE - -- Variable value for parameter or variable `a_name' - -- See `{WSF_REQUEST}.item(s)' - do - Result := request.item (a_name) - end - -note - copyright: "2011-2012, Jocelyn Fiat, Javier Velilla, 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 diff --git a/library/server/wsf/router/uri/wsf_uri_mapping.e b/library/server/wsf/router/uri/wsf_uri_mapping.e new file mode 100644 index 00000000..fcc33642 --- /dev/null +++ b/library/server/wsf/router/uri/wsf_uri_mapping.e @@ -0,0 +1,80 @@ +note + description: "Summary description for EWF_URI_PATH." + author: "" + date: "$Date$" + revision: "$Revision$" + +class + WSF_URI_MAPPING + +inherit + WSF_ROUTER_MAPPING + +create + make, + make_trailing_slash_ignored + +feature {NONE} -- Initialization + + make (a_uri: READABLE_STRING_8; h: like handler) + do + handler := h + uri := a_uri + end + + make_trailing_slash_ignored (a_uri: READABLE_STRING_8; h: like handler) + do + make (a_uri, h) + trailing_slash_ignored := True + end + +feature -- Access + + handler: WSF_URI_HANDLER + + uri: READABLE_STRING_8 + + trailing_slash_ignored: BOOLEAN + +feature -- Status + + routed_handler (req: WSF_REQUEST; res: WSF_RESPONSE; a_router: WSF_ROUTER): detachable WSF_HANDLER + local + p: READABLE_STRING_8 + l_uri: like uri + do + p := source_uri (req) + l_uri := based_uri (uri, a_router) + if l_uri.ends_with ("/") then + if not p.ends_with ("/") then + p := p + "/" + end + else + if p.ends_with ("/") then + p := p.substring (1, p.count - 1) + end + end + if p.same_string (l_uri) then + Result := handler + a_router.execute_before (Current) + handler.execute (req, res) + a_router.execute_after (Current) + end + end + +feature {NONE} -- Implementation + + based_uri (a_uri: like uri; a_router: WSF_ROUTER): like uri + local + s: STRING_8 + do + if attached a_router.base_url as l_base_url then + create s.make_from_string (l_base_url) + s.append_string (a_uri) + Result := s + else + Result := a_uri + end + end + +end diff --git a/library/server/wsf/router/uri/wsf_uri_response_handler.e b/library/server/wsf/router/uri/wsf_uri_response_handler.e new file mode 100644 index 00000000..e956fe92 --- /dev/null +++ b/library/server/wsf/router/uri/wsf_uri_response_handler.e @@ -0,0 +1,41 @@ +note + description: "Summary description for {WSF_URI_RESPONSE_HANDLER}." + author: "" + date: "$Date$" + revision: "$Revision$" + +deferred class + WSF_URI_RESPONSE_HANDLER + +inherit + WSF_URI_HANDLER + +feature -- Response + + response (req: WSF_REQUEST): WSF_RESPONSE_MESSAGE + require + is_valid_context: is_valid_context (req) + deferred + ensure + Result_attached: Result /= Void + end + +feature -- Execution + + execute (req: WSF_REQUEST; res: WSF_RESPONSE) + -- Execute request handler + do + res.send (response (req)) + end + +note + copyright: "2011-2012, Jocelyn Fiat, Javier Velilla, 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 diff --git a/library/server/wsf/router/uri/wsf_uri_router_i.e b/library/server/wsf/router/uri/wsf_uri_router_i.e deleted file mode 100644 index 3058a73d..00000000 --- a/library/server/wsf/router/uri/wsf_uri_router_i.e +++ /dev/null @@ -1,251 +0,0 @@ -note - description: "[ - URL dispatcher/router based on simple URI mapping and request methods if precised - The associated context {WSF_URI_HANDLER_CONTEXT} does not contains any additional information. - - The matching check if the same path is mapped, or if a substring of the path is mapped - - Examples: - - map ("/users/", users_handler) - map_with_request_methods ("/groups/", read_groups_handler, <<"GET">>) - map_with_request_methods ("/groups/", write_groups_handler, <<"POST", "PUT", "DELETE">>) - map_agent_with_request_methods ("/order/", agent do_get_order, <<"GET">>) - map_agent_with_request_methods ("/order/", agent do_post_order, <<"POST">>) - - - ]" - date: "$Date$" - revision: "$Revision$" - -class - WSF_URI_ROUTER_I [H -> WSF_HANDLER [C], C -> WSF_URI_HANDLER_CONTEXT create make end] - -inherit - WSF_ROUTER [H, C] - -create - make, - make_with_base_url - -feature -- Initialization - - make (n: INTEGER) - do - create handlers.make (n) - handlers.compare_objects - initialize - end - - make_with_base_url (n: INTEGER; a_base_url: like base_url) - -- Make router allocated for at least `n' maps, - -- and use `a_base_url' as base_url - do - make (n) - set_base_url (a_base_url) - end - -feature {WSF_ROUTED_SERVICE_I} -- Status report - - handlers_matching_map (a_resource: READABLE_STRING_8; rqst_methods: detachable WSF_ROUTER_METHODS): detachable LIST [H] - local - l_res: READABLE_STRING_8 - do - l_res := based_resource (a_resource) - across - handlers as c - loop - if c.item.resource.same_string (l_res) then - if - rqst_methods = Void or else - across rqst_methods as rq some is_matching_request_methods (rq.item, c.item.request_methods) end - then - if Result = Void then - create {ARRAYED_LIST [H]} Result.make (1) - end - Result.extend (c.item.handler) - end - end - end - end - -feature {WSF_ROUTED_SERVICE_I} -- Default: implementation - - default_handler_context (req: WSF_REQUEST): C - -- - do - Result := handler_context (Void, req) - end - -feature -- Registration - - map_with_request_methods (p: READABLE_STRING_8; h: H; rqst_methods: detachable WSF_ROUTER_METHODS) - local - l_uri: READABLE_STRING_8 - do - if attached base_url as l_base_url then - l_uri := l_base_url + p - else - l_uri := p - end - handlers.force ([h, l_uri, rqst_methods]) - h.on_handler_mapped (l_uri, rqst_methods) - end - -feature {NONE} -- Implementation - - based_resource (a_resource: READABLE_STRING_8): READABLE_STRING_8 - do - if attached base_url as l_base_url then - Result := l_base_url + a_resource - else - Result := a_resource - end - end - -feature {WSF_ROUTED_SERVICE_I} -- Handler - - matching_route (req: WSF_REQUEST): detachable WSF_ROUTE [H, C] - local - h: detachable H - ctx: detachable C - rq_method: READABLE_STRING_8 - do - rq_method := request_method (req) - - h := handler_by_path (source_uri (req), rq_method) - if h = Void then - if attached smart_handler_by_path (source_uri (req), rq_method) as info then - h := info.handler - ctx := handler_context (info.path, req) - end - end - if h /= Void then - if h.is_valid_context (req) then - if ctx = Void then - ctx := handler_context (Void, req) - end - create Result.make (h, ctx) - else - Result := Void - end - end - end - -feature {NONE} -- Access: Implementation - - handler_by_path (a_path: READABLE_STRING_GENERAL; rqst_method: READABLE_STRING_8): detachable H - require - a_path_valid: a_path /= Void - local - l_handlers: like handlers - l_item: like handlers.item - do - l_handlers := handlers - from - l_handlers.start - until - l_handlers.after or Result /= Void - loop - l_item := l_handlers.item - if is_matching_request_methods (rqst_method, l_item.request_methods) and a_path.same_string (l_item.resource) then - Result := l_item.handler - end - l_handlers.forth - end - ensure - a_path_unchanged: a_path.same_string (old a_path) - end - - smart_handler_by_path (a_path: READABLE_STRING_8; rqst_method: READABLE_STRING_8): detachable TUPLE [path: READABLE_STRING_8; handler: H] - require - a_path_valid: a_path /= Void - local - p: INTEGER - l_context_path, l_path: READABLE_STRING_8 - h: detachable H - do - l_context_path := context_path (a_path) - from - p := l_context_path.count + 1 - until - p <= 1 or Result /= Void - loop - l_path := l_context_path.substring (1, p - 1) - h := handler_by_path (l_path, rqst_method) - if h /= Void then - Result := [l_path, h] - else - p := l_context_path.last_index_of ('/', p - 1) - end - variant - p - end - ensure - a_path_unchanged: a_path.same_string (old a_path) - end - -feature {NONE} -- Context factory - - handler_context (p: detachable STRING; req: WSF_REQUEST): C - local - ctx: C - do - if p /= Void then - create ctx.make (req, p) - else - create ctx.make (req, source_uri (req)) - end - Result := ctx - end - -feature -- Access - - new_cursor: ITERATION_CURSOR [TUPLE [handler: H; resource: READABLE_STRING_8; request_methods: detachable WSF_ROUTER_METHODS]] - -- Fresh cursor associated with current structure - do - Result := handlers.new_cursor - end - -feature {NONE} -- Implementation - - handlers: ARRAYED_LIST [TUPLE [handler: H; resource: READABLE_STRING_8; request_methods: detachable WSF_ROUTER_METHODS]] - -- Handlers indexed by the template expression - -- see `templates' - - context_path (a_path: READABLE_STRING_8): READABLE_STRING_8 - -- Prepared path from context which match requirement - -- i.e: not empty, starting with '/' - local - p: INTEGER - s: STRING_8 - do - Result := a_path - if Result.is_empty then - Result := "/" - else - if Result[1] /= '/' then - create s.make_from_string (Result) - s.prepend_character ('/') - Result := s - end - p := Result.index_of ('.', 1) - if p > 0 then - Result := Result.substring (1, p - 1) - end - end - ensure - result_not_empty: not Result.is_empty - end - -note - copyright: "2011-2012, Jocelyn Fiat, Javier Velilla, 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 diff --git a/library/server/wsf/router/wsf_response_handler.e b/library/server/wsf/router/uri/wsf_uri_template_response_handler.e similarity index 59% rename from library/server/wsf/router/wsf_response_handler.e rename to library/server/wsf/router/uri/wsf_uri_template_response_handler.e index 15f60f76..fa8493c0 100644 --- a/library/server/wsf/router/wsf_response_handler.e +++ b/library/server/wsf/router/uri/wsf_uri_template_response_handler.e @@ -1,25 +1,18 @@ note - description: "[ - Request handler object which is called by a WSF_ROUTER - A response handler should implement the method - - response (ctx: C; req: WSF_REQUEST): WSF_RESPONSE_MESSAGE - - - The class is generic, this way one can use a custom WSF_HANDLER_CONTEXT if needed - ]" + description: "Summary description for {WSF_URI_TEMPLATE_RESPONSE_HANDLER}." + author: "" date: "$Date$" revision: "$Revision$" deferred class - WSF_RESPONSE_HANDLER [C -> WSF_HANDLER_CONTEXT] + WSF_URI_TEMPLATE_RESPONSE_HANDLER inherit - WSF_HANDLER [C] + WSF_URI_TEMPLATE_HANDLER feature -- Response - response (ctx: C; req: WSF_REQUEST): WSF_RESPONSE_MESSAGE + response (ctx: WSF_URI_TEMPLATE_HANDLER_CONTEXT; req: WSF_REQUEST): WSF_RESPONSE_MESSAGE require is_valid_context: is_valid_context (req) deferred @@ -29,7 +22,7 @@ feature -- Response feature -- Execution - execute (ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE) + execute (ctx: WSF_URI_TEMPLATE_HANDLER_CONTEXT; req: WSF_REQUEST; res: WSF_RESPONSE) -- Execute request handler do res.send (response (ctx, req)) diff --git a/library/server/wsf/router/uri_template/default/wsf_uri_template_routed_service.e b/library/server/wsf/router/uri_template/default/wsf_uri_template_routed_service.e deleted file mode 100644 index af11bf51..00000000 --- a/library/server/wsf/router/uri_template/default/wsf_uri_template_routed_service.e +++ /dev/null @@ -1,39 +0,0 @@ -note - description: "Summary description for {DEFAULT_URI_TEMPLATE_ROUTED_SERVICE}." - author: "" - date: "$Date$" - revision: "$Revision$" - -deferred class - WSF_URI_TEMPLATE_ROUTED_SERVICE - -inherit - WSF_ROUTED_SERVICE_I [WSF_HANDLER [WSF_URI_TEMPLATE_HANDLER_CONTEXT], WSF_URI_TEMPLATE_HANDLER_CONTEXT] - redefine - router - end - -feature {NONE} -- Initialization - - create_router - -- Create router - --| it can be redefine to create with precise count if needed. - do - create router.make (0) - end - -feature -- Router - - router: WSF_URI_TEMPLATE_ROUTER - -;note - copyright: "2011-2012, Jocelyn Fiat, Javier Velilla, 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 diff --git a/library/server/wsf/router/uri_template/default/wsf_uri_template_router.e b/library/server/wsf/router/uri_template/default/wsf_uri_template_router.e deleted file mode 100644 index e537d0bd..00000000 --- a/library/server/wsf/router/uri_template/default/wsf_uri_template_router.e +++ /dev/null @@ -1,52 +0,0 @@ -note - description: "[ - Default router based on URI Template map - ]" - date: "$Date$" - revision: "$Revision$" - -class - WSF_URI_TEMPLATE_ROUTER - -inherit - WSF_URI_TEMPLATE_ROUTER_I [WSF_HANDLER [WSF_URI_TEMPLATE_HANDLER_CONTEXT], WSF_URI_TEMPLATE_HANDLER_CONTEXT] - redefine - map_agent_with_request_methods, - map_agent_response_with_request_methods - end - -create - make, - make_with_base_url - -feature -- Mapping agent - - map_agent_with_request_methods (a_id: READABLE_STRING_8; a_action: PROCEDURE [ANY, TUPLE [ctx: WSF_URI_TEMPLATE_HANDLER_CONTEXT; req: WSF_REQUEST; res: WSF_RESPONSE]]; - rqst_methods: detachable WSF_ROUTER_METHODS) - local - h: WSF_AGENT_HANDLER [WSF_URI_TEMPLATE_HANDLER_CONTEXT] - do - create h.make (a_action) - map_with_request_methods (a_id, h, rqst_methods) - end - - map_agent_response_with_request_methods (a_id: READABLE_STRING_8; a_action: FUNCTION [ANY, TUPLE [ctx: WSF_URI_TEMPLATE_HANDLER_CONTEXT; req: WSF_REQUEST], WSF_RESPONSE_MESSAGE]; - rqst_methods: detachable WSF_ROUTER_METHODS) - local - h: WSF_AGENT_RESPONSE_HANDLER [WSF_URI_TEMPLATE_HANDLER_CONTEXT] - do - create h.make (a_action) - map_with_request_methods (a_id, h, rqst_methods) - end - -note - copyright: "2011-2012, Jocelyn Fiat, Javier Velilla, 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 diff --git a/library/server/wsf/router/uri_template/default/wsf_uri_template_routing_handler.e b/library/server/wsf/router/uri_template/default/wsf_uri_template_routing_handler.e deleted file mode 100644 index f51843a7..00000000 --- a/library/server/wsf/router/uri_template/default/wsf_uri_template_routing_handler.e +++ /dev/null @@ -1,35 +0,0 @@ -note - description: "[ - WSF_URI_TEMPLATE_ROUTING_HANDLER is a default descendant of WSF_URI_ROUTING_HANDLER_I - for WSF_URI_TEMPLATE_ROUTER - ]" - date: "$Date$" - revision: "$Revision$" - -class - WSF_URI_TEMPLATE_ROUTING_HANDLER - -inherit - WSF_URI_TEMPLATE_ROUTING_HANDLER_I [WSF_HANDLER [WSF_URI_TEMPLATE_HANDLER_CONTEXT], WSF_URI_TEMPLATE_HANDLER_CONTEXT] - redefine - router - end - -create - make - -feature {NONE} -- Routing - - router: WSF_URI_TEMPLATE_ROUTER - -;note - copyright: "2011-2012, Jocelyn Fiat, Javier Velilla, 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 diff --git a/library/server/wsf/router/wsf_agent_handler.e b/library/server/wsf/router/uri_template/wsf_agent_uri_template_handler.e similarity index 55% rename from library/server/wsf/router/wsf_agent_handler.e rename to library/server/wsf/router/uri_template/wsf_agent_uri_template_handler.e index a8afaf5a..99950925 100644 --- a/library/server/wsf/router/wsf_agent_handler.e +++ b/library/server/wsf/router/uri_template/wsf_agent_uri_template_handler.e @@ -1,31 +1,30 @@ note - description: "Summary description for WSF_AGENT_HANDLER." + description: "Summary description for {WSF_AGENT_URI_TEMPLATE_HANDLER}." + author: "" date: "$Date$" revision: "$Revision$" class - WSF_AGENT_HANDLER [C -> WSF_HANDLER_CONTEXT] + WSF_AGENT_URI_TEMPLATE_HANDLER inherit - WSF_HANDLER [C] + WSF_URI_TEMPLATE_HANDLER create make -feature -- Initialization +feature {NONE} -- Initialization - make (act: like action) + make (a_action: like action) do - action := act + action := a_action end -feature -- Access - - action: PROCEDURE [ANY, TUPLE [ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE]] + action: PROCEDURE [ANY, TUPLE [context: WSF_URI_TEMPLATE_HANDLER_CONTEXT; request: WSF_REQUEST; response: WSF_RESPONSE]] feature -- Execution - execute (ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE) + execute (ctx: WSF_URI_TEMPLATE_HANDLER_CONTEXT; req: WSF_REQUEST; res: WSF_RESPONSE) do action.call ([ctx, req, res]) end diff --git a/library/server/wsf/router/uri_template/wsf_uri_template_handler.e b/library/server/wsf/router/uri_template/wsf_uri_template_handler.e new file mode 100644 index 00000000..3f5d8f96 --- /dev/null +++ b/library/server/wsf/router/uri_template/wsf_uri_template_handler.e @@ -0,0 +1,19 @@ +note + description: "Summary description for EWF_URI_TEMPLATE_HANDLER." + author: "" + date: "$Date$" + revision: "$Revision$" + +deferred class + WSF_URI_TEMPLATE_HANDLER + +inherit + WSF_HANDLER + +feature -- Execution + + execute (ctx: WSF_URI_TEMPLATE_HANDLER_CONTEXT; req: WSF_REQUEST; res: WSF_RESPONSE) + deferred + end + +end diff --git a/library/server/wsf/router/uri_template/wsf_uri_template_mapping.e b/library/server/wsf/router/uri_template/wsf_uri_template_mapping.e new file mode 100644 index 00000000..2623af3f --- /dev/null +++ b/library/server/wsf/router/uri_template/wsf_uri_template_mapping.e @@ -0,0 +1,81 @@ +note + description: "Summary description for {EWF_ROUTER_URI_TEMPLATE_PATH}." + author: "" + date: "$Date$" + revision: "$Revision$" + +class + WSF_URI_TEMPLATE_MAPPING + +inherit + WSF_ROUTER_MAPPING + +create + make, + make_from_string + +feature {NONE} -- Initialization + + make_from_string (s: READABLE_STRING_8; h: like handler) + do + make (create {URI_TEMPLATE}.make (s), h) + end + + make (tpl: URI_TEMPLATE; h: like handler) + do + template := tpl + handler := h + end + +feature -- Access + + handler: WSF_URI_TEMPLATE_HANDLER + + template: URI_TEMPLATE + +feature -- Element change + + set_handler (h: like handler) + do + handler := h + end + +feature -- Status + + routed_handler (req: WSF_REQUEST; res: WSF_RESPONSE; a_router: WSF_ROUTER): detachable WSF_HANDLER + local + tpl: URI_TEMPLATE + p: READABLE_STRING_32 + ctx: detachable WSF_URI_TEMPLATE_HANDLER_CONTEXT + do + p := source_uri (req) + tpl := based_uri_template (template, a_router) + if attached tpl.match (p) as tpl_res then + Result := handler + create ctx.make (req, tpl, tpl_res, source_uri (req)) + a_router.execute_before (Current) + ctx.apply (req) + handler.execute (ctx, req, res) + ctx.revert (req) + a_router.execute_after (Current) + end + rescue + if ctx /= Void then + ctx.revert (req) + end + end + +feature {NONE} -- Implementation + + based_uri_template (a_tpl: like template; a_router: WSF_ROUTER): like template + do + if attached a_router.base_url as l_base_url then + Result := a_tpl.duplicate + Result.set_template (l_base_url + a_tpl.template) + else + Result := a_tpl + end + end + + +end diff --git a/library/server/wsf/router/uri_template/wsf_uri_template_router_i.e b/library/server/wsf/router/uri_template/wsf_uri_template_router_i.e deleted file mode 100644 index 24ac6ea3..00000000 --- a/library/server/wsf/router/uri_template/wsf_uri_template_router_i.e +++ /dev/null @@ -1,228 +0,0 @@ -note - description: "[ - URL dispatcher/router based on URI Template mapping and request methods if precised - The associated context {WSF_URI_TEMPLATE_HANDLER_CONTEXT} contains information about the matched map. - - Examples: - - map ("/users/", users_handler) - map_with_request_methods ("/order/{order-id}", order_handler, <<"GET", "POST">>) - map_agent_with_request_methods ("/order/{order-id}", agent do_get_order, <<"GET">>) - map_agent_with_request_methods ("/order/{order-id}", agent do_post_order, <<"POST">>) - - ]" - date: "$Date$" - revision: "$Revision$" - -class - WSF_URI_TEMPLATE_ROUTER_I [H -> WSF_HANDLER [C], C -> WSF_URI_TEMPLATE_HANDLER_CONTEXT create make end] - -inherit - WSF_ROUTER [H, C] - -create - make, - make_with_base_url - -feature -- Initialization - - make (n: INTEGER) - do - create handlers.make (n) - create templates.make (n) - handlers.compare_objects - initialize - end - - make_with_base_url (n: INTEGER; a_base_url: like base_url) - -- Make router allocated for at least `n' maps, - -- and use `a_base_url' as base_url - do - make (n) - set_base_url (a_base_url) - end - -feature -- Status report - - handlers_matching_map (a_resource: READABLE_STRING_8; rqst_methods: detachable WSF_ROUTER_METHODS): detachable LIST [H] - local - l_res: READABLE_STRING_8 - do - l_res := based_resource (a_resource) - across - handlers as c - loop - if c.item.resource.same_string (l_res) then - if - rqst_methods = Void or else - across rqst_methods as rq some is_matching_request_methods (rq.item, c.item.request_methods) end - then - if Result = Void then - create {ARRAYED_LIST [H]} Result.make (1) - end - Result.extend (c.item.handler) - end - end - end - end - -feature -- Registration - - map_with_uri_template (uri: URI_TEMPLATE; h: H) - require - has_not_such_map: not has_map (uri.template, Void, h) - do - map_with_uri_template_and_request_methods (uri, h, Void) - end - - map_with_uri_template_and_request_methods (uri: URI_TEMPLATE; h: H; rqst_methods: detachable WSF_ROUTER_METHODS) - require - uri_is_valid: uri.is_valid - has_not_such_map: not has_map (uri.template, rqst_methods, h) - local - l_tpl: like {URI_TEMPLATE}.template - l_uri: URI_TEMPLATE - do - l_uri := based_uri (uri) - l_tpl := l_uri.template - - handlers.force ([h, l_tpl, rqst_methods]) - templates.force (l_uri, l_tpl) - h.on_handler_mapped (l_tpl, rqst_methods) - end - - map_with_request_methods (tpl: READABLE_STRING_8; h: H; rqst_methods: detachable WSF_ROUTER_METHODS) - do - map_with_uri_template_and_request_methods (create {URI_TEMPLATE}.make (tpl), h, rqst_methods) - end - -feature {NONE} -- Implementation - - based_uri (uri: URI_TEMPLATE): URI_TEMPLATE - do - if attached base_url as l_base_url then - Result := uri.duplicate - Result.set_template (l_base_url + uri.template) - else - Result := uri - end - end - - based_resource (a_resource: READABLE_STRING_8): READABLE_STRING_8 - do - if attached base_url as l_base_url then - Result := l_base_url + a_resource - else - Result := a_resource - end - end - -feature {WSF_ROUTED_SERVICE_I} -- Handler - - matching_route (req: WSF_REQUEST): detachable WSF_ROUTE [H, C] - local - l_handlers: like handlers - t: READABLE_STRING_8 - p: READABLE_STRING_8 - l_req_method: READABLE_STRING_8 - l_res: URI_TEMPLATE_MATCH_RESULT - do - p := source_uri (req) - from - l_req_method := request_method (req) - l_handlers := handlers - l_handlers.start - until - l_handlers.after or Result /= Void - loop - if attached l_handlers.item as l_info then - if is_matching_request_methods (l_req_method, l_info.request_methods) then - t := l_info.resource - if - attached {WSF_ROUTING_HANDLER [H, C]} l_info.handler as rah and then - p.starts_with (t) - then - create l_res.make_empty - l_res.path_variables.force (p.substring (t.count + 1, p.count), "path") - - create Result.make (l_info.handler, handler_context (p, req, create {URI_TEMPLATE}.make (t), l_res)) - elseif attached templates.item (t) as tpl and then - attached tpl.match (p) as res - then - create Result.make (l_info.handler, handler_context (p, req, tpl, res)) - end - end - end - l_handlers.forth - end - end - -feature {WSF_ROUTED_SERVICE_I} -- Default: implementation - - default_handler_context (req: WSF_REQUEST): C - -- - do - Result := handler_context (Void, req, create {URI_TEMPLATE}.make ("/"), create {URI_TEMPLATE_MATCH_RESULT}.make_empty) - end - -feature {NONE} -- Context factory - - handler_context (p: detachable READABLE_STRING_8; req: WSF_REQUEST; tpl: URI_TEMPLATE; tpl_res: URI_TEMPLATE_MATCH_RESULT): C - do - if p /= Void then - create Result.make (req, tpl, tpl_res, p) - else - create Result.make (req, tpl, tpl_res, source_uri (req)) - end - end - -feature -- Access: ITERABLE - - new_cursor: ITERATION_CURSOR [TUPLE [handler: H; resource: READABLE_STRING_8; request_methods: detachable WSF_ROUTER_METHODS]] - -- Fresh cursor associated with current structure - do - Result := handlers.new_cursor - end - -feature {NONE} -- Implementation - - handlers: ARRAYED_LIST [TUPLE [handler: H; resource: READABLE_STRING_8; request_methods: detachable WSF_ROUTER_METHODS]] - -- Handlers indexed by the template expression - -- see `templates' - - templates: HASH_TABLE [URI_TEMPLATE, READABLE_STRING_8] - -- URI Template indexed by the template expression - - context_path (a_path: STRING): STRING - -- Prepared path from context which match requirement - -- i.e: not empty, starting with '/' - local - p: INTEGER - do - Result := a_path - if Result.is_empty then - Result := "/" - else - if Result[1] /= '/' then - Result := "/" + Result - end - p := Result.index_of ('.', 1) - if p > 0 then - Result := Result.substring (1, p - 1) - end - end - ensure - result_not_empty: not Result.is_empty - end - -;note - copyright: "2011-2012, Jocelyn Fiat, Javier Velilla, 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 diff --git a/library/server/wsf/router/uri_template/wsf_uri_template_routing_handler_i.e b/library/server/wsf/router/uri_template/wsf_uri_template_routing_handler_i.e deleted file mode 100644 index d6fd3dcf..00000000 --- a/library/server/wsf/router/uri_template/wsf_uri_template_routing_handler_i.e +++ /dev/null @@ -1,47 +0,0 @@ -note - description: "[ - This class helps to build Routing handler based for WSF_URI_TEMPLATE_ROUTER - ]" - date: "$Date$" - revision: "$Revision$" - -class - WSF_URI_TEMPLATE_ROUTING_HANDLER_I [H -> WSF_HANDLER [C], - C -> WSF_URI_TEMPLATE_HANDLER_CONTEXT create make end] - -inherit - WSF_ROUTING_HANDLER [H, C] - -create - make, - make_with_base_url - -feature {NONE} -- Initialization - - make (n: INTEGER) - do - create router.make (n) - end - - make_with_base_url (n: INTEGER; a_base_url: like base_url) - -- Make allocated for at least `n' maps, - -- and use `a_base_url' as base_url - do - create router.make_with_base_url (n, a_base_url) - end - -feature {NONE} -- Routing - - router: WSF_URI_TEMPLATE_ROUTER_I [H, C] - -;note - copyright: "2011-2012, Jocelyn Fiat, Javier Velilla, 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 diff --git a/library/server/wsf/router/wsf_file_system_handler.e b/library/server/wsf/router/wsf_file_system_handler.e index fc18bedb..01626c60 100644 --- a/library/server/wsf/router/wsf_file_system_handler.e +++ b/library/server/wsf/router/wsf_file_system_handler.e @@ -1,43 +1,69 @@ note - description: "[ - Request handler used to respond file system request. - ]" + description: "Summary description for {WSF_FILE_SYSTEM_HANDLER}." + author: "" date: "$Date$" revision: "$Revision$" class - WSF_FILE_SYSTEM_HANDLER [C -> WSF_HANDLER_CONTEXT] + WSF_FILE_SYSTEM_HANDLER inherit - WSF_HANDLER [C] + WSF_STARTS_WITH_HANDLER + rename + execute as execute_starts_with + end create make feature {NONE} -- Initialization - make (a_root: READABLE_STRING_8) + make (d: like document_root) require - a_root_exists: node_exists (a_root) + valid_d: (d /= Void and then not d.is_empty) implies d.ends_with ("/") + local + e: EXECUTION_ENVIRONMENT do - document_root := a_root + if d.is_empty then + create e + document_root := e.current_working_directory + else + document_root := d + end end -feature -- Access +feature -- Access - document_root: READABLE_STRING_8 - -- Document root for the file system + document_root: STRING + max_age: INTEGER + + index_disabled: BOOLEAN + -- Index disabled? directory_index: detachable ARRAY [READABLE_STRING_8] -- File serve if a directory index is requested - not_found_handler: detachable PROCEDURE [ANY, TUPLE [uri: READABLE_STRING_8; ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE]] - - access_denied_handler: detachable PROCEDURE [ANY, TUPLE [uri: READABLE_STRING_8; ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE]] + not_found_handler: detachable PROCEDURE [ANY, TUPLE [uri: READABLE_STRING_8; req: WSF_REQUEST; res: WSF_RESPONSE]] + access_denied_handler: detachable PROCEDURE [ANY, TUPLE [uri: READABLE_STRING_8; req: WSF_REQUEST; res: WSF_RESPONSE]] feature -- Element change + enable_index + do + index_disabled := False + end + + disable_index + do + index_disabled := True + end + + set_max_age (a_seconds: like max_age) + do + max_age := a_seconds + end + set_directory_index (idx: like directory_index) -- Set `directory_index' as `idx' do @@ -62,38 +88,25 @@ feature -- Element change feature -- Execution - requested_path (ctx: C): detachable READABLE_STRING_8 - -- Path associated with the request - -- i.e: path of the file system resource if any - do - if attached {WSF_STRING} ctx.item ("path") as v_path then - Result := v_path.value.as_string_8 - end - end - - execute (ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE) - -- Execute request handler + execute (a_start_path: READABLE_STRING_8; req: WSF_REQUEST; res: WSF_RESPONSE) local - h: HTTP_HEADER - s: STRING + p: STRING do - if attached requested_path (ctx) as uri then - process_uri (uri, ctx, req, res) + p := req.path_info + if p.starts_with (a_start_path) then + p.remove_head (a_start_path.count) else - s := "Hello " + ctx.path + "%N" - s.append ("root=" + document_root) - - create h.make - h.put_content_type_text_html - h.put_content_length (s.count) - - res.set_status_code ({HTTP_STATUS_CODE}.ok) - res.put_header_text (h.string) - res.put_string (s) + check starts_with_base: False end end + process_uri (p, req, res) end - process_uri (uri: READABLE_STRING_8; ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE) + execute_starts_with (a_start_path: READABLE_STRING_8; req: WSF_REQUEST; res: WSF_RESPONSE) + do + execute (a_start_path,req, res) + end + + process_uri (uri: READABLE_STRING_8; req: WSF_REQUEST; res: WSF_RESPONSE) local f: RAW_FILE fn: READABLE_STRING_8 @@ -103,19 +116,23 @@ feature -- Execution if f.exists then if f.is_readable then if f.is_directory then - respond_index (req.request_uri, fn, ctx, req, res) + if index_disabled then + process_directory_index_disabled (uri, req, res) + else + process_index (req.request_uri, fn, req, res) + end else - respond_file (f, ctx, req, res) + process_file (f, req, res) end else - respond_access_denied (uri, ctx, req, res) + process_access_denied (uri, req, res) end else - respond_not_found (uri, ctx, req, res) + process_not_found (uri, req, res) end end - respond_index (a_uri: READABLE_STRING_8; dn: READABLE_STRING_8; ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE) + process_index (a_uri: READABLE_STRING_8; dn: READABLE_STRING_8; req: WSF_REQUEST; res: WSF_RESPONSE) local h: HTTP_HEADER uri, s: STRING_8 @@ -124,7 +141,7 @@ feature -- Execution do create d.make_open_read (dn) if attached directory_index_file (d) as f then - respond_file (f, ctx, req, res) + process_file (f, req, res) else uri := a_uri if not uri.is_empty and then uri [uri.count] /= '/' then @@ -170,31 +187,72 @@ feature -- Execution d.close end - respond_file (f: FILE; ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE) + process_file (f: FILE; req: WSF_REQUEST; res: WSF_RESPONSE) local ext: READABLE_STRING_8 ct: detachable READABLE_STRING_8 fres: WSF_FILE_RESPONSE + dt: DATE_TIME do ext := extension (f.name) ct := extension_mime_mapping.mime_type (ext) if ct = Void then ct := {HTTP_MIME_TYPES}.application_force_download end - create fres.make_with_content_type (ct, f.name) - fres.set_status_code ({HTTP_STATUS_CODE}.ok) - fres.set_answer_head_request_method (req.request_method.same_string ({HTTP_REQUEST_METHODS}.method_head)) + if + attached req.meta_string_variable ("HTTP_IF_MODIFIED_SINCE") as s_if_modified_since and then + attached file_date (f) as f_date and then (f_date >= rfc1123_http_date_format_to_date (s_if_modified_since)) + then + process_not_modified (f_date, req, res) + else + create fres.make_with_content_type (ct, f.name) + fres.set_status_code ({HTTP_STATUS_CODE}.ok) - res.send (fres) + -- cache control + create dt.make_now_utc + fres.header.put_cache_control ("private, max-age=" + max_age.out) + fres.header.put_utc_date (dt) + if max_age > 0 then + dt := dt.twin + dt.second_add (max_age) + end + fres.header.put_expires_date (dt) + + fres.set_answer_head_request_method (req.request_method.same_string ({HTTP_REQUEST_METHODS}.method_head)) + res.send (fres) + end end - respond_not_found (uri: READABLE_STRING_8; ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE) + process_not_modified (a_utc_date: detachable DATE_TIME; req: WSF_REQUEST; res: WSF_RESPONSE) + local + h: HTTP_HEADER + dt: DATE_TIME + do + create dt.make_now_utc + create h.make + h.put_cache_control ("private, max-age=" + max_age.out) + h.put_utc_date (dt) + if max_age > 0 then + dt := dt.twin + dt.second_add (max_age) + end + h.put_expires_date (dt) + + if a_utc_date /= Void then + h.put_last_modified (a_utc_date) + end + res.set_status_code ({HTTP_STATUS_CODE}.not_modified) + res.put_header_text (h.string) + res.flush + end + + process_not_found (uri: READABLE_STRING_8; req: WSF_REQUEST; res: WSF_RESPONSE) local h: HTTP_HEADER s: STRING_8 do if attached not_found_handler as hdl then - hdl.call ([uri, ctx, req, res]) + hdl.call ([uri, req, res]) else create h.make h.put_content_type_text_plain @@ -208,13 +266,13 @@ feature -- Execution end end - respond_access_denied (uri: READABLE_STRING_8; ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE) + process_access_denied (uri: READABLE_STRING_8; req: WSF_REQUEST; res: WSF_RESPONSE) local h: HTTP_HEADER s: STRING_8 do if attached access_denied_handler as hdl then - hdl.call ([uri, ctx, req, res]) + hdl.call ([uri, req, res]) else create h.make h.put_content_type_text_plain @@ -228,6 +286,26 @@ feature -- Execution end end + process_directory_index_disabled (uri: READABLE_STRING_8; req: WSF_REQUEST; res: WSF_RESPONSE) + local + h: HTTP_HEADER + s: STRING_8 + do + if attached access_denied_handler as hdl then + hdl.call ([uri, req, res]) + else + create h.make + h.put_content_type_text_plain + create s.make_empty + s.append ("Directory index: Access denied%N") + res.set_status_code ({HTTP_STATUS_CODE}.forbidden) + h.put_content_length (s.count) + res.put_header_text (h.string) + res.put_string (s) + res.flush + end + end + feature {NONE} -- Implementation directory_index_file (d: DIRECTORY): detachable FILE @@ -343,14 +421,33 @@ feature {NONE} -- Implementation end end -note - copyright: "2011-2012, Jocelyn Fiat, Javier Velilla, 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 - ]" +feature {NONE} -- implementation: date time + + date_time_utility: HTTP_DATE_TIME_UTILITIES + once + create Result + end + + file_date (f: FILE): DATE_TIME + do + Result := timestamp_to_date (f.date) + end + + rfc1123_http_date_format_to_date (s: STRING): DATE_TIME + -- String representation of `dt' using the RFC 1123 + local + t: STRING + do + t := s + if t.ends_with ("GMT") then + t := t.substring (1, t.count - 4) + end + create Result.make_from_string (t, "ddd,[0]dd mmm yyyy [0]hh:[0]mi:[0]ss.ff2") + end + + timestamp_to_date (n: INTEGER): DATE_TIME + do + Result := date_time_utility.unix_time_stamp_to_date_time (n) + end + end diff --git a/library/server/wsf/router/wsf_handler.e b/library/server/wsf/router/wsf_handler.e index 0bdf431d..17d8d161 100644 --- a/library/server/wsf/router/wsf_handler.e +++ b/library/server/wsf/router/wsf_handler.e @@ -1,20 +1,11 @@ note - description: "[ - Request handler object which is called by a WSF_ROUTER - An handler should implement the method - - execute (ctx, req, res) - - The class is generic, this way one can use a custom WSF_HANDLER_CONTEXT if needed - ]" + description: "Summary description for {WSF_HANDLER}." + author: "" date: "$Date$" revision: "$Revision$" deferred class - WSF_HANDLER [C -> WSF_HANDLER_CONTEXT] - -inherit - ANY + WSF_HANDLER feature -- Status report @@ -23,60 +14,10 @@ feature -- Status report do Result := True end + +feature {WSF_ROUTER} -- Mapping change -feature -- Execution - - execute (ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE) - -- Execute request handler - -- - -- `ctx': contains advanced data related to request_uri - -- in the case of URI_TEMPLATE, it add support for "path_parameter" - -- `req': request data - -- `res': reponse stream - --| note `ctx' can also provide data coming from `req' - require - is_valid_context: is_valid_context (req) - deferred - ensure - response_status_set: res.status_is_set - end - -feature -- Execution: report - - url (req: WSF_REQUEST; a_base: detachable READABLE_STRING_8; args: detachable STRING; abs: BOOLEAN): STRING - -- Associated url based on `a_base' and `args' - -- if `abs' then return absolute url - local - s: detachable STRING - l_base: STRING - do - if a_base /= Void then - l_base := a_base - else - l_base := req.request_uri - end - s := args - if s /= Void and then s.count > 0 then - if s[1] /= '/' then - s := l_base + "/" + s - else - s := l_base + s - end - else - s := l_base - end - if abs then - Result := req.absolute_script_url (s) - else - Result := req.script_url (s) - end - ensure - result_attached: Result /= Void - end - -feature {WSF_ROUTER} -- Routes change - - on_handler_mapped (a_resource: READABLE_STRING_8; a_rqst_methods: detachable WSF_ROUTER_METHODS) + on_mapped (a_mapping: WSF_ROUTER_MAPPING; a_rqst_methods: detachable WSF_ROUTER_METHODS) -- Callback called when a router map a route to Current handler do end diff --git a/library/server/wsf/router/wsf_route.e b/library/server/wsf/router/wsf_route.e deleted file mode 100644 index 57afda65..00000000 --- a/library/server/wsf/router/wsf_route.e +++ /dev/null @@ -1,45 +0,0 @@ -note - description: "[ - a WSF_ROUTE object associates a handler and the associated context at runtime - ]" - date: "$Date$" - revision: "$Revision$" - -class - WSF_ROUTE [H -> WSF_HANDLER [C], C -> WSF_HANDLER_CONTEXT] - -create - make - -feature {NONE} -- Initialization - - make (h: H; c: C) - -- Instantiate Current with `h' and `c' - do - handler := h - context := c - end - -feature -- Access - - handler: H - -- Handler - - context: C - -- Context associated to `handler' for execution - -invariant - handler /= Void - context /= Void - -note - copyright: "2011-2012, Jocelyn Fiat, Javier Velilla, 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 diff --git a/library/server/wsf/router/wsf_router.e b/library/server/wsf/router/wsf_router.e index 0171b1d4..c1403d0b 100644 --- a/library/server/wsf/router/wsf_router.e +++ b/library/server/wsf/router/wsf_router.e @@ -1,111 +1,120 @@ note - description: "[ - URL dispatcher/router based on deferred mapping (to be defined in descendant) - The associated context {WSF_HANDLER_CONTEXT} does contains information related to the matching at runtime. - ]" + description: "Summary description for {EWF_ROUTER}." + author: "" date: "$Date$" revision: "$Revision$" -deferred class - WSF_ROUTER [H -> WSF_HANDLER [C], C -> WSF_HANDLER_CONTEXT] +class + WSF_ROUTER inherit - ITERABLE [TUPLE [handler: H; resource: READABLE_STRING_8; request_methods: detachable WSF_ROUTER_METHODS]] + ITERABLE [TUPLE [mapping: WSF_ROUTER_MAPPING; request_methods: detachable WSF_ROUTER_METHODS]] + +create + make, + make_with_base_url feature {NONE} -- Initialization + make (n: INTEGER) + do + create mappings.make (n) + initialize + end + + make_with_base_url (n: INTEGER; a_base_url: like base_url) + -- Make router allocated for at least `n' maps, + -- and use `a_base_url' as base_url + do + make (n) + set_base_url (a_base_url) + end + initialize -- Initialize router do - create pre_route_execution_actions + create mappings.make (10) + create pre_execution_actions end -feature -- Status report - - has_map (a_resource: READABLE_STRING_8; rqst_methods: detachable WSF_ROUTER_METHODS; a_handler: detachable H): BOOLEAN - -- Has a map corresponding to `a_resource' and `rqst_methods' other than `a_handler'? - do - if attached handlers_matching_map (a_resource, rqst_methods) as lst then - Result := a_handler = Void or else not lst.has (a_handler) - end - end - - handlers_matching_map (a_resource: READABLE_STRING_8; rqst_methods: detachable WSF_ROUTER_METHODS): detachable LIST [H] - -- Existing handlers matching map with `a_resource' and `rqst_methods' - deferred - end + mappings: ARRAYED_LIST [TUPLE [mapping: WSF_ROUTER_MAPPING; request_methods: detachable WSF_ROUTER_METHODS]] + -- Existing mappings feature -- Mapping - map (a_resource: READABLE_STRING_8; h: H) - -- Map handler `h' with `a_resource' - require - has_not_such_map: not has_map (a_resource, Void, h) + map (a_mapping: WSF_ROUTER_MAPPING) + -- Map `a_mapping' do - map_with_request_methods (a_resource, h, Void) + map_with_request_methods (a_mapping, Void) end - map_routing (a_resource: READABLE_STRING_8; h: H) - -- Map handler `h' with `a_resource' - require - has_not_such_map: not has_map (a_resource, Void, h) + map_with_request_methods (a_mapping: WSF_ROUTER_MAPPING; rqst_methods: detachable WSF_ROUTER_METHODS) + -- Map `a_mapping' for request methods `rqst_methods' do - map (a_resource, h) + mappings.extend ([a_mapping, rqst_methods]) + a_mapping.handler.on_mapped (a_mapping, rqst_methods) end - map_with_request_methods (a_resource: READABLE_STRING_8; h: H; rqst_methods: detachable WSF_ROUTER_METHODS) - -- Map handler `h' with `a_resource' and `rqst_methods' - require - has_not_such_map: not has_map (a_resource, rqst_methods, h) - deferred - end +feature -- Access -feature -- Mapping agent + is_dispatched: BOOLEAN + -- `dispatch' set `is_dispatched' to True + -- if handler was found and executed - map_agent (a_resource: READABLE_STRING_8; a_action: PROCEDURE [ANY, TUPLE [ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE]]) - -- Map `a_action' as an handler with `a_resource' + dispatch (req: WSF_REQUEST; res: WSF_RESPONSE) do - map_agent_with_request_methods (a_resource, a_action, Void) - end - - map_agent_with_request_methods (a_resource: READABLE_STRING_8; a_action: PROCEDURE [ANY, TUPLE [ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE]]; - rqst_methods: detachable WSF_ROUTER_METHODS) - -- Map `a_action' as an handler with `a_resource' and `rqst_methods' - local - rah: WSF_AGENT_HANDLER [C] - do - create rah.make (a_action) - if attached {H} rah as h then - map_with_request_methods (a_resource, h, rqst_methods) - else - check valid_agent_handler: False end + if attached dispatch_and_return_handler (req, res) then + check is_dispatched: is_dispatched end end end -feature -- Mapping response agent - - map_agent_response (a_resource: READABLE_STRING_8; a_function: FUNCTION [ANY, TUPLE [ctx: C; req: WSF_REQUEST], WSF_RESPONSE_MESSAGE]) - -- Map response as Result `a_function' as an handler with `a_resource' - do - map_agent_response_with_request_methods (a_resource, a_function, Void) - end - - map_agent_response_with_request_methods (a_resource: READABLE_STRING_8; a_function: FUNCTION [ANY, TUPLE [ctx: C; req: WSF_REQUEST], WSF_RESPONSE_MESSAGE]; - rqst_methods: detachable WSF_ROUTER_METHODS) - -- Map response as Result `a_function' as an handler with `a_resource' and `rqst_methods' + dispatch_and_return_handler (req: WSF_REQUEST; res: WSF_RESPONSE): detachable WSF_HANDLER local - rah: WSF_AGENT_RESPONSE_HANDLER [C] + l_req_method: READABLE_STRING_8 + m: WSF_ROUTER_MAPPING do - create rah.make (a_function) - if attached {H} rah as h then - map_with_request_methods (a_resource, h, rqst_methods) - else - check valid_agent_handler: False end + is_dispatched := False + l_req_method := request_method (req) + + across + mappings as c + until + Result /= Void + loop + if attached c.item as l_info then + if is_matching_request_methods (l_req_method, l_info.request_methods) then + m := l_info.mapping + if attached m.routed_handler (req, res, Current) as r then + is_dispatched := True + Result := r + end + end + end end end +feature -- Hook + + execute_before (a_mapping: WSF_ROUTER_MAPPING) + do + pre_execution_actions.call ([a_mapping]) + end + + execute_after (a_mapping: WSF_ROUTER_MAPPING) + do + end + + pre_execution_actions: ACTION_SEQUENCE [TUPLE [WSF_ROUTER_MAPPING]] + -- Action triggered before a route is execute + --| Could be used for tracing, logging + feature -- Base url + count: INTEGER + do + Result := mappings.count + end + base_url: detachable READABLE_STRING_8 -- Common start of any route url @@ -115,6 +124,7 @@ feature -- Element change -- Set `base_url' to `a_base_url' -- make sure no map is already added (i.e: count = 0) require + a_valid_base_url: (a_base_url /= Void and then a_base_url.is_empty) implies (a_base_url.starts_with ("/") and not a_base_url.ends_with ("/")) no_handler_set: count = 0 do if a_base_url = Void or else a_base_url.is_empty then @@ -124,105 +134,12 @@ feature -- Element change end end -feature -- Hook - - pre_route_execution_actions: ACTION_SEQUENCE [TUPLE [like route]] - -- Action triggered before a route is execute - --| Could be used for tracing, logging - -feature -- Routing - - route (req: WSF_REQUEST): detachable WSF_ROUTE [H, C] - -- Route matching `req'. - do - Result := matching_route (req) - end - -feature -- Execution - - execute_route (a_route: WSF_ROUTE [H,C]; req: WSF_REQUEST; res: WSF_RESPONSE) - -- Process route `a_route' - require - a_route_attached: a_route /= Void - local - ctx: C - do - pre_route_execution_actions.call ([a_route]) - ctx := a_route.context - ctx.apply (req) - a_route.handler.execute (ctx, req, res) - ctx.revert (req) - rescue - a_route.context.revert (req) - end - - dispatch (req: WSF_REQUEST; res: WSF_RESPONSE): BOOLEAN - -- Dispatch `req, res' to the associated handler - -- And return True is handled, otherwise False - do - if attached route (req) as r then - Result := True - execute_route (r, req, res) - end - end - - dispatch_and_return_handler (req: WSF_REQUEST; res: WSF_RESPONSE): detachable H - -- Dispatch `req, res' to the associated handler - -- And return this handler - -- If Result is Void, this means no handler was found. - do - if attached route (req) as r then - Result := r.handler - execute_route (r, req, res) - end - end - -feature {WSF_ROUTED_SERVICE_I} -- Implementation - - default_handler_context (req: WSF_REQUEST): C - -- Default handler context associated with `req'. - --| It can be used to build a context if needed. - deferred - end - -feature -- status report - - count: INTEGER - -- Count of maps handled by current - do - across - Current as curs - loop - if attached {WSF_ROUTING_HANDLER [H, C]} curs.item.handler as rh then - Result := Result + rh.count + 1 --| +1 for the handler itself - else - Result := Result + 1 - end - end - end - feature -- Traversing - new_cursor: ITERATION_CURSOR [TUPLE [handler: H; resource: READABLE_STRING_8; request_methods: detachable WSF_ROUTER_METHODS]] + new_cursor: ITERATION_CURSOR [TUPLE [mapping: WSF_ROUTER_MAPPING; request_methods: detachable WSF_ROUTER_METHODS]] -- Fresh cursor associated with current structure - deferred - end - -feature {WSF_ROUTED_SERVICE_I} -- Handler - - source_uri (req: WSF_REQUEST): READABLE_STRING_32 - -- URI to use to find handler. do - Result := req.path_info - end - - matching_route (req: WSF_REQUEST): detachable WSF_ROUTE [H, C] - -- Handler whose map matched with `req' with associated Context - require - req_valid: source_uri (req) /= Void - deferred - ensure - source_uri_unchanged: source_uri (req).same_string (old source_uri (req)) + Result := mappings.new_cursor end feature -- Request methods helper @@ -343,14 +260,4 @@ feature {NONE} -- Access: Implementation end end -note - copyright: "2011-2012, Jocelyn Fiat, Javier Velilla, 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 diff --git a/library/server/wsf/router/uri/default/wsf_uri_routed_service.e b/library/server/wsf/router/wsf_router_mapping.e similarity index 53% rename from library/server/wsf/router/uri/default/wsf_uri_routed_service.e rename to library/server/wsf/router/wsf_router_mapping.e index f5ff1015..0fcf66da 100644 --- a/library/server/wsf/router/uri/default/wsf_uri_routed_service.e +++ b/library/server/wsf/router/wsf_router_mapping.e @@ -1,31 +1,33 @@ note - description: "Summary description for WSF_URI_ROUTED_SERVICE." + description: "Summary description for {WSF_ROUTER_MAPPING}." author: "" date: "$Date$" revision: "$Revision$" deferred class - WSF_URI_ROUTED_SERVICE + WSF_ROUTER_MAPPING -inherit - WSF_ROUTED_SERVICE_I [WSF_HANDLER [WSF_URI_HANDLER_CONTEXT], WSF_URI_HANDLER_CONTEXT] - redefine - router +feature -- Access + + handler: WSF_HANDLER + deferred end -feature {NONE} -- Initialization +feature -- Status - create_router - -- Create router - --| it can be redefine to create with precise count if needed. + routed_handler (req: WSF_REQUEST; res: WSF_RESPONSE; a_router: WSF_ROUTER): detachable WSF_HANDLER + deferred + end + +feature -- Helper + + source_uri (req: WSF_REQUEST): READABLE_STRING_32 + -- URI to use to find handler. do - create router.make (0) + Result := req.path_info end -feature -- Router - router: WSF_URI_ROUTER - -;note +note copyright: "2011-2012, Jocelyn Fiat, Javier Velilla, Eiffel Software and others" license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)" source: "[ diff --git a/library/server/wsf/router/wsf_routing_handler.e b/library/server/wsf/router/wsf_routing_handler.e deleted file mode 100644 index 384dfa4f..00000000 --- a/library/server/wsf/router/wsf_routing_handler.e +++ /dev/null @@ -1,113 +0,0 @@ -note - description: "[ - WSF_ROUTING_HANDLER is mainly to group a set of handler having the same base - such as /users for - /users/by/id/{id} - /users/by/name/name} - - It can be used to optimize the router, where the router checks only the base path before checking each entries - Then for - /a/a1 - /a/a2 - /a/a3 - /a/a4 - /b/b1 - /b/b2 - /b/b3 - 2 routing handlers could be used "/a" and "/b" - then to find the /b/b2 match, the router has to do only - /a /b /b/b1 and /b/b2 i.e: 4 checks - instead of /a/a1 /a/a2 /a/a3 /a/a4 /b/b1 /b/b2: i.e: 6 checks - On router with deep arborescence this could be significant - ]" - date: "$Date$" - revision: "$Revision$" - -deferred class - WSF_ROUTING_HANDLER [H -> WSF_HANDLER [C], C -> WSF_HANDLER_CONTEXT] - -inherit - WSF_HANDLER [C] - -feature -- Access - - count: INTEGER - -- Count of maps handled by current - do - Result := router.count - end - - base_url: detachable READABLE_STRING_8 - do - Result := router.base_url - end - -feature -- Element change - - set_base_url (a_base_url: like base_url) - -- Set `base_url' to `a_base_url' - -- make sure no map is already added (i.e: count = 0) - require - no_handler_set: count = 0 - do - router.set_base_url (a_base_url) - end - -feature -- Execution - - execute (ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE) - -- Execute request handler - local - r: detachable WSF_ROUTE [H, C] - do - r := router.route (req) - if r = Void then - res.put_header ({HTTP_STATUS_CODE}.not_found, <<[{HTTP_HEADER_NAMES}.header_content_length, "0"]>>) - else - router.execute_route (r, req, res) - end - end - -feature {NONE} -- Routing - - router: WSF_ROUTER [H, C] - deferred - end - -feature -- Mapping - - map (a_resource: READABLE_STRING_8; h: H) - -- Map handler `h' with `a_resource' - do - router.map (a_resource, h) - end - - map_with_request_methods (a_resource: READABLE_STRING_8; h: H; - rqst_methods: detachable WSF_ROUTER_METHODS) - -- Map handler `h' with `a_resource' and `rqst_methods' - do - router.map_with_request_methods (a_resource, h, rqst_methods) - end - - map_agent (a_resource: READABLE_STRING_8; a_action: PROCEDURE [ANY, TUPLE [ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE]]) - do - router.map_agent (a_resource, a_action) - end - - map_agent_with_request_methods (a_resource: READABLE_STRING_8; a_action: PROCEDURE [ANY, TUPLE [ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE]]; - rqst_methods: detachable WSF_ROUTER_METHODS) - do - router.map_agent_with_request_methods (a_resource, a_action, rqst_methods) - end - -note - copyright: "2011-2012, Jocelyn Fiat, Javier Velilla, 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 From 0503e63209f026f16349ce3fb55407f3b7a79236 Mon Sep 17 00:00:00 2001 From: Jocelyn Fiat Date: Tue, 11 Sep 2012 20:51:36 +0200 Subject: [PATCH 2/7] Minor implementation changes (feature renaming, ... ) --- .../starts_with/wsf_starts_with_mapping.e | 14 ++++++++- .../server/wsf/router/uri/wsf_uri_mapping.e | 2 +- .../uri_template/wsf_uri_template_mapping.e | 18 +++++++++-- library/server/wsf/router/wsf_router.e | 30 +++++++++++++++---- .../server/wsf/router/wsf_router_mapping.e | 6 ++-- 5 files changed, 59 insertions(+), 11 deletions(-) diff --git a/library/server/wsf/router/starts_with/wsf_starts_with_mapping.e b/library/server/wsf/router/starts_with/wsf_starts_with_mapping.e index fed15b87..a71f2da8 100644 --- a/library/server/wsf/router/starts_with/wsf_starts_with_mapping.e +++ b/library/server/wsf/router/starts_with/wsf_starts_with_mapping.e @@ -30,11 +30,12 @@ feature -- Access feature -- Status routed_handler (req: WSF_REQUEST; res: WSF_RESPONSE; a_router: WSF_ROUTER): detachable WSF_HANDLER + -- Return the handler if Current matches the request `req'. local p: READABLE_STRING_8 s: like based_uri do - p := source_uri (req) + p := path_from_request (req) s := based_uri (uri, a_router) if p.starts_with (s) then Result := handler @@ -47,6 +48,7 @@ feature -- Status feature {NONE} -- Implementation based_uri (a_uri: like uri; a_router: WSF_ROUTER): like uri + -- `uri' prefixed by the `WSF_ROUTER.base_url' if any local s: STRING_8 do @@ -59,4 +61,14 @@ feature {NONE} -- Implementation end end +note + copyright: "2011-2012, Jocelyn Fiat, Javier Velilla, 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 diff --git a/library/server/wsf/router/uri/wsf_uri_mapping.e b/library/server/wsf/router/uri/wsf_uri_mapping.e index fcc33642..bf6e8d90 100644 --- a/library/server/wsf/router/uri/wsf_uri_mapping.e +++ b/library/server/wsf/router/uri/wsf_uri_mapping.e @@ -43,7 +43,7 @@ feature -- Status p: READABLE_STRING_8 l_uri: like uri do - p := source_uri (req) + p := path_from_request (req) l_uri := based_uri (uri, a_router) if l_uri.ends_with ("/") then if not p.ends_with ("/") then diff --git a/library/server/wsf/router/uri_template/wsf_uri_template_mapping.e b/library/server/wsf/router/uri_template/wsf_uri_template_mapping.e index 2623af3f..af8b7bf3 100644 --- a/library/server/wsf/router/uri_template/wsf_uri_template_mapping.e +++ b/library/server/wsf/router/uri_template/wsf_uri_template_mapping.e @@ -48,14 +48,18 @@ feature -- Status p: READABLE_STRING_32 ctx: detachable WSF_URI_TEMPLATE_HANDLER_CONTEXT do - p := source_uri (req) + p := path_from_request (req) tpl := based_uri_template (template, a_router) if attached tpl.match (p) as tpl_res then Result := handler - create ctx.make (req, tpl, tpl_res, source_uri (req)) + create ctx.make (req, tpl, tpl_res, path_from_request (req)) a_router.execute_before (Current) + --| Applied the context to the request + --| in practice, this will fill the {WSF_REQUEST}.path_parameters ctx.apply (req) handler.execute (ctx, req, res) + --| Revert {WSF_REQUEST}.path_parameters_source to former value + --| In case the request object passed by other handler that alters its values. ctx.revert (req) a_router.execute_after (Current) end @@ -78,4 +82,14 @@ feature {NONE} -- Implementation end +note + copyright: "2011-2012, Jocelyn Fiat, Javier Velilla, 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 diff --git a/library/server/wsf/router/wsf_router.e b/library/server/wsf/router/wsf_router.e index c1403d0b..ed039aed 100644 --- a/library/server/wsf/router/wsf_router.e +++ b/library/server/wsf/router/wsf_router.e @@ -17,23 +17,25 @@ create feature {NONE} -- Initialization make (n: INTEGER) + -- Create the router with a capacity of `n' mappings do create mappings.make (n) - initialize + initialize (n) end make_with_base_url (n: INTEGER; a_base_url: like base_url) -- Make router allocated for at least `n' maps, - -- and use `a_base_url' as base_url + -- and use `a_base_url' as `base_url' + --| This avoids prefixing all the resource string. do make (n) set_base_url (a_base_url) end - initialize + initialize (n: INTEGER) -- Initialize router do - create mappings.make (10) + create mappings.make (n) create pre_execution_actions end @@ -59,9 +61,11 @@ feature -- Access is_dispatched: BOOLEAN -- `dispatch' set `is_dispatched' to True - -- if handler was found and executed + -- if mapping was found, and associated handler executed dispatch (req: WSF_REQUEST; res: WSF_RESPONSE) + -- Dispatch request `req' among the `mappings' + -- Set `is_dispatched' if the request were dispatched do if attached dispatch_and_return_handler (req, res) then check is_dispatched: is_dispatched end @@ -69,6 +73,8 @@ feature -- Access end dispatch_and_return_handler (req: WSF_REQUEST; res: WSF_RESPONSE): detachable WSF_HANDLER + -- Dispatch request `req' among the `mappings' + -- And return the associated handler if mapping found and handler executed. local l_req_method: READABLE_STRING_8 m: WSF_ROUTER_MAPPING @@ -96,11 +102,14 @@ feature -- Access feature -- Hook execute_before (a_mapping: WSF_ROUTER_MAPPING) + -- Execute before the handler associated with the matching mapping is executed do pre_execution_actions.call ([a_mapping]) end execute_after (a_mapping: WSF_ROUTER_MAPPING) + -- Execute after the handler associated with the matching mapping is executed + --| Could be redefined to add specific hook. do end @@ -111,6 +120,7 @@ feature -- Hook feature -- Base url count: INTEGER + -- Number of mappings registered do Result := mappings.count end @@ -260,4 +270,14 @@ feature {NONE} -- Access: Implementation end end +note + copyright: "2011-2012, Jocelyn Fiat, Javier Velilla, 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 diff --git a/library/server/wsf/router/wsf_router_mapping.e b/library/server/wsf/router/wsf_router_mapping.e index 0fcf66da..f5fb7491 100644 --- a/library/server/wsf/router/wsf_router_mapping.e +++ b/library/server/wsf/router/wsf_router_mapping.e @@ -10,19 +10,21 @@ deferred class feature -- Access handler: WSF_HANDLER + -- Handler associated with Current mapping. deferred end feature -- Status routed_handler (req: WSF_REQUEST; res: WSF_RESPONSE; a_router: WSF_ROUTER): detachable WSF_HANDLER + -- Return the handler if Current matches the request `req'. deferred end feature -- Helper - source_uri (req: WSF_REQUEST): READABLE_STRING_32 - -- URI to use to find handler. + path_from_request (req: WSF_REQUEST): READABLE_STRING_32 + -- Path used by Current to check that Current mapping matches request `req'. do Result := req.path_info end From 28186efbe75f006e12955c172b38534124229a7b Mon Sep 17 00:00:00 2001 From: Jocelyn Fiat Date: Tue, 25 Sep 2012 23:18:17 +0200 Subject: [PATCH 3/7] Applied new ROUTER design to the whole EWF project. --- .../src/contrib/doc/rest_api_documentation.e | 327 ------------------ .../rest/src/rest_request_agent_handler.e | 40 +-- .../request/rest/src/rest_request_handler.e | 18 +- .../request/rest/src/rest_request_router.e | 23 -- .../server/request/rest/src/rest_service.e | 4 +- .../server/request/rest/src/rest_service_i.e | 14 +- .../rest/src/uri/rest_request_uri_handler.e | 24 -- .../rest/src/uri/rest_request_uri_router.e | 40 --- .../rest/src/uri/rest_request_uri_router_i.e | 36 -- .../uri/rest_request_uri_routing_handler.e | 33 -- .../uri/rest_request_uri_routing_handler_i.e | 64 ---- .../request/rest/src/uri/rest_uri_service.e | 30 -- .../rest_request_uri_template_handler.e | 4 +- .../rest_request_uri_template_router.e | 41 --- .../rest_request_uri_template_router_i.e | 29 -- ...est_request_uri_template_routing_handler.e | 34 -- ...t_request_uri_template_routing_handler_i.e | 66 ---- .../uri_template/rest_uri_template_service.e | 11 +- .../filter/src/filter/authentication_filter.e | 32 +- examples/filter/src/filter_server.e | 23 +- examples/filter/src/resource/user_handler.e | 20 +- .../src/resource/order_handler.e | 69 ++-- examples/restbucksCRUD/src/restbucks_server.e | 9 +- examples/upload_image/src/image_uploader.e | 14 +- .../{ => context}/wsf_handler_context.e | 0 .../starts_with/wsf_starts_with_handler.e | 36 ++ .../starts_with/wsf_starts_with_mapping.e | 2 +- .../{ => mapping}/uri/wsf_agent_uri_handler.e | 0 .../wsf_agent_uri_template_response_handler.e | 6 +- .../wsf/router/mapping/uri/wsf_uri_handler.e | 36 ++ .../{ => mapping}/uri/wsf_uri_mapping.e | 0 .../uri/wsf_uri_response_handler.e | 0 .../mapping/uri/wsf_uri_routed_service.e | 47 +++ .../uri/wsf_uri_template_response_handler.e | 6 +- .../wsf_agent_uri_template_handler.e | 6 +- .../uri_template/wsf_uri_template_handler.e | 36 ++ .../uri_template/wsf_uri_template_mapping.e | 22 +- .../wsf_uri_template_routed_service.e | 47 +++ .../wsf_uri_template_routing_handler.e | 13 +- ..._agent_uri_template_with_context_handler.e | 42 +++ .../wsf_uri_template_with_context_handler.e | 36 ++ ...i_template_with_context_handler_context.e} | 0 .../wsf_uri_template_with_context_mapping.e | 95 +++++ ...uri_template_with_context_routed_service.e | 47 +++ ...ri_template_with_context_routing_handler.e | 39 +++ .../starts_with/wsf_starts_with_handler.e | 19 - .../server/wsf/router/uri/wsf_uri_handler.e | 19 - .../uri_template/wsf_uri_template_handler.e | 19 - .../wsf/router/wsf_file_system_handler.e | 16 +- library/server/wsf/router/wsf_handler.e | 11 +- library/server/wsf/router/wsf_router.e | 15 + .../server/wsf/router/wsf_router_mapping.e | 6 + .../server/wsf/router/wsf_router_methods.e | 44 ++- .../server/wsf/router/wsf_routing_handler.e | 75 ++++ .../wsf/src/filter/wsf_filter_handler.e | 20 +- .../wsf/src/filter/wsf_filter_uri_handler.e | 34 ++ .../filter/wsf_filter_uri_template_handler.e | 34 ++ ...tered_service.e => wsf_filtered_service.e} | 4 +- .../wsf/src/filter/wsf_routing_filter.e | 75 ---- .../wsf_request_path_parameters_provider.e | 59 ++++ .../src/wsf_resource_handler_helper.e | 118 +++---- 61 files changed, 960 insertions(+), 1129 deletions(-) delete mode 100644 draft/library/server/request/rest/src/contrib/doc/rest_api_documentation.e delete mode 100644 draft/library/server/request/rest/src/rest_request_router.e delete mode 100644 draft/library/server/request/rest/src/uri/rest_request_uri_handler.e delete mode 100644 draft/library/server/request/rest/src/uri/rest_request_uri_router.e delete mode 100644 draft/library/server/request/rest/src/uri/rest_request_uri_router_i.e delete mode 100644 draft/library/server/request/rest/src/uri/rest_request_uri_routing_handler.e delete mode 100644 draft/library/server/request/rest/src/uri/rest_request_uri_routing_handler_i.e delete mode 100644 draft/library/server/request/rest/src/uri/rest_uri_service.e delete mode 100644 draft/library/server/request/rest/src/uri_template/rest_request_uri_template_router.e delete mode 100644 draft/library/server/request/rest/src/uri_template/rest_request_uri_template_router_i.e delete mode 100644 draft/library/server/request/rest/src/uri_template/rest_request_uri_template_routing_handler.e delete mode 100644 draft/library/server/request/rest/src/uri_template/rest_request_uri_template_routing_handler_i.e rename library/server/wsf/router/{ => context}/wsf_handler_context.e (100%) create mode 100644 library/server/wsf/router/mapping/starts_with/wsf_starts_with_handler.e rename library/server/wsf/router/{ => mapping}/starts_with/wsf_starts_with_mapping.e (96%) rename library/server/wsf/router/{ => mapping}/uri/wsf_agent_uri_handler.e (100%) rename library/server/wsf/router/{ => mapping}/uri/wsf_agent_uri_template_response_handler.e (76%) create mode 100644 library/server/wsf/router/mapping/uri/wsf_uri_handler.e rename library/server/wsf/router/{ => mapping}/uri/wsf_uri_mapping.e (100%) rename library/server/wsf/router/{ => mapping}/uri/wsf_uri_response_handler.e (100%) create mode 100644 library/server/wsf/router/mapping/uri/wsf_uri_routed_service.e rename library/server/wsf/router/{ => mapping}/uri/wsf_uri_template_response_handler.e (79%) rename library/server/wsf/router/{ => mapping}/uri_template/wsf_agent_uri_template_handler.e (75%) create mode 100644 library/server/wsf/router/mapping/uri_template/wsf_uri_template_handler.e rename library/server/wsf/router/{ => mapping}/uri_template/wsf_uri_template_mapping.e (80%) create mode 100644 library/server/wsf/router/mapping/uri_template/wsf_uri_template_routed_service.e rename draft/library/server/request/rest/src/uri/rest_request_uri_handler_context.e => library/server/wsf/router/mapping/uri_template/wsf_uri_template_routing_handler.e (59%) create mode 100644 library/server/wsf/router/mapping/uri_template_with_context/wsf_agent_uri_template_with_context_handler.e create mode 100644 library/server/wsf/router/mapping/uri_template_with_context/wsf_uri_template_with_context_handler.e rename library/server/wsf/router/{uri_template/wsf_uri_template_handler_context.e => mapping/uri_template_with_context/wsf_uri_template_with_context_handler_context.e} (100%) create mode 100644 library/server/wsf/router/mapping/uri_template_with_context/wsf_uri_template_with_context_mapping.e create mode 100644 library/server/wsf/router/mapping/uri_template_with_context/wsf_uri_template_with_context_routed_service.e create mode 100644 library/server/wsf/router/mapping/uri_template_with_context/wsf_uri_template_with_context_routing_handler.e delete mode 100644 library/server/wsf/router/starts_with/wsf_starts_with_handler.e delete mode 100644 library/server/wsf/router/uri/wsf_uri_handler.e delete mode 100644 library/server/wsf/router/uri_template/wsf_uri_template_handler.e create mode 100644 library/server/wsf/router/wsf_routing_handler.e create mode 100644 library/server/wsf/src/filter/wsf_filter_uri_handler.e create mode 100644 library/server/wsf/src/filter/wsf_filter_uri_template_handler.e rename library/server/wsf/src/filter/{wsf_uri_template_filtered_service.e => wsf_filtered_service.e} (88%) delete mode 100644 library/server/wsf/src/filter/wsf_routing_filter.e create mode 100644 library/server/wsf/src/wsf_request_path_parameters_provider.e diff --git a/draft/library/server/request/rest/src/contrib/doc/rest_api_documentation.e b/draft/library/server/request/rest/src/contrib/doc/rest_api_documentation.e deleted file mode 100644 index 285683f9..00000000 --- a/draft/library/server/request/rest/src/contrib/doc/rest_api_documentation.e +++ /dev/null @@ -1,327 +0,0 @@ -note - description: "Summary description for {REST_API_DOCUMENTATION}." - author: "" - date: "$Date$" - revision: "$Revision$" - -class - REST_API_DOCUMENTATION [C -> REST_REQUEST_HANDLER_CONTEXT] - -inherit - REST_REQUEST_HANDLER [C] - -create - make - -feature {NONE} -- Initialization - - make (a_router: like router; a_base_doc_url: like base_doc_url) - do - router := a_router - base_doc_url := a_base_doc_url - description := "Technical documention for the API" - end - -feature {NONE} -- Access: Implementation - - router: REST_REQUEST_ROUTER [REST_REQUEST_HANDLER [C], C] - - base_doc_url: READABLE_STRING_8 - -feature -- Access - - authentication_required (req: WSF_REQUEST): BOOLEAN - do - end - - resource_value (ctx: C): detachable READABLE_STRING_32 - do - if attached {WSF_STRING} ctx.item ("resource") as s then - Result := s.value - end - end - -feature -- Execution - - execute_application (ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE) - local - rep: like new_html_page - s: STRING - rq: detachable REST_REQUEST_HANDLER [C] - rq_resource: detachable READABLE_STRING_GENERAL --- l_dft_format_name: detachable STRING - hdl_cursor: like router.new_cursor - do - rep := new_html_page - rep.headers.put_content_type_text_html - create s.make_empty - - if - attached resource_value (ctx) as l_resource - then - from - hdl_cursor := router.new_cursor - until - hdl_cursor.after or rq /= Void - loop - if hdl_cursor.item.resource.same_string_general (l_resource) then - rq := hdl_cursor.item.handler - rq_resource := l_resource - end - hdl_cursor.forth - end - end --- if a_args /= Void and then not a_args.is_empty then --- rq := router.handler_by_path (a_args) --- if rq = Void then --- rq := handler_manager.smart_handler_by_path (a_args) ----- if attached {REST_REQUEST_GROUP_HANDLER} rq as grp then ----- rq := grp.handlers.handler_by_path (a_args) ----- end --- end --- if --- rq /= Void and then --- attached rq.path_information (a_args) as l_info --- then --- l_dft_format_name := l_info.format --- end --- end - - - if rq /= Void and then rq_resource /= Void then - rep.set_big_title ("API: Technical documentation for ["+ rq_resource.as_string_8 +"]") - - s.append_string ("
") - s.append_string ("

") - - s.append_string (".. Show all features ..") - s.append_string ("

%N") - - process_request_handler_doc (rq, rq_resource.as_string_8, s, ctx, req, res, Void) - else - rep.set_big_title ("API: Technical documentation") - - from - hdl_cursor := router.new_cursor - until - hdl_cursor.after - loop - if attached hdl_cursor.item as l_item then - rq := l_item.handler - rep.add_shortcut (l_item.resource) - s.append ("") - process_request_handler_doc (rq, l_item.resource, s, ctx, req, res, Void) - hdl_cursor.forth - end - end - end - rep.set_body (s) - rep.send (res) - rep.recycle - end - - process_request_handler_doc (rq: REST_REQUEST_HANDLER [C]; a_resource: STRING; buf: STRING; ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE; a_dft_format: detachable STRING) - local - l_dft_format_name: detachable STRING - s: STRING - l_uri_tpl: URI_TEMPLATE - do - s := buf - - if a_dft_format /= Void then - if rq.supported_format_names.has (a_dft_format) then - l_dft_format_name := a_dft_format - end - end - - s.append_string ("
") - s.append_string ("

"+ a_resource +"

") - s.append_string ("
") --- if rq.hidden (req) then --- s.append_string ("
This feature is hidden
%N") --- else - if attached rq.description as desc then - s.append_string ("
" + desc + "
") - end --- if attached {REST_REQUEST_GROUP_HANDLER} rq as grp then --- s.append_string ("
Handler: ") --- if attached grp.handlers.new_cursor as l_handlers_cursor then --- from - --- until --- l_handlers_cursor.after --- loop --- s.append_string (" ") --- s.append_string (""+ l_handlers_cursor.item.path +"") --- l_handlers_cursor.forth --- end --- end --- s.append_string ("
") --- end - if attached rq.supported_format_names as l_formats and then not l_formats.is_empty then - s.append_string ("
Supported formats: ") - if attached l_formats.new_cursor as l_formats_cursor then - from - - until - l_formats_cursor.after - loop - s.append_string (" ") - s.append_string (""+ l_formats_cursor.item +"") - l_formats_cursor.forth - end - end - s.append_string ("
") - end - if attached rq.supported_request_method_names as l_methods and then not l_methods.is_empty then - s.append_string ("
Supported request methods: ") - if attached l_methods.new_cursor as l_methods_cursor then - from - - until - l_methods_cursor.after - loop - s.append_string (" ") - s.append_string (l_methods_cursor.item) - l_methods_cursor.forth - end - end - s.append_string ("
") - end - s.append_string ("
Authentication required: " + rq.authentication_required (req).out + "
") - if attached {REST_REQUEST_URI_TEMPLATE_ROUTER_I [REST_REQUEST_HANDLER [REST_REQUEST_URI_TEMPLATE_HANDLER_CONTEXT], REST_REQUEST_URI_TEMPLATE_HANDLER_CONTEXT]} router as l_uri_template_router then - create l_uri_tpl.make (a_resource) - if attached l_uri_tpl.query_variable_names as l_query_variable_names and then not l_query_variable_names.is_empty then - s.append_string ("
Query parameters: ") --- s.append_string (rq.path) - from - l_query_variable_names.start - until - l_query_variable_names.after - loop - if l_query_variable_names.isfirst then - s.append_string ("?") - else - s.append_string ("&") - end - if attached l_query_variable_names.item as l_query_param then - s.append_string ("" + l_query_param + "") - s.append_string ("=" + l_query_param + "") - end - l_query_variable_names.forth - end - s.append_string ("
%N") - end - if attached l_uri_tpl.path_variable_names as l_path_variable_names and then not l_path_variable_names.is_empty then - s.append_string ("
Path Segment parameters: ") --- s.append_string (rq.path) - from - l_path_variable_names.start - until - l_path_variable_names.after - loop - if attached l_path_variable_names.item as l_seg_param then - s.append_string ("{" + l_seg_param + "}") - end - l_path_variable_names.forth - end - s.append_string ("
%N") - end - - end --- if attached rq._parameters as l_uri_params and then not l_uri_params.is_empty then --- s.append_string ("
URI Template: ") --- s.append_string (rq.path) --- if attached l_uri_params.new_cursor as l_uri_params_cursor then --- from - --- until --- l_uri_params_cursor.after --- loop --- if attached l_uri_params_cursor.item as l_uri_param then --- s.append_string ("/" + l_uri_param.name + "") --- s.append_string ("/{" + l_uri_param.name + "}") --- end --- l_uri_params_cursor.forth --- end --- end --- s.append_string ("
%N") --- end --- if attached rq.parameters as l_params and then not l_params.is_empty then --- s.append_string ("
Parameters: ") - --- --| show form only if we have a default format --- if l_dft_format_name = Void then --- s.append_string ("to test the parameter(s), please first select a supported format.%N") --- else --- if rq.method_post_supported then --- s.append_string ("
%N") --- else --- s.append_string ("%N") --- end --- end --- s.append_string ("
    ") --- if attached l_params.new_cursor as l_params_cursor then --- from - --- until --- l_params_cursor.after --- loop --- if attached l_params_cursor.item as l_param then --- s.append_string ("
  • " + l_param.name + "") --- if l_param.optional then --- s.append_string (" (Optional)") --- end --- if attached l_param.description as l_param_desc then --- s.append_string (": " + l_param_desc + "") --- end --- if l_dft_format_name /= Void then --- s.append (" ") --- end --- s.append_string ("
  • ") --- end --- l_params_cursor.forth --- end --- end - --- if l_dft_format_name /= Void then --- s.append_string ("") --- s.append_string ("") --- end --- s.append_string ("
") --- else --- if l_dft_format_name /= Void then --- s.append_string ("Test "+ a_resource + "." + l_dft_format_name + "") --- else --- s.append_string ("Test "+ a_resource +"") --- end --- end - s.append_string ("
%N") --- end - s.append_string ("
%N") -- inner - end - -feature -- Access - - new_html_page: REST_API_DOCUMENTATION_HTML_PAGE - do - create Result.make ("API Documentation") - end - -note - copyright: "Copyright (c) 1984-2012, 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 diff --git a/draft/library/server/request/rest/src/rest_request_agent_handler.e b/draft/library/server/request/rest/src/rest_request_agent_handler.e index f0a43944..f84ddc63 100644 --- a/draft/library/server/request/rest/src/rest_request_agent_handler.e +++ b/draft/library/server/request/rest/src/rest_request_agent_handler.e @@ -1,46 +1,14 @@ -note - description: "Summary description for REST_REQUEST_AGENT_HANDLER." - author: "" - date: "$Date$" - revision: "$Revision$" - class - REST_REQUEST_AGENT_HANDLER [C -> REST_REQUEST_HANDLER_CONTEXT] + REST_REQUEST_AGENT_HANDLER inherit - WSF_AGENT_HANDLER [C] - rename - execute as execute_application - end - - REST_REQUEST_HANDLER [C] - select - execute - end + WSF_AGENT_URI_TEMPLATE_HANDLER create make -feature -- status - - authentication_required (req: WSF_REQUEST): BOOLEAN - do - Result := internal_authentication_required - end - -feature -- Element change - - set_authentication_required (b: like authentication_required) - do - internal_authentication_required := b - end - -feature {NONE} -- Implementation - - internal_authentication_required: BOOLEAN - -;note - copyright: "Copyright (c) 1984-2011, Eiffel Software and others" +note + copyright: "Copyright (c) 1984-2012, Eiffel Software and others" license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)" source: "[ Eiffel Software diff --git a/draft/library/server/request/rest/src/rest_request_handler.e b/draft/library/server/request/rest/src/rest_request_handler.e index bbf799bf..ed33bf59 100644 --- a/draft/library/server/request/rest/src/rest_request_handler.e +++ b/draft/library/server/request/rest/src/rest_request_handler.e @@ -5,10 +5,10 @@ note revision: "$Revision$" deferred class - REST_REQUEST_HANDLER [C -> REST_REQUEST_HANDLER_CONTEXT] + REST_REQUEST_HANDLER inherit - WSF_HANDLER [C] + WSF_URI_TEMPLATE_HANDLER WSF_HANDLER_HELPER @@ -34,7 +34,7 @@ feature -- Element change feature -- Execution - execute (ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE) + execute (ctx: REST_REQUEST_URI_TEMPLATE_HANDLER_CONTEXT; req: WSF_REQUEST; res: WSF_RESPONSE) -- Execute request handler do if request_method_name_supported (req.request_method) then @@ -52,26 +52,26 @@ feature -- Execution execute_rescue (ctx, req, res) end - execute_application (ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE) + execute_application (ctx: REST_REQUEST_URI_TEMPLATE_HANDLER_CONTEXT; req: WSF_REQUEST; res: WSF_RESPONSE) deferred end - pre_execute (ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE) + pre_execute (ctx: REST_REQUEST_URI_TEMPLATE_HANDLER_CONTEXT; req: WSF_REQUEST; res: WSF_RESPONSE) do end - post_execute (ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE) + post_execute (ctx: REST_REQUEST_URI_TEMPLATE_HANDLER_CONTEXT; req: WSF_REQUEST; res: WSF_RESPONSE) do end - execute_rescue (ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE) + execute_rescue (ctx: REST_REQUEST_URI_TEMPLATE_HANDLER_CONTEXT; req: WSF_REQUEST; res: WSF_RESPONSE) do post_execute (ctx, req, res) rescue --| Just in case, the rescue is raising other exceptions ... end - execute_unauthorized (ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE) + execute_unauthorized (ctx: REST_REQUEST_URI_TEMPLATE_HANDLER_CONTEXT; req: WSF_REQUEST; res: WSF_RESPONSE) do res.put_header ({HTTP_STATUS_CODE}.unauthorized, Void) res.put_string ("Unauthorized") @@ -79,7 +79,7 @@ feature -- Execution feature -- Auth - authenticated (ctx: C): BOOLEAN + authenticated (ctx: REST_REQUEST_URI_TEMPLATE_HANDLER_CONTEXT): BOOLEAN -- Is authenticated? do --| To redefine if needed diff --git a/draft/library/server/request/rest/src/rest_request_router.e b/draft/library/server/request/rest/src/rest_request_router.e deleted file mode 100644 index 80a74f21..00000000 --- a/draft/library/server/request/rest/src/rest_request_router.e +++ /dev/null @@ -1,23 +0,0 @@ -note - description: "Summary description for {REST_REQUEST_ROUTER}." - author: "" - date: "$Date$" - revision: "$Revision$" - -deferred class - REST_REQUEST_ROUTER [H -> REST_REQUEST_HANDLER [C], C -> REST_REQUEST_HANDLER_CONTEXT] - -inherit - WSF_ROUTER [H, C] - -;note - copyright: "Copyright (c) 1984-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 diff --git a/draft/library/server/request/rest/src/rest_service.e b/draft/library/server/request/rest/src/rest_service.e index 1a395664..419f25f3 100644 --- a/draft/library/server/request/rest/src/rest_service.e +++ b/draft/library/server/request/rest/src/rest_service.e @@ -8,10 +8,10 @@ deferred class REST_SERVICE inherit - REST_SERVICE_I [REST_REQUEST_HANDLER [REST_REQUEST_HANDLER_CONTEXT], REST_REQUEST_HANDLER_CONTEXT] + REST_SERVICE_I note - copyright: "Copyright (c) 1984-2011, Eiffel Software and others" + copyright: "Copyright (c) 1984-2012, Eiffel Software and others" license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)" source: "[ Eiffel Software diff --git a/draft/library/server/request/rest/src/rest_service_i.e b/draft/library/server/request/rest/src/rest_service_i.e index 198b1d3f..dac1cf91 100644 --- a/draft/library/server/request/rest/src/rest_service_i.e +++ b/draft/library/server/request/rest/src/rest_service_i.e @@ -5,21 +5,13 @@ note revision: "$Revision$" deferred class - REST_SERVICE_I [H -> REST_REQUEST_HANDLER [C], C -> REST_REQUEST_HANDLER_CONTEXT] + REST_SERVICE_I inherit - WSF_ROUTED_SERVICE_I [H, C] - redefine - router - end - -feature -- Setup - - router: REST_REQUEST_ROUTER [H, C] - -- Request router + WSF_URI_TEMPLATE_ROUTED_SERVICE ;note - copyright: "Copyright (c) 1984-2011, Eiffel Software and others" + copyright: "Copyright (c) 1984-2012, Eiffel Software and others" license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)" source: "[ Eiffel Software diff --git a/draft/library/server/request/rest/src/uri/rest_request_uri_handler.e b/draft/library/server/request/rest/src/uri/rest_request_uri_handler.e deleted file mode 100644 index 1d162808..00000000 --- a/draft/library/server/request/rest/src/uri/rest_request_uri_handler.e +++ /dev/null @@ -1,24 +0,0 @@ -note - description: "Summary description for {DEFAULT_REST_REQUEST_URI_HANDLER}." - author: "" - date: "$Date$" - revision: "$Revision$" - -deferred class - REST_REQUEST_URI_HANDLER - -inherit - REST_REQUEST_HANDLER [REST_REQUEST_URI_HANDLER_CONTEXT] - - -;note - copyright: "Copyright (c) 1984-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 diff --git a/draft/library/server/request/rest/src/uri/rest_request_uri_router.e b/draft/library/server/request/rest/src/uri/rest_request_uri_router.e deleted file mode 100644 index 2bb6612c..00000000 --- a/draft/library/server/request/rest/src/uri/rest_request_uri_router.e +++ /dev/null @@ -1,40 +0,0 @@ -note - description: "Summary description for {DEFAULT_REST_REQUEST_URI_ROUTER}." - author: "" - date: "$Date$" - revision: "$Revision$" - -class - REST_REQUEST_URI_ROUTER - -inherit - REST_REQUEST_URI_ROUTER_I [REST_REQUEST_HANDLER [REST_REQUEST_URI_HANDLER_CONTEXT], REST_REQUEST_URI_HANDLER_CONTEXT] - redefine - map_agent_with_request_methods - end - -create - make - -feature -- Mapping - - map_agent_with_request_methods (a_id: READABLE_STRING_8; a_action: PROCEDURE [ANY, TUPLE [ctx: REST_REQUEST_URI_HANDLER_CONTEXT; req: WSF_REQUEST; res: WSF_RESPONSE]]; - rqst_methods: detachable WSF_ROUTER_METHODS) - local - h: REST_REQUEST_AGENT_HANDLER [REST_REQUEST_URI_HANDLER_CONTEXT] - do - create h.make (a_action) - map_with_request_methods (a_id, h, rqst_methods) - end - -note - copyright: "Copyright (c) 1984-2012, 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 diff --git a/draft/library/server/request/rest/src/uri/rest_request_uri_router_i.e b/draft/library/server/request/rest/src/uri/rest_request_uri_router_i.e deleted file mode 100644 index 07fc0bbb..00000000 --- a/draft/library/server/request/rest/src/uri/rest_request_uri_router_i.e +++ /dev/null @@ -1,36 +0,0 @@ -note - description: "Summary description for {REST_REQUEST_URI_ROUTER}." - author: "" - date: "$Date$" - revision: "$Revision$" - -class - REST_REQUEST_URI_ROUTER_I [H -> REST_REQUEST_HANDLER [C], C -> REST_REQUEST_URI_HANDLER_CONTEXT create make end] - -inherit - WSF_URI_ROUTER_I [H, C] - - REST_REQUEST_ROUTER [H, C] - - -create - make - -feature -- Mapping - --- map_agent_with_request_methods (a_id: READABLE_STRING_8; a_action: like {REST_REQUEST_AGENT_HANDLER}.action; rqst_methods: detachable ARRAY [READABLE_STRING_8]) --- do --- Precursor (a_id, a_action, rqst_methods) --- end - -note - copyright: "Copyright (c) 1984-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 diff --git a/draft/library/server/request/rest/src/uri/rest_request_uri_routing_handler.e b/draft/library/server/request/rest/src/uri/rest_request_uri_routing_handler.e deleted file mode 100644 index 374df903..00000000 --- a/draft/library/server/request/rest/src/uri/rest_request_uri_routing_handler.e +++ /dev/null @@ -1,33 +0,0 @@ -note - description: "Summary description for {DEFAULT_REST_REQUEST_URI_ROUTING_HANDLER}." - author: "" - date: "$Date$" - revision: "$Revision$" - -class - REST_REQUEST_URI_ROUTING_HANDLER - -inherit - REST_REQUEST_URI_ROUTING_HANDLER_I [REST_REQUEST_HANDLER [REST_REQUEST_URI_HANDLER_CONTEXT], REST_REQUEST_URI_HANDLER_CONTEXT] - redefine - router - end - -create - make - -feature {NONE} -- Routing - - router: REST_REQUEST_URI_ROUTER - -;note - copyright: "Copyright (c) 1984-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 diff --git a/draft/library/server/request/rest/src/uri/rest_request_uri_routing_handler_i.e b/draft/library/server/request/rest/src/uri/rest_request_uri_routing_handler_i.e deleted file mode 100644 index b05571ba..00000000 --- a/draft/library/server/request/rest/src/uri/rest_request_uri_routing_handler_i.e +++ /dev/null @@ -1,64 +0,0 @@ -note - description: "Summary description for {WSF_ROUTING_HANDLER }." - author: "" - date: "$Date$" - revision: "$Revision$" - -class - REST_REQUEST_URI_ROUTING_HANDLER_I [H -> REST_REQUEST_HANDLER [C], - C -> REST_REQUEST_URI_HANDLER_CONTEXT create make end] - -inherit - WSF_URI_ROUTING_HANDLER_I [H, C] - redefine - router, - execute - end - - REST_REQUEST_HANDLER [C] - undefine - execute - end - -create - make - -feature -- Status report - - authentication_required (req: WSF_REQUEST): BOOLEAN - do - Result := internal_authentication_required - end - -feature {NONE} -- Implementation - - internal_authentication_required: BOOLEAN - -feature -- Execution - - execute (ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE) - do - Precursor {WSF_URI_ROUTING_HANDLER_I} (ctx, req, res) - end - - execute_application (ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE) - do - check should_not_occur: False end - end - - -feature {NONE} -- Routing - - router: REST_REQUEST_URI_ROUTER_I [H, C] - -;note - copyright: "Copyright (c) 1984-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 diff --git a/draft/library/server/request/rest/src/uri/rest_uri_service.e b/draft/library/server/request/rest/src/uri/rest_uri_service.e deleted file mode 100644 index 8d86f861..00000000 --- a/draft/library/server/request/rest/src/uri/rest_uri_service.e +++ /dev/null @@ -1,30 +0,0 @@ -note - description: "Summary description for {DEFAULT_REST_URI_SERVICE}." - author: "" - date: "$Date$" - revision: "$Revision$" - -deferred class - REST_URI_SERVICE - -inherit - REST_SERVICE_I [REST_REQUEST_HANDLER [REST_REQUEST_URI_HANDLER_CONTEXT], REST_REQUEST_URI_HANDLER_CONTEXT] - redefine - router - end - -feature -- Router - - router: REST_REQUEST_URI_ROUTER - -;note - copyright: "Copyright (c) 1984-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 diff --git a/draft/library/server/request/rest/src/uri_template/rest_request_uri_template_handler.e b/draft/library/server/request/rest/src/uri_template/rest_request_uri_template_handler.e index 59198577..fd4bdbcb 100644 --- a/draft/library/server/request/rest/src/uri_template/rest_request_uri_template_handler.e +++ b/draft/library/server/request/rest/src/uri_template/rest_request_uri_template_handler.e @@ -8,11 +8,11 @@ deferred class REST_REQUEST_URI_TEMPLATE_HANDLER inherit - REST_REQUEST_HANDLER [REST_REQUEST_URI_TEMPLATE_HANDLER_CONTEXT] + REST_REQUEST_HANDLER ;note - copyright: "Copyright (c) 1984-2011, Eiffel Software and others" + copyright: "Copyright (c) 1984-2012, Eiffel Software and others" license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)" source: "[ Eiffel Software diff --git a/draft/library/server/request/rest/src/uri_template/rest_request_uri_template_router.e b/draft/library/server/request/rest/src/uri_template/rest_request_uri_template_router.e deleted file mode 100644 index 210080e2..00000000 --- a/draft/library/server/request/rest/src/uri_template/rest_request_uri_template_router.e +++ /dev/null @@ -1,41 +0,0 @@ -note - description: "Summary description for {DEFAULT_REST_REQUEST_URI_TEMPLATE_ROUTER}." - author: "" - date: "$Date$" - revision: "$Revision$" - -class - REST_REQUEST_URI_TEMPLATE_ROUTER - -inherit - REST_REQUEST_URI_TEMPLATE_ROUTER_I [REST_REQUEST_HANDLER [REST_REQUEST_URI_TEMPLATE_HANDLER_CONTEXT], REST_REQUEST_URI_TEMPLATE_HANDLER_CONTEXT] - redefine - map_agent_with_request_methods - end - -create - make, - make_with_base_url - -feature -- Mapping - - map_agent_with_request_methods (a_id: READABLE_STRING_8; a_action: PROCEDURE [ANY, TUPLE [ctx: REST_REQUEST_URI_TEMPLATE_HANDLER_CONTEXT; req: WSF_REQUEST; res: WSF_RESPONSE]]; - rqst_methods: detachable WSF_ROUTER_METHODS) - local - h: REST_REQUEST_AGENT_HANDLER [REST_REQUEST_URI_TEMPLATE_HANDLER_CONTEXT] - do - create h.make (a_action) - map_with_request_methods (a_id, h, rqst_methods) - end - -note - copyright: "Copyright (c) 1984-2012, 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 diff --git a/draft/library/server/request/rest/src/uri_template/rest_request_uri_template_router_i.e b/draft/library/server/request/rest/src/uri_template/rest_request_uri_template_router_i.e deleted file mode 100644 index f8daf292..00000000 --- a/draft/library/server/request/rest/src/uri_template/rest_request_uri_template_router_i.e +++ /dev/null @@ -1,29 +0,0 @@ -note - description: "Summary description for {REST_REQUEST_URI_TEMPLATE_ROUTER}." - author: "" - date: "$Date$" - revision: "$Revision$" - -class - REST_REQUEST_URI_TEMPLATE_ROUTER_I [H -> REST_REQUEST_HANDLER [C], C -> REST_REQUEST_URI_TEMPLATE_HANDLER_CONTEXT create make end] - -inherit - WSF_URI_TEMPLATE_ROUTER_I [H, C] - - REST_REQUEST_ROUTER [H, C] - -create - make, - make_with_base_url - -note - copyright: "Copyright (c) 1984-2012, 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 diff --git a/draft/library/server/request/rest/src/uri_template/rest_request_uri_template_routing_handler.e b/draft/library/server/request/rest/src/uri_template/rest_request_uri_template_routing_handler.e deleted file mode 100644 index 4888c271..00000000 --- a/draft/library/server/request/rest/src/uri_template/rest_request_uri_template_routing_handler.e +++ /dev/null @@ -1,34 +0,0 @@ -note - description: "Summary description for {DEFAULT_REST_REQUEST_URI_TEMPLATE_ROUTING_HANDLER}." - author: "" - date: "$Date$" - revision: "$Revision$" - -class - REST_REQUEST_URI_TEMPLATE_ROUTING_HANDLER - -inherit - REST_REQUEST_URI_TEMPLATE_ROUTING_HANDLER_I [REST_REQUEST_HANDLER [REST_REQUEST_URI_TEMPLATE_HANDLER_CONTEXT], REST_REQUEST_URI_TEMPLATE_HANDLER_CONTEXT] - redefine - router - end - -create - make, - make_with_base_url - -feature {NONE} -- Routing - - router: REST_REQUEST_URI_TEMPLATE_ROUTER - -;note - copyright: "Copyright (c) 1984-2012, 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 diff --git a/draft/library/server/request/rest/src/uri_template/rest_request_uri_template_routing_handler_i.e b/draft/library/server/request/rest/src/uri_template/rest_request_uri_template_routing_handler_i.e deleted file mode 100644 index 43bd5ea9..00000000 --- a/draft/library/server/request/rest/src/uri_template/rest_request_uri_template_routing_handler_i.e +++ /dev/null @@ -1,66 +0,0 @@ -note - description: "Summary description for {WSF_ROUTING_HANDLER }." - author: "" - date: "$Date$" - revision: "$Revision$" - -class - REST_REQUEST_URI_TEMPLATE_ROUTING_HANDLER_I [H -> REST_REQUEST_HANDLER [C], - C -> REST_REQUEST_URI_TEMPLATE_HANDLER_CONTEXT create make end] - -inherit - WSF_URI_TEMPLATE_ROUTING_HANDLER_I [H, C] - redefine - router, - execute - end - - REST_REQUEST_HANDLER [C] - undefine - execute - end - -create - make, - make_with_base_url - -feature -- Status report - - authentication_required (req: WSF_REQUEST): BOOLEAN - do - Result := internal_authentication_required - end - -feature {NONE} -- Implementation - - internal_authentication_required: BOOLEAN - -feature -- Execution - - execute (ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE) - do - pre_execute (ctx, req, res) - Precursor {WSF_URI_TEMPLATE_ROUTING_HANDLER_I} (ctx, req, res) - post_execute (ctx, req, res) - end - - execute_application (ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE) - do - check should_not_occur: False end - end - -feature {NONE} -- Routing - - router: REST_REQUEST_URI_TEMPLATE_ROUTER_I [H, C] - -;note - copyright: "Copyright (c) 1984-2012, 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 diff --git a/draft/library/server/request/rest/src/uri_template/rest_uri_template_service.e b/draft/library/server/request/rest/src/uri_template/rest_uri_template_service.e index d8c5bb89..d77e2ff7 100644 --- a/draft/library/server/request/rest/src/uri_template/rest_uri_template_service.e +++ b/draft/library/server/request/rest/src/uri_template/rest_uri_template_service.e @@ -8,17 +8,10 @@ deferred class REST_URI_TEMPLATE_SERVICE inherit - REST_SERVICE_I [REST_REQUEST_HANDLER [REST_REQUEST_URI_TEMPLATE_HANDLER_CONTEXT], REST_REQUEST_URI_TEMPLATE_HANDLER_CONTEXT] - redefine - router - end - -feature -- Router - - router: REST_REQUEST_URI_TEMPLATE_ROUTER + REST_SERVICE_I ;note - copyright: "Copyright (c) 1984-2011, Eiffel Software and others" + copyright: "Copyright (c) 1984-2012, Eiffel Software and others" license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)" source: "[ Eiffel Software diff --git a/examples/filter/src/filter/authentication_filter.e b/examples/filter/src/filter/authentication_filter.e index 3f4809bc..949ff380 100644 --- a/examples/filter/src/filter/authentication_filter.e +++ b/examples/filter/src/filter/authentication_filter.e @@ -5,16 +5,27 @@ note revision: "$Revision$" class - AUTHENTICATION_FILTER [C -> WSF_URI_TEMPLATE_HANDLER_CONTEXT] + AUTHENTICATION_FILTER inherit - WSF_FILTER_HANDLER [C] + WSF_FILTER_HANDLER [WSF_URI_TEMPLATE_HANDLER] SHARED_DATABASE_API + WSF_URI_TEMPLATE_HANDLER + + WSF_RESOURCE_HANDLER_HELPER +-- redefine +-- do_get +-- end + + SHARED_DATABASE_API + + SHARED_EJSON + feature -- Basic operations - execute (ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE) + execute (req: WSF_REQUEST; res: WSF_RESPONSE) -- Execute the filter local l_auth: HTTP_AUTHORIZATION @@ -24,15 +35,24 @@ feature -- Basic operations attached Db_access.users.item (1) as l_user and then (attached l_auth.login as l_auth_login and then l_auth_login.is_equal (l_user.name) and attached l_auth.password as l_auth_password and then l_auth_password.is_equal (l_user.password)) then - execute_next (ctx, req, res) + execute_next (req, res) else - handle_unauthorized ("Unauthorized", ctx, req, res) + handle_unauthorized ("Unauthorized", req, res) + end + end + +feature -- Filter + + execute_next (req: WSF_REQUEST; res: WSF_RESPONSE) + do + if attached next as n then + n.execute (req, res) end end feature {NONE} -- Implementation - handle_unauthorized (a_description: STRING; ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE) + handle_unauthorized (a_description: STRING; req: WSF_REQUEST; res: WSF_RESPONSE) -- Handle forbidden. local h: HTTP_HEADER diff --git a/examples/filter/src/filter_server.e b/examples/filter/src/filter_server.e index b956fc16..c407cfc6 100644 --- a/examples/filter/src/filter_server.e +++ b/examples/filter/src/filter_server.e @@ -10,7 +10,7 @@ class inherit ANY - WSF_URI_TEMPLATE_FILTERED_SERVICE + WSF_FILTERED_SERVICE WSF_HANDLER_HELPER @@ -34,18 +34,21 @@ feature {NONE} -- Initialization create_filter -- Create `filter' local - l_router: WSF_URI_TEMPLATE_ROUTER - l_authentication_filter: AUTHENTICATION_FILTER [WSF_URI_TEMPLATE_HANDLER_CONTEXT] - l_user_filter: USER_HANDLER [WSF_URI_TEMPLATE_HANDLER_CONTEXT] - l_user_handler: WSF_HANDLER [WSF_URI_TEMPLATE_HANDLER_CONTEXT] - l_routing_filter: WSF_ROUTING_FILTER [WSF_HANDLER [WSF_URI_TEMPLATE_HANDLER_CONTEXT], WSF_URI_TEMPLATE_HANDLER_CONTEXT] + l_router: WSF_ROUTER + l_authentication_filter_hdl: AUTHENTICATION_FILTER + l_user_filter: USER_HANDLER + l_user_handler: WSF_URI_TEMPLATE_HANDLER +-- l_routing_hdl: WSF_URI_TEMPLATE_ROUTING_HANDLER --[WSF_HANDLER [WSF_URI_TEMPLATE_HANDLER_CONTEXT], WSF_URI_TEMPLATE_HANDLER_CONTEXT] + l_routing_filter: WSF_ROUTING_FILTER do create l_router.make (1) - create l_authentication_filter + create l_authentication_filter_hdl create l_user_filter - l_authentication_filter.set_next (l_user_filter) - l_user_handler := l_authentication_filter - l_router.map_with_request_methods ("/user/{userid}", l_user_handler, << "GET" >>) + l_authentication_filter_hdl.set_next (l_user_filter) + l_user_handler := l_authentication_filter_hdl + l_router.handle_with_request_methods ("/user/{userid}", l_user_handler, l_router.methods_get) +-- l_router.map_with_request_methods ("/user/{userid}", l_user_handler, << "GET" >>) +-- create l_routing_hdl.make_with_router (l_router) create l_routing_filter.make (l_router) l_routing_filter.set_execute_default_action (agent execute_default) filter := l_routing_filter diff --git a/examples/filter/src/resource/user_handler.e b/examples/filter/src/resource/user_handler.e index f6e9a7c1..dad66c18 100644 --- a/examples/filter/src/resource/user_handler.e +++ b/examples/filter/src/resource/user_handler.e @@ -5,12 +5,14 @@ note revision: "$Revision$" class - USER_HANDLER [C -> WSF_HANDLER_CONTEXT] + USER_HANDLER inherit - WSF_FILTER_HANDLER [C] + WSF_FILTER_HANDLER [WSF_URI_TEMPLATE_HANDLER] - WSF_RESOURCE_HANDLER_HELPER [C] + WSF_URI_TEMPLATE_HANDLER + + WSF_RESOURCE_HANDLER_HELPER redefine do_get end @@ -21,13 +23,13 @@ inherit feature -- Basic operations - execute (ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE) + execute (req: WSF_REQUEST; res: WSF_RESPONSE) -- Execute request handler do - execute_methods (ctx, req, res) + execute_methods (req, res) end - do_get (ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE) + do_get (req: WSF_REQUEST; res: WSF_RESPONSE) -- Using GET to retrieve resource information. -- If the GET request is SUCCESS, we response with -- 200 OK, and a representation of the user @@ -39,16 +41,16 @@ feature -- Basic operations if attached req.orig_path_info as orig_path then id := get_user_id_from_path (orig_path) if attached retrieve_user (id) as l_user then - compute_response_get (ctx, req, res, l_user) + compute_response_get (req, res, l_user) else - handle_resource_not_found_response ("The following resource " + orig_path + " is not found ", ctx, req, res) + handle_resource_not_found_response ("The following resource " + orig_path + " is not found ", req, res) end end end feature {NONE} -- Implementation - compute_response_get (ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE; l_user : USER) + compute_response_get (req: WSF_REQUEST; res: WSF_RESPONSE; l_user : USER) local h: HTTP_HEADER l_msg : STRING diff --git a/examples/restbucksCRUD/src/resource/order_handler.e b/examples/restbucksCRUD/src/resource/order_handler.e index 570484ae..600ba033 100644 --- a/examples/restbucksCRUD/src/resource/order_handler.e +++ b/examples/restbucksCRUD/src/resource/order_handler.e @@ -5,10 +5,23 @@ note revision: "$Revision$" class - ORDER_HANDLER [C -> WSF_HANDLER_CONTEXT] + ORDER_HANDLER inherit - WSF_HANDLER [C] - WSF_RESOURCE_HANDLER_HELPER [C] + WSF_URI_HANDLER + rename + execute as uri_execute, + new_mapping as new_uri_mapping + end + + WSF_URI_TEMPLATE_HANDLER + rename + execute as uri_template_execute, + new_mapping as new_uri_template_mapping + select + new_uri_template_mapping + end + + WSF_RESOURCE_HANDLER_HELPER redefine do_get, do_post, @@ -22,10 +35,16 @@ inherit feature -- execute - execute (ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE) + uri_execute (req: WSF_REQUEST; res: WSF_RESPONSE) -- Execute request handler do - execute_methods (ctx, req, res) + execute_methods (req, res) + end + + uri_template_execute (ctx: WSF_URI_TEMPLATE_HANDLER_CONTEXT; req: WSF_REQUEST; res: WSF_RESPONSE) + -- Execute request handler + do + execute_methods (req, res) end feature -- API DOC @@ -34,7 +53,7 @@ feature -- API DOC feature -- HTTP Methods - do_get (ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE) + do_get (req: WSF_REQUEST; res: WSF_RESPONSE) -- Using GET to retrieve resource information. -- If the GET request is SUCCESS, we response with -- 200 OK, and a representation of the order @@ -49,12 +68,12 @@ feature -- HTTP Methods id := get_order_id_from_path (orig_path) if attached retrieve_order (id) as l_order then if is_conditional_get (req, l_order) then - handle_resource_not_modified_response ("The resource" + orig_path + "does not change", ctx, req, res) + handle_resource_not_modified_response ("The resource" + orig_path + "does not change", req, res) else - compute_response_get (ctx, req, res, l_order) + compute_response_get (req, res, l_order) end else - handle_resource_not_found_response ("The following resource" + orig_path + " is not found ", ctx, req, res) + handle_resource_not_found_response ("The following resource" + orig_path + " is not found ", req, res) end end end @@ -74,7 +93,7 @@ feature -- HTTP Methods end end - compute_response_get (ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE; l_order : ORDER) + compute_response_get (req: WSF_REQUEST; res: WSF_RESPONSE; l_order : ORDER) local h: HTTP_HEADER l_msg : STRING @@ -96,7 +115,7 @@ feature -- HTTP Methods end end - do_put (ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE) + do_put (req: WSF_REQUEST; res: WSF_RESPONSE) -- Updating a resource with PUT -- A successful PUT request will not create a new resource, instead it will -- change the state of the resource identified by the current uri. @@ -120,16 +139,16 @@ feature -- HTTP Methods if is_valid_to_update(l_order) then if is_conditional_put (req, l_order) then update_order( l_order) - compute_response_put (ctx, req, res, l_order) + compute_response_put (req, res, l_order) else - handle_precondition_fail_response ("", ctx, req, res) + handle_precondition_fail_response ("", req, res) end else --| FIXME: Here we need to define the Allow methods - handle_resource_conflict_response (l_put +"%N There is conflict while trying to update the order, the order could not be update in the current state", ctx, req, res) + handle_resource_conflict_response (l_put +"%N There is conflict while trying to update the order, the order could not be update in the current state", req, res) end else - handle_bad_request_response (l_put +"%N is not a valid ORDER, maybe the order does not exist in the system", ctx, req, res) + handle_bad_request_response (l_put +"%N is not a valid ORDER, maybe the order does not exist in the system", req, res) end end end @@ -153,7 +172,7 @@ feature -- HTTP Methods end - compute_response_put (ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE; l_order : ORDER) + compute_response_put (req: WSF_REQUEST; res: WSF_RESPONSE; l_order : ORDER) local h: HTTP_HEADER joc : JSON_ORDER_CONVERTER @@ -179,7 +198,7 @@ feature -- HTTP Methods end - do_delete (ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE) + do_delete (req: WSF_REQUEST; res: WSF_RESPONSE) -- Here we use DELETE to cancel an order, if that order is in state where -- it can still be canceled. -- 200 if is ok @@ -194,18 +213,18 @@ feature -- HTTP Methods if db_access.orders.has_key (id) then if is_valid_to_delete (id) then delete_order( id) - compute_response_delete (ctx, req, res) + compute_response_delete (req, res) else --| FIXME: Here we need to define the Allow methods - handle_method_not_allowed_response (orig_path + "%N There is conflict while trying to delete the order, the order could not be deleted in the current state", ctx, req, res) + handle_method_not_allowed_response (orig_path + "%N There is conflict while trying to delete the order, the order could not be deleted in the current state", req, res) end else - handle_resource_not_found_response (orig_path + " not found in this server", ctx, req, res) + handle_resource_not_found_response (orig_path + " not found in this server", req, res) end end end - compute_response_delete (ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE) + compute_response_delete (req: WSF_REQUEST; res: WSF_RESPONSE) local h : HTTP_HEADER do @@ -218,7 +237,7 @@ feature -- HTTP Methods res.put_header_text (h.string) end - do_post (ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE) + do_post (req: WSF_REQUEST; res: WSF_RESPONSE) -- Here the convention is the following. -- POST is used for creation and the server determines the URI -- of the created resource. @@ -233,13 +252,13 @@ feature -- HTTP Methods l_post := retrieve_data (req) if attached extract_order_request (l_post) as l_order then save_order (l_order) - compute_response_post (ctx, req, res, l_order) + compute_response_post (req, res, l_order) else - handle_bad_request_response (l_post +"%N is not a valid ORDER", ctx, req, res) + handle_bad_request_response (l_post +"%N is not a valid ORDER", req, res) end end - compute_response_post (ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE; l_order : ORDER) + compute_response_post (req: WSF_REQUEST; res: WSF_RESPONSE; l_order : ORDER) local h: HTTP_HEADER l_msg : STRING diff --git a/examples/restbucksCRUD/src/restbucks_server.e b/examples/restbucksCRUD/src/restbucks_server.e index 79efc423..ad1beb4d 100644 --- a/examples/restbucksCRUD/src/restbucks_server.e +++ b/examples/restbucksCRUD/src/restbucks_server.e @@ -1,6 +1,5 @@ note - description : "Objects that ..." - author : "$Author$" + description : "REST Buck server" date : "$Date$" revision : "$Revision$" @@ -30,11 +29,11 @@ feature {NONE} -- Initialization setup_router local - order_handler: ORDER_HANDLER [WSF_URI_TEMPLATE_HANDLER_CONTEXT] + order_handler: ORDER_HANDLER do create order_handler - router.map_with_request_methods ("/order", order_handler, <<"POST">>) - router.map_with_request_methods ("/order/{orderid}", order_handler, <<"GET", "DELETE", "PUT">>) + router.handle_with_request_methods ("/order", order_handler, router.methods_POST) + router.handle_with_request_methods ("/order/{orderid}", order_handler, router.methods_GET + router.methods_DELETE + router.methods_PUT) end feature -- Execution diff --git a/examples/upload_image/src/image_uploader.e b/examples/upload_image/src/image_uploader.e index 0517c6a8..876870e7 100644 --- a/examples/upload_image/src/image_uploader.e +++ b/examples/upload_image/src/image_uploader.e @@ -10,8 +10,12 @@ class inherit ANY + WSF_ROUTED_SERVICE + WSF_URI_TEMPLATE_ROUTED_SERVICE + WSF_URI_ROUTED_SERVICE + WSF_DEFAULT_SERVICE create @@ -34,14 +38,14 @@ feature {NONE} -- Initialization setup_router -- Setup router local - www: WSF_FILE_SYSTEM_HANDLER [WSF_URI_TEMPLATE_HANDLER_CONTEXT] + www: WSF_FILE_SYSTEM_HANDLER do - router.map_agent ("/upload{?nb}", agent execute_upload) + map_uri_template_agent ("/upload{?nb}", agent execute_upload) create www.make (document_root) www.set_directory_index (<<"index.html">>) www.set_not_found_handler (agent execute_not_found) - router.map_with_request_methods ("{/path}{?query}", www, <<"GET">>) + router.handle_with_request_methods ("", www, router.methods_GET) end feature -- Configuration @@ -59,6 +63,8 @@ feature -- Configuration if Result [Result.count] = Operating_environment.directory_separator then Result := Result.substring (1, Result.count - 1) end + ensure + not Result.ends_with (Operating_environment.directory_separator.out) end files_root: READABLE_STRING_8 @@ -79,7 +85,7 @@ feature -- Execution res.redirect_now_with_content (req.script_url ("/"), "Redirection to " + req.script_url ("/"), "text/html") end - execute_not_found (uri: READABLE_STRING_8; ctx: WSF_URI_TEMPLATE_HANDLER_CONTEXT; req: WSF_REQUEST; res: WSF_RESPONSE) + execute_not_found (uri: READABLE_STRING_8; req: WSF_REQUEST; res: WSF_RESPONSE) -- `uri' is not found, redirect to default page do res.redirect_now_with_content (req.script_url ("/"), uri + ": not found.%NRedirection to " + req.script_url ("/"), "text/html") diff --git a/library/server/wsf/router/wsf_handler_context.e b/library/server/wsf/router/context/wsf_handler_context.e similarity index 100% rename from library/server/wsf/router/wsf_handler_context.e rename to library/server/wsf/router/context/wsf_handler_context.e diff --git a/library/server/wsf/router/mapping/starts_with/wsf_starts_with_handler.e b/library/server/wsf/router/mapping/starts_with/wsf_starts_with_handler.e new file mode 100644 index 00000000..0da0fc96 --- /dev/null +++ b/library/server/wsf/router/mapping/starts_with/wsf_starts_with_handler.e @@ -0,0 +1,36 @@ +note + description: "Summary description for {WSF_STARTS_WITH_HANDLER}." + author: "" + date: "$Date$" + revision: "$Revision$" + +deferred class + WSF_STARTS_WITH_HANDLER + +inherit + WSF_HANDLER + +feature -- Execution + + execute (a_start_path: READABLE_STRING_8; req: WSF_REQUEST; res: WSF_RESPONSE) + deferred + end + +feature {WSF_ROUTER} -- Mapping + + new_mapping (a_uri: READABLE_STRING_8): WSF_STARTS_WITH_MAPPING + do + create Result.make (a_uri, Current) + end + +note + copyright: "2011-2012, Jocelyn Fiat, Javier Velilla, 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 diff --git a/library/server/wsf/router/starts_with/wsf_starts_with_mapping.e b/library/server/wsf/router/mapping/starts_with/wsf_starts_with_mapping.e similarity index 96% rename from library/server/wsf/router/starts_with/wsf_starts_with_mapping.e rename to library/server/wsf/router/mapping/starts_with/wsf_starts_with_mapping.e index a71f2da8..5013aa56 100644 --- a/library/server/wsf/router/starts_with/wsf_starts_with_mapping.e +++ b/library/server/wsf/router/mapping/starts_with/wsf_starts_with_mapping.e @@ -1,5 +1,5 @@ note - description: "Summary description for EWF_URI_PATH." + description: "Summary description for EWF_STARTS_WITH_PATH." author: "" date: "$Date$" revision: "$Revision$" diff --git a/library/server/wsf/router/uri/wsf_agent_uri_handler.e b/library/server/wsf/router/mapping/uri/wsf_agent_uri_handler.e similarity index 100% rename from library/server/wsf/router/uri/wsf_agent_uri_handler.e rename to library/server/wsf/router/mapping/uri/wsf_agent_uri_handler.e diff --git a/library/server/wsf/router/uri/wsf_agent_uri_template_response_handler.e b/library/server/wsf/router/mapping/uri/wsf_agent_uri_template_response_handler.e similarity index 76% rename from library/server/wsf/router/uri/wsf_agent_uri_template_response_handler.e rename to library/server/wsf/router/mapping/uri/wsf_agent_uri_template_response_handler.e index e178ccf4..5909cb30 100644 --- a/library/server/wsf/router/uri/wsf_agent_uri_template_response_handler.e +++ b/library/server/wsf/router/mapping/uri/wsf_agent_uri_template_response_handler.e @@ -22,13 +22,13 @@ feature -- Initialization feature -- Access - action: FUNCTION [ANY, TUPLE [ctx: WSF_URI_TEMPLATE_HANDLER_CONTEXT; req: WSF_REQUEST], WSF_RESPONSE_MESSAGE] + action: FUNCTION [ANY, TUPLE [req: WSF_REQUEST], WSF_RESPONSE_MESSAGE] feature -- Execution - response (ctx: WSF_URI_TEMPLATE_HANDLER_CONTEXT; req: WSF_REQUEST): WSF_RESPONSE_MESSAGE + response (req: WSF_REQUEST): WSF_RESPONSE_MESSAGE do - Result := action.item ([ctx, req]) + Result := action.item ([req]) end note diff --git a/library/server/wsf/router/mapping/uri/wsf_uri_handler.e b/library/server/wsf/router/mapping/uri/wsf_uri_handler.e new file mode 100644 index 00000000..82037a52 --- /dev/null +++ b/library/server/wsf/router/mapping/uri/wsf_uri_handler.e @@ -0,0 +1,36 @@ +note + description: "Summary description for {EWF_ROUTER_URI_PATH_HANDLER}." + author: "" + date: "$Date$" + revision: "$Revision$" + +deferred class + WSF_URI_HANDLER + +inherit + WSF_HANDLER + +feature -- Execution + + execute (req: WSF_REQUEST; res: WSF_RESPONSE) + deferred + end + +feature {WSF_ROUTER} -- Mapping + + new_mapping (a_uri: READABLE_STRING_8): WSF_URI_MAPPING + do + create Result.make (a_uri, Current) + end + +note + copyright: "2011-2012, Jocelyn Fiat, Javier Velilla, 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 diff --git a/library/server/wsf/router/uri/wsf_uri_mapping.e b/library/server/wsf/router/mapping/uri/wsf_uri_mapping.e similarity index 100% rename from library/server/wsf/router/uri/wsf_uri_mapping.e rename to library/server/wsf/router/mapping/uri/wsf_uri_mapping.e diff --git a/library/server/wsf/router/uri/wsf_uri_response_handler.e b/library/server/wsf/router/mapping/uri/wsf_uri_response_handler.e similarity index 100% rename from library/server/wsf/router/uri/wsf_uri_response_handler.e rename to library/server/wsf/router/mapping/uri/wsf_uri_response_handler.e diff --git a/library/server/wsf/router/mapping/uri/wsf_uri_routed_service.e b/library/server/wsf/router/mapping/uri/wsf_uri_routed_service.e new file mode 100644 index 00000000..ccb2fdaa --- /dev/null +++ b/library/server/wsf/router/mapping/uri/wsf_uri_routed_service.e @@ -0,0 +1,47 @@ +note + description: "Summary description for {WSF_URI_ROUTED_SERVICE}." + author: "" + date: "$Date$" + revision: "$Revision$" + +deferred class + WSF_URI_ROUTED_SERVICE + +inherit + WSF_ROUTED_SERVICE + +feature -- Mapping helper: uri + + map_uri (a_uri: READABLE_STRING_8; h: WSF_URI_HANDLER) + do + map_uri_with_request_methods (a_uri, h, Void) + end + + map_uri_with_request_methods (a_uri: READABLE_STRING_8; h: WSF_URI_HANDLER; rqst_methods: detachable WSF_ROUTER_METHODS) + do + router.map_with_request_methods (create {WSF_URI_MAPPING}.make (a_uri, h), rqst_methods) + end + +feature -- Mapping helper: uri agent + + map_uri_agent (a_uri: READABLE_STRING_8; proc: PROCEDURE [ANY, TUPLE [req: WSF_REQUEST; res: WSF_RESPONSE]]) + do + map_uri_agent_with_request_methods (a_uri, proc, Void) + end + + map_uri_agent_with_request_methods (a_uri: READABLE_STRING_8; proc: PROCEDURE [ANY, TUPLE [req: WSF_REQUEST; res: WSF_RESPONSE]]; rqst_methods: detachable WSF_ROUTER_METHODS) + do + map_uri_with_request_methods (a_uri, create {WSF_AGENT_URI_HANDLER}.make (proc), rqst_methods) + end + +note + copyright: "2011-2012, Jocelyn Fiat, Javier Velilla, 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 diff --git a/library/server/wsf/router/uri/wsf_uri_template_response_handler.e b/library/server/wsf/router/mapping/uri/wsf_uri_template_response_handler.e similarity index 79% rename from library/server/wsf/router/uri/wsf_uri_template_response_handler.e rename to library/server/wsf/router/mapping/uri/wsf_uri_template_response_handler.e index fa8493c0..5a671204 100644 --- a/library/server/wsf/router/uri/wsf_uri_template_response_handler.e +++ b/library/server/wsf/router/mapping/uri/wsf_uri_template_response_handler.e @@ -12,7 +12,7 @@ inherit feature -- Response - response (ctx: WSF_URI_TEMPLATE_HANDLER_CONTEXT; req: WSF_REQUEST): WSF_RESPONSE_MESSAGE + response (req: WSF_REQUEST): WSF_RESPONSE_MESSAGE require is_valid_context: is_valid_context (req) deferred @@ -22,10 +22,10 @@ feature -- Response feature -- Execution - execute (ctx: WSF_URI_TEMPLATE_HANDLER_CONTEXT; req: WSF_REQUEST; res: WSF_RESPONSE) + execute (req: WSF_REQUEST; res: WSF_RESPONSE) -- Execute request handler do - res.send (response (ctx, req)) + res.send (response (req)) end note diff --git a/library/server/wsf/router/uri_template/wsf_agent_uri_template_handler.e b/library/server/wsf/router/mapping/uri_template/wsf_agent_uri_template_handler.e similarity index 75% rename from library/server/wsf/router/uri_template/wsf_agent_uri_template_handler.e rename to library/server/wsf/router/mapping/uri_template/wsf_agent_uri_template_handler.e index 99950925..e41e546a 100644 --- a/library/server/wsf/router/uri_template/wsf_agent_uri_template_handler.e +++ b/library/server/wsf/router/mapping/uri_template/wsf_agent_uri_template_handler.e @@ -20,13 +20,13 @@ feature {NONE} -- Initialization action := a_action end - action: PROCEDURE [ANY, TUPLE [context: WSF_URI_TEMPLATE_HANDLER_CONTEXT; request: WSF_REQUEST; response: WSF_RESPONSE]] + action: PROCEDURE [ANY, TUPLE [request: WSF_REQUEST; response: WSF_RESPONSE]] feature -- Execution - execute (ctx: WSF_URI_TEMPLATE_HANDLER_CONTEXT; req: WSF_REQUEST; res: WSF_RESPONSE) + execute (req: WSF_REQUEST; res: WSF_RESPONSE) do - action.call ([ctx, req, res]) + action.call ([req, res]) end note diff --git a/library/server/wsf/router/mapping/uri_template/wsf_uri_template_handler.e b/library/server/wsf/router/mapping/uri_template/wsf_uri_template_handler.e new file mode 100644 index 00000000..620a0c74 --- /dev/null +++ b/library/server/wsf/router/mapping/uri_template/wsf_uri_template_handler.e @@ -0,0 +1,36 @@ +note + description: "Summary description for EWF_URI_TEMPLATE_HANDLER." + author: "" + date: "$Date$" + revision: "$Revision$" + +deferred class + WSF_URI_TEMPLATE_HANDLER + +inherit + WSF_HANDLER + +feature -- Execution + + execute (req: WSF_REQUEST; res: WSF_RESPONSE) + deferred + end + +feature {WSF_ROUTER} -- Mapping + + new_mapping (a_tpl: READABLE_STRING_8): WSF_URI_TEMPLATE_MAPPING + do + create Result.make (a_tpl, Current) + end + +note + copyright: "2011-2012, Jocelyn Fiat, Javier Velilla, 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 diff --git a/library/server/wsf/router/uri_template/wsf_uri_template_mapping.e b/library/server/wsf/router/mapping/uri_template/wsf_uri_template_mapping.e similarity index 80% rename from library/server/wsf/router/uri_template/wsf_uri_template_mapping.e rename to library/server/wsf/router/mapping/uri_template/wsf_uri_template_mapping.e index af8b7bf3..c76484da 100644 --- a/library/server/wsf/router/uri_template/wsf_uri_template_mapping.e +++ b/library/server/wsf/router/mapping/uri_template/wsf_uri_template_mapping.e @@ -12,16 +12,16 @@ inherit create make, - make_from_string + make_from_template feature {NONE} -- Initialization - make_from_string (s: READABLE_STRING_8; h: like handler) + make (s: READABLE_STRING_8; h: like handler) do - make (create {URI_TEMPLATE}.make (s), h) + make_from_template (create {URI_TEMPLATE}.make (s), h) end - make (tpl: URI_TEMPLATE; h: like handler) + make_from_template (tpl: URI_TEMPLATE; h: like handler) do template := tpl handler := h @@ -46,26 +46,26 @@ feature -- Status local tpl: URI_TEMPLATE p: READABLE_STRING_32 - ctx: detachable WSF_URI_TEMPLATE_HANDLER_CONTEXT + new_src: detachable WSF_REQUEST_PATH_PARAMETERS_PROVIDER do p := path_from_request (req) tpl := based_uri_template (template, a_router) if attached tpl.match (p) as tpl_res then Result := handler - create ctx.make (req, tpl, tpl_res, path_from_request (req)) a_router.execute_before (Current) --| Applied the context to the request --| in practice, this will fill the {WSF_REQUEST}.path_parameters - ctx.apply (req) - handler.execute (ctx, req, res) + create new_src.make (tpl_res.path_variables.count, tpl_res.path_variables) + new_src.apply (req) + handler.execute (req, res) --| Revert {WSF_REQUEST}.path_parameters_source to former value --| In case the request object passed by other handler that alters its values. - ctx.revert (req) + new_src.revert (req) a_router.execute_after (Current) end rescue - if ctx /= Void then - ctx.revert (req) + if new_src /= Void then + new_src.revert (req) end end diff --git a/library/server/wsf/router/mapping/uri_template/wsf_uri_template_routed_service.e b/library/server/wsf/router/mapping/uri_template/wsf_uri_template_routed_service.e new file mode 100644 index 00000000..5b607a9f --- /dev/null +++ b/library/server/wsf/router/mapping/uri_template/wsf_uri_template_routed_service.e @@ -0,0 +1,47 @@ +note + description: "Summary description for {WSF_URI_TEMPLATE_ROUTED_SERVICE}." + author: "" + date: "$Date$" + revision: "$Revision$" + +deferred class + WSF_URI_TEMPLATE_ROUTED_SERVICE + +inherit + WSF_ROUTED_SERVICE + +feature -- Mapping helper: uri + + map_uri_template (a_tpl: STRING; h: WSF_URI_TEMPLATE_HANDLER) + do + map_uri_template_with_request_methods (a_tpl, h, Void) + end + + map_uri_template_with_request_methods (a_tpl: READABLE_STRING_8; h: WSF_URI_TEMPLATE_HANDLER; rqst_methods: detachable WSF_ROUTER_METHODS) + do + router.map_with_request_methods (create {WSF_URI_TEMPLATE_MAPPING}.make (a_tpl, h), rqst_methods) + end + +feature -- Mapping helper: uri agent + + map_uri_template_agent (a_tpl: READABLE_STRING_8; proc: PROCEDURE [ANY, TUPLE [req: WSF_REQUEST; res: WSF_RESPONSE]]) + do + map_uri_template_agent_with_request_methods (a_tpl, proc, Void) + end + + map_uri_template_agent_with_request_methods (a_tpl: READABLE_STRING_8; proc: PROCEDURE [ANY, TUPLE [req: WSF_REQUEST; res: WSF_RESPONSE]]; rqst_methods: detachable WSF_ROUTER_METHODS) + do + map_uri_template_with_request_methods (a_tpl, create {WSF_AGENT_URI_TEMPLATE_HANDLER}.make (proc), rqst_methods) + end + +note + copyright: "2011-2012, Jocelyn Fiat, Javier Velilla, 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 diff --git a/draft/library/server/request/rest/src/uri/rest_request_uri_handler_context.e b/library/server/wsf/router/mapping/uri_template/wsf_uri_template_routing_handler.e similarity index 59% rename from draft/library/server/request/rest/src/uri/rest_request_uri_handler_context.e rename to library/server/wsf/router/mapping/uri_template/wsf_uri_template_routing_handler.e index c70a132a..ba2199cc 100644 --- a/draft/library/server/request/rest/src/uri/rest_request_uri_handler_context.e +++ b/library/server/wsf/router/mapping/uri_template/wsf_uri_template_routing_handler.e @@ -1,22 +1,23 @@ note - description: "Summary description for {WSF_URI_HANDLER_CONTEXT}." + description: "Summary description for {WSF_URI_TEMPLATE_ROUTING_HANDLER}." author: "" date: "$Date$" revision: "$Revision$" class - REST_REQUEST_URI_HANDLER_CONTEXT + WSF_URI_TEMPLATE_ROUTING_HANDLER inherit - WSF_URI_HANDLER_CONTEXT + WSF_ROUTING_HANDLER - REST_REQUEST_HANDLER_CONTEXT + WSF_URI_TEMPLATE_HANDLER create - make + make, + make_with_router note - copyright: "Copyright (c) 1984-2011, Eiffel Software and others" + copyright: "2011-2012, Jocelyn Fiat, Javier Velilla, Eiffel Software and others" license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)" source: "[ Eiffel Software diff --git a/library/server/wsf/router/mapping/uri_template_with_context/wsf_agent_uri_template_with_context_handler.e b/library/server/wsf/router/mapping/uri_template_with_context/wsf_agent_uri_template_with_context_handler.e new file mode 100644 index 00000000..b7051f80 --- /dev/null +++ b/library/server/wsf/router/mapping/uri_template_with_context/wsf_agent_uri_template_with_context_handler.e @@ -0,0 +1,42 @@ +note + description: "Summary description for {WSF_AGENT_URI_TEMPLATE_WITH_CONTEXT_HANDLER}." + author: "" + date: "$Date$" + revision: "$Revision$" + +class + WSF_AGENT_URI_TEMPLATE_WITH_CONTEXT_HANDLER + +inherit + WSF_URI_TEMPLATE_WITH_CONTEXT_HANDLER + +create + make + +feature {NONE} -- Initialization + + make (a_action: like action) + do + action := a_action + end + + action: PROCEDURE [ANY, TUPLE [context: WSF_URI_TEMPLATE_HANDLER_CONTEXT; request: WSF_REQUEST; response: WSF_RESPONSE]] + +feature -- Execution + + execute (ctx: WSF_URI_TEMPLATE_HANDLER_CONTEXT; req: WSF_REQUEST; res: WSF_RESPONSE) + do + action.call ([ctx, req, res]) + end + +note + copyright: "2011-2012, Jocelyn Fiat, Javier Velilla, 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 diff --git a/library/server/wsf/router/mapping/uri_template_with_context/wsf_uri_template_with_context_handler.e b/library/server/wsf/router/mapping/uri_template_with_context/wsf_uri_template_with_context_handler.e new file mode 100644 index 00000000..1f1fde78 --- /dev/null +++ b/library/server/wsf/router/mapping/uri_template_with_context/wsf_uri_template_with_context_handler.e @@ -0,0 +1,36 @@ +note + description: "Summary description for EWF_URI_TEMPLATE_WITH_CONTEXT_HANDLER." + author: "" + date: "$Date$" + revision: "$Revision$" + +deferred class + WSF_URI_TEMPLATE_WITH_CONTEXT_HANDLER + +inherit + WSF_HANDLER + +feature -- Execution + + execute (ctx: WSF_URI_TEMPLATE_HANDLER_CONTEXT; req: WSF_REQUEST; res: WSF_RESPONSE) + deferred + end + +feature {WSF_ROUTER} -- Mapping + + new_mapping (a_tpl: READABLE_STRING_8): WSF_URI_TEMPLATE_WITH_CONTEXT_MAPPING + do + create Result.make (a_tpl, Current) + end + +note + copyright: "2011-2012, Jocelyn Fiat, Javier Velilla, 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 diff --git a/library/server/wsf/router/uri_template/wsf_uri_template_handler_context.e b/library/server/wsf/router/mapping/uri_template_with_context/wsf_uri_template_with_context_handler_context.e similarity index 100% rename from library/server/wsf/router/uri_template/wsf_uri_template_handler_context.e rename to library/server/wsf/router/mapping/uri_template_with_context/wsf_uri_template_with_context_handler_context.e diff --git a/library/server/wsf/router/mapping/uri_template_with_context/wsf_uri_template_with_context_mapping.e b/library/server/wsf/router/mapping/uri_template_with_context/wsf_uri_template_with_context_mapping.e new file mode 100644 index 00000000..e4c34090 --- /dev/null +++ b/library/server/wsf/router/mapping/uri_template_with_context/wsf_uri_template_with_context_mapping.e @@ -0,0 +1,95 @@ +note + description: "Summary description for {EWF_ROUTER_URI_TEMPLATE_WITH_CONTEXT_PATH}." + author: "" + date: "$Date$" + revision: "$Revision$" + +class + WSF_URI_TEMPLATE_WITH_CONTEXT_MAPPING + +inherit + WSF_ROUTER_MAPPING + +create + make, + make_from_template + +feature {NONE} -- Initialization + + make (s: READABLE_STRING_8; h: like handler) + do + make_from_template (create {URI_TEMPLATE}.make (s), h) + end + + make_from_template (tpl: URI_TEMPLATE; h: like handler) + do + template := tpl + handler := h + end + +feature -- Access + + handler: WSF_URI_TEMPLATE_WITH_CONTEXT_HANDLER + + template: URI_TEMPLATE + +feature -- Element change + + set_handler (h: like handler) + do + handler := h + end + +feature -- Status + + routed_handler (req: WSF_REQUEST; res: WSF_RESPONSE; a_router: WSF_ROUTER): detachable WSF_HANDLER + local + tpl: URI_TEMPLATE + p: READABLE_STRING_32 + ctx: detachable WSF_URI_TEMPLATE_HANDLER_CONTEXT + do + p := path_from_request (req) + tpl := based_uri_template (template, a_router) + if attached tpl.match (p) as tpl_res then + Result := handler + create ctx.make (req, tpl, tpl_res, path_from_request (req)) + a_router.execute_before (Current) + --| Applied the context to the request + --| in practice, this will fill the {WSF_REQUEST}.path_parameters + ctx.apply (req) + handler.execute (ctx, req, res) + --| Revert {WSF_REQUEST}.path_parameters_source to former value + --| In case the request object passed by other handler that alters its values. + ctx.revert (req) + a_router.execute_after (Current) + end + rescue + if ctx /= Void then + ctx.revert (req) + end + end + +feature {NONE} -- Implementation + + based_uri_template (a_tpl: like template; a_router: WSF_ROUTER): like template + do + if attached a_router.base_url as l_base_url then + Result := a_tpl.duplicate + Result.set_template (l_base_url + a_tpl.template) + else + Result := a_tpl + end + end + + +note + copyright: "2011-2012, Jocelyn Fiat, Javier Velilla, 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 diff --git a/library/server/wsf/router/mapping/uri_template_with_context/wsf_uri_template_with_context_routed_service.e b/library/server/wsf/router/mapping/uri_template_with_context/wsf_uri_template_with_context_routed_service.e new file mode 100644 index 00000000..8b92556a --- /dev/null +++ b/library/server/wsf/router/mapping/uri_template_with_context/wsf_uri_template_with_context_routed_service.e @@ -0,0 +1,47 @@ +note + description: "Summary description for {WSF_URI_TEMPLATE_WITH_CONTEXT_ROUTED_SERVICE}." + author: "" + date: "$Date$" + revision: "$Revision$" + +deferred class + WSF_URI_TEMPLATE_WITH_CONTEXT_ROUTED_SERVICE + +inherit + WSF_ROUTED_SERVICE + +feature -- Mapping helper: uri + + map_uri_template (a_tpl: STRING; h: WSF_URI_TEMPLATE_WITH_CONTEXT_HANDLER) + do + map_uri_template_with_request_methods (a_tpl, h, Void) + end + + map_uri_template_with_request_methods (a_tpl: READABLE_STRING_8; h: WSF_URI_TEMPLATE_WITH_CONTEXT_HANDLER; rqst_methods: detachable WSF_ROUTER_METHODS) + do + router.map_with_request_methods (create {WSF_URI_TEMPLATE_WITH_CONTEXT_MAPPING}.make (a_tpl, h), rqst_methods) + end + +feature -- Mapping helper: uri agent + + map_uri_template_agent (a_tpl: READABLE_STRING_8; proc: PROCEDURE [ANY, TUPLE [ctx: WSF_URI_TEMPLATE_HANDLER_CONTEXT; req: WSF_REQUEST; res: WSF_RESPONSE]]) + do + map_uri_template_agent_with_request_methods (a_tpl, proc, Void) + end + + map_uri_template_agent_with_request_methods (a_tpl: READABLE_STRING_8; proc: PROCEDURE [ANY, TUPLE [ctx: WSF_URI_TEMPLATE_HANDLER_CONTEXT; req: WSF_REQUEST; res: WSF_RESPONSE]]; rqst_methods: detachable WSF_ROUTER_METHODS) + do + map_uri_template_with_request_methods (a_tpl, create {WSF_AGENT_URI_TEMPLATE_WITH_CONTEXT_HANDLER}.make (proc), rqst_methods) + end + +note + copyright: "2011-2012, Jocelyn Fiat, Javier Velilla, 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 diff --git a/library/server/wsf/router/mapping/uri_template_with_context/wsf_uri_template_with_context_routing_handler.e b/library/server/wsf/router/mapping/uri_template_with_context/wsf_uri_template_with_context_routing_handler.e new file mode 100644 index 00000000..09db9834 --- /dev/null +++ b/library/server/wsf/router/mapping/uri_template_with_context/wsf_uri_template_with_context_routing_handler.e @@ -0,0 +1,39 @@ +note + description: "Summary description for {WSF_URI_TEMPLATE_WITH_CONTEXT_ROUTING_HANDLER}." + author: "" + date: "$Date$" + revision: "$Revision$" + +class + WSF_URI_TEMPLATE_WITH_CONTEXT_ROUTING_HANDLER + +inherit + WSF_ROUTING_HANDLER + + WSF_URI_TEMPLATE_WITH_CONTEXT_HANDLER + rename + execute as uri_template_xecute + end + +create + make, + make_with_router + +feature -- Execution + + uri_template_xecute (ctx: WSF_URI_TEMPLATE_HANDLER_CONTEXT; req: WSF_REQUEST; res: WSF_RESPONSE) + do + execute (req, res) + end + +note + copyright: "2011-2012, Jocelyn Fiat, Javier Velilla, 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 diff --git a/library/server/wsf/router/starts_with/wsf_starts_with_handler.e b/library/server/wsf/router/starts_with/wsf_starts_with_handler.e deleted file mode 100644 index 19c3a037..00000000 --- a/library/server/wsf/router/starts_with/wsf_starts_with_handler.e +++ /dev/null @@ -1,19 +0,0 @@ -note - description: "Summary description for {WSF_STARTS_WITH_HANDLER}." - author: "" - date: "$Date$" - revision: "$Revision$" - -deferred class - WSF_STARTS_WITH_HANDLER - -inherit - WSF_HANDLER - -feature -- Execution - - execute (a_start_path: READABLE_STRING_8; req: WSF_REQUEST; res: WSF_RESPONSE) - deferred - end - -end diff --git a/library/server/wsf/router/uri/wsf_uri_handler.e b/library/server/wsf/router/uri/wsf_uri_handler.e deleted file mode 100644 index 74e63523..00000000 --- a/library/server/wsf/router/uri/wsf_uri_handler.e +++ /dev/null @@ -1,19 +0,0 @@ -note - description: "Summary description for {EWF_ROUTER_URI_PATH_HANDLER}." - author: "" - date: "$Date$" - revision: "$Revision$" - -deferred class - WSF_URI_HANDLER - -inherit - WSF_HANDLER - -feature -- Execution - - execute (req: WSF_REQUEST; res: WSF_RESPONSE) - deferred - end - -end diff --git a/library/server/wsf/router/uri_template/wsf_uri_template_handler.e b/library/server/wsf/router/uri_template/wsf_uri_template_handler.e deleted file mode 100644 index 3f5d8f96..00000000 --- a/library/server/wsf/router/uri_template/wsf_uri_template_handler.e +++ /dev/null @@ -1,19 +0,0 @@ -note - description: "Summary description for EWF_URI_TEMPLATE_HANDLER." - author: "" - date: "$Date$" - revision: "$Revision$" - -deferred class - WSF_URI_TEMPLATE_HANDLER - -inherit - WSF_HANDLER - -feature -- Execution - - execute (ctx: WSF_URI_TEMPLATE_HANDLER_CONTEXT; req: WSF_REQUEST; res: WSF_RESPONSE) - deferred - end - -end diff --git a/library/server/wsf/router/wsf_file_system_handler.e b/library/server/wsf/router/wsf_file_system_handler.e index 01626c60..c1500d86 100644 --- a/library/server/wsf/router/wsf_file_system_handler.e +++ b/library/server/wsf/router/wsf_file_system_handler.e @@ -20,7 +20,7 @@ feature {NONE} -- Initialization make (d: like document_root) require - valid_d: (d /= Void and then not d.is_empty) implies d.ends_with ("/") + valid_d: (d /= Void and then not d.is_empty) implies not d.ends_with (operating_environment.directory_separator.out) local e: EXECUTION_ENVIRONMENT do @@ -30,6 +30,8 @@ feature {NONE} -- Initialization else document_root := d end + ensure + not document_root.is_empty and then not document_root.ends_with (operating_environment.directory_separator.out) end feature -- Access @@ -337,7 +339,7 @@ feature {NONE} -- Implementation resource_filename (uri: READABLE_STRING_8): READABLE_STRING_8 do - Result := real_filename (document_root + real_filename (uri)) + Result := real_filename (document_root + operating_environment.directory_separator.out + real_filename (uri)) end dirname (uri: READABLE_STRING_8): READABLE_STRING_8 @@ -450,4 +452,14 @@ feature {NONE} -- implementation: date time Result := date_time_utility.unix_time_stamp_to_date_time (n) end +note + copyright: "2011-2012, Jocelyn Fiat, Javier Velilla, 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 diff --git a/library/server/wsf/router/wsf_handler.e b/library/server/wsf/router/wsf_handler.e index 17d8d161..e39c89d1 100644 --- a/library/server/wsf/router/wsf_handler.e +++ b/library/server/wsf/router/wsf_handler.e @@ -14,8 +14,15 @@ feature -- Status report do Result := True end - -feature {WSF_ROUTER} -- Mapping change + +feature {WSF_ROUTER} -- Mapping + + new_mapping (a_resource: READABLE_STRING_8): WSF_ROUTER_MAPPING + -- New mapping built with Current as handler + deferred + ensure + Result /= Void and then Result.handler = Current + end on_mapped (a_mapping: WSF_ROUTER_MAPPING; a_rqst_methods: detachable WSF_ROUTER_METHODS) -- Callback called when a router map a route to Current handler diff --git a/library/server/wsf/router/wsf_router.e b/library/server/wsf/router/wsf_router.e index ed039aed..99cbd191 100644 --- a/library/server/wsf/router/wsf_router.e +++ b/library/server/wsf/router/wsf_router.e @@ -57,6 +57,21 @@ feature -- Mapping a_mapping.handler.on_mapped (a_mapping, rqst_methods) end +feature -- Mapping handler + + handle (a_resource: READABLE_STRING_8; h: WSF_HANDLER) + -- Map the mapping associated to handler `h' for resource `a_resource' + do + handle_with_request_methods (a_resource, h, Void) + end + + handle_with_request_methods (a_resource: READABLE_STRING_8; h: WSF_HANDLER; rqst_methods: detachable WSF_ROUTER_METHODS) + -- Map the mapping associated to handler `h' for resource `a_resource' + -- and only for request methods `rqst_methods' + do + map_with_request_methods (h.new_mapping (a_resource), rqst_methods) + end + feature -- Access is_dispatched: BOOLEAN diff --git a/library/server/wsf/router/wsf_router_mapping.e b/library/server/wsf/router/wsf_router_mapping.e index f5fb7491..a04b5cdb 100644 --- a/library/server/wsf/router/wsf_router_mapping.e +++ b/library/server/wsf/router/wsf_router_mapping.e @@ -7,6 +7,12 @@ note deferred class WSF_ROUTER_MAPPING +feature {NONE} -- Initialization + + make (a_resource: READABLE_STRING_8; h: like handler) + deferred + end + feature -- Access handler: WSF_HANDLER diff --git a/library/server/wsf/router/wsf_router_methods.e b/library/server/wsf/router/wsf_router_methods.e index 8d975789..efbad2b2 100644 --- a/library/server/wsf/router/wsf_router_methods.e +++ b/library/server/wsf/router/wsf_router_methods.e @@ -62,11 +62,7 @@ feature {NONE} -- Initialization make_from_iterable (v: ITERABLE [READABLE_STRING_8]) do make (1) - across - v as vc - loop - add_method_using_constant (vc.item) - end + add_methods (v) end make_from_string (v: READABLE_STRING_8) @@ -115,6 +111,19 @@ feature -- Status change is_locked := True end +feature -- Basic operations + + add alias "+" (a_other: WSF_ROUTER_METHODS): WSF_ROUTER_METHODS + -- Merge Current and a_other into Result + require + a_other_not_void: a_other /= Void + do + create Result.make_from_iterable (Current) + Result.add_methods (a_other) + ensure + + end + feature -- Element change enable_get @@ -328,7 +337,21 @@ feature -- Access Result := methods.to_array end -feature {NONE} -- Implementation +feature {WSF_ROUTER_METHODS} -- Implementation + + add_methods (lst: ITERABLE [READABLE_STRING_8]) + -- Enable methods from `lst' + do + if not is_locked then + across + lst as c + loop + add_method_using_constant (c.item) + end + end + end + +feature {NONE} -- Implementation add_method_using_constant (v: READABLE_STRING_8) -- Add method `v' using method_* constant @@ -358,15 +381,6 @@ feature {NONE} -- Implementation method_set: has (v.as_upper) end - add_method (v: READABLE_STRING_8) - require - is_upper_case: v.same_string (v.as_upper) - do - if not is_locked then - methods.extend (v) - end - end - prune_method (v: READABLE_STRING_8) require is_upper_case: v.same_string (v.as_upper) diff --git a/library/server/wsf/router/wsf_routing_handler.e b/library/server/wsf/router/wsf_routing_handler.e new file mode 100644 index 00000000..917ac167 --- /dev/null +++ b/library/server/wsf/router/wsf_routing_handler.e @@ -0,0 +1,75 @@ +note + description: "Summary description for {WSF_ROUTING_HANDLER}." + author: "" + date: "$Date$" + revision: "$Revision$" + +deferred class + WSF_ROUTING_HANDLER + +inherit + WSF_HANDLER + +feature {NONE} -- Initialization + + make_with_router (a_router: like router) + do + router := a_router + end + + make (n: INTEGER) + do + make_with_router (create {WSF_ROUTER}.make (n)) + end + +feature -- Access + + router: WSF_ROUTER + +feature -- Access + + count: INTEGER + -- Count of maps handled by current + do + Result := router.count + end + + base_url: detachable READABLE_STRING_8 + do + Result := router.base_url + end + +feature -- Element change + + set_base_url (a_base_url: like base_url) + -- Set `base_url' to `a_base_url' + -- make sure no map is already added (i.e: count = 0) + require + no_handler_set: count = 0 + do + router.set_base_url (a_base_url) + end + +feature -- Execution + + execute (req: WSF_REQUEST; res: WSF_RESPONSE) + -- Execute request handler + do + if attached router.dispatch_and_return_handler (req, res) as h then + check is_dispatched: router.is_dispatched end + else + res.put_header ({HTTP_STATUS_CODE}.not_found, <<[{HTTP_HEADER_NAMES}.header_content_length, "0"]>>) + end + end + +note + copyright: "2011-2012, Jocelyn Fiat, Javier Velilla, 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 diff --git a/library/server/wsf/src/filter/wsf_filter_handler.e b/library/server/wsf/src/filter/wsf_filter_handler.e index f06f0082..0ea0669d 100644 --- a/library/server/wsf/src/filter/wsf_filter_handler.e +++ b/library/server/wsf/src/filter/wsf_filter_handler.e @@ -8,19 +8,19 @@ note revision: "$Revision$" deferred class - WSF_FILTER_HANDLER [C -> WSF_HANDLER_CONTEXT] + WSF_FILTER_HANDLER [H -> WSF_HANDLER] inherit - WSF_HANDLER [C] + WSF_HANDLER feature -- Access - next: detachable WSF_FILTER_HANDLER [C] - -- Next filter + next: detachable H + -- Next handler feature -- Element change - set_next (a_next: WSF_FILTER_HANDLER [C]) + set_next (a_next: like next) -- Set `next' to `a_next' do next := a_next @@ -28,16 +28,6 @@ feature -- Element change next_set: next = a_next end -feature {NONE} -- Implementation - - execute_next (ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE) - -- Execute the `next' filter. - do - if attached next as n then - n.execute (ctx, req, res) - end - end - note copyright: "2011-2012, Jocelyn Fiat, Javier Velilla, Eiffel Software and others" license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)" diff --git a/library/server/wsf/src/filter/wsf_filter_uri_handler.e b/library/server/wsf/src/filter/wsf_filter_uri_handler.e new file mode 100644 index 00000000..19d4e87a --- /dev/null +++ b/library/server/wsf/src/filter/wsf_filter_uri_handler.e @@ -0,0 +1,34 @@ +note + description : "Objects that ..." + author : "$Author$" + date : "$Date$" + revision : "$Revision$" + +deferred class + WSF_FILTER_URI_HANDLER + +inherit + WSF_FILTER_HANDLER [WSF_URI_HANDLER] + + WSF_URI_HANDLER + +feature -- Execution + + execute_next (req: WSF_REQUEST; res: WSF_RESPONSE) + do + if attached next as n then + n.execute (req, res) + end + end + +note + copyright: "2011-2012, Jocelyn Fiat, Javier Velilla, 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 diff --git a/library/server/wsf/src/filter/wsf_filter_uri_template_handler.e b/library/server/wsf/src/filter/wsf_filter_uri_template_handler.e new file mode 100644 index 00000000..296d4fde --- /dev/null +++ b/library/server/wsf/src/filter/wsf_filter_uri_template_handler.e @@ -0,0 +1,34 @@ +note + description : "Objects that ..." + author : "$Author$" + date : "$Date$" + revision : "$Revision$" + +deferred class + WSF_FILTER_URI_TEMPLATE_HANDLER + +inherit + WSF_FILTER_HANDLER [WSF_URI_TEMPLATE_HANDLER] + + WSF_URI_TEMPLATE_HANDLER + +feature -- Execution + + execute_next (req: WSF_REQUEST; res: WSF_RESPONSE) + do + if attached next as n then + n.execute (req, res) + end + end + +note + copyright: "2011-2012, Jocelyn Fiat, Javier Velilla, 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 diff --git a/library/server/wsf/src/filter/wsf_uri_template_filtered_service.e b/library/server/wsf/src/filter/wsf_filtered_service.e similarity index 88% rename from library/server/wsf/src/filter/wsf_uri_template_filtered_service.e rename to library/server/wsf/src/filter/wsf_filtered_service.e index cc8a859b..781c59c1 100644 --- a/library/server/wsf/src/filter/wsf_uri_template_filtered_service.e +++ b/library/server/wsf/src/filter/wsf_filtered_service.e @@ -1,11 +1,11 @@ note - description: "Summary description for {WSF_URI_TEMPLATE_FILTERED_SERVICE}." + description: "Summary description for {WSF_FILTERED_SERVICE}." author: "" date: "$Date$" revision: "$Revision$" deferred class - WSF_URI_TEMPLATE_FILTERED_SERVICE + WSF_FILTERED_SERVICE feature {NONE} -- Initialization diff --git a/library/server/wsf/src/filter/wsf_routing_filter.e b/library/server/wsf/src/filter/wsf_routing_filter.e deleted file mode 100644 index 9b42cbf7..00000000 --- a/library/server/wsf/src/filter/wsf_routing_filter.e +++ /dev/null @@ -1,75 +0,0 @@ -note - description: "Routing filter." - author: "Olivier Ligot" - date: "$Date$" - revision: "$Revision$" - -class - WSF_ROUTING_FILTER [H -> WSF_HANDLER [C], C -> WSF_HANDLER_CONTEXT] - -inherit - WSF_FILTER - -create - make - -feature {NONE} -- Initialization - - make (a_router: WSF_ROUTER [H, C]) - do - router := a_router - ensure - router_set: router = a_router - end - -feature -- Access - - router: WSF_ROUTER [H, C] - -- Router - - execute_default_action: detachable PROCEDURE [ANY, TUPLE [req: WSF_REQUEST; res: WSF_RESPONSE]] - -- `execute_default' action - -feature -- Element change - - set_execute_default_action (an_action: like execute_default_action) - -- Set `execute_default_action' to `an_action' - do - execute_default_action := an_action - ensure - execute_default_action_set: execute_default_action = an_action - end - -feature -- Basic operations - - execute (req: WSF_REQUEST; res: WSF_RESPONSE) - -- Execute the filter - do - if attached router.route (req) as r then - router.execute_route (r, req, res) - else - execute_default (req, res) - end - execute_next (req, res) - end - - execute_default (req: WSF_REQUEST; res: WSF_RESPONSE) - do - if attached execute_default_action as action then - action.call ([req, res]) - else - do_nothing - end - end - -note - copyright: "2011-2012, Jocelyn Fiat, Javier Velilla, 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 diff --git a/library/server/wsf/src/wsf_request_path_parameters_provider.e b/library/server/wsf/src/wsf_request_path_parameters_provider.e new file mode 100644 index 00000000..59f60860 --- /dev/null +++ b/library/server/wsf/src/wsf_request_path_parameters_provider.e @@ -0,0 +1,59 @@ +note + description: "Summary description for {WSF_REQUEST_PATH_PARAMETERS_PROVIDER}." + author: "" + date: "$Date$" + revision: "$Revision$" + +class + WSF_REQUEST_PATH_PARAMETERS_PROVIDER + +inherit + WSF_REQUEST_PATH_PARAMETERS_SOURCE + +create + make + +feature {NONE} -- Initialization + + make (nb: INTEGER; a_urlencoded_path_parameters: like urlencoded_path_parameters) + do + path_parameters_count := nb + urlencoded_path_parameters := a_urlencoded_path_parameters + end + +feature -- Access + + path_parameters_count: INTEGER + + urlencoded_path_parameters: TABLE_ITERABLE [READABLE_STRING_8, READABLE_STRING_8] + -- Raw urlencoded path parameters. + +feature -- Operation + + previous_path_parameters_source: detachable WSF_REQUEST_PATH_PARAMETERS_SOURCE + + apply (req: WSF_REQUEST) + -- + do + previous_path_parameters_source := req.path_parameters_source + req.set_path_parameters_source (Current) + end + + revert (req: WSF_REQUEST) + -- + do + req.set_path_parameters_source (previous_path_parameters_source) + previous_path_parameters_source := Void + end + +note + copyright: "2011-2012, Jocelyn Fiat, Javier Velilla, 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 diff --git a/library/server/wsf_extension/src/wsf_resource_handler_helper.e b/library/server/wsf_extension/src/wsf_resource_handler_helper.e index 041cd9c5..eef2ba1e 100644 --- a/library/server/wsf_extension/src/wsf_resource_handler_helper.e +++ b/library/server/wsf_extension/src/wsf_resource_handler_helper.e @@ -5,160 +5,160 @@ note revision: "$Revision$" class - WSF_RESOURCE_HANDLER_HELPER [C -> WSF_HANDLER_CONTEXT] + WSF_RESOURCE_HANDLER_HELPER feature -- Execute template - execute_methods (ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE) + execute_methods (req: WSF_REQUEST; res: WSF_RESPONSE) -- Execute request and dispatch according to the request method local m: READABLE_STRING_8 do m := req.request_method.as_upper if m.same_string ({HTTP_REQUEST_METHODS}.method_get) then - execute_get (ctx, req, res) + execute_get (req, res) elseif m.same_string ({HTTP_REQUEST_METHODS}.method_put) then - execute_put (ctx, req, res) + execute_put (req, res) elseif m.same_string ({HTTP_REQUEST_METHODS}.method_delete) then - execute_delete (ctx, req, res) + execute_delete (req, res) elseif m.same_string ({HTTP_REQUEST_METHODS}.method_post) then - execute_post (ctx, req, res) + execute_post (req, res) elseif m.same_string ({HTTP_REQUEST_METHODS}.method_trace) then - execute_trace (ctx, req, res) + execute_trace (req, res) elseif m.same_string ({HTTP_REQUEST_METHODS}.method_options) then - execute_options (ctx, req, res) + execute_options (req, res) elseif m.same_string ({HTTP_REQUEST_METHODS}.method_head) then - execute_head (ctx, req, res) + execute_head (req, res) elseif m.same_string ({HTTP_REQUEST_METHODS}.method_connect) then - execute_connect (ctx, req, res) + execute_connect (req, res) else --| Eventually handle other methods... - execute_extension_method (ctx, req, res) + execute_extension_method (req, res) end end feature -- Method Post - execute_post (ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE) + execute_post (req: WSF_REQUEST; res: WSF_RESPONSE) do if req.is_chunked_input then - do_post (ctx, req, res) + do_post (req, res) else if req.content_length_value > 0 then - do_post (ctx, req, res) + do_post (req, res) else - handle_bad_request_response ("Bad request, content_length empty", ctx, req, res) + handle_bad_request_response ("Bad request, content_length empty", req, res) end end end - do_post (ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE) + do_post (req: WSF_REQUEST; res: WSF_RESPONSE) do - handle_not_implemented ("Method POST not implemented", ctx, req, res) + handle_not_implemented ("Method POST not implemented", req, res) end feature-- Method Put - execute_put (ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE) + execute_put (req: WSF_REQUEST; res: WSF_RESPONSE) do if req.is_chunked_input then - do_put (ctx, req, res) + do_put (req, res) else if req.content_length_value > 0 then - do_put (ctx, req, res) + do_put (req, res) else - handle_bad_request_response ("Bad request, content_length empty", ctx, req, res) + handle_bad_request_response ("Bad request, content_length empty", req, res) end end end - do_put (ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE) + do_put (req: WSF_REQUEST; res: WSF_RESPONSE) do - handle_not_implemented ("Method PUT not implemented", ctx, req, res) + handle_not_implemented ("Method PUT not implemented", req, res) end feature -- Method Get - execute_get (ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE) + execute_get (req: WSF_REQUEST; res: WSF_RESPONSE) do - do_get (ctx, req, res) + do_get (req, res) end - do_get (ctx: C;req: WSF_REQUEST; res: WSF_RESPONSE) + do_get (req: WSF_REQUEST; res: WSF_RESPONSE) do - handle_not_implemented ("Method GET not implemented", ctx, req, res) + handle_not_implemented ("Method GET not implemented", req, res) end feature -- Method DELETE - execute_delete (ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE) + execute_delete (req: WSF_REQUEST; res: WSF_RESPONSE) do - do_delete (ctx, req, res) + do_delete (req, res) end - do_delete (ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE) + do_delete (req: WSF_REQUEST; res: WSF_RESPONSE) do - handle_not_implemented ("Method DELETE not implemented", ctx, req, res) + handle_not_implemented ("Method DELETE not implemented", req, res) end feature -- Method CONNECT - execute_connect (ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE) + execute_connect (req: WSF_REQUEST; res: WSF_RESPONSE) do - do_connect (ctx, req, res) + do_connect (req, res) end - do_connect (ctx: C;req: WSF_REQUEST; res: WSF_RESPONSE) + do_connect (req: WSF_REQUEST; res: WSF_RESPONSE) do - handle_not_implemented ("Method CONNECT not implemented", ctx, req, res) + handle_not_implemented ("Method CONNECT not implemented", req, res) end feature -- Method HEAD - execute_head (ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE) + execute_head (req: WSF_REQUEST; res: WSF_RESPONSE) do - do_head (ctx, req, res) + do_head (req, res) end - do_head (ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE) + do_head (req: WSF_REQUEST; res: WSF_RESPONSE) do - handle_not_implemented ("Method HEAD not implemented", ctx, req, res) + handle_not_implemented ("Method HEAD not implemented", req, res) end feature -- Method OPTIONS - execute_options (ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE) + execute_options (req: WSF_REQUEST; res: WSF_RESPONSE) do - do_options (ctx, req, res) + do_options (req, res) end - do_options (ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE) + do_options (req: WSF_REQUEST; res: WSF_RESPONSE) do - handle_not_implemented ("Method OPTIONS not implemented", ctx, req, res) + handle_not_implemented ("Method OPTIONS not implemented", req, res) end feature -- Method TRACE - execute_trace (ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE) + execute_trace (req: WSF_REQUEST; res: WSF_RESPONSE) do - do_trace (ctx, req, res) + do_trace (req, res) end - do_trace (ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE) + do_trace (req: WSF_REQUEST; res: WSF_RESPONSE) do - handle_not_implemented ("Method TRACE not implemented", ctx, req, res) + handle_not_implemented ("Method TRACE not implemented", req, res) end feature -- Method Extension Method - execute_extension_method (ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE) + execute_extension_method (req: WSF_REQUEST; res: WSF_RESPONSE) do - do_extension_method (ctx, req, res) + do_extension_method (req, res) end - do_extension_method (ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE) + do_extension_method (req: WSF_REQUEST; res: WSF_RESPONSE) do - handle_not_implemented ("Method extension-method not implemented", ctx, req, res) + handle_not_implemented ("Method extension-method not implemented", req, res) end feature -- Retrieve content from WGI_INPUT_STREAM @@ -208,7 +208,7 @@ feature -- Handle responses Result := Void end - handle_bad_request_response (a_description: STRING; ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE ) + handle_bad_request_response (a_description: STRING; req: WSF_REQUEST; res: WSF_RESPONSE ) local h : HTTP_HEADER do @@ -221,7 +221,7 @@ feature -- Handle responses res.put_string (a_description) end - handle_precondition_fail_response (a_description: STRING; ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE ) + handle_precondition_fail_response (a_description: STRING; req: WSF_REQUEST; res: WSF_RESPONSE ) local h : HTTP_HEADER do @@ -234,7 +234,7 @@ feature -- Handle responses res.put_string (a_description) end - handle_internal_server_error (a_description: STRING; ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE ) + handle_internal_server_error (a_description: STRING; req: WSF_REQUEST; res: WSF_RESPONSE ) local h : HTTP_HEADER do @@ -247,7 +247,7 @@ feature -- Handle responses res.put_string (a_description) end - handle_not_implemented (a_description: STRING; ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE ) + handle_not_implemented (a_description: STRING; req: WSF_REQUEST; res: WSF_RESPONSE ) local h : HTTP_HEADER do @@ -260,7 +260,7 @@ feature -- Handle responses res.put_string (a_description) end - handle_method_not_allowed_response (a_description: STRING; ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE) + handle_method_not_allowed_response (a_description: STRING; req: WSF_REQUEST; res: WSF_RESPONSE) local h : HTTP_HEADER do @@ -273,7 +273,7 @@ feature -- Handle responses res.put_string (a_description) end - handle_resource_not_found_response (a_description: STRING; ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE) + handle_resource_not_found_response (a_description: STRING; req: WSF_REQUEST; res: WSF_RESPONSE) local h : HTTP_HEADER do @@ -287,7 +287,7 @@ feature -- Handle responses end - handle_resource_not_modified_response (a_description: STRING; ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE) + handle_resource_not_modified_response (a_description: STRING; req: WSF_REQUEST; res: WSF_RESPONSE) local h : HTTP_HEADER do @@ -302,7 +302,7 @@ feature -- Handle responses end - handle_resource_conflict_response (a_description: STRING; ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE) + handle_resource_conflict_response (a_description: STRING; req: WSF_REQUEST; res: WSF_RESPONSE) local h : HTTP_HEADER do From 94a91fa4aa69eb3ceb6985f7de7ab443c7f5d851 Mon Sep 17 00:00:00 2001 From: Jocelyn Fiat Date: Wed, 26 Sep 2012 09:45:33 +0200 Subject: [PATCH 4/7] added missing wsf_routing_filter --- .../wsf/src/filter/wsf_routing_filter.e | 75 +++++++++++++++++++ 1 file changed, 75 insertions(+) create mode 100644 library/server/wsf/src/filter/wsf_routing_filter.e diff --git a/library/server/wsf/src/filter/wsf_routing_filter.e b/library/server/wsf/src/filter/wsf_routing_filter.e new file mode 100644 index 00000000..349178d6 --- /dev/null +++ b/library/server/wsf/src/filter/wsf_routing_filter.e @@ -0,0 +1,75 @@ +note + description: "Routing filter." + author: "Olivier Ligot" + date: "$Date$" + revision: "$Revision$" + +class + WSF_ROUTING_FILTER + +inherit + WSF_FILTER + +create + make + +feature {NONE} -- Initialization + + make (a_router: WSF_ROUTER) + do + router := a_router + ensure + router_set: router = a_router + end + +feature -- Access + + router: WSF_ROUTER + -- Router + + execute_default_action: detachable PROCEDURE [ANY, TUPLE [req: WSF_REQUEST; res: WSF_RESPONSE]] + -- `execute_default' action + +feature -- Element change + + set_execute_default_action (an_action: like execute_default_action) + -- Set `execute_default_action' to `an_action' + do + execute_default_action := an_action + ensure + execute_default_action_set: execute_default_action = an_action + end + +feature -- Basic operations + + execute (req: WSF_REQUEST; res: WSF_RESPONSE) + -- Execute the filter + do + if attached router.dispatch_and_return_handler (req, res) then + check router.is_dispatched end + else + execute_default (req, res) + end + execute_next (req, res) + end + + execute_default (req: WSF_REQUEST; res: WSF_RESPONSE) + do + if attached execute_default_action as action then + action.call ([req, res]) + else + do_nothing + end + end + +note + copyright: "2011-2012, Jocelyn Fiat, Javier Velilla, 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 From cdb88059bcf8e9e1ce74da5347914dcc854d1daf Mon Sep 17 00:00:00 2001 From: Jocelyn Fiat Date: Wed, 26 Sep 2012 16:41:13 +0200 Subject: [PATCH 5/7] Fixed Restbuck examples with new router design --- examples/restbucksCRUD/src/resource/order_handler.e | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/examples/restbucksCRUD/src/resource/order_handler.e b/examples/restbucksCRUD/src/resource/order_handler.e index 600ba033..16fba5bd 100644 --- a/examples/restbucksCRUD/src/resource/order_handler.e +++ b/examples/restbucksCRUD/src/resource/order_handler.e @@ -41,7 +41,7 @@ feature -- execute execute_methods (req, res) end - uri_template_execute (ctx: WSF_URI_TEMPLATE_HANDLER_CONTEXT; req: WSF_REQUEST; res: WSF_RESPONSE) + uri_template_execute (req: WSF_REQUEST; res: WSF_RESPONSE) -- Execute request handler do execute_methods (req, res) @@ -366,7 +366,9 @@ feature {NONE} -- Implementation Repository Layer json.add_converter(joc) create parser.make_parser (l_post) if attached parser.parse as jv and parser.is_parsed then - Result ?= json.object (jv, "ORDER") + if attached {like extract_order_request} json.object (jv, "ORDER") as res then + Result := res + end end end From e01c5bec57706e70320ed55ec24719080fc95054 Mon Sep 17 00:00:00 2001 From: Jocelyn Fiat Date: Thu, 27 Sep 2012 15:09:41 +0200 Subject: [PATCH 6/7] Reviewed the semantic of the handler context. Adapted existing code to fit the new router design. --- .../rest/src/rest_request_agent_handler.e | 2 +- .../request/rest/src/rest_request_handler.e | 2 +- .../rest/src/rest_request_handler_context.e | 10 +- ...est_request_uri_template_handler_context.e | 2 +- examples/filter/src/filter_server.e | 1 - .../step_4/hello/src/hello_application.e | 12 +- .../step_4/hello/src/user_message_handler.e | 12 +- examples/upload_image/src/image_uploader.e | 10 +- .../wsf_agent_context_handler.e} | 21 +- .../wsf/router/context/wsf_context_handler.e | 36 +++ .../wsf/router/context/wsf_handler_context.e | 228 +----------------- .../context/wsf_router_context_mapping.e | 30 +++ ...ri_template_with_context_handler_context.e | 137 ----------- .../starts_with/wsf_starts_with_handler.e | 0 .../starts_with/wsf_starts_with_mapping.e | 0 .../uri/helpers/wsf_uri_agent_handler.e} | 4 +- .../uri/helpers}/wsf_uri_response_handler.e | 0 .../uri/helpers}/wsf_uri_routed_service.e | 2 +- .../uri/wsf_uri_handler.e | 0 .../uri/wsf_uri_mapping.e | 0 .../helpers/wsf_uri_template_agent_handler.e} | 4 +- ...wsf_uri_template_response_agent_handler.e} | 4 +- .../wsf_uri_template_response_handler.e | 0 .../wsf_uri_template_routed_service.e | 2 +- .../wsf_uri_template_routing_handler.e | 0 .../uri_template/wsf_uri_template_handler.e | 0 .../uri_template/wsf_uri_template_mapping.e | 0 .../wsf_uri_template_agent_context_handler.e | 31 +++ ...wsf_uri_template_context_routed_service.e} | 16 +- ...sf_uri_template_routing_context_handler.e} | 12 +- .../wsf_uri_template_context_handler.e} | 12 +- .../wsf_uri_template_context_mapping.e} | 22 +- library/server/wsf/router/wsf_handler.e | 2 +- .../router/{service => }/wsf_routed_service.e | 7 + .../wsf_extension/src/wsf_request_utility.e | 112 +++++++++ .../wsf_extension/src/wsf_value_utility.e | 156 ++++++++++++ 36 files changed, 458 insertions(+), 431 deletions(-) rename library/server/wsf/router/{mapping/uri_template_with_context/wsf_agent_uri_template_with_context_handler.e => context/wsf_agent_context_handler.e} (54%) create mode 100644 library/server/wsf/router/context/wsf_context_handler.e create mode 100644 library/server/wsf/router/context/wsf_router_context_mapping.e delete mode 100644 library/server/wsf/router/mapping/uri_template_with_context/wsf_uri_template_with_context_handler_context.e rename library/server/wsf/router/{mapping => support}/starts_with/wsf_starts_with_handler.e (100%) rename library/server/wsf/router/{mapping => support}/starts_with/wsf_starts_with_mapping.e (100%) rename library/server/wsf/router/{mapping/uri/wsf_agent_uri_handler.e => support/uri/helpers/wsf_uri_agent_handler.e} (89%) rename library/server/wsf/router/{mapping/uri => support/uri/helpers}/wsf_uri_response_handler.e (100%) rename library/server/wsf/router/{mapping/uri => support/uri/helpers}/wsf_uri_routed_service.e (95%) rename library/server/wsf/router/{mapping => support}/uri/wsf_uri_handler.e (100%) rename library/server/wsf/router/{mapping => support}/uri/wsf_uri_mapping.e (100%) rename library/server/wsf/router/{mapping/uri_template/wsf_agent_uri_template_handler.e => support/uri_template/helpers/wsf_uri_template_agent_handler.e} (89%) rename library/server/wsf/router/{mapping/uri/wsf_agent_uri_template_response_handler.e => support/uri_template/helpers/wsf_uri_template_response_agent_handler.e} (86%) rename library/server/wsf/router/{mapping/uri => support/uri_template/helpers}/wsf_uri_template_response_handler.e (100%) rename library/server/wsf/router/{mapping/uri_template => support/uri_template/helpers}/wsf_uri_template_routed_service.e (92%) rename library/server/wsf/router/{mapping/uri_template => support/uri_template/helpers}/wsf_uri_template_routing_handler.e (100%) rename library/server/wsf/router/{mapping => support}/uri_template/wsf_uri_template_handler.e (100%) rename library/server/wsf/router/{mapping => support}/uri_template/wsf_uri_template_mapping.e (100%) create mode 100644 library/server/wsf/router/support/uri_template_with_context/helpers/wsf_uri_template_agent_context_handler.e rename library/server/wsf/router/{mapping/uri_template_with_context/wsf_uri_template_with_context_routed_service.e => support/uri_template_with_context/helpers/wsf_uri_template_context_routed_service.e} (53%) rename library/server/wsf/router/{mapping/uri_template_with_context/wsf_uri_template_with_context_routing_handler.e => support/uri_template_with_context/helpers/wsf_uri_template_routing_context_handler.e} (59%) rename library/server/wsf/router/{mapping/uri_template_with_context/wsf_uri_template_with_context_handler.e => support/uri_template_with_context/wsf_uri_template_context_handler.e} (70%) rename library/server/wsf/router/{mapping/uri_template_with_context/wsf_uri_template_with_context_mapping.e => support/uri_template_with_context/wsf_uri_template_context_mapping.e} (78%) rename library/server/wsf/router/{service => }/wsf_routed_service.e (77%) create mode 100644 library/server/wsf_extension/src/wsf_request_utility.e create mode 100644 library/server/wsf_extension/src/wsf_value_utility.e diff --git a/draft/library/server/request/rest/src/rest_request_agent_handler.e b/draft/library/server/request/rest/src/rest_request_agent_handler.e index f84ddc63..eb0c3ffb 100644 --- a/draft/library/server/request/rest/src/rest_request_agent_handler.e +++ b/draft/library/server/request/rest/src/rest_request_agent_handler.e @@ -2,7 +2,7 @@ class REST_REQUEST_AGENT_HANDLER inherit - WSF_AGENT_URI_TEMPLATE_HANDLER + WSF_URI_TEMPLATE_AGENT_HANDLER create make diff --git a/draft/library/server/request/rest/src/rest_request_handler.e b/draft/library/server/request/rest/src/rest_request_handler.e index ed33bf59..c61a980d 100644 --- a/draft/library/server/request/rest/src/rest_request_handler.e +++ b/draft/library/server/request/rest/src/rest_request_handler.e @@ -8,7 +8,7 @@ deferred class REST_REQUEST_HANDLER inherit - WSF_URI_TEMPLATE_HANDLER + WSF_URI_TEMPLATE_CONTEXT_HANDLER [WSF_HANDLER_CONTEXT] WSF_HANDLER_HELPER diff --git a/draft/library/server/request/rest/src/rest_request_handler_context.e b/draft/library/server/request/rest/src/rest_request_handler_context.e index a90e7d20..b928b4d8 100644 --- a/draft/library/server/request/rest/src/rest_request_handler_context.e +++ b/draft/library/server/request/rest/src/rest_request_handler_context.e @@ -10,6 +10,8 @@ deferred class inherit WSF_HANDLER_CONTEXT + WSF_REQUEST_UTILITY + feature -- Accept: Content-Type accepted_content_type: detachable READABLE_STRING_8 @@ -23,7 +25,7 @@ feature -- Accept: Content-Type get_accepted_content_type (a_supported_content_types: detachable ARRAY [STRING_8]) do if internal_accepted_content_type = Void then - internal_accepted_content_type := request_accepted_content_type (a_supported_content_types) + internal_accepted_content_type := request_accepted_content_type (request, a_supported_content_types) end end @@ -73,10 +75,10 @@ feature -- Format request_accepted_format (a_format_variable_name: detachable READABLE_STRING_8; a_supported_content_types: detachable ARRAY [READABLE_STRING_8]): detachable READABLE_STRING_8 -- Format id for the request based on {HTTP_FORMAT_CONSTANTS} do - if a_format_variable_name /= Void and then attached string_item (a_format_variable_name) as ctx_format then - Result := ctx_format.as_string_8 + if a_format_variable_name /= Void and then attached {WSF_STRING} request.item (a_format_variable_name) as ctx_format then + Result := ctx_format.value else - Result := request_format_from_content_type (request_accepted_content_type (a_supported_content_types)) + Result := request_format_from_content_type (request_accepted_content_type (request, a_supported_content_types)) end end diff --git a/draft/library/server/request/rest/src/uri_template/rest_request_uri_template_handler_context.e b/draft/library/server/request/rest/src/uri_template/rest_request_uri_template_handler_context.e index 74fcc03f..d44f0eae 100644 --- a/draft/library/server/request/rest/src/uri_template/rest_request_uri_template_handler_context.e +++ b/draft/library/server/request/rest/src/uri_template/rest_request_uri_template_handler_context.e @@ -8,7 +8,7 @@ class REST_REQUEST_URI_TEMPLATE_HANDLER_CONTEXT inherit - WSF_URI_TEMPLATE_HANDLER_CONTEXT + WSF_HANDLER_CONTEXT REST_REQUEST_HANDLER_CONTEXT diff --git a/examples/filter/src/filter_server.e b/examples/filter/src/filter_server.e index c407cfc6..17c345cc 100644 --- a/examples/filter/src/filter_server.e +++ b/examples/filter/src/filter_server.e @@ -38,7 +38,6 @@ feature {NONE} -- Initialization l_authentication_filter_hdl: AUTHENTICATION_FILTER l_user_filter: USER_HANDLER l_user_handler: WSF_URI_TEMPLATE_HANDLER --- l_routing_hdl: WSF_URI_TEMPLATE_ROUTING_HANDLER --[WSF_HANDLER [WSF_URI_TEMPLATE_HANDLER_CONTEXT], WSF_URI_TEMPLATE_HANDLER_CONTEXT] l_routing_filter: WSF_ROUTING_FILTER do create l_router.make (1) diff --git a/examples/tutorial/step_4/hello/src/hello_application.e b/examples/tutorial/step_4/hello/src/hello_application.e index 38d09ced..b2c4d250 100644 --- a/examples/tutorial/step_4/hello/src/hello_application.e +++ b/examples/tutorial/step_4/hello/src/hello_application.e @@ -42,9 +42,9 @@ feature {NONE} -- Initialization feature -- Helper: mapping - map_agent_uri (a_uri: READABLE_STRING_8; a_action: like {WSF_AGENT_URI_HANDLER}.action; rqst_methods: detachable WSF_ROUTER_METHODS) + map_agent_uri (a_uri: READABLE_STRING_8; a_action: like {WSF_URI_AGENT_HANDLER}.action; rqst_methods: detachable WSF_ROUTER_METHODS) do - router.map_with_request_methods (create {WSF_URI_MAPPING}.make (a_uri, create {WSF_AGENT_URI_HANDLER}.make (a_action)), rqst_methods) + router.map_with_request_methods (create {WSF_URI_MAPPING}.make (a_uri, create {WSF_URI_AGENT_HANDLER}.make (a_action)), rqst_methods) end map_uri_template (a_tpl: READABLE_STRING_8; a_handler: WSF_URI_TEMPLATE_HANDLER; rqst_methods: detachable WSF_ROUTER_METHODS) @@ -52,9 +52,9 @@ feature -- Helper: mapping router.map_with_request_methods (create {WSF_URI_TEMPLATE_MAPPING}.make (a_tpl, a_handler), rqst_methods) end - map_agent_uri_template_response (a_tpl: READABLE_STRING_8; a_action: like {WSF_AGENT_URI_TEMPLATE_RESPONSE_HANDLER}.action; rqst_methods: detachable WSF_ROUTER_METHODS) + map_agent_uri_template_response (a_tpl: READABLE_STRING_8; a_action: like {WSF_URI_TEMPLATE_RESPONSE_AGENT_HANDLER}.action; rqst_methods: detachable WSF_ROUTER_METHODS) do - router.map_with_request_methods (create {WSF_URI_TEMPLATE_MAPPING}.make (a_tpl, create {WSF_AGENT_URI_TEMPLATE_RESPONSE_HANDLER}.make (a_action)), rqst_methods) + router.map_with_request_methods (create {WSF_URI_TEMPLATE_MAPPING}.make (a_tpl, create {WSF_URI_TEMPLATE_RESPONSE_AGENT_HANDLER}.make (a_action)), rqst_methods) end feature -- Execution @@ -114,7 +114,7 @@ feature -- Execution res.send (mesg) end - response_user (ctx: WSF_URI_TEMPLATE_HANDLER_CONTEXT; req: WSF_REQUEST): WSF_RESPONSE_MESSAGE + response_user (req: WSF_REQUEST): WSF_RESPONSE_MESSAGE -- Computed response message. local html: WSF_HTML_PAGE_RESPONSE @@ -122,7 +122,7 @@ feature -- Execution s: STRING_8 l_username: STRING_32 do - if attached {WSF_STRING} ctx.path_parameter ("user") as u then + if attached {WSF_STRING} req.path_parameter ("user") as u then l_username := (create {HTML_ENCODER}).general_decoded_string (u.value) if attached {WSF_STRING} req.query_parameter ("op") as l_op diff --git a/examples/tutorial/step_4/hello/src/user_message_handler.e b/examples/tutorial/step_4/hello/src/user_message_handler.e index cbc95f17..12a6a0e8 100644 --- a/examples/tutorial/step_4/hello/src/user_message_handler.e +++ b/examples/tutorial/step_4/hello/src/user_message_handler.e @@ -13,16 +13,16 @@ inherit feature -- Access - response (ctx: WSF_URI_TEMPLATE_HANDLER_CONTEXT; req: WSF_REQUEST): WSF_RESPONSE_MESSAGE + response (req: WSF_REQUEST): WSF_RESPONSE_MESSAGE local l_username: READABLE_STRING_32 do - if attached {WSF_STRING} ctx.path_parameter ("user") as u then + if attached {WSF_STRING} req.path_parameter ("user") as u then l_username := html_decoded_string (u.value) if req.is_request_method ("GET") then - Result := user_message_get (l_username, ctx, req) + Result := user_message_get (l_username, req) elseif req.is_request_method ("POST") then - Result := user_message_response_post (l_username, ctx, req) + Result := user_message_response_post (l_username, req) else Result := unsupported_method_response (req) end @@ -46,7 +46,7 @@ feature -- Access end - user_message_get (u: READABLE_STRING_32; ctx: WSF_URI_TEMPLATE_HANDLER_CONTEXT; req: WSF_REQUEST): WSF_HTML_PAGE_RESPONSE + user_message_get (u: READABLE_STRING_32; req: WSF_REQUEST): WSF_HTML_PAGE_RESPONSE local s: STRING_8 do @@ -59,7 +59,7 @@ feature -- Access Result.set_body (s) end - user_message_response_post (u: READABLE_STRING_32; ctx: WSF_URI_TEMPLATE_HANDLER_CONTEXT; req: WSF_REQUEST): WSF_HTML_PAGE_RESPONSE + user_message_response_post (u: READABLE_STRING_32; req: WSF_REQUEST): WSF_HTML_PAGE_RESPONSE local s: STRING_8 do diff --git a/examples/upload_image/src/image_uploader.e b/examples/upload_image/src/image_uploader.e index 876870e7..e60602d8 100644 --- a/examples/upload_image/src/image_uploader.e +++ b/examples/upload_image/src/image_uploader.e @@ -91,7 +91,7 @@ feature -- Execution res.redirect_now_with_content (req.script_url ("/"), uri + ": not found.%NRedirection to " + req.script_url ("/"), "text/html") end - execute_upload (ctx: WSF_URI_TEMPLATE_HANDLER_CONTEXT; req: WSF_REQUEST; res: WSF_RESPONSE) + execute_upload (req: WSF_REQUEST; res: WSF_RESPONSE) -- Upload page is requested, either GET or POST -- On GET display the web form to upload file, by passing ?nb=5 you can upload 5 images -- On POST display the uploaded files @@ -110,14 +110,14 @@ feature -- Execution page.set_body (l_body) l_body.append ("

EWF: Upload image file

%N") l_body.append ("
%N") - if attached ctx.string_query_parameter ("nb") as p_nb and then p_nb.is_integer then - n := p_nb.to_integer + if attached {WSF_STRING} req.query_parameter ("nb") as p_nb and then p_nb.is_integer then + n := p_nb.integer_value else n := 1 end - if attached ctx.string_query_parameter ("demo") as p_demo then + if attached {WSF_STRING} req.query_parameter ("demo") as p_demo then create fn.make_from_string (document_root) - fn.set_file_name (p_demo.string) + fn.set_file_name (p_demo.value) l_body.append ("File:
%N") end diff --git a/library/server/wsf/router/mapping/uri_template_with_context/wsf_agent_uri_template_with_context_handler.e b/library/server/wsf/router/context/wsf_agent_context_handler.e similarity index 54% rename from library/server/wsf/router/mapping/uri_template_with_context/wsf_agent_uri_template_with_context_handler.e rename to library/server/wsf/router/context/wsf_agent_context_handler.e index b7051f80..06923b5a 100644 --- a/library/server/wsf/router/mapping/uri_template_with_context/wsf_agent_uri_template_with_context_handler.e +++ b/library/server/wsf/router/context/wsf_agent_context_handler.e @@ -1,30 +1,29 @@ note - description: "Summary description for {WSF_AGENT_URI_TEMPLATE_WITH_CONTEXT_HANDLER}." + description: "Summary description for {WSF_AGENT_CONTEXT_HANDLER}." author: "" date: "$Date$" revision: "$Revision$" -class - WSF_AGENT_URI_TEMPLATE_WITH_CONTEXT_HANDLER +deferred class + WSF_AGENT_CONTEXT_HANDLER [C -> WSF_HANDLER_CONTEXT create make end] inherit - WSF_URI_TEMPLATE_WITH_CONTEXT_HANDLER + WSF_CONTEXT_HANDLER [C] -create - make +feature -- Change -feature {NONE} -- Initialization - - make (a_action: like action) + set_action (a_action: like action) do action := a_action end - action: PROCEDURE [ANY, TUPLE [context: WSF_URI_TEMPLATE_HANDLER_CONTEXT; request: WSF_REQUEST; response: WSF_RESPONSE]] +feature -- Access + + action: PROCEDURE [ANY, TUPLE [context: C; request: WSF_REQUEST; response: WSF_RESPONSE]] feature -- Execution - execute (ctx: WSF_URI_TEMPLATE_HANDLER_CONTEXT; req: WSF_REQUEST; res: WSF_RESPONSE) + execute (ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE) do action.call ([ctx, req, res]) end diff --git a/library/server/wsf/router/context/wsf_context_handler.e b/library/server/wsf/router/context/wsf_context_handler.e new file mode 100644 index 00000000..fcc117fb --- /dev/null +++ b/library/server/wsf/router/context/wsf_context_handler.e @@ -0,0 +1,36 @@ +note + description: "Summary description for {WSF_CONTEXT_HANDLER}." + author: "" + date: "$Date$" + revision: "$Revision$" + +deferred class + WSF_CONTEXT_HANDLER [C -> WSF_HANDLER_CONTEXT create make end] + +inherit + WSF_HANDLER + +feature -- Execution + + execute (ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE) + deferred + end + +feature {WSF_ROUTER} -- Mapping + + new_mapping (a_resource: READABLE_STRING_8): WSF_ROUTER_CONTEXT_MAPPING [C] + -- New mapping built with Current as handler + deferred + end + +note + copyright: "2011-2012, Jocelyn Fiat, Javier Velilla, 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 diff --git a/library/server/wsf/router/context/wsf_handler_context.e b/library/server/wsf/router/context/wsf_handler_context.e index 4e060916..6d1bf1d9 100644 --- a/library/server/wsf/router/context/wsf_handler_context.e +++ b/library/server/wsf/router/context/wsf_handler_context.e @@ -8,233 +8,27 @@ note date: "$Date$" revision: "$Revision$" -deferred class +class WSF_HANDLER_CONTEXT -inherit - ANY +create + make - WSF_FORMAT_UTILITY - export - {NONE} all +feature {NONE} -- Initialization + + make (req: like request; map: like mapping) + do + request := req + mapping := map end - DEBUG_OUTPUT - feature -- Access request: WSF_REQUEST -- Associated request - path: READABLE_STRING_8 - -- Associated path - -feature -- Request data - - apply (req: WSF_REQUEST) - -- Apply current data to request `req' - --| mainly to fill {WSF_REQUEST}.path_parameters - deferred - end - - revert (req: WSF_REQUEST) - -- Revert potential previous `apply' for request `req' - --| mainly to restore previous {WSF_REQUEST}.path_parameters - deferred - end - -feature -- Url Query - - script_absolute_url (a_path: STRING): STRING - -- Absolute Url for the script if any, extended by `a_path' - do - Result := request.absolute_script_url (a_path) - end - - script_url (a_path: STRING): STRING - -- Url relative to script name if any, extended by `a_path' - require - a_path_attached: a_path /= Void - do - Result := request.script_url (a_path) - end - - url (args: detachable STRING; abs: BOOLEAN): STRING - -- Associated url based on `path' and `args' - -- if `abs' then return absolute url - local - s,t: detachable STRING - do - s := args - if s /= Void and then s.count > 0 then - create t.make_from_string (path) - if s[1] /= '/' and t[t.count] /= '/' then - t.append_character ('/') - t.append (s) - else - t.append (s) - end - s := t - else - s := path - end - if abs then - Result := script_absolute_url (s) - else - Result := script_url (s) - end - ensure - result_attached: Result /= Void - end - -feature -- Query - - request_accepted_content_type (a_supported_content_types: detachable ARRAY [READABLE_STRING_8]): detachable READABLE_STRING_8 - -- Accepted content-type for the request, among the supported content types `a_supported_content_types' - local - s: detachable READABLE_STRING_8 - i,n: INTEGER - do - if - attached accepted_content_types (request) as l_accept_lst and then - not l_accept_lst.is_empty - then - from - l_accept_lst.start - until - l_accept_lst.after or Result /= Void - loop - s := l_accept_lst.item - if a_supported_content_types /= Void then - from - i := a_supported_content_types.lower - n := a_supported_content_types.upper - until - i > n or Result /= Void - loop - if a_supported_content_types [i].same_string (s) then - Result := s - end - i := i + 1 - end - else - Result := s - end - l_accept_lst.forth - end - end - end - -feature -- Item - - item (a_name: READABLE_STRING_GENERAL): detachable WSF_VALUE - -- Variable value for parameter or variable `a_name' - -- See `{WSF_REQUEST}.item(s)' - deferred - end - -feature -- Parameter - - string_item (a_name: READABLE_STRING_GENERAL): detachable READABLE_STRING_32 - -- String value for any variable of parameter `a_name' if relevant. - do - Result := string_from (item (a_name)) - end - - string_array_item (a_name: READABLE_STRING_GENERAL): detachable ARRAY [READABLE_STRING_32] - -- Array of string values for query parameter `a_name' if relevant. - do - Result := string_array_for (a_name, agent string_item) - end - -feature -- Query parameter - - query_parameter (a_name: READABLE_STRING_GENERAL): detachable WSF_VALUE - -- Parameter value for query variable `a_name' - --| i.e after the ? character - do - Result := request.query_parameter (a_name) - end - - string_query_parameter (a_name: READABLE_STRING_GENERAL): detachable READABLE_STRING_32 - -- String value for query parameter `a_name' if relevant. - do - Result := string_from (query_parameter (a_name)) - end - - string_array_query_parameter (a_name: READABLE_STRING_GENERAL): detachable ARRAY [READABLE_STRING_32] - -- Array of string values for query parameter `a_name' if relevant. - do - Result := string_array_for (a_name, agent string_query_parameter) - end - - is_integer_query_parameter (a_name: READABLE_STRING_GENERAL): BOOLEAN - -- Is query parameter related to `a_name' an integer value? - do - Result := attached string_query_parameter (a_name) as s and then s.is_integer - end - - integer_query_parameter (a_name: READABLE_STRING_GENERAL): INTEGER - -- Integer value for query parameter `a_name' if relevant. - require - is_integer_query_parameter: is_integer_query_parameter (a_name) - do - Result := integer_from (query_parameter (a_name)) - end - -feature -- Convertion - - string_from (a_value: detachable WSF_VALUE): detachable READABLE_STRING_32 - -- String value from `a_value' if relevant. - do - if attached {WSF_STRING} a_value as val then - Result := val.value - end - end - - integer_from (a_value: detachable WSF_VALUE): INTEGER - -- String value from `a_value' if relevant. - do - if attached string_from (a_value) as val then - if val.is_integer then - Result := val.to_integer - end - end - end - -feature {NONE} -- Implementation - - string_array_for (a_name: READABLE_STRING_GENERAL; a_item_fct: FUNCTION [ANY, TUPLE [READABLE_STRING_GENERAL], detachable READABLE_STRING_32]): detachable ARRAY [READABLE_STRING_32] - -- Array of string values for query parameter `a_name' if relevant. - local - i: INTEGER - n: INTEGER - do - from - i := 1 - n := 1 - create Result.make_filled ("", 1, 5) - until - i = 0 - loop - if attached a_item_fct.item ([a_name + "[" + i.out + "]"]) as v then - Result.force (v, n) - n := n + 1 - i := i + 1 - else - i := 0 -- Exit - end - end - Result.keep_head (n - 1) - end - -feature -- Status report - - debug_output: STRING - -- String that should be displayed in debugger to represent `Current'. - do - Result := path - end + mapping: WSF_ROUTER_MAPPING + -- Associated mapping ;note copyright: "2011-2012, Jocelyn Fiat, Javier Velilla, Eiffel Software and others" diff --git a/library/server/wsf/router/context/wsf_router_context_mapping.e b/library/server/wsf/router/context/wsf_router_context_mapping.e new file mode 100644 index 00000000..7dcae158 --- /dev/null +++ b/library/server/wsf/router/context/wsf_router_context_mapping.e @@ -0,0 +1,30 @@ +note + description: "Summary description for {WSF_ROUTER_CONTEXT_MAPPING}." + author: "" + date: "$Date$" + revision: "$Revision$" + +deferred class + WSF_ROUTER_CONTEXT_MAPPING [C -> WSF_HANDLER_CONTEXT create make end] + +inherit + WSF_ROUTER_MAPPING + +feature -- Access + + handler: WSF_CONTEXT_HANDLER [C] + -- Handler associated with Current mapping. + deferred + end + +note + copyright: "2011-2012, Jocelyn Fiat, Javier Velilla, 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 diff --git a/library/server/wsf/router/mapping/uri_template_with_context/wsf_uri_template_with_context_handler_context.e b/library/server/wsf/router/mapping/uri_template_with_context/wsf_uri_template_with_context_handler_context.e deleted file mode 100644 index 7e9ad4f5..00000000 --- a/library/server/wsf/router/mapping/uri_template_with_context/wsf_uri_template_with_context_handler_context.e +++ /dev/null @@ -1,137 +0,0 @@ -note - description: "[ - Context for the handler execution - - The associated context {WSF_URI_TEMPLATE_HANDLER_CONTEXT} add information about the matched map - - uri_template : the associated URI_TEMPLATE - - uri_template_match : the matching result providing path variables - - additional path_parameter (..) and related queries - - In addition to what WSF_HANDLER_CONTEXT already provides, i.e: - - request: WSF_REQUEST -- Associated request - - path: READABLE_STRING_8 -- Associated path - - ]" - date: "$Date$" - revision: "$Revision$" - -class - WSF_URI_TEMPLATE_HANDLER_CONTEXT - -inherit - WSF_HANDLER_CONTEXT - redefine - item - end - - WSF_REQUEST_PATH_PARAMETERS_SOURCE - -create - make - -feature {NONE} -- Initialization - - make (req: WSF_REQUEST; tpl: URI_TEMPLATE; tpl_res: URI_TEMPLATE_MATCH_RESULT; p: like path) - do - request := req - uri_template := tpl - uri_template_match := tpl_res - path := p - end - -feature -- Access - - uri_template: URI_TEMPLATE - - uri_template_match: URI_TEMPLATE_MATCH_RESULT - -feature -- Environment - - path_parameters_count: INTEGER - do - Result := uri_template_match.path_variables.count - end - - urlencoded_path_parameters: TABLE_ITERABLE [READABLE_STRING_8, READABLE_STRING_8] - -- - do - Result := uri_template_match.path_variables - end - - previous_path_parameters_source: detachable WSF_REQUEST_PATH_PARAMETERS_SOURCE - - apply (req: WSF_REQUEST) - -- - do - previous_path_parameters_source := req.path_parameters_source - req.set_path_parameters_source (Current) - end - - revert (req: WSF_REQUEST) - -- - do - req.set_path_parameters_source (previous_path_parameters_source) - previous_path_parameters_source := Void - end - -feature -- Item - - item (a_name: READABLE_STRING_GENERAL): detachable WSF_VALUE - -- Variable value for parameter or variable `a_name' - -- See `{WSF_REQUEST}.item(s)' - do - Result := path_parameter (a_name) --| Should we handle url-encoded name? - if Result = Void then - Result := request.item (a_name) - end - end - -feature -- Path parameter - - path_parameter (a_name: READABLE_STRING_GENERAL): detachable WSF_VALUE - local - n: READABLE_STRING_8 - do - n := uri_template_match.encoded_name (a_name) - if attached uri_template_match.path_variable (n) as s then - create {WSF_STRING} Result.make (n, s) - end - end - - is_integer_path_parameter (a_name: READABLE_STRING_GENERAL): BOOLEAN - -- Is path parameter related to `a_name' an integer value? - do - Result := attached string_path_parameter (a_name) as s and then s.is_integer - end - - integer_path_parameter (a_name: READABLE_STRING_GENERAL): INTEGER - -- Integer value for path parameter `a_name' if relevant. - require - is_integer_path_parameter: is_integer_path_parameter (a_name) - do - Result := integer_from (path_parameter (a_name)) - end - - string_path_parameter (a_name: READABLE_STRING_GENERAL): detachable READABLE_STRING_32 - -- String value for path parameter `a_name' if relevant. - do - Result := string_from (path_parameter (a_name)) - end - - string_array_path_parameter (a_name: READABLE_STRING_GENERAL): detachable ARRAY [READABLE_STRING_32] - -- Array of string values for path parameter `a_name' if relevant. - do - Result := string_array_for (a_name, agent string_path_parameter) - end - -note - copyright: "2011-2012, Jocelyn Fiat, Javier Velilla, 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 diff --git a/library/server/wsf/router/mapping/starts_with/wsf_starts_with_handler.e b/library/server/wsf/router/support/starts_with/wsf_starts_with_handler.e similarity index 100% rename from library/server/wsf/router/mapping/starts_with/wsf_starts_with_handler.e rename to library/server/wsf/router/support/starts_with/wsf_starts_with_handler.e diff --git a/library/server/wsf/router/mapping/starts_with/wsf_starts_with_mapping.e b/library/server/wsf/router/support/starts_with/wsf_starts_with_mapping.e similarity index 100% rename from library/server/wsf/router/mapping/starts_with/wsf_starts_with_mapping.e rename to library/server/wsf/router/support/starts_with/wsf_starts_with_mapping.e diff --git a/library/server/wsf/router/mapping/uri/wsf_agent_uri_handler.e b/library/server/wsf/router/support/uri/helpers/wsf_uri_agent_handler.e similarity index 89% rename from library/server/wsf/router/mapping/uri/wsf_agent_uri_handler.e rename to library/server/wsf/router/support/uri/helpers/wsf_uri_agent_handler.e index 8fda84fa..f424da42 100644 --- a/library/server/wsf/router/mapping/uri/wsf_agent_uri_handler.e +++ b/library/server/wsf/router/support/uri/helpers/wsf_uri_agent_handler.e @@ -1,11 +1,11 @@ note - description: "Summary description for {WSF_AGENT_HANDLER}." + description: "Summary description for {WSF_URI_AGENT_HANDLER}." author: "" date: "$Date$" revision: "$Revision$" class - WSF_AGENT_URI_HANDLER + WSF_URI_AGENT_HANDLER inherit WSF_URI_HANDLER diff --git a/library/server/wsf/router/mapping/uri/wsf_uri_response_handler.e b/library/server/wsf/router/support/uri/helpers/wsf_uri_response_handler.e similarity index 100% rename from library/server/wsf/router/mapping/uri/wsf_uri_response_handler.e rename to library/server/wsf/router/support/uri/helpers/wsf_uri_response_handler.e diff --git a/library/server/wsf/router/mapping/uri/wsf_uri_routed_service.e b/library/server/wsf/router/support/uri/helpers/wsf_uri_routed_service.e similarity index 95% rename from library/server/wsf/router/mapping/uri/wsf_uri_routed_service.e rename to library/server/wsf/router/support/uri/helpers/wsf_uri_routed_service.e index ccb2fdaa..764e2254 100644 --- a/library/server/wsf/router/mapping/uri/wsf_uri_routed_service.e +++ b/library/server/wsf/router/support/uri/helpers/wsf_uri_routed_service.e @@ -31,7 +31,7 @@ feature -- Mapping helper: uri agent map_uri_agent_with_request_methods (a_uri: READABLE_STRING_8; proc: PROCEDURE [ANY, TUPLE [req: WSF_REQUEST; res: WSF_RESPONSE]]; rqst_methods: detachable WSF_ROUTER_METHODS) do - map_uri_with_request_methods (a_uri, create {WSF_AGENT_URI_HANDLER}.make (proc), rqst_methods) + map_uri_with_request_methods (a_uri, create {WSF_URI_AGENT_HANDLER}.make (proc), rqst_methods) end note diff --git a/library/server/wsf/router/mapping/uri/wsf_uri_handler.e b/library/server/wsf/router/support/uri/wsf_uri_handler.e similarity index 100% rename from library/server/wsf/router/mapping/uri/wsf_uri_handler.e rename to library/server/wsf/router/support/uri/wsf_uri_handler.e diff --git a/library/server/wsf/router/mapping/uri/wsf_uri_mapping.e b/library/server/wsf/router/support/uri/wsf_uri_mapping.e similarity index 100% rename from library/server/wsf/router/mapping/uri/wsf_uri_mapping.e rename to library/server/wsf/router/support/uri/wsf_uri_mapping.e diff --git a/library/server/wsf/router/mapping/uri_template/wsf_agent_uri_template_handler.e b/library/server/wsf/router/support/uri_template/helpers/wsf_uri_template_agent_handler.e similarity index 89% rename from library/server/wsf/router/mapping/uri_template/wsf_agent_uri_template_handler.e rename to library/server/wsf/router/support/uri_template/helpers/wsf_uri_template_agent_handler.e index e41e546a..9cfadd68 100644 --- a/library/server/wsf/router/mapping/uri_template/wsf_agent_uri_template_handler.e +++ b/library/server/wsf/router/support/uri_template/helpers/wsf_uri_template_agent_handler.e @@ -1,11 +1,11 @@ note - description: "Summary description for {WSF_AGENT_URI_TEMPLATE_HANDLER}." + description: "Summary description for {WSF_URI_TEMPLATE_AGENT_HANDLER}." author: "" date: "$Date$" revision: "$Revision$" class - WSF_AGENT_URI_TEMPLATE_HANDLER + WSF_URI_TEMPLATE_AGENT_HANDLER inherit WSF_URI_TEMPLATE_HANDLER diff --git a/library/server/wsf/router/mapping/uri/wsf_agent_uri_template_response_handler.e b/library/server/wsf/router/support/uri_template/helpers/wsf_uri_template_response_agent_handler.e similarity index 86% rename from library/server/wsf/router/mapping/uri/wsf_agent_uri_template_response_handler.e rename to library/server/wsf/router/support/uri_template/helpers/wsf_uri_template_response_agent_handler.e index 5909cb30..bd9ed2e7 100644 --- a/library/server/wsf/router/mapping/uri/wsf_agent_uri_template_response_handler.e +++ b/library/server/wsf/router/support/uri_template/helpers/wsf_uri_template_response_agent_handler.e @@ -1,11 +1,11 @@ note - description: "Summary description for {WSF_AGENT_URI_TEMPLATE_RESPONSE_HANDLER}." + description: "Summary description for {WSF_URI_TEMPLATE_RESPONSE_AGENT_HANDLER}." author: "" date: "$Date$" revision: "$Revision$" class - WSF_AGENT_URI_TEMPLATE_RESPONSE_HANDLER + WSF_URI_TEMPLATE_RESPONSE_AGENT_HANDLER inherit WSF_URI_TEMPLATE_RESPONSE_HANDLER diff --git a/library/server/wsf/router/mapping/uri/wsf_uri_template_response_handler.e b/library/server/wsf/router/support/uri_template/helpers/wsf_uri_template_response_handler.e similarity index 100% rename from library/server/wsf/router/mapping/uri/wsf_uri_template_response_handler.e rename to library/server/wsf/router/support/uri_template/helpers/wsf_uri_template_response_handler.e diff --git a/library/server/wsf/router/mapping/uri_template/wsf_uri_template_routed_service.e b/library/server/wsf/router/support/uri_template/helpers/wsf_uri_template_routed_service.e similarity index 92% rename from library/server/wsf/router/mapping/uri_template/wsf_uri_template_routed_service.e rename to library/server/wsf/router/support/uri_template/helpers/wsf_uri_template_routed_service.e index 5b607a9f..f740e5a2 100644 --- a/library/server/wsf/router/mapping/uri_template/wsf_uri_template_routed_service.e +++ b/library/server/wsf/router/support/uri_template/helpers/wsf_uri_template_routed_service.e @@ -31,7 +31,7 @@ feature -- Mapping helper: uri agent map_uri_template_agent_with_request_methods (a_tpl: READABLE_STRING_8; proc: PROCEDURE [ANY, TUPLE [req: WSF_REQUEST; res: WSF_RESPONSE]]; rqst_methods: detachable WSF_ROUTER_METHODS) do - map_uri_template_with_request_methods (a_tpl, create {WSF_AGENT_URI_TEMPLATE_HANDLER}.make (proc), rqst_methods) + map_uri_template_with_request_methods (a_tpl, create {WSF_URI_TEMPLATE_AGENT_HANDLER}.make (proc), rqst_methods) end note diff --git a/library/server/wsf/router/mapping/uri_template/wsf_uri_template_routing_handler.e b/library/server/wsf/router/support/uri_template/helpers/wsf_uri_template_routing_handler.e similarity index 100% rename from library/server/wsf/router/mapping/uri_template/wsf_uri_template_routing_handler.e rename to library/server/wsf/router/support/uri_template/helpers/wsf_uri_template_routing_handler.e diff --git a/library/server/wsf/router/mapping/uri_template/wsf_uri_template_handler.e b/library/server/wsf/router/support/uri_template/wsf_uri_template_handler.e similarity index 100% rename from library/server/wsf/router/mapping/uri_template/wsf_uri_template_handler.e rename to library/server/wsf/router/support/uri_template/wsf_uri_template_handler.e diff --git a/library/server/wsf/router/mapping/uri_template/wsf_uri_template_mapping.e b/library/server/wsf/router/support/uri_template/wsf_uri_template_mapping.e similarity index 100% rename from library/server/wsf/router/mapping/uri_template/wsf_uri_template_mapping.e rename to library/server/wsf/router/support/uri_template/wsf_uri_template_mapping.e diff --git a/library/server/wsf/router/support/uri_template_with_context/helpers/wsf_uri_template_agent_context_handler.e b/library/server/wsf/router/support/uri_template_with_context/helpers/wsf_uri_template_agent_context_handler.e new file mode 100644 index 00000000..c6e9dec4 --- /dev/null +++ b/library/server/wsf/router/support/uri_template_with_context/helpers/wsf_uri_template_agent_context_handler.e @@ -0,0 +1,31 @@ +note + description: "Summary description for {WSF_URI_TEMPLATE_AGENT_CONTEXT_HANDLER}." + author: "" + date: "$Date$" + revision: "$Revision$" + +class + WSF_URI_TEMPLATE_AGENT_CONTEXT_HANDLER [C -> WSF_HANDLER_CONTEXT create make end] + +inherit + WSF_URI_TEMPLATE_CONTEXT_HANDLER [C] + + WSF_AGENT_CONTEXT_HANDLER [C] + rename + set_action as make + end + +create + make + +note + copyright: "2011-2012, Jocelyn Fiat, Javier Velilla, 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 diff --git a/library/server/wsf/router/mapping/uri_template_with_context/wsf_uri_template_with_context_routed_service.e b/library/server/wsf/router/support/uri_template_with_context/helpers/wsf_uri_template_context_routed_service.e similarity index 53% rename from library/server/wsf/router/mapping/uri_template_with_context/wsf_uri_template_with_context_routed_service.e rename to library/server/wsf/router/support/uri_template_with_context/helpers/wsf_uri_template_context_routed_service.e index 8b92556a..5c7abe90 100644 --- a/library/server/wsf/router/mapping/uri_template_with_context/wsf_uri_template_with_context_routed_service.e +++ b/library/server/wsf/router/support/uri_template_with_context/helpers/wsf_uri_template_context_routed_service.e @@ -1,37 +1,37 @@ note - description: "Summary description for {WSF_URI_TEMPLATE_WITH_CONTEXT_ROUTED_SERVICE}." + description: "Summary description for {WSF_URI_TEMPLATE_CONTEXT_ROUTED_SERVICE}." author: "" date: "$Date$" revision: "$Revision$" deferred class - WSF_URI_TEMPLATE_WITH_CONTEXT_ROUTED_SERVICE + WSF_URI_TEMPLATE_CONTEXT_ROUTED_SERVICE [C -> WSF_HANDLER_CONTEXT create make end] inherit WSF_ROUTED_SERVICE feature -- Mapping helper: uri - map_uri_template (a_tpl: STRING; h: WSF_URI_TEMPLATE_WITH_CONTEXT_HANDLER) + map_uri_template (a_tpl: STRING; h: WSF_URI_TEMPLATE_CONTEXT_HANDLER [C]) do map_uri_template_with_request_methods (a_tpl, h, Void) end - map_uri_template_with_request_methods (a_tpl: READABLE_STRING_8; h: WSF_URI_TEMPLATE_WITH_CONTEXT_HANDLER; rqst_methods: detachable WSF_ROUTER_METHODS) + map_uri_template_with_request_methods (a_tpl: READABLE_STRING_8; h: WSF_URI_TEMPLATE_CONTEXT_HANDLER [C]; rqst_methods: detachable WSF_ROUTER_METHODS) do - router.map_with_request_methods (create {WSF_URI_TEMPLATE_WITH_CONTEXT_MAPPING}.make (a_tpl, h), rqst_methods) + router.map_with_request_methods (create {WSF_URI_TEMPLATE_CONTEXT_MAPPING [C]}.make (a_tpl, h), rqst_methods) end feature -- Mapping helper: uri agent - map_uri_template_agent (a_tpl: READABLE_STRING_8; proc: PROCEDURE [ANY, TUPLE [ctx: WSF_URI_TEMPLATE_HANDLER_CONTEXT; req: WSF_REQUEST; res: WSF_RESPONSE]]) + map_uri_template_agent (a_tpl: READABLE_STRING_8; proc: PROCEDURE [ANY, TUPLE [ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE]]) do map_uri_template_agent_with_request_methods (a_tpl, proc, Void) end - map_uri_template_agent_with_request_methods (a_tpl: READABLE_STRING_8; proc: PROCEDURE [ANY, TUPLE [ctx: WSF_URI_TEMPLATE_HANDLER_CONTEXT; req: WSF_REQUEST; res: WSF_RESPONSE]]; rqst_methods: detachable WSF_ROUTER_METHODS) + map_uri_template_agent_with_request_methods (a_tpl: READABLE_STRING_8; proc: PROCEDURE [ANY, TUPLE [ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE]]; rqst_methods: detachable WSF_ROUTER_METHODS) do - map_uri_template_with_request_methods (a_tpl, create {WSF_AGENT_URI_TEMPLATE_WITH_CONTEXT_HANDLER}.make (proc), rqst_methods) + map_uri_template_with_request_methods (a_tpl, create {WSF_URI_TEMPLATE_AGENT_CONTEXT_HANDLER [C] }.make (proc), rqst_methods) end note diff --git a/library/server/wsf/router/mapping/uri_template_with_context/wsf_uri_template_with_context_routing_handler.e b/library/server/wsf/router/support/uri_template_with_context/helpers/wsf_uri_template_routing_context_handler.e similarity index 59% rename from library/server/wsf/router/mapping/uri_template_with_context/wsf_uri_template_with_context_routing_handler.e rename to library/server/wsf/router/support/uri_template_with_context/helpers/wsf_uri_template_routing_context_handler.e index 09db9834..c3e5be6c 100644 --- a/library/server/wsf/router/mapping/uri_template_with_context/wsf_uri_template_with_context_routing_handler.e +++ b/library/server/wsf/router/support/uri_template_with_context/helpers/wsf_uri_template_routing_context_handler.e @@ -1,18 +1,18 @@ note - description: "Summary description for {WSF_URI_TEMPLATE_WITH_CONTEXT_ROUTING_HANDLER}." + description: "Summary description for {WSF_URI_TEMPLATE_ROUTING_CONTEXT_HANDLER}." author: "" date: "$Date$" revision: "$Revision$" class - WSF_URI_TEMPLATE_WITH_CONTEXT_ROUTING_HANDLER + WSF_URI_TEMPLATE_ROUTING_CONTEXT_HANDLER [C -> WSF_HANDLER_CONTEXT create make end] inherit WSF_ROUTING_HANDLER - WSF_URI_TEMPLATE_WITH_CONTEXT_HANDLER + WSF_URI_TEMPLATE_CONTEXT_HANDLER [C] rename - execute as uri_template_xecute + execute as uri_template_execute end create @@ -21,7 +21,9 @@ create feature -- Execution - uri_template_xecute (ctx: WSF_URI_TEMPLATE_HANDLER_CONTEXT; req: WSF_REQUEST; res: WSF_RESPONSE) + uri_template_execute (ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE) + -- + --| For such routing handler, the previous context is lost do execute (req, res) end diff --git a/library/server/wsf/router/mapping/uri_template_with_context/wsf_uri_template_with_context_handler.e b/library/server/wsf/router/support/uri_template_with_context/wsf_uri_template_context_handler.e similarity index 70% rename from library/server/wsf/router/mapping/uri_template_with_context/wsf_uri_template_with_context_handler.e rename to library/server/wsf/router/support/uri_template_with_context/wsf_uri_template_context_handler.e index 1f1fde78..f430ab6d 100644 --- a/library/server/wsf/router/mapping/uri_template_with_context/wsf_uri_template_with_context_handler.e +++ b/library/server/wsf/router/support/uri_template_with_context/wsf_uri_template_context_handler.e @@ -5,20 +5,14 @@ note revision: "$Revision$" deferred class - WSF_URI_TEMPLATE_WITH_CONTEXT_HANDLER + WSF_URI_TEMPLATE_CONTEXT_HANDLER [C -> WSF_HANDLER_CONTEXT create make end] inherit - WSF_HANDLER - -feature -- Execution - - execute (ctx: WSF_URI_TEMPLATE_HANDLER_CONTEXT; req: WSF_REQUEST; res: WSF_RESPONSE) - deferred - end + WSF_CONTEXT_HANDLER [C] feature {WSF_ROUTER} -- Mapping - new_mapping (a_tpl: READABLE_STRING_8): WSF_URI_TEMPLATE_WITH_CONTEXT_MAPPING + new_mapping (a_tpl: READABLE_STRING_8): WSF_URI_TEMPLATE_CONTEXT_MAPPING [C] do create Result.make (a_tpl, Current) end diff --git a/library/server/wsf/router/mapping/uri_template_with_context/wsf_uri_template_with_context_mapping.e b/library/server/wsf/router/support/uri_template_with_context/wsf_uri_template_context_mapping.e similarity index 78% rename from library/server/wsf/router/mapping/uri_template_with_context/wsf_uri_template_with_context_mapping.e rename to library/server/wsf/router/support/uri_template_with_context/wsf_uri_template_context_mapping.e index e4c34090..c82a6ed0 100644 --- a/library/server/wsf/router/mapping/uri_template_with_context/wsf_uri_template_with_context_mapping.e +++ b/library/server/wsf/router/support/uri_template_with_context/wsf_uri_template_context_mapping.e @@ -1,14 +1,14 @@ note - description: "Summary description for {EWF_ROUTER_URI_TEMPLATE_WITH_CONTEXT_PATH}." + description: "Summary description for {WSF_URI_TEMPLATE_CONTEXT_MAPPING}." author: "" date: "$Date$" revision: "$Revision$" class - WSF_URI_TEMPLATE_WITH_CONTEXT_MAPPING + WSF_URI_TEMPLATE_CONTEXT_MAPPING [C -> WSF_HANDLER_CONTEXT create make end] inherit - WSF_ROUTER_MAPPING + WSF_ROUTER_CONTEXT_MAPPING [C] create make, @@ -29,7 +29,7 @@ feature {NONE} -- Initialization feature -- Access - handler: WSF_URI_TEMPLATE_WITH_CONTEXT_HANDLER + handler: WSF_URI_TEMPLATE_CONTEXT_HANDLER [C] template: URI_TEMPLATE @@ -46,26 +46,28 @@ feature -- Status local tpl: URI_TEMPLATE p: READABLE_STRING_32 - ctx: detachable WSF_URI_TEMPLATE_HANDLER_CONTEXT + ctx: detachable C + new_src: detachable WSF_REQUEST_PATH_PARAMETERS_PROVIDER do p := path_from_request (req) tpl := based_uri_template (template, a_router) if attached tpl.match (p) as tpl_res then Result := handler - create ctx.make (req, tpl, tpl_res, path_from_request (req)) + create ctx.make (req, Current) a_router.execute_before (Current) --| Applied the context to the request --| in practice, this will fill the {WSF_REQUEST}.path_parameters - ctx.apply (req) + create new_src.make (tpl_res.path_variables.count, tpl_res.path_variables) + new_src.apply (req) handler.execute (ctx, req, res) --| Revert {WSF_REQUEST}.path_parameters_source to former value --| In case the request object passed by other handler that alters its values. - ctx.revert (req) + new_src.revert (req) a_router.execute_after (Current) end rescue - if ctx /= Void then - ctx.revert (req) + if new_src /= Void then + new_src.revert (req) end end diff --git a/library/server/wsf/router/wsf_handler.e b/library/server/wsf/router/wsf_handler.e index e39c89d1..53bd564c 100644 --- a/library/server/wsf/router/wsf_handler.e +++ b/library/server/wsf/router/wsf_handler.e @@ -24,7 +24,7 @@ feature {WSF_ROUTER} -- Mapping Result /= Void and then Result.handler = Current end - on_mapped (a_mapping: WSF_ROUTER_MAPPING; a_rqst_methods: detachable WSF_ROUTER_METHODS) + on_mapped (a_mapping: like new_mapping; a_rqst_methods: detachable WSF_ROUTER_METHODS) -- Callback called when a router map a route to Current handler do end diff --git a/library/server/wsf/router/service/wsf_routed_service.e b/library/server/wsf/router/wsf_routed_service.e similarity index 77% rename from library/server/wsf/router/service/wsf_routed_service.e rename to library/server/wsf/router/wsf_routed_service.e index 11c09ba1..afc41ebb 100644 --- a/library/server/wsf/router/service/wsf_routed_service.e +++ b/library/server/wsf/router/wsf_routed_service.e @@ -10,6 +10,7 @@ deferred class feature -- Initialization initialize_router + -- Initialize router do create_router setup_router @@ -17,6 +18,7 @@ feature -- Initialization create_router -- Create `router' + --| could be redefine to initialize with proper capacity do create router.make (10) ensure @@ -33,6 +35,8 @@ feature -- Initialization feature -- Execution execute (req: WSF_REQUEST; res: WSF_RESPONSE) + -- Dispatch the request + -- and if you dispatch is found, execute the default procedure `execute_default' do if attached router.dispatch_and_return_handler (req, res) as p then -- executed @@ -42,12 +46,15 @@ feature -- Execution end execute_default (req: WSF_REQUEST; res: WSF_RESPONSE) + -- Default procedure deferred end feature -- Access router: WSF_ROUTER + -- Router used to dispatch the request according to the WSF_REQUEST object + -- and associated request methods ;note copyright: "2011-2012, Jocelyn Fiat, Javier Velilla, Eiffel Software and others" diff --git a/library/server/wsf_extension/src/wsf_request_utility.e b/library/server/wsf_extension/src/wsf_request_utility.e new file mode 100644 index 00000000..88566954 --- /dev/null +++ b/library/server/wsf_extension/src/wsf_request_utility.e @@ -0,0 +1,112 @@ +note + description: "Summary description for {WSF_REQUEST_UTILITY}." + author: "" + date: "$Date$" + revision: "$Revision$" + +class + WSF_REQUEST_UTILITY + +inherit + ANY + + WSF_FORMAT_UTILITY + export + {NONE} all + end + + WSF_VALUE_UTILITY + +feature -- Url Query + + script_absolute_url (req: WSF_REQUEST; a_path: STRING): STRING + -- Absolute Url for the script if any, extended by `a_path' + do + Result := req.absolute_script_url (a_path) + end + + script_url (req: WSF_REQUEST; a_path: STRING): STRING + -- Url relative to script name if any, extended by `a_path' + require + a_path_attached: a_path /= Void + do + Result := req.script_url (a_path) + end + + url (req: WSF_REQUEST; a_path: STRING; args: detachable STRING; abs: BOOLEAN): STRING + -- Associated url based on `path' and `args' + -- if `abs' then return absolute url + local + s,t: detachable STRING + do + s := args + if s /= Void and then s.count > 0 then + create t.make_from_string (a_path) + if s[1] /= '/' and t[t.count] /= '/' then + t.append_character ('/') + t.append (s) + else + t.append (s) + end + s := t + else + s := a_path + end + if abs then + Result := script_absolute_url (req, s) + else + Result := script_url (req, s) + end + ensure + result_attached: Result /= Void + end + +feature -- Query + + request_accepted_content_type (req: WSF_REQUEST; a_supported_content_types: detachable ARRAY [READABLE_STRING_8]): detachable READABLE_STRING_8 + -- Accepted content-type for the request, among the supported content types `a_supported_content_types' + local + s: detachable READABLE_STRING_8 + i,n: INTEGER + do + if + attached accepted_content_types (req) as l_accept_lst and then + not l_accept_lst.is_empty + then + from + l_accept_lst.start + until + l_accept_lst.after or Result /= Void + loop + s := l_accept_lst.item + if a_supported_content_types /= Void then + from + i := a_supported_content_types.lower + n := a_supported_content_types.upper + until + i > n or Result /= Void + loop + if a_supported_content_types [i].same_string (s) then + Result := s + end + i := i + 1 + end + else + Result := s + end + l_accept_lst.forth + end + end + end + +note + copyright: "2011-2012, Jocelyn Fiat, Javier Velilla, 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 diff --git a/library/server/wsf_extension/src/wsf_value_utility.e b/library/server/wsf_extension/src/wsf_value_utility.e new file mode 100644 index 00000000..9e5eb188 --- /dev/null +++ b/library/server/wsf_extension/src/wsf_value_utility.e @@ -0,0 +1,156 @@ +note + description: "Summary description for {WSF_VALUE_UTILITY}." + author: "" + date: "$Date$" + revision: "$Revision$" + +class + WSF_VALUE_UTILITY + +feature -- Parameter + + item (req: WSF_REQUEST; a_name: READABLE_STRING_GENERAL): detachable WSF_VALUE + -- Variable value for parameter or variable `a_name' + -- See `{WSF_REQUEST}.item(s)' + do + Result := req.item (a_name) + end + + string_item (req: WSF_REQUEST; a_name: READABLE_STRING_GENERAL): detachable READABLE_STRING_32 + -- String value for any variable of parameter `a_name' if relevant. + do + Result := string_from (item (req, a_name)) + end + + string_array_item (req: WSF_REQUEST; a_name: READABLE_STRING_GENERAL): detachable ARRAY [READABLE_STRING_32] + -- Array of string values for query parameter `a_name' if relevant. + do + Result := string_array_for (req, a_name, agent string_item) + end + +feature -- Query parameter + + query_parameter (req: WSF_REQUEST; a_name: READABLE_STRING_GENERAL): detachable WSF_VALUE + -- Parameter value for query variable `a_name' + --| i.e after the ? character + do + Result := req.query_parameter (a_name) + end + + string_query_parameter (req: WSF_REQUEST; a_name: READABLE_STRING_GENERAL): detachable READABLE_STRING_32 + -- String value for query parameter `a_name' if relevant. + do + Result := string_from (query_parameter (req, a_name)) + end + + string_array_query_parameter (req: WSF_REQUEST; a_name: READABLE_STRING_GENERAL): detachable ARRAY [READABLE_STRING_32] + -- Array of string values for query parameter `a_name' if relevant. + do + Result := string_array_for (req, a_name, agent string_query_parameter) + end + + is_integer_query_parameter (req: WSF_REQUEST; a_name: READABLE_STRING_GENERAL): BOOLEAN + -- Is query parameter related to `a_name' an integer value? + do + Result := attached string_query_parameter (req, a_name) as s and then s.is_integer + end + + integer_query_parameter (req: WSF_REQUEST; a_name: READABLE_STRING_GENERAL): INTEGER + -- Integer value for query parameter `a_name' if relevant. + require + is_integer_query_parameter: is_integer_query_parameter (req, a_name) + do + Result := integer_from (query_parameter (req, a_name)) + end + +feature -- Path parameter + + path_parameter (req: WSF_REQUEST; a_name: READABLE_STRING_GENERAL): detachable WSF_VALUE + do + Result := req.path_parameter (a_name) + end + + + string_path_parameter (req: WSF_REQUEST; a_name: READABLE_STRING_GENERAL): detachable READABLE_STRING_32 + -- String value for path parameter `a_name' if relevant. + do + Result := string_from (path_parameter (req, a_name)) + end + + string_array_path_parameter (req: WSF_REQUEST; a_name: READABLE_STRING_GENERAL): detachable ARRAY [READABLE_STRING_32] + -- Array of string values for path parameter `a_name' if relevant. + do + Result := string_array_for (req, a_name, agent string_path_parameter) + end + + is_integer_path_parameter (req: WSF_REQUEST; a_name: READABLE_STRING_GENERAL): BOOLEAN + -- Is path parameter related to `a_name' an integer value? + do + Result := attached string_path_parameter (req, a_name) as s and then s.is_integer + end + + integer_path_parameter (req: WSF_REQUEST; a_name: READABLE_STRING_GENERAL): INTEGER + -- Integer value for path parameter `a_name' if relevant. + require + is_integer_path_parameter: is_integer_path_parameter (req, a_name) + do + Result := integer_from (path_parameter (req, a_name)) + end + +feature -- Convertion + + string_from (a_value: detachable WSF_VALUE): detachable READABLE_STRING_32 + -- String value from `a_value' if relevant. + do + if attached {WSF_STRING} a_value as val then + Result := val.value + end + end + + integer_from (a_value: detachable WSF_VALUE): INTEGER + -- String value from `a_value' if relevant. + do + if attached string_from (a_value) as val then + if val.is_integer then + Result := val.to_integer + end + end + end + +feature {NONE} -- Implementation + + string_array_for (req: WSF_REQUEST; a_name: READABLE_STRING_GENERAL; a_item_fct: FUNCTION [ANY, TUPLE [WSF_REQUEST, READABLE_STRING_GENERAL], detachable READABLE_STRING_32]): detachable ARRAY [READABLE_STRING_32] + -- Array of string values for query parameter `a_name' if relevant. + local + i: INTEGER + n: INTEGER + do + from + i := 1 + n := 1 + create Result.make_filled ("", 1, 5) + until + i = 0 + loop + if attached a_item_fct.item ([req, a_name + "[" + i.out + "]"]) as v then + Result.force (v, n) + n := n + 1 + i := i + 1 + else + i := 0 -- Exit + end + end + Result.keep_head (n - 1) + end + +note + copyright: "2011-2012, Jocelyn Fiat, Javier Velilla, 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 From 80c1cc1c0d6da118b9156ecfb0c89874ae5be546 Mon Sep 17 00:00:00 2001 From: Jocelyn Fiat Date: Thu, 27 Sep 2012 16:10:50 +0200 Subject: [PATCH 7/7] Fixed wizard generated code with new router design --- tools/ise_wizard/resources/ewf_application-uri-template.e | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/ise_wizard/resources/ewf_application-uri-template.e b/tools/ise_wizard/resources/ewf_application-uri-template.e index 8a1ecaab..5e99364c 100644 --- a/tools/ise_wizard/resources/ewf_application-uri-template.e +++ b/tools/ise_wizard/resources/ewf_application-uri-template.e @@ -27,7 +27,7 @@ feature {NONE} -- Initialization setup_router do -- Set the router here - router.map_agent ("/hello/{user}", agent execute_hello) + map_uri_template_agent ("/hello/{user}", agent execute_hello) end feature -- Execution @@ -43,7 +43,7 @@ feature -- Execution res.redirect_now_with_content (l_url, "Redirection to " + l_url, "text/html") end - execute_hello (ctx: WSF_URI_TEMPLATE_HANDLER_CONTEXT; req: WSF_REQUEST; res: WSF_RESPONSE) + execute_hello (req: WSF_REQUEST; res: WSF_RESPONSE) -- Computed response message. local mesg: WSF_HTML_PAGE_RESPONSE