Merge pull request #16 from colin-adams/master
Implementation for automatic HEAD and first pass at HTTP 1.1 conformance contracts
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
<system xmlns="http://www.eiffel.com/developers/xml/configuration-1-9-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-9-0 http://www.eiffel.com/developers/xml/configuration-1-9-0.xsd" name="restbucks" uuid="7C9887BD-4AE4-47F2-A0AA-4BBB6736D433">
|
||||
<system xmlns="http://www.eiffel.com/developers/xml/configuration-1-10-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-10-0 http://www.eiffel.com/developers/xml/configuration-1-10-0.xsd" name="restbucks" uuid="7C9887BD-4AE4-47F2-A0AA-4BBB6736D433">
|
||||
<target name="restbucks">
|
||||
<root class="RESTBUCKS_SERVER" feature="make"/>
|
||||
<file_rule>
|
||||
@@ -9,7 +9,7 @@
|
||||
</file_rule>
|
||||
<option debug="true" warning="true" full_class_checking="true" is_attached_by_default="true" void_safety="all" syntax="provisional">
|
||||
<debug name="nino" enabled="true"/>
|
||||
<assertions precondition="true" postcondition="true" invariant="true" supplier_precondition="true"/>
|
||||
<assertions precondition="true" postcondition="true" check="true" invariant="true" loop="true" supplier_precondition="true"/>
|
||||
</option>
|
||||
<setting name="concurrency" value="thread"/>
|
||||
<library name="base" location="$ISE_LIBRARY\library\base\base-safe.ecf"/>
|
||||
@@ -21,9 +21,9 @@
|
||||
<library name="default_nino" location="..\..\library\server\wsf\default\nino-safe.ecf" readonly="false"/>
|
||||
<library name="eel" location="..\..\contrib\ise_library\text\encryption\eel\eel-safe.ecf" readonly="false"/>
|
||||
<library name="encoder" location="..\..\library\text\encoder\encoder-safe.ecf" readonly="false"/>
|
||||
<library name="http" location="../../library/network/protocol/http/http-safe.ecf" readonly="false"/>
|
||||
<library name="http" location="..\..\library\network\protocol\http\http-safe.ecf" readonly="false"/>
|
||||
<library name="json" location="..\..\contrib\library\text\parser\json\library\json-safe.ecf" readonly="false"/>
|
||||
<library name="uri_template" location="../../library/text/parser/uri_template/uri_template-safe.ecf" readonly="false"/>
|
||||
<library name="uri_template" location="..\..\library\text\parser\uri_template\uri_template-safe.ecf" readonly="false"/>
|
||||
<library name="wsf" location="..\..\library\server\wsf\wsf-safe.ecf" readonly="false"/>
|
||||
<library name="wsf_extension" location="..\..\library\server\wsf\wsf_extension-safe.ecf" readonly="false"/>
|
||||
<cluster name="src" location="src\" recursive="true"/>
|
||||
|
||||
@@ -54,13 +54,7 @@ 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
|
||||
-- <Precursor>
|
||||
local
|
||||
id: STRING
|
||||
do
|
||||
|
||||
72
library/server/wsf/extension/wsf_method_handler.e
Normal file
72
library/server/wsf/extension/wsf_method_handler.e
Normal file
@@ -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
|
||||
|
||||
78
library/server/wsf/extension/wsf_method_handlers.e
Normal file
78
library/server/wsf/extension/wsf_method_handlers.e
Normal file
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user