From ff57d0ecd429a774f190d81a87707a7b44d0b59c Mon Sep 17 00:00:00 2001 From: Olivier Ligot Date: Wed, 9 Jan 2013 17:34:50 +0100 Subject: [PATCH 01/23] Cross-Origin Resource Sharing initial support Initial support for the Cross-Origin Resource Sharing specification. This allows JavaScript to make requests across domain boundaries. Also reviewed the filter example to get rid of the context and the generic classes (we can actually use {WSF_REQUEST}.execution_variable and {WSF_REQUEST}.set_execution_variable). Links: * How to enable server-side: http://enable-cors.org/server.html * Specification: http://www.w3.org/TR/cors/ * Github: http://developer.github.com/v3/#cross-origin-resource-sharing --- examples/filter/filter-safe.ecf | 25 +++--- .../filter/src/filter/authentication_filter.e | 12 +-- examples/filter/src/filter_server.e | 83 +++++++++++-------- examples/filter/src/resource/user_handler.e | 22 ++--- .../network/protocol/http/src/http_header.e | 63 ++++++++++---- .../protocol/http/src/http_header_names.e | 19 ++++- .../wsf/router/filter/wsf_cors_filter.e | 33 ++++++++ .../router/filter/wsf_cors_options_filter.e | 59 +++++++++++++ .../src/response/wsf_cors_options_response.e | 64 ++++++++++++++ library/server/wsf/src/wsf_response.e | 26 +++++- 10 files changed, 324 insertions(+), 82 deletions(-) create mode 100644 library/server/wsf/router/filter/wsf_cors_filter.e create mode 100644 library/server/wsf/router/filter/wsf_cors_options_filter.e create mode 100644 library/server/wsf/src/response/wsf_cors_options_response.e diff --git a/examples/filter/filter-safe.ecf b/examples/filter/filter-safe.ecf index ade4f80f..6c86cb8e 100644 --- a/examples/filter/filter-safe.ecf +++ b/examples/filter/filter-safe.ecf @@ -12,22 +12,23 @@ - - + + + + - - - - - - - - - - + + + + + + + + + diff --git a/examples/filter/src/filter/authentication_filter.e b/examples/filter/src/filter/authentication_filter.e index 9b407c7b..a18da1e7 100644 --- a/examples/filter/src/filter/authentication_filter.e +++ b/examples/filter/src/filter/authentication_filter.e @@ -8,9 +8,9 @@ class AUTHENTICATION_FILTER inherit - WSF_FILTER_CONTEXT_HANDLER [FILTER_HANDLER_CONTEXT] + WSF_FILTER - WSF_URI_TEMPLATE_CONTEXT_HANDLER [FILTER_HANDLER_CONTEXT] + WSF_URI_TEMPLATE_HANDLER SHARED_DATABASE_API @@ -18,7 +18,7 @@ inherit feature -- Basic operations - execute (ctx: FILTER_HANDLER_CONTEXT; req: WSF_REQUEST; res: WSF_RESPONSE) + execute (req: WSF_REQUEST; res: WSF_RESPONSE) -- Execute the filter local l_auth: HTTP_AUTHORIZATION @@ -31,8 +31,8 @@ feature -- Basic operations attached l_auth.password as l_auth_password and then l_auth_password.same_string (l_user.password) then - ctx.set_user (l_user) - execute_next (ctx, req, res) + req.set_execution_variable ("user", l_user) + execute_next (req, res) else handle_unauthorized ("Unauthorized", req, res) end @@ -56,6 +56,6 @@ feature {NONE} -- Implementation end note - copyright: "2011-2012, Olivier Ligot, Jocelyn Fiat and others" + copyright: "2011-2013, Olivier Ligot, Jocelyn Fiat and others" license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)" end diff --git a/examples/filter/src/filter_server.e b/examples/filter/src/filter_server.e index 25d16fef..7368581d 100644 --- a/examples/filter/src/filter_server.e +++ b/examples/filter/src/filter_server.e @@ -24,39 +24,60 @@ create feature {NONE} -- Initialization make + local + l_message: STRING + l_factory: INET_ADDRESS_FACTORY do + create router.make (1) initialize_filter initialize_json - set_service_option ("port", 9090) + set_service_option ("port", port) + create l_message.make_empty + l_message.append_string ("Launching filter server at ") + create l_factory + l_message.append_string (l_factory.create_localhost.host_name) + l_message.append_string (" port ") + l_message.append_integer (port) + io.put_string (l_message) + io.put_new_line make_and_launch end create_filter -- Create `filter' local - l_router: WSF_ROUTER - l_authentication_filter_hdl: AUTHENTICATION_FILTER - l_user_filter: USER_HANDLER - l_routing_filter: WSF_ROUTING_FILTER + l_cors_filter: WSF_CORS_FILTER do - create l_router.make (1) - create l_authentication_filter_hdl - create l_user_filter - l_authentication_filter_hdl.set_next (l_user_filter) - - l_router.handle_with_request_methods ("/user/{userid}", l_authentication_filter_hdl, l_router.methods_get) - create l_routing_filter.make (l_router) - l_routing_filter.set_execute_default_action (agent execute_default) - filter := l_routing_filter + create l_cors_filter + filter := l_cors_filter end setup_filter -- Setup `filter' local + l_options_filter: WSF_CORS_OPTIONS_FILTER + l_authentication_filter: AUTHENTICATION_FILTER + l_user_filter: USER_HANDLER + l_methods: WSF_REQUEST_METHODS + l_routing_filter: WSF_ROUTING_FILTER l_logging_filter: WSF_LOGGING_FILTER do + create l_options_filter.make (router) + create l_authentication_filter + l_options_filter.set_next (l_authentication_filter) + create l_user_filter + l_authentication_filter.set_next (l_user_filter) + + create l_methods + l_methods.enable_options + l_methods.enable_get + router.handle_with_request_methods ("/user/{userid}", l_options_filter, l_methods) + create l_routing_filter.make (router) + l_routing_filter.set_execute_default_action (agent execute_default) + filter.set_next (l_routing_filter) + create l_logging_filter - filter.set_next (l_logging_filter) + l_routing_filter.set_next (l_logging_filter) end initialize_json @@ -73,30 +94,24 @@ feature -- Basic operations end execute_default (req: WSF_REQUEST; res: WSF_RESPONSE) - -- I'm using this method to handle the method not allowed response - -- in the case that the given uri does not have a corresponding http method - -- to handle it. local - h : HTTP_HEADER - l_description : STRING - l_api_doc : STRING + l_message: WSF_DEFAULT_ROUTER_RESPONSE do - if req.content_length_value > 0 then - req.input.read_string (req.content_length_value.as_integer_32) - end - create h.make - h.put_content_type_text_plain - l_api_doc := "%NPlease check the API%NURI:/user/{userid} METHOD: GET%N" - l_description := req.request_method + req.request_uri + " is not allowed" + "%N" + l_api_doc - h.put_content_length (l_description.count) - h.put_current_date - res.set_status_code ({HTTP_STATUS_CODE}.method_not_allowed) - res.put_header_text (h.string) - res.put_string (l_description) + create l_message.make_with_router (req, router) + l_message.set_documentation_included (True) + res.send (l_message) end +feature {NONE} -- Implementation + + port: INTEGER = 9090 + -- Port number + + router: WSF_ROUTER; + -- Router + note - copyright: "2011-2012, Olivier Ligot, Jocelyn Fiat and others" + copyright: "2011-2013, Olivier Ligot, Jocelyn Fiat and others" license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)" source: "[ Eiffel Software diff --git a/examples/filter/src/resource/user_handler.e b/examples/filter/src/resource/user_handler.e index 223e93d5..722ccd03 100644 --- a/examples/filter/src/resource/user_handler.e +++ b/examples/filter/src/resource/user_handler.e @@ -8,11 +8,11 @@ class USER_HANDLER inherit - WSF_FILTER_CONTEXT_HANDLER [FILTER_HANDLER_CONTEXT] + WSF_FILTER - WSF_URI_TEMPLATE_CONTEXT_HANDLER [FILTER_HANDLER_CONTEXT] + WSF_URI_TEMPLATE_HANDLER - WSF_RESOURCE_CONTEXT_HANDLER_HELPER [FILTER_HANDLER_CONTEXT] + WSF_RESOURCE_HANDLER_HELPER redefine do_get end @@ -23,30 +23,30 @@ inherit feature -- Basic operations - execute (ctx: FILTER_HANDLER_CONTEXT; req: WSF_REQUEST; res: WSF_RESPONSE) + execute (req: WSF_REQUEST; res: WSF_RESPONSE) -- Execute request handler do - execute_methods (ctx, req, res) - execute_next (ctx, req, res) + execute_methods (req, res) + execute_next (req, res) end - do_get (ctx: FILTER_HANDLER_CONTEXT; 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 -- If the GET request is not SUCCESS, we response with -- 404 Resource not found require else - authenticated_user_attached: attached ctx.user + authenticated_user_attached: attached {USER} req.execution_variable ("user") local id : STRING do 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 - if l_user ~ ctx.user then + if l_user ~ req.execution_variable ("user") then compute_response_get (req, res, l_user) - elseif attached ctx.user as l_auth_user then + elseif attached {USER} req.execution_variable ("user") as l_auth_user then -- Trying to access another user that the authenticated one, -- which is forbidden in this example... handle_forbidden ("You try to access the user " + id.out + " while authenticating with the user " + l_auth_user.id.out, req, res) @@ -92,6 +92,6 @@ feature {NONE} -- Implementation end note - copyright: "2011-2012, Olivier Ligot, Jocelyn Fiat and others" + copyright: "2011-2013, Olivier Ligot, Jocelyn Fiat and others" license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)" end diff --git a/library/network/protocol/http/src/http_header.e b/library/network/protocol/http/src/http_header.e index 001067a9..4e89707e 100644 --- a/library/network/protocol/http/src/http_header.e +++ b/library/network/protocol/http/src/http_header.e @@ -213,6 +213,25 @@ feature -- Header change: general put_header (k + colon_space + v) end + put_header_key_methods (k: READABLE_STRING_8; a_methods: ITERABLE [READABLE_STRING_8]) + -- Add header `k: a_methods', or replace existing header of same header methods/key + local + s: STRING_8 + do + create s.make_empty + across + a_methods as c + loop + if not s.is_empty then + s.append_string (", ") + end + s.append (c.item) + end + if not s.is_empty then + put_header_key_value (k, s) + end + end + feature -- Content related header put_content_type (t: READABLE_STRING_8) @@ -397,26 +416,38 @@ feature -- Content-type helpers put_content_type_multipart_encrypted do put_content_type ({HTTP_MIME_TYPES}.multipart_encrypted) end put_content_type_application_x_www_form_encoded do put_content_type ({HTTP_MIME_TYPES}.application_x_www_form_encoded) end +feature -- Cross-Origin Resource Sharing + + put_access_control_allow_origin (s: READABLE_STRING_8) + -- Put "Access-Control-Allow-Origin" header. + do + put_header_key_value ({HTTP_HEADER_NAMES}.header_access_control_allow_origin, s) + end + + put_access_control_allow_all_origin + -- Put "Access-Control-Allow-Origin: *" header. + do + put_access_control_allow_origin ("*") + end + + put_access_control_allow_methods (a_methods: ITERABLE [READABLE_STRING_8]) + -- If `a_methods' is not empty, put `Access-Control-Allow-Methods' header with list `a_methods' of methods + do + put_header_key_methods ({HTTP_HEADER_NAMES}.header_access_control_allow_methods, a_methods) + end + + put_access_control_allow_headers (s: READABLE_STRING_8) + -- Put "Access-Control-Allow-Headers" header. + do + put_header_key_value ({HTTP_HEADER_NAMES}.header_access_control_allow_headers, s) + end + feature -- Method related put_allow (a_methods: ITERABLE [READABLE_STRING_8]) -- If `a_methods' is not empty, put `Allow' header with list `a_methods' of methods - local - s: STRING_8 do - create s.make_empty - across - a_methods as c - loop - if not s.is_empty then - s.append_character (',') - end - s.append_character (' ') - s.append (c.item) - end - if not s.is_empty then - put_header_key_value ({HTTP_HEADER_NAMES}.header_allow, s) - end + put_header_key_methods ({HTTP_HEADER_NAMES}.header_allow, a_methods) end feature -- Date @@ -738,7 +769,7 @@ feature {NONE} -- Constants semi_colon_space: STRING = "; " note - copyright: "2011-2012, Jocelyn Fiat, Eiffel Software and others" + copyright: "2011-2013, Jocelyn Fiat, Eiffel Software and others" license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)" source: "[ Eiffel Software diff --git a/library/network/protocol/http/src/http_header_names.e b/library/network/protocol/http/src/http_header_names.e index 8d679ea9..4bab76e8 100644 --- a/library/network/protocol/http/src/http_header_names.e +++ b/library/network/protocol/http/src/http_header_names.e @@ -194,6 +194,23 @@ feature -- Response header name -- Indicates the authentication scheme that should be used to access the requested entity. --| Example: WWW-Authenticate: Basic +feature -- Cross-Origin Resource Sharing + + header_access_control_allow_origin: STRING = "Access-Control-Allow-Origin" + -- Indicates whether a resource can be shared based by returning + -- the value of the Origin request header in the response. + -- | Example: Access-Control-Allow-Origin: http://example.org + + header_access_control_allow_methods: STRING = "Access-Control-Allow-Methods" + -- Indicates, as part of the response to a preflight request, + -- which methods can be used during the actual request. + -- | Example: Access-Control-Allow-Methods: PUT, DELETE + + header_access_control_allow_headers: STRING = "Access-Control-Allow-Headers" + -- Indicates, as part of the response to a preflight request, + -- which header field names can be used during the actual request. + -- | Example: Access-Control-Allow-Headers: Authorization + feature -- Request or Response header name header_cache_control: STRING = "Cache-Control" @@ -248,7 +265,7 @@ feature -- MIME related header_content_transfer_encoding: STRING = "Content-Transfer-Encoding" note - copyright: "2011-2012, Jocelyn Fiat, Eiffel Software and others" + copyright: "2011-2013, Jocelyn Fiat, 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/filter/wsf_cors_filter.e b/library/server/wsf/router/filter/wsf_cors_filter.e new file mode 100644 index 00000000..b306ad60 --- /dev/null +++ b/library/server/wsf/router/filter/wsf_cors_filter.e @@ -0,0 +1,33 @@ +note + description: "Cross-Origin Resource Sharing filter." + author: "Olivier Ligot" + date: "$Date$" + revision: "$Revision$" + EIS: "name=Cross-Origin Resource Sharing", "src=http://www.w3.org/TR/cors/", "tag=W3C" + +class + WSF_CORS_FILTER + +inherit + WSF_FILTER + +feature -- Basic operations + + execute (req: WSF_REQUEST; res: WSF_RESPONSE) + -- Execute the filter. + do + res.header.put_access_control_allow_all_origin + execute_next (req, res) + end + +note + copyright: "2011-2013, Jocelyn Fiat, Javier Velilla, Olivier Ligot, 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/filter/wsf_cors_options_filter.e b/library/server/wsf/router/filter/wsf_cors_options_filter.e new file mode 100644 index 00000000..7ca0bd87 --- /dev/null +++ b/library/server/wsf/router/filter/wsf_cors_options_filter.e @@ -0,0 +1,59 @@ +note + description: "Filter that handles an OPTIONS request, with Cross-Origin Resource Sharing support." + author: "Olvier Ligot" + date: "$Date$" + revision: "$Revision$" + EIS: "name=Cross-Origin Resource Sharing", "src=http://www.w3.org/TR/cors/", "tag=W3C" + +class + WSF_CORS_OPTIONS_FILTER + +inherit + WSF_FILTER + + WSF_URI_TEMPLATE_HANDLER + +create + make + +feature {NONE} -- Initialization + + make (a_router: like router) + -- Initialize Current with `a_router'. + do + router := a_router + ensure + router_set: router = a_router + end + +feature -- Access + + router: WSF_ROUTER + -- Associated router + +feature -- Basic operations + + execute (req: WSF_REQUEST; res: WSF_RESPONSE) + -- Execute the filter. + local + msg: WSF_CORS_OPTIONS_RESPONSE + do + if req.is_request_method ({HTTP_REQUEST_METHODS}.method_options) then + create msg.make (req, router) + res.send (msg) + else + execute_next (req, res) + end + end + +note + copyright: "2011-2013, Jocelyn Fiat, Javier Velilla, Olivier Ligot, 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/response/wsf_cors_options_response.e b/library/server/wsf/src/response/wsf_cors_options_response.e new file mode 100644 index 00000000..a0790a0b --- /dev/null +++ b/library/server/wsf/src/response/wsf_cors_options_response.e @@ -0,0 +1,64 @@ +note + description: "Response to an OPTIONS request, with Cross-Origin Resource Sharing support." + author: "Olivier Ligt" + date: "$Date$" + revision: "$Revision$" + EIS: "name=Cross-Origin Resource Sharing", "src=http://www.w3.org/TR/cors/", "tag=W3C" + +class + WSF_CORS_OPTIONS_RESPONSE + +inherit + WSF_RESPONSE_MESSAGE + +create + make + +feature {NONE} -- Initialization + + make (req: WSF_REQUEST; a_router: like router) + do + request := req + router := a_router + create header.make + end + +feature -- Access + + request: WSF_REQUEST + -- Associated request + + router: WSF_ROUTER + -- Associated router + + header: HTTP_HEADER + -- Response' header + +feature {WSF_RESPONSE} -- Output + + send_to (res: WSF_RESPONSE) + local + l_methods: WSF_REQUEST_METHODS + do + res.set_status_code ({HTTP_STATUS_CODE}.No_content) + header.put_current_date + header.put_access_control_allow_headers ({HTTP_HEADER_NAMES}.header_authorization) + l_methods := router.allowed_methods_for_request (request) + if not l_methods.is_empty then + header.put_allow (l_methods) + header.put_access_control_allow_methods (l_methods) + end + res.put_header_text (header.string) + end + +note + copyright: "2011-2013, Jocelyn Fiat, Javier Velilla, Olivier Ligot, 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_response.e b/library/server/wsf/src/wsf_response.e index edd69fed..81d1e208 100644 --- a/library/server/wsf/src/wsf_response.e +++ b/library/server/wsf/src/wsf_response.e @@ -31,6 +31,7 @@ feature {NONE} -- Initialization do transfered_content_length := 0 wgi_response := r + create header.make end feature {WSF_RESPONSE_EXPORTER} -- Properties @@ -114,6 +115,13 @@ feature -- Status setting feature -- Header output operation + header: HTTP_HEADER + -- Header + -- This is useful when we want to fill the `header' + -- in two pass (i.e. in two different classes). + -- We first call features of `header', and finally + -- we call `put_header_text' + put_header_text (a_text: READABLE_STRING_8) -- Sent `a_text' and just before send the status code require @@ -121,9 +129,23 @@ feature -- Header output operation header_not_committed: not header_committed a_text_ends_with_single_crlf: a_text.count > 2 implies not a_text.substring (a_text.count - 2, a_text.count).same_string ("%R%N") a_text_does_not_end_with_double_crlf: a_text.count > 4 implies not a_text.substring (a_text.count - 4, a_text.count).same_string ("%R%N%R%N") + local + l_text: READABLE_STRING_8 + l_header: HTTP_HEADER do wgi_response.set_status_code (status_code, status_reason_phrase) - wgi_response.put_header_text (a_text) + if header.is_empty then + l_text := a_text + else + create l_header.make_from_raw_header_data (a_text) + across + l_header as c + loop + header.put_header (c.item.string) + end + l_text := header.string + end + wgi_response.put_header_text (l_text) ensure status_set: status_is_set status_committed: status_committed @@ -376,7 +398,7 @@ feature -- Error reporting end note - copyright: "2011-2012, Jocelyn Fiat, Javier Velilla, Olivier Ligot, Eiffel Software and others" + copyright: "2011-2013, Jocelyn Fiat, Javier Velilla, Olivier Ligot, Eiffel Software and others" license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)" source: "[ Eiffel Software From 12404a2d5cf309229735d6f6ced7f86c6d3fcf8e Mon Sep 17 00:00:00 2001 From: Olivier Ligot Date: Fri, 22 Feb 2013 15:58:09 +0100 Subject: [PATCH 02/23] CORS: respect specification regarding Access-Control-Allow-Headers According to the specification, the value of the response header Access-Control-Allow-Headers must contain at least all the values of the request header Access-Control-Request-Headers to be considered a valid request. Before this commit, only the Authorization value was present, which is enough for Firefox but not for Chrome. This should now work as expected. --- .../server/ewsgi/specification/request/wgi_meta_names.e | 2 ++ library/server/ewsgi/specification/request/wgi_request.e | 6 ++++++ .../ewsgi/src/implementation/wgi_request_from_table.e | 7 +++++++ .../server/wsf/src/response/wsf_cors_options_response.e | 8 ++++++-- library/server/wsf/src/wsf_request.e | 7 +++++++ 5 files changed, 28 insertions(+), 2 deletions(-) diff --git a/library/server/ewsgi/specification/request/wgi_meta_names.e b/library/server/ewsgi/specification/request/wgi_meta_names.e index 4b2f10b8..7eeb913e 100644 --- a/library/server/ewsgi/specification/request/wgi_meta_names.e +++ b/library/server/ewsgi/specification/request/wgi_meta_names.e @@ -50,6 +50,8 @@ feature -- Access http_transfer_encoding: STRING = "HTTP_TRANSFER_ENCODING" + http_access_control_request_headers: STRING = "HTTP_ACCESS_CONTROL_REQUEST_HEADERS" + gateway_interface: STRING = "GATEWAY_INTERFACE" auth_type: STRING = "AUTH_TYPE" diff --git a/library/server/ewsgi/specification/request/wgi_request.e b/library/server/ewsgi/specification/request/wgi_request.e index 1dccd709..86e1e489 100644 --- a/library/server/ewsgi/specification/request/wgi_request.e +++ b/library/server/ewsgi/specification/request/wgi_request.e @@ -598,6 +598,12 @@ feature -- HTTP_* deferred end + http_access_control_request_headers: detachable READABLE_STRING_8 + -- Indicates which headers will be used in the actual request + -- as part of the preflight request + deferred + end + feature -- Extra CGI environment variables request_uri: READABLE_STRING_8 diff --git a/library/server/ewsgi/src/implementation/wgi_request_from_table.e b/library/server/ewsgi/src/implementation/wgi_request_from_table.e index 2bfa00d6..79fb3007 100644 --- a/library/server/ewsgi/src/implementation/wgi_request_from_table.e +++ b/library/server/ewsgi/src/implementation/wgi_request_from_table.e @@ -241,6 +241,13 @@ feature -- Access: HTTP_* CGI meta parameters - 1.1 Result := meta_string_variable ({WGI_META_NAMES}.http_transfer_encoding) end + http_access_control_request_headers: detachable READABLE_STRING_8 + -- Indicates which headers will be used in the actual request + -- as part of the preflight request + do + Result := meta_string_variable ({WGI_META_NAMES}.http_access_control_request_headers) + end + feature -- Access: Extension to CGI meta parameters - 1.1 request_uri: READABLE_STRING_8 diff --git a/library/server/wsf/src/response/wsf_cors_options_response.e b/library/server/wsf/src/response/wsf_cors_options_response.e index a0790a0b..0c928e2a 100644 --- a/library/server/wsf/src/response/wsf_cors_options_response.e +++ b/library/server/wsf/src/response/wsf_cors_options_response.e @@ -40,9 +40,13 @@ feature {WSF_RESPONSE} -- Output local l_methods: WSF_REQUEST_METHODS do - res.set_status_code ({HTTP_STATUS_CODE}.No_content) + res.set_status_code ({HTTP_STATUS_CODE}.Ok) + header.put_content_type ({HTTP_MIME_TYPES}.text_plain) header.put_current_date - header.put_access_control_allow_headers ({HTTP_HEADER_NAMES}.header_authorization) + header.put_content_length (0) + if attached request.http_access_control_request_headers as l_headers then + header.put_access_control_allow_headers (l_headers) + end l_methods := router.allowed_methods_for_request (request) if not l_methods.is_empty then header.put_allow (l_methods) diff --git a/library/server/wsf/src/wsf_request.e b/library/server/wsf/src/wsf_request.e index d90d89b2..6cc4e65d 100644 --- a/library/server/wsf/src/wsf_request.e +++ b/library/server/wsf/src/wsf_request.e @@ -958,6 +958,13 @@ feature -- HTTP_* Result := wgi_request.http_transfer_encoding end + http_access_control_request_headers: detachable READABLE_STRING_8 + -- Indicates which headers will be used in the actual request + -- as part of the preflight request + do + Result := wgi_request.http_access_control_request_headers + end + feature -- Extra CGI environment variables request_uri: READABLE_STRING_8 From 45f0971594ef2dcbc3ebf7280a4d3e8846fc2fa4 Mon Sep 17 00:00:00 2001 From: Olivier Ligot Date: Fri, 15 Mar 2013 13:38:40 +0100 Subject: [PATCH 03/23] Use new upstrem method put_header_key_values --- .../network/protocol/http/src/http_header.e | 21 +------------------ library/server/wsf/src/wsf_response.e | 3 --- 2 files changed, 1 insertion(+), 23 deletions(-) diff --git a/library/network/protocol/http/src/http_header.e b/library/network/protocol/http/src/http_header.e index 1460baaa..82281ccd 100644 --- a/library/network/protocol/http/src/http_header.e +++ b/library/network/protocol/http/src/http_header.e @@ -320,25 +320,6 @@ feature -- Header change: general end end - put_header_key_methods (k: READABLE_STRING_8; a_methods: ITERABLE [READABLE_STRING_8]) - -- Add header `k: a_methods', or replace existing header of same header methods/key - local - s: STRING_8 - do - create s.make_empty - across - a_methods as c - loop - if not s.is_empty then - s.append_string (", ") - end - s.append (c.item) - end - if not s.is_empty then - put_header_key_value (k, s) - end - end - feature -- Content related header put_content_type (t: READABLE_STRING_8) @@ -540,7 +521,7 @@ feature -- Cross-Origin Resource Sharing put_access_control_allow_methods (a_methods: ITERABLE [READABLE_STRING_8]) -- If `a_methods' is not empty, put `Access-Control-Allow-Methods' header with list `a_methods' of methods do - put_header_key_methods ({HTTP_HEADER_NAMES}.header_access_control_allow_methods, a_methods) + put_header_key_values ({HTTP_HEADER_NAMES}.header_access_control_allow_methods, a_methods, Void) end put_access_control_allow_headers (s: READABLE_STRING_8) diff --git a/library/server/wsf/src/wsf_response.e b/library/server/wsf/src/wsf_response.e index bacd9dc8..c70c1da3 100644 --- a/library/server/wsf/src/wsf_response.e +++ b/library/server/wsf/src/wsf_response.e @@ -187,9 +187,6 @@ feature -- Header output operation header_not_committed: not header_committed a_text_ends_with_single_crlf: a_text.count > 2 implies not a_text.substring (a_text.count - 2, a_text.count).same_string ("%R%N") a_text_does_not_end_with_double_crlf: a_text.count > 4 implies not a_text.substring (a_text.count - 4, a_text.count).same_string ("%R%N%R%N") - local - l_text: READABLE_STRING_8 - l_header: HTTP_HEADER do if header_committed then report_content_already_sent_and_header_ignored From 69495e69a97c672adb8525b2240a47911b95f18f Mon Sep 17 00:00:00 2001 From: Olivier Ligot Date: Fri, 15 Mar 2013 13:44:24 +0100 Subject: [PATCH 04/23] Filter example: remove unused libraries in ecf file --- examples/filter/filter-safe.ecf | 9 --------- 1 file changed, 9 deletions(-) diff --git a/examples/filter/filter-safe.ecf b/examples/filter/filter-safe.ecf index 6c86cb8e..f77a20c8 100644 --- a/examples/filter/filter-safe.ecf +++ b/examples/filter/filter-safe.ecf @@ -14,18 +14,9 @@ - - - - - - - From dde70512d8ec4db2c671c8b909a0a7dc5e3e1448 Mon Sep 17 00:00:00 2001 From: Olivier Ligot Date: Fri, 15 Mar 2013 14:15:17 +0100 Subject: [PATCH 05/23] Use features from the flexible_response branch --- library/server/wsf/router/filter/wsf_cors_filter.e | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/library/server/wsf/router/filter/wsf_cors_filter.e b/library/server/wsf/router/filter/wsf_cors_filter.e index b306ad60..75db6afe 100644 --- a/library/server/wsf/router/filter/wsf_cors_filter.e +++ b/library/server/wsf/router/filter/wsf_cors_filter.e @@ -15,8 +15,12 @@ feature -- Basic operations execute (req: WSF_REQUEST; res: WSF_RESPONSE) -- Execute the filter. + local + l_header: HTTP_HEADER do - res.header.put_access_control_allow_all_origin + create l_header.make + l_header.put_access_control_allow_all_origin + res.put_header_text (l_header.string) execute_next (req, res) end From c8845e73545a460b8272934974b8bb110b1510e0 Mon Sep 17 00:00:00 2001 From: Olivier Ligot Date: Fri, 15 Mar 2013 14:18:13 +0100 Subject: [PATCH 06/23] Fix indentation --- examples/filter/filter-safe.ecf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/filter/filter-safe.ecf b/examples/filter/filter-safe.ecf index f77a20c8..8edae596 100644 --- a/examples/filter/filter-safe.ecf +++ b/examples/filter/filter-safe.ecf @@ -19,7 +19,7 @@ - + From fc954c9521a20d06fa035c3f5a9d0ef2df626f3e Mon Sep 17 00:00:00 2001 From: Jocelyn Fiat Date: Mon, 18 Mar 2013 16:23:13 +0100 Subject: [PATCH 07/23] added small doc on how to include EWF git repo in another git repository --- doc/how-to-include-ewf-in-my-git-repository.txt | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 doc/how-to-include-ewf-in-my-git-repository.txt diff --git a/doc/how-to-include-ewf-in-my-git-repository.txt b/doc/how-to-include-ewf-in-my-git-repository.txt new file mode 100644 index 00000000..1b54b051 --- /dev/null +++ b/doc/how-to-include-ewf-in-my-git-repository.txt @@ -0,0 +1,15 @@ +GOAL: include EWF into your own git repository +For instance, let's put it under lib/EWF + + git remote add -f _ewf https://github.com/EiffelWebFramework/EWF.git + git merge --squash -s ours --no-commit _ewf/master + git read-tree --prefix=lib/EWF/ -u _ewf/master + git commit -m "Imported EWF into subtree lib/EWF/" + +Then to update lib/EWF + git pull -X subtree=lib/EWF _ewf master + +From another git clone, reconnect this "import" + git remote add -f _ewf https://github.com/EiffelWebFramework/EWF.git + git merge -s ours --no-commit --squash _ewf/master + and then update lib/EWF as described before From 4d7660a9e3962b93f6fc428946009ce4d6f1577f Mon Sep 17 00:00:00 2001 From: Jocelyn Fiat Date: Mon, 18 Mar 2013 22:05:34 +0100 Subject: [PATCH 08/23] Added deferred WSF_AGENT_HANDLER Added WSF_NOT_IMPLEMENTED_RESPONSE --- .../uri/helpers/wsf_uri_agent_handler.e | 23 ++---- .../helpers/wsf_uri_template_agent_handler.e | 23 ++---- library/server/wsf/router/wsf_agent_handler.e | 41 ++++++++++ .../response/wsf_not_implemented_response.e | 80 +++++++++++++++++++ 4 files changed, 133 insertions(+), 34 deletions(-) create mode 100644 library/server/wsf/router/wsf_agent_handler.e create mode 100644 library/server/wsf/src/response/wsf_not_implemented_response.e diff --git a/library/server/wsf/router/support/uri/helpers/wsf_uri_agent_handler.e b/library/server/wsf/router/support/uri/helpers/wsf_uri_agent_handler.e index 9750cc81..b2a5089c 100644 --- a/library/server/wsf/router/support/uri/helpers/wsf_uri_agent_handler.e +++ b/library/server/wsf/router/support/uri/helpers/wsf_uri_agent_handler.e @@ -10,27 +10,16 @@ class inherit WSF_URI_HANDLER + WSF_AGENT_HANDLER + rename + set_action as make + end + create make -feature {NONE} -- Initialization - - make (a_action: like action) - do - action := a_action - end - - action: PROCEDURE [ANY, TUPLE [request: WSF_REQUEST; response: WSF_RESPONSE]] - -feature -- Execution - - execute (req: WSF_REQUEST; res: WSF_RESPONSE) - do - action.call ([req, res]) - end - note - copyright: "2011-2012, Jocelyn Fiat, Javier Velilla, Olivier Ligot, Eiffel Software and others" + copyright: "2011-2013, Jocelyn Fiat, Javier Velilla, Olivier Ligot, 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/support/uri_template/helpers/wsf_uri_template_agent_handler.e b/library/server/wsf/router/support/uri_template/helpers/wsf_uri_template_agent_handler.e index 477e0545..c8e83fc0 100644 --- a/library/server/wsf/router/support/uri_template/helpers/wsf_uri_template_agent_handler.e +++ b/library/server/wsf/router/support/uri_template/helpers/wsf_uri_template_agent_handler.e @@ -10,27 +10,16 @@ class inherit WSF_URI_TEMPLATE_HANDLER + WSF_AGENT_HANDLER + rename + set_action as make + end + create make -feature {NONE} -- Initialization - - make (a_action: like action) - do - action := a_action - end - - action: PROCEDURE [ANY, TUPLE [request: WSF_REQUEST; response: WSF_RESPONSE]] - -feature -- Execution - - execute (req: WSF_REQUEST; res: WSF_RESPONSE) - do - action.call ([req, res]) - end - note - copyright: "2011-2012, Jocelyn Fiat, Javier Velilla, Olivier Ligot, Eiffel Software and others" + copyright: "2011-2013, Jocelyn Fiat, Javier Velilla, Olivier Ligot, 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/wsf_agent_handler.e b/library/server/wsf/router/wsf_agent_handler.e new file mode 100644 index 00000000..3a25afef --- /dev/null +++ b/library/server/wsf/router/wsf_agent_handler.e @@ -0,0 +1,41 @@ +note + description: "Summary description for {WSF_AGENT_HANDLER}." + author: "" + date: "$Date$" + revision: "$Revision$" + +deferred class + WSF_AGENT_HANDLER + +inherit + WSF_HANDLER + +feature -- Change + + set_action (a_action: like action) + do + action := a_action + end + +feature -- Access + + action: PROCEDURE [ANY, TUPLE [request: WSF_REQUEST; response: WSF_RESPONSE]] + +feature -- Execution + + execute (req: WSF_REQUEST; res: WSF_RESPONSE) + do + action.call ([req, res]) + end + +note + copyright: "2011-2012, Jocelyn Fiat, Javier Velilla, Olivier Ligot, 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/response/wsf_not_implemented_response.e b/library/server/wsf/src/response/wsf_not_implemented_response.e new file mode 100644 index 00000000..297dafc3 --- /dev/null +++ b/library/server/wsf/src/response/wsf_not_implemented_response.e @@ -0,0 +1,80 @@ +note + description: "[ + This class is used to report a 501 not implemented + ]" + date: "$Date$" + revision: "$Revision$" + +class + WSF_NOT_IMPLEMENTED_RESPONSE + +inherit + WSF_RESPONSE_MESSAGE + + SHARED_HTML_ENCODER + +create + make + +feature {NONE} -- Initialization + + make (req: WSF_REQUEST) + do + create header.make + request := req + end + +feature -- Header + + header: HTTP_HEADER + -- Response' header + + request: WSF_REQUEST + -- Associated request. + + body: detachable READABLE_STRING_8 + -- Optional body + -- Displayed as extra content + +feature -- Element change + + set_body (b: like body) + -- Set `body' to `b' + do + body := b + end + +feature {WSF_RESPONSE} -- Output + + send_to (res: WSF_RESPONSE) + local + s: STRING + h: like header + do + h := header + res.set_status_code ({HTTP_STATUS_CODE}.not_implemented) + + s := "Error 501 Not Implemented !" + if attached body as b then + s.append ("%N") + s.append (b) + s.append ("%N") + end + h.put_content_type_text_plain + h.put_content_length (s.count) + res.put_header_text (h.string) + res.put_string (s) + res.flush + end + +note + copyright: "2011-2013, Jocelyn Fiat, Javier Velilla, Olivier Ligot, 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 3faa2ab815ba6c899f76dd9d3ecaf04b0845faa4 Mon Sep 17 00:00:00 2001 From: Jocelyn Fiat Date: Tue, 19 Mar 2013 11:54:01 +0100 Subject: [PATCH 09/23] Moved all *_CONTEXT_* router related classes into wsf_router_context.ecf library This makes wsf simpler to discover. And advanced context enabled handler, mapping, ... are still available for now in wsf_router_context.ecf library --- examples/filter/filter-safe.ecf | 1 + .../wsf_starts_with_agent_context_handler.e | 0 .../wsf_starts_with_context_routed_service.e | 0 .../wsf_starts_with_routing_context_handler.e | 0 .../wsf_starts_with_context_handler.e | 0 .../wsf_starts_with_context_mapping.e | 0 .../helpers}/wsf_uri_agent_context_handler.e | 0 .../helpers}/wsf_uri_context_routed_service.e | 0 .../helpers}/wsf_uri_routing_context_handler.e | 0 .../support/uri/wsf_uri_context_handler.e | 0 .../support/uri/wsf_uri_context_mapping.e | 0 .../wsf_uri_template_agent_context_handler.e | 0 .../wsf_uri_template_context_routed_service.e | 0 .../wsf_uri_template_filter_context_handler.e- | 0 .../wsf_uri_template_routing_context_handler.e | 0 .../wsf_uri_template_context_handler.e | 0 .../wsf_uri_template_context_mapping.e | 0 .../wsf_agent_context_handler.e | 0 .../wsf_context_handler.e | 0 .../wsf_filter_context_handler.e | 0 .../wsf_handler_context.e | 2 +- .../wsf_router_context_mapping.e | 0 .../wsf_routing_context_handler.e | 0 library/server/wsf/wsf_extension-safe.ecf | 3 ++- library/server/wsf/wsf_extension.ecf | 1 + library/server/wsf/wsf_router_context-safe.ecf | 16 ++++++++++++++++ library/server/wsf/wsf_router_context.ecf | 17 +++++++++++++++++ tests/all-safe.ecf | 1 + 28 files changed, 39 insertions(+), 2 deletions(-) rename library/server/wsf/{router/support/starts_with/context_helpers => router_context/support/starts_with/helpers}/wsf_starts_with_agent_context_handler.e (100%) rename library/server/wsf/{router/support/starts_with/context_helpers => router_context/support/starts_with/helpers}/wsf_starts_with_context_routed_service.e (100%) rename library/server/wsf/{router/support/starts_with/context_helpers => router_context/support/starts_with/helpers}/wsf_starts_with_routing_context_handler.e (100%) rename library/server/wsf/{router => router_context}/support/starts_with/wsf_starts_with_context_handler.e (100%) rename library/server/wsf/{router => router_context}/support/starts_with/wsf_starts_with_context_mapping.e (100%) rename library/server/wsf/{router/support/uri/context_helpers => router_context/support/uri/helpers}/wsf_uri_agent_context_handler.e (100%) rename library/server/wsf/{router/support/uri/context_helpers => router_context/support/uri/helpers}/wsf_uri_context_routed_service.e (100%) rename library/server/wsf/{router/support/uri/context_helpers => router_context/support/uri/helpers}/wsf_uri_routing_context_handler.e (100%) rename library/server/wsf/{router => router_context}/support/uri/wsf_uri_context_handler.e (100%) rename library/server/wsf/{router => router_context}/support/uri/wsf_uri_context_mapping.e (100%) rename library/server/wsf/{router/support/uri_template/context_helpers => router_context/support/uri_template/helpers}/wsf_uri_template_agent_context_handler.e (100%) rename library/server/wsf/{router/support/uri_template/context_helpers => router_context/support/uri_template/helpers}/wsf_uri_template_context_routed_service.e (100%) rename library/server/wsf/{router/support/uri_template/context_helpers => router_context/support/uri_template/helpers}/wsf_uri_template_filter_context_handler.e- (100%) rename library/server/wsf/{router/support/uri_template/context_helpers => router_context/support/uri_template/helpers}/wsf_uri_template_routing_context_handler.e (100%) rename library/server/wsf/{router => router_context}/support/uri_template/wsf_uri_template_context_handler.e (100%) rename library/server/wsf/{router => router_context}/support/uri_template/wsf_uri_template_context_mapping.e (100%) rename library/server/wsf/{router/context => router_context}/wsf_agent_context_handler.e (100%) rename library/server/wsf/{router/context => router_context}/wsf_context_handler.e (100%) rename library/server/wsf/{router/context => router_context}/wsf_filter_context_handler.e (100%) rename library/server/wsf/{router/context => router_context}/wsf_handler_context.e (93%) rename library/server/wsf/{router/context => router_context}/wsf_router_context_mapping.e (100%) rename library/server/wsf/{router/context => router_context}/wsf_routing_context_handler.e (100%) create mode 100644 library/server/wsf/wsf_router_context-safe.ecf create mode 100644 library/server/wsf/wsf_router_context.ecf diff --git a/examples/filter/filter-safe.ecf b/examples/filter/filter-safe.ecf index 8edae596..0495befc 100644 --- a/examples/filter/filter-safe.ecf +++ b/examples/filter/filter-safe.ecf @@ -18,6 +18,7 @@ + diff --git a/library/server/wsf/router/support/starts_with/context_helpers/wsf_starts_with_agent_context_handler.e b/library/server/wsf/router_context/support/starts_with/helpers/wsf_starts_with_agent_context_handler.e similarity index 100% rename from library/server/wsf/router/support/starts_with/context_helpers/wsf_starts_with_agent_context_handler.e rename to library/server/wsf/router_context/support/starts_with/helpers/wsf_starts_with_agent_context_handler.e diff --git a/library/server/wsf/router/support/starts_with/context_helpers/wsf_starts_with_context_routed_service.e b/library/server/wsf/router_context/support/starts_with/helpers/wsf_starts_with_context_routed_service.e similarity index 100% rename from library/server/wsf/router/support/starts_with/context_helpers/wsf_starts_with_context_routed_service.e rename to library/server/wsf/router_context/support/starts_with/helpers/wsf_starts_with_context_routed_service.e diff --git a/library/server/wsf/router/support/starts_with/context_helpers/wsf_starts_with_routing_context_handler.e b/library/server/wsf/router_context/support/starts_with/helpers/wsf_starts_with_routing_context_handler.e similarity index 100% rename from library/server/wsf/router/support/starts_with/context_helpers/wsf_starts_with_routing_context_handler.e rename to library/server/wsf/router_context/support/starts_with/helpers/wsf_starts_with_routing_context_handler.e diff --git a/library/server/wsf/router/support/starts_with/wsf_starts_with_context_handler.e b/library/server/wsf/router_context/support/starts_with/wsf_starts_with_context_handler.e similarity index 100% rename from library/server/wsf/router/support/starts_with/wsf_starts_with_context_handler.e rename to library/server/wsf/router_context/support/starts_with/wsf_starts_with_context_handler.e diff --git a/library/server/wsf/router/support/starts_with/wsf_starts_with_context_mapping.e b/library/server/wsf/router_context/support/starts_with/wsf_starts_with_context_mapping.e similarity index 100% rename from library/server/wsf/router/support/starts_with/wsf_starts_with_context_mapping.e rename to library/server/wsf/router_context/support/starts_with/wsf_starts_with_context_mapping.e diff --git a/library/server/wsf/router/support/uri/context_helpers/wsf_uri_agent_context_handler.e b/library/server/wsf/router_context/support/uri/helpers/wsf_uri_agent_context_handler.e similarity index 100% rename from library/server/wsf/router/support/uri/context_helpers/wsf_uri_agent_context_handler.e rename to library/server/wsf/router_context/support/uri/helpers/wsf_uri_agent_context_handler.e diff --git a/library/server/wsf/router/support/uri/context_helpers/wsf_uri_context_routed_service.e b/library/server/wsf/router_context/support/uri/helpers/wsf_uri_context_routed_service.e similarity index 100% rename from library/server/wsf/router/support/uri/context_helpers/wsf_uri_context_routed_service.e rename to library/server/wsf/router_context/support/uri/helpers/wsf_uri_context_routed_service.e diff --git a/library/server/wsf/router/support/uri/context_helpers/wsf_uri_routing_context_handler.e b/library/server/wsf/router_context/support/uri/helpers/wsf_uri_routing_context_handler.e similarity index 100% rename from library/server/wsf/router/support/uri/context_helpers/wsf_uri_routing_context_handler.e rename to library/server/wsf/router_context/support/uri/helpers/wsf_uri_routing_context_handler.e diff --git a/library/server/wsf/router/support/uri/wsf_uri_context_handler.e b/library/server/wsf/router_context/support/uri/wsf_uri_context_handler.e similarity index 100% rename from library/server/wsf/router/support/uri/wsf_uri_context_handler.e rename to library/server/wsf/router_context/support/uri/wsf_uri_context_handler.e diff --git a/library/server/wsf/router/support/uri/wsf_uri_context_mapping.e b/library/server/wsf/router_context/support/uri/wsf_uri_context_mapping.e similarity index 100% rename from library/server/wsf/router/support/uri/wsf_uri_context_mapping.e rename to library/server/wsf/router_context/support/uri/wsf_uri_context_mapping.e diff --git a/library/server/wsf/router/support/uri_template/context_helpers/wsf_uri_template_agent_context_handler.e b/library/server/wsf/router_context/support/uri_template/helpers/wsf_uri_template_agent_context_handler.e similarity index 100% rename from library/server/wsf/router/support/uri_template/context_helpers/wsf_uri_template_agent_context_handler.e rename to library/server/wsf/router_context/support/uri_template/helpers/wsf_uri_template_agent_context_handler.e diff --git a/library/server/wsf/router/support/uri_template/context_helpers/wsf_uri_template_context_routed_service.e b/library/server/wsf/router_context/support/uri_template/helpers/wsf_uri_template_context_routed_service.e similarity index 100% rename from library/server/wsf/router/support/uri_template/context_helpers/wsf_uri_template_context_routed_service.e rename to library/server/wsf/router_context/support/uri_template/helpers/wsf_uri_template_context_routed_service.e diff --git a/library/server/wsf/router/support/uri_template/context_helpers/wsf_uri_template_filter_context_handler.e- b/library/server/wsf/router_context/support/uri_template/helpers/wsf_uri_template_filter_context_handler.e- similarity index 100% rename from library/server/wsf/router/support/uri_template/context_helpers/wsf_uri_template_filter_context_handler.e- rename to library/server/wsf/router_context/support/uri_template/helpers/wsf_uri_template_filter_context_handler.e- diff --git a/library/server/wsf/router/support/uri_template/context_helpers/wsf_uri_template_routing_context_handler.e b/library/server/wsf/router_context/support/uri_template/helpers/wsf_uri_template_routing_context_handler.e similarity index 100% rename from library/server/wsf/router/support/uri_template/context_helpers/wsf_uri_template_routing_context_handler.e rename to library/server/wsf/router_context/support/uri_template/helpers/wsf_uri_template_routing_context_handler.e diff --git a/library/server/wsf/router/support/uri_template/wsf_uri_template_context_handler.e b/library/server/wsf/router_context/support/uri_template/wsf_uri_template_context_handler.e similarity index 100% rename from library/server/wsf/router/support/uri_template/wsf_uri_template_context_handler.e rename to library/server/wsf/router_context/support/uri_template/wsf_uri_template_context_handler.e diff --git a/library/server/wsf/router/support/uri_template/wsf_uri_template_context_mapping.e b/library/server/wsf/router_context/support/uri_template/wsf_uri_template_context_mapping.e similarity index 100% rename from library/server/wsf/router/support/uri_template/wsf_uri_template_context_mapping.e rename to library/server/wsf/router_context/support/uri_template/wsf_uri_template_context_mapping.e diff --git a/library/server/wsf/router/context/wsf_agent_context_handler.e b/library/server/wsf/router_context/wsf_agent_context_handler.e similarity index 100% rename from library/server/wsf/router/context/wsf_agent_context_handler.e rename to library/server/wsf/router_context/wsf_agent_context_handler.e diff --git a/library/server/wsf/router/context/wsf_context_handler.e b/library/server/wsf/router_context/wsf_context_handler.e similarity index 100% rename from library/server/wsf/router/context/wsf_context_handler.e rename to library/server/wsf/router_context/wsf_context_handler.e diff --git a/library/server/wsf/router/context/wsf_filter_context_handler.e b/library/server/wsf/router_context/wsf_filter_context_handler.e similarity index 100% rename from library/server/wsf/router/context/wsf_filter_context_handler.e rename to library/server/wsf/router_context/wsf_filter_context_handler.e diff --git a/library/server/wsf/router/context/wsf_handler_context.e b/library/server/wsf/router_context/wsf_handler_context.e similarity index 93% rename from library/server/wsf/router/context/wsf_handler_context.e rename to library/server/wsf/router_context/wsf_handler_context.e index 7babdb27..91eaf745 100644 --- a/library/server/wsf/router/context/wsf_handler_context.e +++ b/library/server/wsf/router_context/wsf_handler_context.e @@ -31,7 +31,7 @@ feature -- Access -- Associated mapping ;note - copyright: "2011-2012, Jocelyn Fiat, Javier Velilla, Olivier Ligot, Eiffel Software and others" + copyright: "2011-2013, Jocelyn Fiat, Javier Velilla, Olivier Ligot, 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/context/wsf_router_context_mapping.e b/library/server/wsf/router_context/wsf_router_context_mapping.e similarity index 100% rename from library/server/wsf/router/context/wsf_router_context_mapping.e rename to library/server/wsf/router_context/wsf_router_context_mapping.e diff --git a/library/server/wsf/router/context/wsf_routing_context_handler.e b/library/server/wsf/router_context/wsf_routing_context_handler.e similarity index 100% rename from library/server/wsf/router/context/wsf_routing_context_handler.e rename to library/server/wsf/router_context/wsf_routing_context_handler.e diff --git a/library/server/wsf/wsf_extension-safe.ecf b/library/server/wsf/wsf_extension-safe.ecf index 7bfa4489..5a46b2b5 100644 --- a/library/server/wsf/wsf_extension-safe.ecf +++ b/library/server/wsf/wsf_extension-safe.ecf @@ -12,7 +12,8 @@ - + + diff --git a/library/server/wsf/wsf_extension.ecf b/library/server/wsf/wsf_extension.ecf index cef881de..b9ce417f 100644 --- a/library/server/wsf/wsf_extension.ecf +++ b/library/server/wsf/wsf_extension.ecf @@ -13,6 +13,7 @@ + diff --git a/library/server/wsf/wsf_router_context-safe.ecf b/library/server/wsf/wsf_router_context-safe.ecf new file mode 100644 index 00000000..91b84d36 --- /dev/null +++ b/library/server/wsf/wsf_router_context-safe.ecf @@ -0,0 +1,16 @@ + + + + + + /.git$ + /EIFGENs$ + /.svn$ + + + + + + + diff --git a/library/server/wsf/wsf_router_context.ecf b/library/server/wsf/wsf_router_context.ecf new file mode 100644 index 00000000..7dd0f8de --- /dev/null +++ b/library/server/wsf/wsf_router_context.ecf @@ -0,0 +1,17 @@ + + + + + + + /.git$ + /EIFGENs$ + /.svn$ + + + + + + + diff --git a/tests/all-safe.ecf b/tests/all-safe.ecf index 16747e1a..c7d6efe5 100644 --- a/tests/all-safe.ecf +++ b/tests/all-safe.ecf @@ -31,6 +31,7 @@ + From b629bba5cc9c33491b9dc2ee771a8cf2612479f3 Mon Sep 17 00:00:00 2001 From: Jocelyn Fiat Date: Tue, 19 Mar 2013 17:09:18 +0100 Subject: [PATCH 10/23] WSF_CORS_OPTIONS_FILTER should not inherit from WSF_URI_TEMPLATE_HANDLER --- examples/filter/src/filter_server.e | 2 +- library/server/wsf/router/filter/wsf_cors_options_filter.e | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/examples/filter/src/filter_server.e b/examples/filter/src/filter_server.e index 7368581d..9061e1f1 100644 --- a/examples/filter/src/filter_server.e +++ b/examples/filter/src/filter_server.e @@ -71,7 +71,7 @@ feature {NONE} -- Initialization create l_methods l_methods.enable_options l_methods.enable_get - router.handle_with_request_methods ("/user/{userid}", l_options_filter, l_methods) + router.handle_with_request_methods ("/user/{userid}", create {WSF_URI_TEMPLATE_AGENT_HANDLER}.make (agent l_options_filter.execute), l_methods) create l_routing_filter.make (router) l_routing_filter.set_execute_default_action (agent execute_default) filter.set_next (l_routing_filter) diff --git a/library/server/wsf/router/filter/wsf_cors_options_filter.e b/library/server/wsf/router/filter/wsf_cors_options_filter.e index 7ca0bd87..9b2ad468 100644 --- a/library/server/wsf/router/filter/wsf_cors_options_filter.e +++ b/library/server/wsf/router/filter/wsf_cors_options_filter.e @@ -11,8 +11,6 @@ class inherit WSF_FILTER - WSF_URI_TEMPLATE_HANDLER - create make From 73f675db60d514860d4774ecb78859788d313162 Mon Sep 17 00:00:00 2001 From: Jocelyn Fiat Date: Tue, 19 Mar 2013 17:17:14 +0100 Subject: [PATCH 11/23] added WSF_..._ROUTER_HELPER and made the previous WSF_..._ROUTED_SERVICE obsolete --- .../uri/helpers/wsf_uri_routed_service.e | 28 ++------ .../uri/helpers/wsf_uri_router_helper.e | 50 ++++++++++++++ .../helpers/wsf_uri_template_routed_service.e | 42 +----------- .../helpers/wsf_uri_template_router_helper.e | 66 +++++++++++++++++++ .../wsf_starts_with_context_routed_service.e | 26 +------- .../wsf_starts_with_context_router_helper.e | 50 ++++++++++++++ .../helpers/wsf_uri_context_routed_service.e | 27 ++------ .../helpers/wsf_uri_context_router_helper.e | 50 ++++++++++++++ .../wsf_uri_template_context_routed_service.e | 28 ++------ .../wsf_uri_template_context_router_helper.e | 50 ++++++++++++++ 10 files changed, 284 insertions(+), 133 deletions(-) create mode 100644 library/server/wsf/router/support/uri/helpers/wsf_uri_router_helper.e create mode 100644 library/server/wsf/router/support/uri_template/helpers/wsf_uri_template_router_helper.e create mode 100644 library/server/wsf/router_context/support/starts_with/helpers/wsf_starts_with_context_router_helper.e create mode 100644 library/server/wsf/router_context/support/uri/helpers/wsf_uri_context_router_helper.e create mode 100644 library/server/wsf/router_context/support/uri_template/helpers/wsf_uri_template_context_router_helper.e diff --git a/library/server/wsf/router/support/uri/helpers/wsf_uri_routed_service.e b/library/server/wsf/router/support/uri/helpers/wsf_uri_routed_service.e index cbb68d28..f57ee2c2 100644 --- a/library/server/wsf/router/support/uri/helpers/wsf_uri_routed_service.e +++ b/library/server/wsf/router/support/uri/helpers/wsf_uri_routed_service.e @@ -7,35 +7,15 @@ note deferred class WSF_URI_ROUTED_SERVICE +obsolete "Inherit from WSF_ROUTED_SERVICE and WSF_URI_ROUTER_HELPER [2013-mar-19]" + 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_REQUEST_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_REQUEST_METHODS) - do - map_uri_with_request_methods (a_uri, create {WSF_URI_AGENT_HANDLER}.make (proc), rqst_methods) - end + WSF_URI_ROUTER_HELPER note - copyright: "2011-2012, Jocelyn Fiat, Javier Velilla, Olivier Ligot, Eiffel Software and others" + copyright: "2011-2013, Jocelyn Fiat, Javier Velilla, Olivier Ligot, 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/support/uri/helpers/wsf_uri_router_helper.e b/library/server/wsf/router/support/uri/helpers/wsf_uri_router_helper.e new file mode 100644 index 00000000..607e5bb8 --- /dev/null +++ b/library/server/wsf/router/support/uri/helpers/wsf_uri_router_helper.e @@ -0,0 +1,50 @@ +note + description: "Summary description for {WSF_URI_ROUTER_HELPER}." + author: "" + date: "$Date$" + revision: "$Revision$" + +deferred class + WSF_URI_ROUTER_HELPER + +feature -- Access + + router: WSF_ROUTER + deferred + end + +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_REQUEST_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_REQUEST_METHODS) + do + map_uri_with_request_methods (a_uri, create {WSF_URI_AGENT_HANDLER}.make (proc), rqst_methods) + end + +note + copyright: "2011-2012, Jocelyn Fiat, Javier Velilla, Olivier Ligot, 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/support/uri_template/helpers/wsf_uri_template_routed_service.e b/library/server/wsf/router/support/uri_template/helpers/wsf_uri_template_routed_service.e index 7dc8b5a6..8db2b0e0 100644 --- a/library/server/wsf/router/support/uri_template/helpers/wsf_uri_template_routed_service.e +++ b/library/server/wsf/router/support/uri_template/helpers/wsf_uri_template_routed_service.e @@ -7,48 +7,12 @@ note deferred class WSF_URI_TEMPLATE_ROUTED_SERVICE +obsolete "Inherit from WSF_ROUTED_SERVICE and WSF_URI_ROUTER_HELPER [2013-mar-19]" + inherit WSF_ROUTED_SERVICE -feature -- Mapping helper: uri - - map_uri_template (a_tpl: STRING; h: WSF_URI_TEMPLATE_HANDLER) - -- Map `h' as handler for `a_tpl' - require - a_tpl_attached: a_tpl /= Void - h_attached: h /= Void - 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_REQUEST_METHODS) - -- Map `h' as handler for `a_tpl' for request methods `rqst_methods'. - require - a_tpl_attached: a_tpl /= Void - h_attached: h /= Void - 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]]) - -- Map `proc' as handler for `a_tpl' - require - a_tpl_attached: a_tpl /= Void - proc_attached: proc /= Void - 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_REQUEST_METHODS) - -- Map `proc' as handler for `a_tpl' for request methods `rqst_methods'. - require - a_tpl_attached: a_tpl /= Void - proc_attached: proc /= Void - do - map_uri_template_with_request_methods (a_tpl, create {WSF_URI_TEMPLATE_AGENT_HANDLER}.make (proc), rqst_methods) - end + WSF_URI_TEMPLATE_ROUTER_HELPER note copyright: "2011-2013, Jocelyn Fiat, Javier Velilla, Olivier Ligot, Eiffel Software and others" diff --git a/library/server/wsf/router/support/uri_template/helpers/wsf_uri_template_router_helper.e b/library/server/wsf/router/support/uri_template/helpers/wsf_uri_template_router_helper.e new file mode 100644 index 00000000..cf60b7f0 --- /dev/null +++ b/library/server/wsf/router/support/uri_template/helpers/wsf_uri_template_router_helper.e @@ -0,0 +1,66 @@ +note + description: "Summary description for {WSF_URI_TEMPLATE_ROUTER_HELPER}." + author: "" + date: "$Date$" + revision: "$Revision$" + +deferred class + WSF_URI_TEMPLATE_ROUTER_HELPER + +feature -- Access + + router: WSF_ROUTER + deferred + end + +feature -- Mapping helper: uri + + map_uri_template (a_tpl: STRING; h: WSF_URI_TEMPLATE_HANDLER) + -- Map `h' as handler for `a_tpl' + require + a_tpl_attached: a_tpl /= Void + h_attached: h /= Void + 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_REQUEST_METHODS) + -- Map `h' as handler for `a_tpl' for request methods `rqst_methods'. + require + a_tpl_attached: a_tpl /= Void + h_attached: h /= Void + 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]]) + -- Map `proc' as handler for `a_tpl' + require + a_tpl_attached: a_tpl /= Void + proc_attached: proc /= Void + 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_REQUEST_METHODS) + -- Map `proc' as handler for `a_tpl' for request methods `rqst_methods'. + require + a_tpl_attached: a_tpl /= Void + proc_attached: proc /= Void + do + map_uri_template_with_request_methods (a_tpl, create {WSF_URI_TEMPLATE_AGENT_HANDLER}.make (proc), rqst_methods) + end + +note + copyright: "2011-2013, Jocelyn Fiat, Javier Velilla, Olivier Ligot, 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/support/starts_with/helpers/wsf_starts_with_context_routed_service.e b/library/server/wsf/router_context/support/starts_with/helpers/wsf_starts_with_context_routed_service.e index 19480c41..c7b8245e 100644 --- a/library/server/wsf/router_context/support/starts_with/helpers/wsf_starts_with_context_routed_service.e +++ b/library/server/wsf/router_context/support/starts_with/helpers/wsf_starts_with_context_routed_service.e @@ -7,32 +7,12 @@ note deferred class WSF_STARTS_WITH_CONTEXT_ROUTED_SERVICE [C -> WSF_HANDLER_CONTEXT create make end] +obsolete "Inherit from WSF_ROUTED_SERVICE and WSF_STARTS_WITH_CONTEXT_ROUTER_HELPER [2013-mar-19]" + inherit WSF_ROUTED_SERVICE -feature -- Mapping helper: starts_with - - map_starts_with (a_uri: READABLE_STRING_8; h: WSF_STARTS_WITH_CONTEXT_HANDLER [C]) - do - map_starts_with_request_methods (a_uri, h, Void) - end - - map_starts_with_request_methods (a_uri: READABLE_STRING_8; h: WSF_STARTS_WITH_CONTEXT_HANDLER [C]; rqst_methods: detachable WSF_REQUEST_METHODS) - do - router.map_with_request_methods (create {WSF_STARTS_WITH_CONTEXT_MAPPING [C]}.make (a_uri, h), rqst_methods) - end - -feature -- Mapping helper: starts_with agent - - map_starts_with_agent (a_uri: READABLE_STRING_8; proc: PROCEDURE [ANY, TUPLE [start_path: READABLE_STRING_8; ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE]]) - do - map_starts_with_agent_with_request_methods (a_uri, proc, Void) - end - - map_starts_with_agent_with_request_methods (a_uri: READABLE_STRING_8; proc: PROCEDURE [ANY, TUPLE [start_path: READABLE_STRING_8; ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE]]; rqst_methods: detachable WSF_REQUEST_METHODS) - do - map_starts_with_request_methods (a_uri, create {WSF_STARTS_WITH_AGENT_CONTEXT_HANDLER [C] }.make (proc), rqst_methods) - end + WSF_STARTS_WITH_CONTEXT_ROUTER_HELPER [C] note copyright: "2011-2012, Jocelyn Fiat, Javier Velilla, Olivier Ligot, Eiffel Software and others" diff --git a/library/server/wsf/router_context/support/starts_with/helpers/wsf_starts_with_context_router_helper.e b/library/server/wsf/router_context/support/starts_with/helpers/wsf_starts_with_context_router_helper.e new file mode 100644 index 00000000..32fd3f62 --- /dev/null +++ b/library/server/wsf/router_context/support/starts_with/helpers/wsf_starts_with_context_router_helper.e @@ -0,0 +1,50 @@ +note + description: "Summary description for {WSF_STARTS_WITH_CONTEXT_ROUTED_SERVICE}." + author: "" + date: "$Date$" + revision: "$Revision$" + +deferred class + WSF_STARTS_WITH_CONTEXT_ROUTER_HELPER [C -> WSF_HANDLER_CONTEXT create make end] + +feature -- Access + + router: WSF_ROUTER + deferred + end + +feature -- Mapping helper: starts_with + + map_starts_with (a_uri: READABLE_STRING_8; h: WSF_STARTS_WITH_CONTEXT_HANDLER [C]) + do + map_starts_with_request_methods (a_uri, h, Void) + end + + map_starts_with_request_methods (a_uri: READABLE_STRING_8; h: WSF_STARTS_WITH_CONTEXT_HANDLER [C]; rqst_methods: detachable WSF_REQUEST_METHODS) + do + router.map_with_request_methods (create {WSF_STARTS_WITH_CONTEXT_MAPPING [C]}.make (a_uri, h), rqst_methods) + end + +feature -- Mapping helper: starts_with agent + + map_starts_with_agent (a_uri: READABLE_STRING_8; proc: PROCEDURE [ANY, TUPLE [start_path: READABLE_STRING_8; ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE]]) + do + map_starts_with_agent_with_request_methods (a_uri, proc, Void) + end + + map_starts_with_agent_with_request_methods (a_uri: READABLE_STRING_8; proc: PROCEDURE [ANY, TUPLE [start_path: READABLE_STRING_8; ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE]]; rqst_methods: detachable WSF_REQUEST_METHODS) + do + map_starts_with_request_methods (a_uri, create {WSF_STARTS_WITH_AGENT_CONTEXT_HANDLER [C] }.make (proc), rqst_methods) + end + +note + copyright: "2011-2012, Jocelyn Fiat, Javier Velilla, Olivier Ligot, 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/support/uri/helpers/wsf_uri_context_routed_service.e b/library/server/wsf/router_context/support/uri/helpers/wsf_uri_context_routed_service.e index e0e2220b..46be558a 100644 --- a/library/server/wsf/router_context/support/uri/helpers/wsf_uri_context_routed_service.e +++ b/library/server/wsf/router_context/support/uri/helpers/wsf_uri_context_routed_service.e @@ -7,35 +7,16 @@ note deferred class WSF_URI_CONTEXT_ROUTED_SERVICE [C -> WSF_HANDLER_CONTEXT create make end] +obsolete "Inherit from WSF_ROUTED_SERVICE and WSF_URI_CONTEXT_ROUTER_HELPER [2013-mar-19]" + inherit WSF_ROUTED_SERVICE -feature -- Mapping helper: uri + WSF_URI_CONTEXT_ROUTER_HELPER [C] - map_uri (a_uri: READABLE_STRING_8; h: WSF_URI_CONTEXT_HANDLER [C]) - do - map_uri_with_request_methods (a_uri, h, Void) - end - - map_uri_with_request_methods (a_uri: READABLE_STRING_8; h: WSF_URI_CONTEXT_HANDLER [C]; rqst_methods: detachable WSF_REQUEST_METHODS) - do - router.map_with_request_methods (create {WSF_URI_CONTEXT_MAPPING [C]}.make (a_uri, h), rqst_methods) - end - -feature -- Mapping helper: uri agent - - map_uri_agent (a_uri: READABLE_STRING_8; proc: PROCEDURE [ANY, TUPLE [ctx: C; 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 [ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE]]; rqst_methods: detachable WSF_REQUEST_METHODS) - do - map_uri_with_request_methods (a_uri, create {WSF_URI_AGENT_CONTEXT_HANDLER [C] }.make (proc), rqst_methods) - end note - copyright: "2011-2012, Jocelyn Fiat, Javier Velilla, Olivier Ligot, Eiffel Software and others" + copyright: "2011-2013, Jocelyn Fiat, Javier Velilla, Olivier Ligot, 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_context/support/uri/helpers/wsf_uri_context_router_helper.e b/library/server/wsf/router_context/support/uri/helpers/wsf_uri_context_router_helper.e new file mode 100644 index 00000000..db9734cf --- /dev/null +++ b/library/server/wsf/router_context/support/uri/helpers/wsf_uri_context_router_helper.e @@ -0,0 +1,50 @@ +note + description: "Summary description for {WSF_URI_CONTEXT_ROUTER_HELPER}." + author: "" + date: "$Date$" + revision: "$Revision$" + +deferred class + WSF_URI_CONTEXT_ROUTER_HELPER [C -> WSF_HANDLER_CONTEXT create make end] + +feature -- Access + + router: WSF_ROUTER + deferred + end + +feature -- Mapping helper: uri + + map_uri (a_uri: READABLE_STRING_8; h: WSF_URI_CONTEXT_HANDLER [C]) + do + map_uri_with_request_methods (a_uri, h, Void) + end + + map_uri_with_request_methods (a_uri: READABLE_STRING_8; h: WSF_URI_CONTEXT_HANDLER [C]; rqst_methods: detachable WSF_REQUEST_METHODS) + do + router.map_with_request_methods (create {WSF_URI_CONTEXT_MAPPING [C]}.make (a_uri, h), rqst_methods) + end + +feature -- Mapping helper: uri agent + + map_uri_agent (a_uri: READABLE_STRING_8; proc: PROCEDURE [ANY, TUPLE [ctx: C; 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 [ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE]]; rqst_methods: detachable WSF_REQUEST_METHODS) + do + map_uri_with_request_methods (a_uri, create {WSF_URI_AGENT_CONTEXT_HANDLER [C] }.make (proc), rqst_methods) + end + +note + copyright: "2011-2012, Jocelyn Fiat, Javier Velilla, Olivier Ligot, 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/support/uri_template/helpers/wsf_uri_template_context_routed_service.e b/library/server/wsf/router_context/support/uri_template/helpers/wsf_uri_template_context_routed_service.e index 45f698b9..e6ef848b 100644 --- a/library/server/wsf/router_context/support/uri_template/helpers/wsf_uri_template_context_routed_service.e +++ b/library/server/wsf/router_context/support/uri_template/helpers/wsf_uri_template_context_routed_service.e @@ -7,35 +7,15 @@ note deferred class WSF_URI_TEMPLATE_CONTEXT_ROUTED_SERVICE [C -> WSF_HANDLER_CONTEXT create make end] +obsolete "Inherit from WSF_ROUTED_SERVICE and WSF_URI_TEMPLATE_CONTEXT_ROUTER_HELPER [2013-mar-19]" + inherit WSF_ROUTED_SERVICE -feature -- Mapping helper: uri - - map_uri_template (a_tpl: READABLE_STRING_8; 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_CONTEXT_HANDLER [C]; rqst_methods: detachable WSF_REQUEST_METHODS) - do - 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: 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: C; req: WSF_REQUEST; res: WSF_RESPONSE]]; rqst_methods: detachable WSF_REQUEST_METHODS) - do - map_uri_template_with_request_methods (a_tpl, create {WSF_URI_TEMPLATE_AGENT_CONTEXT_HANDLER [C] }.make (proc), rqst_methods) - end + WSF_URI_TEMPLATE_CONTEXT_ROUTER_HELPER [C] note - copyright: "2011-2012, Jocelyn Fiat, Javier Velilla, Olivier Ligot, Eiffel Software and others" + copyright: "2011-2013, Jocelyn Fiat, Javier Velilla, Olivier Ligot, 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_context/support/uri_template/helpers/wsf_uri_template_context_router_helper.e b/library/server/wsf/router_context/support/uri_template/helpers/wsf_uri_template_context_router_helper.e new file mode 100644 index 00000000..d67c4db2 --- /dev/null +++ b/library/server/wsf/router_context/support/uri_template/helpers/wsf_uri_template_context_router_helper.e @@ -0,0 +1,50 @@ +note + description: "Summary description for {WSF_URI_TEMPLATE_CONTEXT_ROUTER_HELPER}." + author: "" + date: "$Date$" + revision: "$Revision$" + +deferred class + WSF_URI_TEMPLATE_CONTEXT_ROUTER_HELPER [C -> WSF_HANDLER_CONTEXT create make end] + +feature -- Access + + router: WSF_ROUTER + deferred + end + +feature -- Mapping helper: uri + + map_uri_template (a_tpl: READABLE_STRING_8; 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_CONTEXT_HANDLER [C]; rqst_methods: detachable WSF_REQUEST_METHODS) + do + 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: 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: C; req: WSF_REQUEST; res: WSF_RESPONSE]]; rqst_methods: detachable WSF_REQUEST_METHODS) + do + map_uri_template_with_request_methods (a_tpl, create {WSF_URI_TEMPLATE_AGENT_CONTEXT_HANDLER [C] }.make (proc), rqst_methods) + end + +note + copyright: "2011-2012, Jocelyn Fiat, Javier Velilla, Olivier Ligot, 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 f502e6a6f7b76162cfccd29cb2d42eb7651d301c Mon Sep 17 00:00:00 2001 From: Jocelyn Fiat Date: Tue, 19 Mar 2013 17:17:44 +0100 Subject: [PATCH 12/23] Updated WSF_NOT_IMPLEMENTED_RESPONSE to include the request uri --- library/server/wsf/src/response/wsf_not_implemented_response.e | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/library/server/wsf/src/response/wsf_not_implemented_response.e b/library/server/wsf/src/response/wsf_not_implemented_response.e index 297dafc3..d97388d1 100644 --- a/library/server/wsf/src/response/wsf_not_implemented_response.e +++ b/library/server/wsf/src/response/wsf_not_implemented_response.e @@ -54,7 +54,8 @@ feature {WSF_RESPONSE} -- Output h := header res.set_status_code ({HTTP_STATUS_CODE}.not_implemented) - s := "Error 501 Not Implemented !" + s := "Error 501 Not Implemented ! " + s.append (request.request_uri) if attached body as b then s.append ("%N") s.append (b) From 115b622724f58fe4e2bf228594ae6189dd931d41 Mon Sep 17 00:00:00 2001 From: Jocelyn Fiat Date: Tue, 19 Mar 2013 17:17:59 +0100 Subject: [PATCH 13/23] updated install and uninstall scripts --- tools/install_ewf.bat | 5 +++++ tools/install_ewf.sh | 3 +++ tools/uninstall_ewf.bat | 6 +++++- 3 files changed, 13 insertions(+), 1 deletion(-) diff --git a/tools/install_ewf.bat b/tools/install_ewf.bat index 0b8c344f..87f82c80 100644 --- a/tools/install_ewf.bat +++ b/tools/install_ewf.bat @@ -77,6 +77,11 @@ echo Install library: http echo Install library: http_authorization %SAFE_MD% %TMP_CONTRIB_DIR%\library\network\authentication %COPYCMD% %TMP_DIR%\library\server\authentication\http_authorization %TMP_CONTRIB_DIR%\library\network\authentication\http_authorization + +echo Install library: openid +%SAFE_MD% %TMP_CONTRIB_DIR%\library\security +%COPYCMD% %TMP_DIR%\library\security\openid %TMP_CONTRIB_DIR%\library\security\openid + echo Install library: uri_template %COPYCMD% %TMP_DIR%\library\text\parser\uri_template %TMP_CONTRIB_DIR%\library\text\parser\uri_template diff --git a/tools/install_ewf.sh b/tools/install_ewf.sh index 1275abb6..b36c5bfd 100644 --- a/tools/install_ewf.sh +++ b/tools/install_ewf.sh @@ -70,6 +70,9 @@ COPYCMD $TMP_DIR/library/network/protocol/http $TMP_CONTRIB_DIR/library/network/ echo Install library: http_authorization mkdir -p $TMP_CONTRIB_DIR/library/network/authentication COPYCMD $TMP_DIR/library/server/authentication/http_authorization $TMP_CONTRIB_DIR/library/network/authentication/http_authorization +echo Install library: openid +mkdir -p $TMP_CONTRIB_DIR/library/security/openid +COPYCMD $TMP_DIR/library/security/openid $TMP_CONTRIB_DIR/library/security/openid echo Install library: uri_template mkdir -p $TMP_CONTRIB_DIR/library/text/parser COPYCMD $TMP_DIR/library/text/parser/uri_template $TMP_CONTRIB_DIR/library/text/parser/uri_template diff --git a/tools/uninstall_ewf.bat b/tools/uninstall_ewf.bat index 6f76a298..5bee1b31 100644 --- a/tools/uninstall_ewf.bat +++ b/tools/uninstall_ewf.bat @@ -54,10 +54,14 @@ echo Uninstall library: http_client %RDCMD% %TMP_CONTRIB_DIR%\library\network\http_client echo Uninstall library: http %RDCMD% %TMP_CONTRIB_DIR%\library\network\protocol\http +echo Uninstall library: http_authorization +%RDCMD% %TMP_CONTRIB_DIR%\library\network\authentication\http_authorization +echo Uninstall library: security\openid +%RDCMD% %TMP_CONTRIB_DIR%\library\security\openid echo Uninstall library: uri_template %RDCMD% %TMP_CONTRIB_DIR%\library\text\parser\uri_template echo Uninstall contrib library: nino -%RDCMD% %TMP_CONTRIB_DIR%\contrib\library\network\server\nino +%RDCMD% %TMP_CONTRIB_DIR%\library\network\server\nino :end From 3f237c737dfe60d30f24e851a1b2dfb1a1842e64 Mon Sep 17 00:00:00 2001 From: Jocelyn Fiat Date: Tue, 19 Mar 2013 22:00:25 +0100 Subject: [PATCH 14/23] mimic design of WSF_ROUTED_SERVICE for WSF_FILTERED_SERVICE and update the filter example to make it simpler and reuse code. --- examples/filter/src/filter_server.e | 61 ++++++++----------- .../wsf/router/filter/wsf_filtered_service.e | 9 ++- 2 files changed, 34 insertions(+), 36 deletions(-) diff --git a/examples/filter/src/filter_server.e b/examples/filter/src/filter_server.e index 9061e1f1..92b579c4 100644 --- a/examples/filter/src/filter_server.e +++ b/examples/filter/src/filter_server.e @@ -10,12 +10,22 @@ class inherit ANY - WSF_FILTERED_SERVICE - WSF_HANDLER_HELPER WSF_DEFAULT_SERVICE + WSF_ROUTED_SERVICE + rename + execute as execute_router + end + + WSF_FILTERED_SERVICE + + WSF_FILTER + rename + execute as execute_router + end + SHARED_EJSON create @@ -28,7 +38,7 @@ feature {NONE} -- Initialization l_message: STRING l_factory: INET_ADDRESS_FACTORY do - create router.make (1) + initialize_router initialize_filter initialize_json set_service_option ("port", port) @@ -45,39 +55,39 @@ feature {NONE} -- Initialization create_filter -- Create `filter' - local - l_cors_filter: WSF_CORS_FILTER do - create l_cors_filter - filter := l_cors_filter + create {WSF_CORS_FILTER} filter end setup_filter -- Setup `filter' + local + l_logging_filter: WSF_LOGGING_FILTER + do + create l_logging_filter + filter.set_next (l_logging_filter) + l_logging_filter.set_next (Current) + end + + setup_router + -- Setup `router' local l_options_filter: WSF_CORS_OPTIONS_FILTER l_authentication_filter: AUTHENTICATION_FILTER l_user_filter: USER_HANDLER l_methods: WSF_REQUEST_METHODS - l_routing_filter: WSF_ROUTING_FILTER - l_logging_filter: WSF_LOGGING_FILTER do create l_options_filter.make (router) create l_authentication_filter - l_options_filter.set_next (l_authentication_filter) create l_user_filter + + l_options_filter.set_next (l_authentication_filter) l_authentication_filter.set_next (l_user_filter) create l_methods l_methods.enable_options l_methods.enable_get router.handle_with_request_methods ("/user/{userid}", create {WSF_URI_TEMPLATE_AGENT_HANDLER}.make (agent l_options_filter.execute), l_methods) - create l_routing_filter.make (router) - l_routing_filter.set_execute_default_action (agent execute_default) - filter.set_next (l_routing_filter) - - create l_logging_filter - l_routing_filter.set_next (l_logging_filter) end initialize_json @@ -86,30 +96,11 @@ feature {NONE} -- Initialization json.add_converter (create {JSON_USER_CONVERTER}.make) end -feature -- Basic operations - - execute (req: WSF_REQUEST; res: WSF_RESPONSE) - do - filter.execute (req, res) - end - - execute_default (req: WSF_REQUEST; res: WSF_RESPONSE) - local - l_message: WSF_DEFAULT_ROUTER_RESPONSE - do - create l_message.make_with_router (req, router) - l_message.set_documentation_included (True) - res.send (l_message) - end - feature {NONE} -- Implementation port: INTEGER = 9090 -- Port number - router: WSF_ROUTER; - -- Router - note copyright: "2011-2013, Olivier Ligot, Jocelyn Fiat and others" license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)" diff --git a/library/server/wsf/router/filter/wsf_filtered_service.e b/library/server/wsf/router/filter/wsf_filtered_service.e index f60740e0..f7cb826d 100644 --- a/library/server/wsf/router/filter/wsf_filtered_service.e +++ b/library/server/wsf/router/filter/wsf_filtered_service.e @@ -35,8 +35,15 @@ feature -- Access filter: WSF_FILTER -- Filter +feature -- Execution + + execute (req: WSF_REQUEST; res: WSF_RESPONSE) + do + filter.execute (req, res) + end + ;note - copyright: "2011-2012, Jocelyn Fiat, Javier Velilla, Olivier Ligot, Eiffel Software and others" + copyright: "2011-2013, Jocelyn Fiat, Javier Velilla, Olivier Ligot, Eiffel Software and others" license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)" source: "[ Eiffel Software From ade9a30c035692cc57c8e764efde08bba0d911ff Mon Sep 17 00:00:00 2001 From: Jocelyn Fiat Date: Thu, 21 Mar 2013 15:23:08 +0100 Subject: [PATCH 15/23] Fixed WSF_FILE_RESPONSE and WSF_DOWNLOAD_RESPONSE and set the status code to be Ok by default --- .../wsf/src/response/wsf_download_response.e | 17 +++++++++++++++-- .../server/wsf/src/response/wsf_file_response.e | 4 +++- 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/library/server/wsf/src/response/wsf_download_response.e b/library/server/wsf/src/response/wsf_download_response.e index aa8b7f3f..fada53f8 100644 --- a/library/server/wsf/src/response/wsf_download_response.e +++ b/library/server/wsf/src/response/wsf_download_response.e @@ -19,6 +19,7 @@ feature {NONE} -- Initialization make (a_file_name: READABLE_STRING_8) do + set_status_code ({HTTP_STATUS_CODE}.ok) file_name := a_file_name base_name := basename (a_file_name) get_content_type @@ -28,6 +29,7 @@ feature {NONE} -- Initialization make_with_content_type (a_content_type: READABLE_STRING_8; a_filename: READABLE_STRING_8) -- Initialize `Current'. do + set_status_code ({HTTP_STATUS_CODE}.ok) file_name := a_filename base_name := basename (a_filename) content_type := a_content_type @@ -54,6 +56,14 @@ feature {NONE} -- Initialization feature -- Element change + set_base_name (n: like base_name) + do + base_name := n + header.put_content_disposition ("attachment", "filename=%""+ n +"%"") + ensure + base_name_set: n.same_string (base_name) + end + set_expires (t: INTEGER) do header.put_expires (t) @@ -91,7 +101,7 @@ feature -- Element change set_status_code (c: like status_code) -- Set `status_code' to `c'. require - valid_status_code: status_code > 0 + valid_status_code: c > 0 do status_code := c ensure @@ -207,8 +217,11 @@ feature -- Implementation: output f.close end +invariant + status_code_set: status_code /= 0 + note - copyright: "2011-2012, Jocelyn Fiat, Javier Velilla, Olivier Ligot, Eiffel Software and others" + copyright: "2011-2013, Jocelyn Fiat, Javier Velilla, Olivier Ligot, 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/src/response/wsf_file_response.e b/library/server/wsf/src/response/wsf_file_response.e index 790cd944..8d00455b 100644 --- a/library/server/wsf/src/response/wsf_file_response.e +++ b/library/server/wsf/src/response/wsf_file_response.e @@ -19,6 +19,7 @@ feature {NONE} -- Initialization make (a_file_name: READABLE_STRING_8) do + set_status_code ({HTTP_STATUS_CODE}.ok) file_name := a_file_name get_content_type initialize @@ -27,6 +28,7 @@ feature {NONE} -- Initialization make_with_content_type (a_content_type: READABLE_STRING_8; a_filename: READABLE_STRING_8) -- Initialize `Current'. do + set_status_code ({HTTP_STATUS_CODE}.ok) file_name := a_filename content_type := a_content_type initialize @@ -279,7 +281,7 @@ feature {NONE} -- Implementation: output end note - copyright: "2011-2012, Jocelyn Fiat, Javier Velilla, Olivier Ligot, Eiffel Software and others" + copyright: "2011-2013, Jocelyn Fiat, Javier Velilla, Olivier Ligot, Eiffel Software and others" license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)" source: "[ Eiffel Software From 7c7bf9a3f8180453f1867504e5c603ef59e4584f Mon Sep 17 00:00:00 2001 From: Jocelyn Fiat Date: Thu, 21 Mar 2013 15:41:46 +0100 Subject: [PATCH 16/23] Introduced WSF_ROUTER_SESSION This fixes CQS violation from WSF_ROUTER.dispatch_and_return_handler (...): ? WSF_HANDLER and related code, and this is more compliant with concurrency. In addition, the WSF_ROUTER_SESSION can be enhanced in the future to answer more advanced needs. --- .../wsf/router/filter/wsf_routing_filter.e | 10 ++-- .../starts_with/wsf_starts_with_mapping_i.e | 6 +- .../router/support/uri/wsf_uri_mapping_i.e | 6 +- .../uri_template/wsf_uri_template_mapping_i.e | 8 +-- .../server/wsf/router/wsf_routed_service.e | 8 ++- library/server/wsf/router/wsf_router.e | 59 +++++++++++-------- .../server/wsf/router/wsf_router_mapping.e | 19 +++--- .../server/wsf/router/wsf_router_session.e | 46 +++++++++++++++ .../server/wsf/router/wsf_routing_handler.e | 10 ++-- 9 files changed, 118 insertions(+), 54 deletions(-) create mode 100644 library/server/wsf/router/wsf_router_session.e diff --git a/library/server/wsf/router/filter/wsf_routing_filter.e b/library/server/wsf/router/filter/wsf_routing_filter.e index d1018610..7f398ef4 100644 --- a/library/server/wsf/router/filter/wsf_routing_filter.e +++ b/library/server/wsf/router/filter/wsf_routing_filter.e @@ -44,10 +44,12 @@ feature -- Basic operations execute (req: WSF_REQUEST; res: WSF_RESPONSE) -- Execute the filter + local + sess: WSF_ROUTER_SESSION do - if attached router.dispatch_and_return_handler (req, res) then - check router.is_dispatched end - else + create sess + router.dispatch (req, res, sess) + if not sess.dispatched then execute_default (req, res) end execute_next (req, res) @@ -63,7 +65,7 @@ feature -- Basic operations end note - copyright: "2011-2012, Jocelyn Fiat, Javier Velilla, Olivier Ligot, Eiffel Software and others" + copyright: "2011-2013, Jocelyn Fiat, Javier Velilla, Olivier Ligot, 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/support/starts_with/wsf_starts_with_mapping_i.e b/library/server/wsf/router/support/starts_with/wsf_starts_with_mapping_i.e index 7618171c..63774e5f 100644 --- a/library/server/wsf/router/support/starts_with/wsf_starts_with_mapping_i.e +++ b/library/server/wsf/router/support/starts_with/wsf_starts_with_mapping_i.e @@ -58,7 +58,7 @@ feature -- Status Result := p.starts_with (s) end - routed_handler (req: WSF_REQUEST; res: WSF_RESPONSE; a_router: WSF_ROUTER): detachable WSF_HANDLER + try (req: WSF_REQUEST; res: WSF_RESPONSE; sess: WSF_ROUTER_SESSION; a_router: WSF_ROUTER) -- Return the handler if Current matches the request `req'. local p: READABLE_STRING_8 @@ -67,7 +67,7 @@ feature -- Status p := path_from_request (req) s := based_uri (uri, a_router) if p.starts_with (s) then - Result := handler + sess.set_dispatched_handler (handler) a_router.execute_before (Current) execute_handler (handler, s, req, res) a_router.execute_after (Current) @@ -113,7 +113,7 @@ invariant uri_attached: uri /= Void note - copyright: "2011-2012, Jocelyn Fiat, Javier Velilla, Olivier Ligot, Eiffel Software and others" + copyright: "2011-2013, Jocelyn Fiat, Javier Velilla, Olivier Ligot, 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/support/uri/wsf_uri_mapping_i.e b/library/server/wsf/router/support/uri/wsf_uri_mapping_i.e index cac518fd..aa69a860 100644 --- a/library/server/wsf/router/support/uri/wsf_uri_mapping_i.e +++ b/library/server/wsf/router/support/uri/wsf_uri_mapping_i.e @@ -72,10 +72,10 @@ feature -- Status end end - routed_handler (req: WSF_REQUEST; res: WSF_RESPONSE; a_router: WSF_ROUTER): detachable WSF_HANDLER + try (req: WSF_REQUEST; res: WSF_RESPONSE; sess: WSF_ROUTER_SESSION; a_router: WSF_ROUTER) do if is_mapping (req, a_router) then - Result := handler + sess.set_dispatched_handler (handler) a_router.execute_before (Current) execute_handler (handler, req, res) a_router.execute_after (Current) @@ -105,7 +105,7 @@ feature {NONE} -- Implementation end note - copyright: "2011-2012, Jocelyn Fiat, Javier Velilla, Olivier Ligot, Eiffel Software and others" + copyright: "2011-2013, Jocelyn Fiat, Javier Velilla, Olivier Ligot, 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/support/uri_template/wsf_uri_template_mapping_i.e b/library/server/wsf/router/support/uri_template/wsf_uri_template_mapping_i.e index 0a047949..f1430fa0 100644 --- a/library/server/wsf/router/support/uri_template/wsf_uri_template_mapping_i.e +++ b/library/server/wsf/router/support/uri_template/wsf_uri_template_mapping_i.e @@ -24,7 +24,7 @@ feature {NONE} -- Initialization -- Create with `h' as the handler for resources matching `tpl' require tpl_attached: tpl /= Void - h_attached: h /= Void + h_attached: h /= Void do template := tpl set_handler (h) @@ -68,7 +68,7 @@ feature -- Status Result := tpl.match (p) /= Void end - routed_handler (req: WSF_REQUEST; res: WSF_RESPONSE; a_router: WSF_ROUTER): detachable WSF_HANDLER + try (req: WSF_REQUEST; res: WSF_RESPONSE; sess: WSF_ROUTER_SESSION; a_router: WSF_ROUTER) -- local tpl: URI_TEMPLATE @@ -78,7 +78,7 @@ feature -- Status p := path_from_request (req) tpl := based_uri_template (template, a_router) if attached tpl.match (p) as tpl_res then - Result := handler + sess.set_dispatched_handler (handler) a_router.execute_before (Current) --| Applied the context to the request --| in practice, this will fill the {WSF_REQUEST}.path_parameters @@ -126,7 +126,7 @@ feature {NONE} -- Implementation end note - copyright: "2011-2012, Jocelyn Fiat, Javier Velilla, Olivier Ligot, Eiffel Software and others" + copyright: "2011-2013, Jocelyn Fiat, Javier Velilla, Olivier Ligot, 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/wsf_routed_service.e b/library/server/wsf/router/wsf_routed_service.e index 5f2c3499..06cd6a9e 100644 --- a/library/server/wsf/router/wsf_routed_service.e +++ b/library/server/wsf/router/wsf_routed_service.e @@ -40,10 +40,12 @@ feature -- Execution require req_attached: req /= Void res_attached: res /= Void + local + sess: WSF_ROUTER_SESSION do - if attached router.dispatch_and_return_handler (req, res) as p then - -- executed - else + create sess + router.dispatch (req, res, sess) + if not sess.dispatched then execute_default (req, res) end end diff --git a/library/server/wsf/router/wsf_router.e b/library/server/wsf/router/wsf_router.e index 08a9c965..095a9b9b 100644 --- a/library/server/wsf/router/wsf_router.e +++ b/library/server/wsf/router/wsf_router.e @@ -112,75 +112,84 @@ feature -- Mapping handler map_with_request_methods (f.new_mapping (a_resource), rqst_methods) end -feature -- Access - - is_dispatched: BOOLEAN - -- `dispatch' set `is_dispatched' to True - -- if mapping was found, and associated handler executed - feature -- Basic operations - dispatch (req: WSF_REQUEST; res: WSF_RESPONSE) + dispatch (req: WSF_REQUEST; res: WSF_RESPONSE; sess: detachable WSF_ROUTER_SESSION) -- Dispatch request `req' among the `mappings'. - -- Set `is_dispatched' if the request were dispatched. + -- Set `sess' if the request were dispatched and `sess' attached. require req_attached: req /= Void res_attached: res /= Void + local + l_sess: detachable WSF_ROUTER_SESSION do - if attached dispatch_and_return_handler (req, res) then - check is_dispatched: is_dispatched end + l_sess := sess + if l_sess = Void then + create l_sess end + router_dispatch (req, res, l_sess) 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. --| Violates CQS + obsolete + "Use `dispatch' [2013-mar-21]" require req_attached: req /= Void res_attached: res /= Void + local + sess: WSF_ROUTER_SESSION + do + create sess + router_dispatch (req, res, sess) + Result := sess.dispatched_handler + end + +feature {NONE} -- Dispatch implementation + + router_dispatch (req: WSF_REQUEST; res: WSF_RESPONSE; sess: WSF_ROUTER_SESSION) + require + req_attached: req /= Void + res_attached: res /= Void + sess_attached: sess /= Void + sess_not_dispatched: not sess.dispatched local l_req_method: READABLE_STRING_8 head_res: WSF_HEAD_RESPONSE_WRAPPER do l_req_method := request_method (req) - is_dispatched := False - Result := dispatch_and_return_handler_for_request_method (req, res, l_req_method) - if Result = Void and l_req_method = {HTTP_REQUEST_METHODS}.method_head then - check is_not_dispatched: not is_dispatched end + router_dispatch_for_request_method (req, res, sess, l_req_method) + if not sess.dispatched and l_req_method = {HTTP_REQUEST_METHODS}.method_head then create head_res.make_from_response (res) req.set_request_method ({HTTP_REQUEST_METHODS}.method_GET) - Result := dispatch_and_return_handler_for_request_method (req, head_res, {HTTP_REQUEST_METHODS}.method_GET) + router_dispatch_for_request_method (req, head_res, sess, {HTTP_REQUEST_METHODS}.method_GET) end end -feature {NONE} -- Dispatch implementation - - dispatch_and_return_handler_for_request_method (req: WSF_REQUEST; res: WSF_RESPONSE; a_request_method: READABLE_STRING_8): detachable WSF_HANDLER + router_dispatch_for_request_method (req: WSF_REQUEST; res: WSF_RESPONSE; sess: WSF_ROUTER_SESSION; a_request_method: READABLE_STRING_8) -- Dispatch request `req' among the `mappings' -- And return the associated handler if mapping found and handler executed. --| Violates CQS require req_attached: req /= Void res_attached: res /= Void + sess_attached: sess /= Void + sess_not_dispatched: not sess.dispatched a_request_method_attached: a_request_method /= Void local m: WSF_ROUTER_MAPPING do - is_dispatched := False - across mappings as c until - Result /= Void + sess.dispatched loop if attached c.item as l_info then if is_matching_request_methods (a_request_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 + m.try (req, res, sess, Current) end end end diff --git a/library/server/wsf/router/wsf_router_mapping.e b/library/server/wsf/router/wsf_router_mapping.e index 89f53303..6f7b4605 100644 --- a/library/server/wsf/router/wsf_router_mapping.e +++ b/library/server/wsf/router/wsf_router_mapping.e @@ -1,6 +1,7 @@ note - description: "Summary description for {WSF_ROUTER_MAPPING}." - author: "" + description: "[ + Describes a route or mapping for the WSF_ROUTER + ]" date: "$Date$" revision: "$Revision$" @@ -23,14 +24,14 @@ feature {NONE} -- Initialization feature -- Access associated_resource: READABLE_STRING_8 - -- Name (URI, or URI template or regular expression or ...) of handled resource + -- Name (URI, or URI template or regular expression or ...) of handled resource. deferred ensure assciated_resource_not_void: Result /= Void end handler: WSF_HANDLER - -- Handler associated with `Current' mapping + -- Handler associated with `Current' mapping. deferred ensure handler_attached: Result /= Void @@ -39,7 +40,7 @@ feature -- Access feature -- Documentation description: READABLE_STRING_32 - -- Short description of associated mapping + -- Short description of associated mapping. deferred ensure description_attached: Result /= Void @@ -63,11 +64,13 @@ feature -- Status deferred end - routed_handler (req: WSF_REQUEST; res: WSF_RESPONSE; a_router: WSF_ROUTER): detachable WSF_HANDLER - -- Handler when `Current' matches the request `req' + try (req: WSF_REQUEST; res: WSF_RESPONSE; sess: WSF_ROUTER_SESSION; a_router: WSF_ROUTER) + -- Try using `Current' mapping and if it matches request `req' + -- execute associated handler and set this handler in session `sess'. require req_attached: req /= Void res_attached: res /= Void + sess_attached: sess /= Void a_router_attached: a_router /= Void deferred end @@ -75,7 +78,7 @@ feature -- Status feature -- Helper path_from_request (req: WSF_REQUEST): READABLE_STRING_32 - -- Path used by `Current' to check that mapping matches request `req' + -- Path used by `Current' to check that mapping matches request `req'. require req_attached: req /= Void do diff --git a/library/server/wsf/router/wsf_router_session.e b/library/server/wsf/router/wsf_router_session.e new file mode 100644 index 00000000..e5af83d0 --- /dev/null +++ b/library/server/wsf/router/wsf_router_session.e @@ -0,0 +1,46 @@ +note + description: "[ + This class represents the processing of a request via a WSF_ROUTER. + + ]" + date: "$Date$" + revision: "$Revision$" + +class + WSF_ROUTER_SESSION + +feature -- Status report + + dispatched: BOOLEAN + -- Handler dispatched? + do + Result := dispatched_handler /= Void + ensure + Result implies dispatched_handler /= Void + end + +feature -- Access + + dispatched_handler: detachable WSF_HANDLER + -- Handler dispatched + +feature -- Change + + set_dispatched_handler (h: like dispatched_handler) + do + dispatched_handler := h + ensure + h_set: dispatched_handler = h + end + +note + copyright: "2011-2013, Jocelyn Fiat, Javier Velilla, Olivier Ligot, 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_routing_handler.e b/library/server/wsf/router/wsf_routing_handler.e index 94b97fed..5aa855e5 100644 --- a/library/server/wsf/router/wsf_routing_handler.e +++ b/library/server/wsf/router/wsf_routing_handler.e @@ -54,16 +54,18 @@ feature -- Execution execute (req: WSF_REQUEST; res: WSF_RESPONSE) -- Execute request handler + local + sess: WSF_ROUTER_SESSION do - if attached router.dispatch_and_return_handler (req, res) as h then - check is_dispatched: router.is_dispatched end - else + create sess + router.dispatch (req, res, sess) + if not sess.dispatched then 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, Olivier Ligot, Eiffel Software and others" + copyright: "2011-2013, Jocelyn Fiat, Javier Velilla, Olivier Ligot, Eiffel Software and others" license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)" source: "[ Eiffel Software From 78c83a4b698f31167d8aa34a5e3263d226f46d74 Mon Sep 17 00:00:00 2001 From: Jocelyn Fiat Date: Thu, 21 Mar 2013 15:42:16 +0100 Subject: [PATCH 17/23] Added HTTP_AUTHORIZATION.is_basic: BOOLEAN query to know if this is a Basic HTTP Authorization. --- .../http_authorization/src/http_authorization.e | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/library/server/authentication/http_authorization/src/http_authorization.e b/library/server/authentication/http_authorization/src/http_authorization.e index 6d1877a7..9e00dc70 100644 --- a/library/server/authentication/http_authorization/src/http_authorization.e +++ b/library/server/authentication/http_authorization/src/http_authorization.e @@ -92,5 +92,19 @@ feature -- Access http_authorization: detachable IMMUTABLE_STRING_8 +feature -- Status report + + is_basic: BOOLEAN + -- Is Basic authorization? + do + if attached type as t then + Result := t.same_string ("basic") + end + end + +invariant + + type_is_lower: attached type as t implies t.same_string (t.as_lower) + end From 19df76c3326a91a6fb9f757b9657dfb0710f4ac8 Mon Sep 17 00:00:00 2001 From: Jocelyn Fiat Date: Thu, 21 Mar 2013 15:44:29 +0100 Subject: [PATCH 18/23] Added WSF_HANDLER_FILTER_WRAPPER to build a bridge from router to filter. --- .../filter/wsf_handler_filter_wrapper.e | 46 +++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 library/server/wsf/router/filter/wsf_handler_filter_wrapper.e diff --git a/library/server/wsf/router/filter/wsf_handler_filter_wrapper.e b/library/server/wsf/router/filter/wsf_handler_filter_wrapper.e new file mode 100644 index 00000000..9a6285a2 --- /dev/null +++ b/library/server/wsf/router/filter/wsf_handler_filter_wrapper.e @@ -0,0 +1,46 @@ +note + description: "[ + Handler wrapping a filter + ]" + author: "" + date: "$Date$" + revision: "$Revision$" + +class + WSF_HANDLER_FILTER_WRAPPER + +inherit + WSF_HANDLER + +create + make_with_filter + +feature {NONE} -- Initialization + + make_with_filter (f: WSF_FILTER) + do + filter := f + end + +feature -- Access + + filter: WSF_FILTER + +feature -- Execution + + execute (req: WSF_REQUEST; res: WSF_RESPONSE) + do + filter.execute (req, res) + end + +note + copyright: "2011-2013, Jocelyn Fiat, Javier Velilla, Olivier Ligot, 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 1f76fd53605196dea3f1252691b0438b78a2afc3 Mon Sep 17 00:00:00 2001 From: Jocelyn Fiat Date: Thu, 21 Mar 2013 15:47:10 +0100 Subject: [PATCH 19/23] Now WSF_FILTER_HANDLER is a handler and has formal generic G constrained to WSF_HANDLER This eases implementation of potential descendants. --- .../server/wsf/router/filter/wsf_filter_handler.e | 6 +++--- .../helpers/wsf_starts_with_filter_handler.e | 12 ++---------- .../support/uri/helpers/wsf_uri_filter_handler.e | 12 ++---------- .../helpers/wsf_uri_template_filter_handler.e | 12 ++---------- .../wsf/router_context/wsf_filter_context_handler.e | 12 ++---------- 5 files changed, 11 insertions(+), 43 deletions(-) diff --git a/library/server/wsf/router/filter/wsf_filter_handler.e b/library/server/wsf/router/filter/wsf_filter_handler.e index 7fc63ca1..0fa0ccbb 100644 --- a/library/server/wsf/router/filter/wsf_filter_handler.e +++ b/library/server/wsf/router/filter/wsf_filter_handler.e @@ -8,14 +8,14 @@ note revision: "$Revision$" deferred class - WSF_FILTER_HANDLER + WSF_FILTER_HANDLER [G -> WSF_HANDLER] inherit WSF_HANDLER feature -- Access - next: detachable WSF_HANDLER + next: detachable G -- Next handler feature -- Element change @@ -29,7 +29,7 @@ feature -- Element change end note - copyright: "2011-2012, Jocelyn Fiat, Javier Velilla, Olivier Ligot, Eiffel Software and others" + copyright: "2011-2013, Jocelyn Fiat, Javier Velilla, Olivier Ligot, 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/support/starts_with/helpers/wsf_starts_with_filter_handler.e b/library/server/wsf/router/support/starts_with/helpers/wsf_starts_with_filter_handler.e index fe3c15c8..3fd11575 100644 --- a/library/server/wsf/router/support/starts_with/helpers/wsf_starts_with_filter_handler.e +++ b/library/server/wsf/router/support/starts_with/helpers/wsf_starts_with_filter_handler.e @@ -8,18 +8,10 @@ deferred class WSF_STARTS_WITH_FILTER_HANDLER inherit - WSF_FILTER_HANDLER - redefine - next - end + WSF_FILTER_HANDLER [WSF_STARTS_WITH_HANDLER] WSF_STARTS_WITH_HANDLER -feature -- Access - - next: detachable WSF_STARTS_WITH_FILTER_HANDLER - -- Next handler - feature -- Execution execute_next (a_start_path: READABLE_STRING_8; req: WSF_REQUEST; res: WSF_RESPONSE) @@ -30,7 +22,7 @@ feature -- Execution end note - copyright: "2011-2012, Jocelyn Fiat, Javier Velilla, Olivier Ligot, Eiffel Software and others" + copyright: "2011-2013, Jocelyn Fiat, Javier Velilla, Olivier Ligot, 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/support/uri/helpers/wsf_uri_filter_handler.e b/library/server/wsf/router/support/uri/helpers/wsf_uri_filter_handler.e index 79ae3970..2758c84a 100644 --- a/library/server/wsf/router/support/uri/helpers/wsf_uri_filter_handler.e +++ b/library/server/wsf/router/support/uri/helpers/wsf_uri_filter_handler.e @@ -8,18 +8,10 @@ deferred class WSF_URI_FILTER_HANDLER inherit - WSF_FILTER_HANDLER - redefine - next - end + WSF_FILTER_HANDLER [WSF_URI_HANDLER] WSF_URI_HANDLER -feature -- Access - - next: detachable WSF_URI_FILTER_HANDLER - -- Next handler - feature -- Execution execute_next (req: WSF_REQUEST; res: WSF_RESPONSE) @@ -30,7 +22,7 @@ feature -- Execution end note - copyright: "2011-2012, Jocelyn Fiat, Javier Velilla, Olivier Ligot, Eiffel Software and others" + copyright: "2011-2013, Jocelyn Fiat, Javier Velilla, Olivier Ligot, 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/support/uri_template/helpers/wsf_uri_template_filter_handler.e b/library/server/wsf/router/support/uri_template/helpers/wsf_uri_template_filter_handler.e index e6a1d02a..8762a0e2 100644 --- a/library/server/wsf/router/support/uri_template/helpers/wsf_uri_template_filter_handler.e +++ b/library/server/wsf/router/support/uri_template/helpers/wsf_uri_template_filter_handler.e @@ -8,18 +8,10 @@ deferred class WSF_URI_TEMPLATE_FILTER_HANDLER inherit - WSF_FILTER_HANDLER - redefine - next - end + WSF_FILTER_HANDLER [WSF_URI_TEMPLATE_HANDLER] WSF_URI_TEMPLATE_HANDLER -feature -- Access - - next: detachable WSF_URI_TEMPLATE_HANDLER - -- Next handler - feature -- Execution execute_next (req: WSF_REQUEST; res: WSF_RESPONSE) @@ -30,7 +22,7 @@ feature -- Execution end note - copyright: "2011-2012, Jocelyn Fiat, Javier Velilla, Olivier Ligot, Eiffel Software and others" + copyright: "2011-2013, Jocelyn Fiat, Javier Velilla, Olivier Ligot, 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_context/wsf_filter_context_handler.e b/library/server/wsf/router_context/wsf_filter_context_handler.e index 761d509f..b137e066 100644 --- a/library/server/wsf/router_context/wsf_filter_context_handler.e +++ b/library/server/wsf/router_context/wsf_filter_context_handler.e @@ -8,18 +8,10 @@ deferred class WSF_FILTER_CONTEXT_HANDLER [C -> WSF_HANDLER_CONTEXT create make end] inherit - WSF_FILTER_HANDLER - redefine - next - end + WSF_FILTER_HANDLER [WSF_CONTEXT_HANDLER [C]] WSF_CONTEXT_HANDLER [C] -feature -- Access - - next: detachable WSF_CONTEXT_HANDLER [C] - -- Next handler - feature {NONE} -- Implementation execute_next (ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE) @@ -30,7 +22,7 @@ feature {NONE} -- Implementation end note - copyright: "2011-2012, Jocelyn Fiat, Javier Velilla, Olivier Ligot, Eiffel Software and others" + copyright: "2011-2013, Jocelyn Fiat, Javier Velilla, Olivier Ligot, Eiffel Software and others" license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)" source: "[ Eiffel Software From 62d880a7c106ea95bfc417d8ed2f4fe38a7b7fc7 Mon Sep 17 00:00:00 2001 From: Jocelyn Fiat Date: Thu, 21 Mar 2013 15:47:52 +0100 Subject: [PATCH 20/23] Fixed signature of `set_next' to allow redefinition. Added assertions --- library/server/wsf/router/filter/wsf_filter.e | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/library/server/wsf/router/filter/wsf_filter.e b/library/server/wsf/router/filter/wsf_filter.e index 7b6e5136..9e4ea502 100644 --- a/library/server/wsf/router/filter/wsf_filter.e +++ b/library/server/wsf/router/filter/wsf_filter.e @@ -14,7 +14,7 @@ feature -- Access feature -- Element change - set_next (a_next: WSF_FILTER) + set_next (a_next: like next) -- Set `next' to `a_next' do next := a_next @@ -26,6 +26,9 @@ feature -- Basic operations execute (req: WSF_REQUEST; res: WSF_RESPONSE) -- Execute the filter. + require + req_attached: req /= Void + res_attached: res /= Void deferred end @@ -33,6 +36,9 @@ feature {NONE} -- Implementation execute_next (req: WSF_REQUEST; res: WSF_RESPONSE) -- Execute the `next' filter. + require + req_attached: req /= Void + res_attached: res /= Void do if attached next as n then n.execute (req, res) @@ -40,7 +46,7 @@ feature {NONE} -- Implementation end note - copyright: "2011-2012, Jocelyn Fiat, Javier Velilla, Olivier Ligot, Eiffel Software and others" + copyright: "2011-2013, Jocelyn Fiat, Javier Velilla, Olivier Ligot, Eiffel Software and others" license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)" source: "[ Eiffel Software From de8d36d0db09821b07495ceb25e997c023716401 Mon Sep 17 00:00:00 2001 From: Jocelyn Fiat Date: Thu, 21 Mar 2013 15:48:07 +0100 Subject: [PATCH 21/23] cosmetic --- library/server/wsf/router/wsf_handler.e | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/library/server/wsf/router/wsf_handler.e b/library/server/wsf/router/wsf_handler.e index 3d15e03f..ae258233 100644 --- a/library/server/wsf/router/wsf_handler.e +++ b/library/server/wsf/router/wsf_handler.e @@ -1,6 +1,7 @@ note - description: "Summary description for {WSF_HANDLER}." - author: "" + description: "[ + Represents the ancestor of all the WSF_ROUTER handler. + ]" date: "$Date$" revision: "$Revision$" @@ -27,7 +28,7 @@ feature {WSF_ROUTER} -- Mapping end note - copyright: "2011-2012, Jocelyn Fiat, Javier Velilla, Olivier Ligot, Eiffel Software and others" + copyright: "2011-2013, Jocelyn Fiat, Javier Velilla, Olivier Ligot, Eiffel Software and others" license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)" source: "[ Eiffel Software From 813caa15e03e4d848b7d9657a418e25bbe33f325 Mon Sep 17 00:00:00 2001 From: Jocelyn Fiat Date: Thu, 21 Mar 2013 15:50:10 +0100 Subject: [PATCH 22/23] Removed WSF_AGENT_HANDLER since it was an artificial notion, as we have no common ancestor for WSF_HANDLER having execute (req: WSF_REQUEST; res: WSF_RESPONSE) --- .../uri/helpers/wsf_uri_agent_handler.e | 23 ++++++++--- .../helpers/wsf_uri_template_agent_handler.e | 23 ++++++++--- library/server/wsf/router/wsf_agent_handler.e | 41 ------------------- 3 files changed, 36 insertions(+), 51 deletions(-) delete mode 100644 library/server/wsf/router/wsf_agent_handler.e diff --git a/library/server/wsf/router/support/uri/helpers/wsf_uri_agent_handler.e b/library/server/wsf/router/support/uri/helpers/wsf_uri_agent_handler.e index b2a5089c..03a28fdd 100644 --- a/library/server/wsf/router/support/uri/helpers/wsf_uri_agent_handler.e +++ b/library/server/wsf/router/support/uri/helpers/wsf_uri_agent_handler.e @@ -10,14 +10,27 @@ class inherit WSF_URI_HANDLER - WSF_AGENT_HANDLER - rename - set_action as make - end - create make +feature {NONE} -- Initialization + + make (a_action: like action) + do + action := a_action + end + +feature -- Access + + action: PROCEDURE [ANY, TUPLE [request: WSF_REQUEST; response: WSF_RESPONSE]] + +feature -- Execution + + execute (req: WSF_REQUEST; res: WSF_RESPONSE) + do + action.call ([req, res]) + end + note copyright: "2011-2013, Jocelyn Fiat, Javier Velilla, Olivier Ligot, Eiffel Software and others" license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)" diff --git a/library/server/wsf/router/support/uri_template/helpers/wsf_uri_template_agent_handler.e b/library/server/wsf/router/support/uri_template/helpers/wsf_uri_template_agent_handler.e index c8e83fc0..cfe05c53 100644 --- a/library/server/wsf/router/support/uri_template/helpers/wsf_uri_template_agent_handler.e +++ b/library/server/wsf/router/support/uri_template/helpers/wsf_uri_template_agent_handler.e @@ -10,14 +10,27 @@ class inherit WSF_URI_TEMPLATE_HANDLER - WSF_AGENT_HANDLER - rename - set_action as make - end - create make +feature {NONE} -- Initialization + + make (a_action: like action) + do + action := a_action + end + +feature -- Access + + action: PROCEDURE [ANY, TUPLE [request: WSF_REQUEST; response: WSF_RESPONSE]] + +feature -- Execution + + execute (req: WSF_REQUEST; res: WSF_RESPONSE) + do + action.call ([req, res]) + end + note copyright: "2011-2013, Jocelyn Fiat, Javier Velilla, Olivier Ligot, Eiffel Software and others" license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)" diff --git a/library/server/wsf/router/wsf_agent_handler.e b/library/server/wsf/router/wsf_agent_handler.e deleted file mode 100644 index 3a25afef..00000000 --- a/library/server/wsf/router/wsf_agent_handler.e +++ /dev/null @@ -1,41 +0,0 @@ -note - description: "Summary description for {WSF_AGENT_HANDLER}." - author: "" - date: "$Date$" - revision: "$Revision$" - -deferred class - WSF_AGENT_HANDLER - -inherit - WSF_HANDLER - -feature -- Change - - set_action (a_action: like action) - do - action := a_action - end - -feature -- Access - - action: PROCEDURE [ANY, TUPLE [request: WSF_REQUEST; response: WSF_RESPONSE]] - -feature -- Execution - - execute (req: WSF_REQUEST; res: WSF_RESPONSE) - do - action.call ([req, res]) - end - -note - copyright: "2011-2012, Jocelyn Fiat, Javier Velilla, Olivier Ligot, 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 07ac6a6742d3e2fed2a233eb030a2ad05ca2aac0 Mon Sep 17 00:00:00 2001 From: Jocelyn Fiat Date: Thu, 21 Mar 2013 15:55:42 +0100 Subject: [PATCH 23/23] cosmetic --- .../wsf/router/filter/wsf_handler_filter_wrapper.e | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/library/server/wsf/router/filter/wsf_handler_filter_wrapper.e b/library/server/wsf/router/filter/wsf_handler_filter_wrapper.e index 9a6285a2..f0a312e2 100644 --- a/library/server/wsf/router/filter/wsf_handler_filter_wrapper.e +++ b/library/server/wsf/router/filter/wsf_handler_filter_wrapper.e @@ -2,7 +2,6 @@ note description: "[ Handler wrapping a filter ]" - author: "" date: "$Date$" revision: "$Revision$" @@ -18,17 +17,25 @@ create feature {NONE} -- Initialization make_with_filter (f: WSF_FILTER) + -- Build Current with `f'. + require + f_attached: f /= Void do filter := f + ensure + filter_set: filter = f end feature -- Access filter: WSF_FILTER + -- Associated filter. feature -- Execution execute (req: WSF_REQUEST; res: WSF_RESPONSE) + -- Execute handler for `req' and respond in `res' + -- by passing through filter `filter' do filter.execute (req, res) end