diff --git a/examples/restbucksCRUD/restbucks-safe.ecf b/examples/restbucksCRUD/restbucks-safe.ecf index 5e884262..30267388 100644 --- a/examples/restbucksCRUD/restbucks-safe.ecf +++ b/examples/restbucksCRUD/restbucks-safe.ecf @@ -1,5 +1,5 @@ - + @@ -9,7 +9,7 @@ @@ -21,9 +21,9 @@ - + - + diff --git a/examples/restbucksCRUD/src/resource/order_handler.e b/examples/restbucksCRUD/src/resource/order_handler.e index 16fba5bd..057a3a95 100644 --- a/examples/restbucksCRUD/src/resource/order_handler.e +++ b/examples/restbucksCRUD/src/resource/order_handler.e @@ -54,15 +54,9 @@ feature -- API DOC feature -- HTTP Methods do_get (req: WSF_REQUEST; res: WSF_RESPONSE) - -- Using GET to retrieve resource information. - -- If the GET request is SUCCESS, we response with - -- 200 OK, and a representation of the order - -- If the GET request is not SUCCESS, we response with - -- 404 Resource not found - -- If is a Condition GET and the resource does not change we send a - -- 304, Resource not modifed + -- local - id : STRING + id: STRING do if attached req.orig_path_info as orig_path then id := get_order_id_from_path (orig_path) @@ -93,7 +87,7 @@ feature -- HTTP Methods end end - compute_response_get (req: WSF_REQUEST; res: WSF_RESPONSE; l_order : ORDER) + compute_response_get (req: WSF_REQUEST; res: WSF_RESPONSE; l_order: ORDER) local h: HTTP_HEADER l_msg : STRING diff --git a/library/server/wsf/extension/wsf_method_handler.e b/library/server/wsf/extension/wsf_method_handler.e new file mode 100644 index 00000000..0b76e1f6 --- /dev/null +++ b/library/server/wsf/extension/wsf_method_handler.e @@ -0,0 +1,72 @@ +note + + description: "Conforming handler for any HTTP 1.1 standard method" + + author: "Colin Adams" + date: "$Date$" + revision: "$Revision$" + +deferred class WSF_METHOD_HANDLER + +feature -- Method + + do_method (req: WSF_REQUEST; res: WSF_RESPONSE) + -- Respond to `req' using `res'. + require + req_not_void: req /= Void + res_not_void: res /= Void + deferred + ensure + valid_response_for_http_1_0: is_1_0 (req.server_protocol) implies + valid_response_for_http_1_0 (res.status_code) + empty_body_for_no_content_response: is_no_content_response (res.status_code) implies is_empty_content (res) + end + +feature -- Contract support + + is_1_0 (a_protocol: READABLE_STRING_8): BOOLEAN + -- Is `a_protocol' (a variant of) HTTP 1.0? + require + a_protocol_not_void: a_protocol /= Void + do + Result := a_protocol.count >= 8 and then + a_protocol.substring (1, 8) ~ "HTTP/1.0" + end + + valid_response_for_http_1_0 (a_status_code: INTEGER): BOOLEAN + -- Is `a_status_code' a valid response to HTTP 1.0? + do + -- 1XX is forbidden + + -- first approximation + Result := a_status_code >= {HTTP_STATUS_CODE}.ok + end + + is_no_content_response (a_status_code: INTEGER): BOOLEAN + -- Is `a_status_code' one that does not permit an entity in the response? + do + inspect + a_status_code + when {HTTP_STATUS_CODE}.no_content then + Result := True + when {HTTP_STATUS_CODE}.reset_content then + Result := True + when {HTTP_STATUS_CODE}.not_modified then + Result := True + when {HTTP_STATUS_CODE}.conflict then + Result := True + else + -- default to False + end + end + + is_empty_content (res: WSF_RESPONSE): BOOLEAN + -- Does `res' not contain an entity? + require + res_not_void: res /= Void + do + Result := res.transfered_content_length = 0 -- Is that the right measure? + end + +end + diff --git a/library/server/wsf/extension/wsf_method_handlers.e b/library/server/wsf/extension/wsf_method_handlers.e new file mode 100644 index 00000000..06e828c1 --- /dev/null +++ b/library/server/wsf/extension/wsf_method_handlers.e @@ -0,0 +1,78 @@ +note + + description: "Conforming handlers for HTTP 1.1 standard methods" + + author: "Colin Adams" + date: "$Date$" + revision: "$Revision$" + +deferred class WSF_METHOD_HANDLERS + +inherit + + WSF_METHOD_HANDLER + rename + do_method as do_get + select + do_get + end + + WSF_METHOD_HANDLER + rename + do_method as do_put + end + + WSF_METHOD_HANDLER + rename + do_method as do_put + end + + WSF_METHOD_HANDLER + rename + do_method as do_connect + end + + WSF_METHOD_HANDLER + rename + do_method as do_head + end + + WSF_METHOD_HANDLER + rename + do_method as do_options + end + + WSF_METHOD_HANDLER + rename + do_method as do_trace + end + +feature -- Method + + do_head (req: WSF_REQUEST; res: WSF_RESPONSE) + -- Respond to `req' using `res'. + deferred + ensure then + empty_body: is_empty_content (res) + end + + do_post (req: WSF_REQUEST; res: WSF_RESPONSE) + -- Respond to `req' using `res'. + deferred + ensure then + non_empty_body: res.status_code = {HTTP_STATUS_CODE}.created implies + not is_empty_content (res) + location_header: res.status_code = {HTTP_STATUS_CODE}.created implies True -- WSF_RESPONSE needs enhancing + end + + do_trace (req: WSF_REQUEST; res: WSF_RESPONSE) + -- Respond to `req' using `res'. + deferred + ensure then + non_empty_body: res.status_code = {HTTP_STATUS_CODE}.ok implies + not is_empty_content (res) + end + +end + + diff --git a/library/server/wsf/extension/wsf_resource_handler_helper.e b/library/server/wsf/extension/wsf_resource_handler_helper.e index 0f1f0732..dab8cb64 100644 --- a/library/server/wsf/extension/wsf_resource_handler_helper.e +++ b/library/server/wsf/extension/wsf_resource_handler_helper.e @@ -4,13 +4,16 @@ note date: "$Date$" revision: "$Revision$" -class - WSF_RESOURCE_HANDLER_HELPER +class WSF_RESOURCE_HANDLER_HELPER + +inherit + + WSF_METHOD_HANDLERS feature -- Execute template execute_methods (req: WSF_REQUEST; res: WSF_RESPONSE) - -- Execute request and dispatch according to the request method + -- Execute request and dispatch according to the request method. local m: READABLE_STRING_8 do @@ -46,8 +49,8 @@ feature -- Method Get 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 person + -- If the GET request is SUCCESS, we respond with + -- 200 OK, and a representation of the resource. -- If the GET request is not SUCCESS, we response with -- 404 Resource not found -- If is a Condition GET and the resource does not change we send a @@ -141,12 +144,12 @@ feature -- Method HEAD do_head (req: WSF_REQUEST; res: WSF_RESPONSE) -- Using HEAD to retrieve resource information. - -- If the HEAD request is SUCCESS, we response with - -- 200 OK, and WITHOUT a representation of the person - -- If the HEAD request is not SUCCESS, we response with - -- 404 Resource not found - -- If is a Condition HEAD and the resource does not change we send a - -- 304, Resource not modifed + -- If the HEAD request is SUCCESS, we respond with + -- 200 OK, and WITHOUT a representation of the resource. + -- If the HEAD request is not SUCCESS, we respond with + -- 404 Resource not found. + -- If Conditional HEAD and the resource does not change we send a + -- 304, Resource not modifed. do handle_not_implemented ("Method HEAD not implemented", req, res) end @@ -160,6 +163,7 @@ feature -- Method OPTIONS do_options (req: WSF_REQUEST; res: WSF_RESPONSE) do + -- TODO - implement a default method that lists the accepted methods for the resource. handle_not_implemented ("Method OPTIONS not implemented", req, res) end @@ -172,6 +176,7 @@ feature -- Method TRACE do_trace (req: WSF_REQUEST; res: WSF_RESPONSE) do + -- TODO - implement frozen, as there is only one permitted semantic. handle_not_implemented ("Method TRACE not implemented", req, res) end diff --git a/library/server/wsf/router/wsf_router.e b/library/server/wsf/router/wsf_router.e index c3db762e..dd7a5940 100644 --- a/library/server/wsf/router/wsf_router.e +++ b/library/server/wsf/router/wsf_router.e @@ -69,7 +69,6 @@ feature -- Mapping io.error.put_string ("%N") end end - mappings.extend (create {WSF_ROUTER_ITEM}.make_with_request_methods (a_mapping, rqst_methods)) a_mapping.handler.on_mapped (a_mapping, rqst_methods) end