Fixes as picked up by code review
This commit is contained in:
@@ -18,7 +18,7 @@
|
|||||||
<debug name="nino" enabled="true"/>
|
<debug name="nino" enabled="true"/>
|
||||||
</option>
|
</option>
|
||||||
</library>
|
</library>
|
||||||
<library name="conneg" location="\home\colin\EWF\library\network\protocol\CONNEG\conneg-safe.ecf"/>
|
<library name="conneg" location="..\..\library\network\protocol\CONNEG\conneg-safe.ecf"/>
|
||||||
<library name="default_nino" location="..\..\library\server\wsf\default\nino-safe.ecf" readonly="false"/>
|
<library name="default_nino" location="..\..\library\server\wsf\default\nino-safe.ecf" readonly="false"/>
|
||||||
<library name="eel" location="$ISE_LIBRARY\contrib\library\text\encryption\eel\eel-safe.ecf" readonly="false"/>
|
<library name="eel" location="$ISE_LIBRARY\contrib\library\text\encryption\eel\eel-safe.ecf" readonly="false"/>
|
||||||
<library name="encoder" location="..\..\library\text\encoder\encoder-safe.ecf" readonly="false"/>
|
<library name="encoder" location="..\..\library\text\encoder\encoder-safe.ecf" readonly="false"/>
|
||||||
|
|||||||
@@ -28,9 +28,14 @@ create
|
|||||||
|
|
||||||
make_with_router
|
make_with_router
|
||||||
|
|
||||||
feature -- API DOC
|
feature -- Documentation
|
||||||
|
|
||||||
api_doc : STRING = "URI:/order METHOD: POST%N URI:/order/{orderid} METHOD: GET, HEAD, PUT, DELETE%N"
|
description: READABLE_STRING_GENERAL
|
||||||
|
-- General description for self-generated documentation;
|
||||||
|
-- The specific URI templates supported will be described automatically
|
||||||
|
do
|
||||||
|
Result := "Create, Read, Update or Delete an ORDER."
|
||||||
|
end
|
||||||
|
|
||||||
feature -- Access
|
feature -- Access
|
||||||
|
|
||||||
@@ -93,7 +98,7 @@ feature -- Access
|
|||||||
-- Maximum age in seconds before response to `req` is considered stale;
|
-- Maximum age in seconds before response to `req` is considered stale;
|
||||||
-- This is used to generate a Cache-Control: max-age header.
|
-- This is used to generate a Cache-Control: max-age header.
|
||||||
-- Return 0 to indicate already expired.
|
-- Return 0 to indicate already expired.
|
||||||
-- Return (365 * 1440 = 1 year) to indicate never expires.
|
-- Return Never_expires to indicate never expires.
|
||||||
do
|
do
|
||||||
-- All our responses are considered stale.
|
-- All our responses are considered stale.
|
||||||
end
|
end
|
||||||
@@ -315,7 +320,7 @@ feature -- PUT/POST
|
|||||||
-- No. We don't care for this example.
|
-- No. We don't care for this example.
|
||||||
end
|
end
|
||||||
|
|
||||||
check_content_headers (req: WSF_REQUEST)
|
check_content_headers (req: WSF_REQUEST)
|
||||||
-- Check we can support all content headers on request entity.
|
-- Check we can support all content headers on request entity.
|
||||||
-- Set `req.execution_variable ("CONTENT_CHECK_CODE")' to {NATURAL} zero if OK, or 415 or 501 if not.
|
-- Set `req.execution_variable ("CONTENT_CHECK_CODE")' to {NATURAL} zero if OK, or 415 or 501 if not.
|
||||||
do
|
do
|
||||||
@@ -350,13 +355,11 @@ feature -- PUT/POST
|
|||||||
if attached {ORDER} req.execution_variable ("EXTRACTED_ORDER") as l_order then
|
if attached {ORDER} req.execution_variable ("EXTRACTED_ORDER") as l_order then
|
||||||
if not is_valid_to_update (l_order) then
|
if not is_valid_to_update (l_order) then
|
||||||
req.set_execution_variable ("CONFLICT_CHECK_CODE", {NATURAL} 409)
|
req.set_execution_variable ("CONFLICT_CHECK_CODE", {NATURAL} 409)
|
||||||
--| FIXME: Here we need to define the Allow methods
|
|
||||||
handle_resource_conflict_response (l_order.out +"%N There is conflict while trying to update the order, the order could not be update in the current state", req, res)
|
handle_resource_conflict_response (l_order.out +"%N There is conflict while trying to update the order, the order could not be update in the current state", req, res)
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
req.set_execution_variable ("CONFLICT_CHECK_CODE", {NATURAL} 409)
|
req.set_execution_variable ("CONFLICT_CHECK_CODE", {NATURAL} 409)
|
||||||
--| FIXME: Here we need to define the Allow methods
|
--| This ought to be a 500, as if attached should probably be check attached. But as yet I lack a proof.
|
||||||
--| This ought to be a 500, as if attached should probably be check attached. But as yet I lack a proof. TODO.
|
|
||||||
handle_resource_conflict_response ("There is conflict while trying to update the order, the order could not be update in the current state", req, res)
|
handle_resource_conflict_response ("There is conflict while trying to update the order, the order could not be update in the current state", req, res)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -553,6 +556,6 @@ feature {NONE} -- Implementation Repository Layer
|
|||||||
end
|
end
|
||||||
|
|
||||||
note
|
note
|
||||||
copyright: "2011-2012, Javier Velilla and others"
|
copyright: "2011-2013, Javier Velilla and others"
|
||||||
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -350,7 +350,9 @@ feature -- Header change: general
|
|||||||
end
|
end
|
||||||
|
|
||||||
add_header_key_value (k,v: READABLE_STRING_8)
|
add_header_key_value (k,v: READABLE_STRING_8)
|
||||||
-- Add header `k:v', or replace existing header of same header name/key
|
-- Add header `k:v'.
|
||||||
|
-- If it already exists, there will be multiple header with same name
|
||||||
|
-- which can also be valid
|
||||||
local
|
local
|
||||||
s: STRING_8
|
s: STRING_8
|
||||||
do
|
do
|
||||||
@@ -509,10 +511,10 @@ feature -- Content related header
|
|||||||
put_header_key_value ({HTTP_HEADER_NAMES}.header_content_transfer_encoding, a_mechanism)
|
put_header_key_value ({HTTP_HEADER_NAMES}.header_content_transfer_encoding, a_mechanism)
|
||||||
end
|
end
|
||||||
|
|
||||||
put_content_language (a_enc: READABLE_STRING_8)
|
put_content_language (a_lang: READABLE_STRING_8)
|
||||||
-- Put "Content-Language" header of value `a_enc'.
|
-- Put "Content-Language" header of value `a_lang'.
|
||||||
do
|
do
|
||||||
put_header_key_value ({HTTP_HEADER_NAMES}.header_content_language, a_enc)
|
put_header_key_value ({HTTP_HEADER_NAMES}.header_content_language, a_lang)
|
||||||
end
|
end
|
||||||
|
|
||||||
put_content_encoding (a_enc: READABLE_STRING_8)
|
put_content_encoding (a_enc: READABLE_STRING_8)
|
||||||
|
|||||||
@@ -10,16 +10,20 @@ deferred class WSF_CACHING_POLICY
|
|||||||
|
|
||||||
feature -- Access
|
feature -- Access
|
||||||
|
|
||||||
|
Never_expires: NATURAL = 525600
|
||||||
|
-- 525600 = 365 * 24 * 60 * 60 = (almost) 1 year;
|
||||||
|
-- See http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.21 for an explanation of why this means never expire
|
||||||
|
|
||||||
age (req: WSF_REQUEST): NATURAL
|
age (req: WSF_REQUEST): NATURAL
|
||||||
-- Maximum age in seconds before response to `req` is considered stale;
|
-- Maximum age in seconds before response to `req` is considered stale;
|
||||||
-- This is used to generate a Cache-Control: max-age header.
|
-- This is used to generate a Cache-Control: max-age header.
|
||||||
-- Return 0 to indicate already expired.
|
-- Return 0 to indicate already expired.
|
||||||
-- Return (365 * 1440 = 1 year) to indicate never expires.
|
-- Return `Never_expires' to indicate never expires.
|
||||||
require
|
require
|
||||||
req_attached: req /= Void
|
req_attached: req /= Void
|
||||||
deferred
|
deferred
|
||||||
ensure
|
ensure
|
||||||
not_more_than_1_year: Result <= (365 * 1440).as_natural_32
|
not_more_than_1_year: Result <= Never_expires
|
||||||
end
|
end
|
||||||
|
|
||||||
shared_age (req: WSF_REQUEST): NATURAL
|
shared_age (req: WSF_REQUEST): NATURAL
|
||||||
@@ -27,13 +31,13 @@ feature -- Access
|
|||||||
-- This is used to generate a Cache-Control: s-maxage header.
|
-- This is used to generate a Cache-Control: s-maxage header.
|
||||||
-- If you wish to have different expiry ages for shared and provate caches, redefine this routine.
|
-- If you wish to have different expiry ages for shared and provate caches, redefine this routine.
|
||||||
-- Return 0 to indicate already expired.
|
-- Return 0 to indicate already expired.
|
||||||
-- Return (365 * 1440 = 1 year) to indicate never expires.
|
-- Return `Never_expires' to indicate never expires.
|
||||||
require
|
require
|
||||||
req_attached: req /= Void
|
req_attached: req /= Void
|
||||||
do
|
do
|
||||||
Result := age (req)
|
Result := age (req)
|
||||||
ensure
|
ensure
|
||||||
not_more_than_1_year: Result <= (365 * 1440).as_natural_32
|
not_more_than_1_year: Result <= Never_expires
|
||||||
end
|
end
|
||||||
|
|
||||||
http_1_0_age (req: WSF_REQUEST): NATURAL
|
http_1_0_age (req: WSF_REQUEST): NATURAL
|
||||||
@@ -41,7 +45,7 @@ feature -- Access
|
|||||||
-- This is used to generate an Expires header, which HTTP/1.0 caches understand.
|
-- This is used to generate an Expires header, which HTTP/1.0 caches understand.
|
||||||
-- If you wish to generate a different age for HTTP/1.0 caches, then redefine this routine.
|
-- If you wish to generate a different age for HTTP/1.0 caches, then redefine this routine.
|
||||||
-- Return 0 to indicate already expired.
|
-- Return 0 to indicate already expired.
|
||||||
-- Return (365 * 1440 = 1 year) to indicate never expires. Note this will
|
-- Return `Never_expires' to indicate never expires. Note this will
|
||||||
-- make a result cachecable that would not normally be cacheable (such as as response
|
-- make a result cachecable that would not normally be cacheable (such as as response
|
||||||
-- to a POST), unless overriden by cache-control headers, so be sure to check `req.request_method'.
|
-- to a POST), unless overriden by cache-control headers, so be sure to check `req.request_method'.
|
||||||
require
|
require
|
||||||
@@ -49,7 +53,7 @@ feature -- Access
|
|||||||
do
|
do
|
||||||
Result := age (req)
|
Result := age (req)
|
||||||
ensure
|
ensure
|
||||||
not_more_than_1_year: Result <= (365 * 1440).as_natural_32
|
not_more_than_1_year: Result <= Never_expires
|
||||||
end
|
end
|
||||||
|
|
||||||
is_freely_cacheable (req: WSF_REQUEST): BOOLEAN
|
is_freely_cacheable (req: WSF_REQUEST): BOOLEAN
|
||||||
@@ -81,7 +85,6 @@ feature -- Access
|
|||||||
-- Redefine to force revalidation.
|
-- Redefine to force revalidation.
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
must_proxy_revalidate (req: WSF_REQUEST): BOOLEAN
|
must_proxy_revalidate (req: WSF_REQUEST): BOOLEAN
|
||||||
-- If a shared cache is configured to ignore server's expiration time,
|
-- If a shared cache is configured to ignore server's expiration time,
|
||||||
-- should we force revalidation anyway?
|
-- should we force revalidation anyway?
|
||||||
@@ -92,7 +95,6 @@ feature -- Access
|
|||||||
-- Redefine to force revalidation.
|
-- Redefine to force revalidation.
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
private_headers (req: WSF_REQUEST): detachable LIST [READABLE_STRING_8]
|
private_headers (req: WSF_REQUEST): detachable LIST [READABLE_STRING_8]
|
||||||
-- Header names intended for a single user.
|
-- Header names intended for a single user.
|
||||||
-- If non-Void, then a Cache-Control: private header will be generated.
|
-- If non-Void, then a Cache-Control: private header will be generated.
|
||||||
@@ -122,4 +124,14 @@ feature -- Access
|
|||||||
deferred
|
deferred
|
||||||
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
|
end
|
||||||
|
|||||||
@@ -11,15 +11,10 @@ class WSF_DELETE_HELPER
|
|||||||
inherit
|
inherit
|
||||||
|
|
||||||
WSF_METHOD_HELPER
|
WSF_METHOD_HELPER
|
||||||
rename
|
|
||||||
send_get_response as handle_delete
|
|
||||||
redefine
|
|
||||||
handle_delete
|
|
||||||
end
|
|
||||||
|
|
||||||
feature {NONE} -- Implementation
|
feature {NONE} -- Implementation
|
||||||
|
|
||||||
handle_delete (req: WSF_REQUEST; res: WSF_RESPONSE; a_handler: WSF_SKELETON_HANDLER; a_header: HTTP_HEADER;
|
send_response (req: WSF_REQUEST; res: WSF_RESPONSE; a_handler: WSF_SKELETON_HANDLER; a_header: HTTP_HEADER;
|
||||||
a_media_type, a_language_type, a_character_type, a_compression_type: detachable READABLE_STRING_8; a_new_resource: BOOLEAN)
|
a_media_type, a_language_type, a_character_type, a_compression_type: detachable READABLE_STRING_8; a_new_resource: BOOLEAN)
|
||||||
-- Write response to deletion of resource named by `req' into `res' in accordance with `a_media_type' etc.
|
-- Write response to deletion of resource named by `req' into `res' in accordance with `a_media_type' etc.
|
||||||
local
|
local
|
||||||
|
|||||||
@@ -12,4 +12,45 @@ inherit
|
|||||||
|
|
||||||
WSF_METHOD_HELPER
|
WSF_METHOD_HELPER
|
||||||
|
|
||||||
|
feature {NONE} -- Implementation
|
||||||
|
|
||||||
|
send_response (req: WSF_REQUEST; res: WSF_RESPONSE; a_handler: WSF_SKELETON_HANDLER; a_header: HTTP_HEADER;
|
||||||
|
a_media_type, a_language_type, a_character_type, a_compression_type: detachable READABLE_STRING_8; a_new_resource: BOOLEAN)
|
||||||
|
-- Write response to `req' into `res' in accordance with `a_media_type' etc.
|
||||||
|
local
|
||||||
|
l_chunked, l_ok: BOOLEAN
|
||||||
|
l_dt: STRING
|
||||||
|
do
|
||||||
|
a_handler.ensure_content_available (req, a_media_type, a_language_type, a_character_type, a_compression_type)
|
||||||
|
l_chunked := a_handler.is_chunking (req)
|
||||||
|
if l_chunked then
|
||||||
|
a_header.put_transfer_encoding_chunked
|
||||||
|
else
|
||||||
|
a_header.put_content_length (a_handler.content_length (req).as_integer_32)
|
||||||
|
end
|
||||||
|
if attached req.request_time as l_time then
|
||||||
|
l_dt := (create {HTTP_DATE}.make_from_date_time (l_time)).rfc1123_string
|
||||||
|
a_header.put_header_key_value ({HTTP_HEADER_NAMES}.header_date, l_dt)
|
||||||
|
generate_cache_headers (req, a_handler, a_header, l_time)
|
||||||
|
end
|
||||||
|
l_ok := a_handler.response_ok (req)
|
||||||
|
if l_ok then
|
||||||
|
res.set_status_code ({HTTP_STATUS_CODE}.ok)
|
||||||
|
else
|
||||||
|
-- TODO - req.error_handler.has_error = True
|
||||||
|
--handle_internal_server_error (a_handler.last_error (req), req, res)
|
||||||
|
end
|
||||||
|
if attached a_handler.etag (req, a_media_type, a_language_type, a_character_type, a_compression_type) as l_etag then
|
||||||
|
a_header.put_header_key_value ({HTTP_HEADER_NAMES}.header_etag, l_etag)
|
||||||
|
end
|
||||||
|
res.put_header_text (a_header.string)
|
||||||
|
if l_ok then
|
||||||
|
if l_chunked then
|
||||||
|
send_chunked_response (req, res, a_handler, a_header, a_media_type, a_language_type, a_character_type, a_compression_type)
|
||||||
|
else
|
||||||
|
res.put_string (a_handler.content (req, a_media_type, a_language_type, a_character_type, a_compression_type))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -2,12 +2,19 @@ note
|
|||||||
|
|
||||||
description: "[
|
description: "[
|
||||||
Policy-driven helpers to implement a method.
|
Policy-driven helpers to implement a method.
|
||||||
This implementation is suitable for GET and HEAD.
|
|
||||||
]"
|
]"
|
||||||
date: "$Date$"
|
date: "$Date$"
|
||||||
revision: "$Revision$"
|
revision: "$Revision$"
|
||||||
|
|
||||||
class WSF_METHOD_HELPER
|
deferred class WSF_METHOD_HELPER
|
||||||
|
|
||||||
|
inherit
|
||||||
|
|
||||||
|
HTTP_STATUS_CODE_MESSAGES
|
||||||
|
|
||||||
|
SHARED_HTML_ENCODER
|
||||||
|
export {NONE} all end
|
||||||
|
|
||||||
feature -- Access
|
feature -- Access
|
||||||
|
|
||||||
@@ -42,17 +49,17 @@ feature -- Basic operations
|
|||||||
if a_handler.resource_previously_existed (req) then
|
if a_handler.resource_previously_existed (req) then
|
||||||
if a_handler.resource_moved_permanently (req) then
|
if a_handler.resource_moved_permanently (req) then
|
||||||
l_locs := a_handler.previous_location (req)
|
l_locs := a_handler.previous_location (req)
|
||||||
-- TODO 301 Moved permanently response
|
handle_redirection_error (req, res, l_locs, {HTTP_STATUS_CODE}.moved_permanently)
|
||||||
elseif a_handler.resource_moved_temporarily (req) then
|
elseif a_handler.resource_moved_temporarily (req) then
|
||||||
l_locs := a_handler.previous_location (req)
|
l_locs := a_handler.previous_location (req)
|
||||||
-- TODO := 302 Found response
|
handle_redirection_error (req, res, l_locs, {HTTP_STATUS_CODE}.found)
|
||||||
else
|
else
|
||||||
create h.make
|
create h.make
|
||||||
h.put_content_type_text_plain
|
h.put_content_type_text_plain
|
||||||
h.put_current_date
|
h.put_current_date
|
||||||
h.put_content_length (0)
|
h.put_content_length (0)
|
||||||
res.set_status_code ({HTTP_STATUS_CODE}.gone)
|
res.set_status_code ({HTTP_STATUS_CODE}.gone)
|
||||||
res.put_header_text (h.string)
|
res.put_header_lines (h)
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
create h.make
|
create h.make
|
||||||
@@ -60,7 +67,7 @@ feature -- Basic operations
|
|||||||
h.put_current_date
|
h.put_current_date
|
||||||
h.put_content_length (0)
|
h.put_content_length (0)
|
||||||
res.set_status_code ({HTTP_STATUS_CODE}.not_found)
|
res.set_status_code ({HTTP_STATUS_CODE}.not_found)
|
||||||
res.put_header_text (h.string)
|
res.put_header_lines (h)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -78,7 +85,7 @@ feature -- Basic operations
|
|||||||
l_date: HTTP_DATE
|
l_date: HTTP_DATE
|
||||||
do
|
do
|
||||||
if attached req.http_if_match as l_if_match then
|
if attached req.http_if_match as l_if_match then
|
||||||
-- TODO - also if-range when we add support for range requests
|
-- also if-range when we add support for range requests
|
||||||
if not l_if_match.same_string ("*") then
|
if not l_if_match.same_string ("*") then
|
||||||
l_etags := l_if_match.split (',')
|
l_etags := l_if_match.split (',')
|
||||||
l_failed := not across l_etags as i_etags some a_handler.matching_etag (req, i_etags.item, True) end
|
l_failed := not across l_etags as i_etags some a_handler.matching_etag (req, i_etags.item, True) end
|
||||||
@@ -105,14 +112,14 @@ feature -- Basic operations
|
|||||||
across l_etags as i_etags some a_handler.matching_etag (req, i_etags.item, False) end
|
across l_etags as i_etags some a_handler.matching_etag (req, i_etags.item, False) end
|
||||||
end
|
end
|
||||||
if l_failed then
|
if l_failed then
|
||||||
handle_if_none_match_failed (req, res)
|
handle_if_none_match_failed (req, res, a_handler)
|
||||||
else
|
else
|
||||||
if attached req.http_if_modified_since as l_if_modified_since then
|
if attached req.http_if_modified_since as l_if_modified_since then
|
||||||
if l_if_modified_since.is_string_8 then
|
if l_if_modified_since.is_string_8 then
|
||||||
create l_date.make_from_string (l_if_modified_since.as_string_8)
|
create l_date.make_from_string (l_if_modified_since.as_string_8)
|
||||||
if not l_date.has_error then
|
if not l_date.has_error then
|
||||||
if not a_handler.modified_since (req, l_date.date_time) then
|
if not a_handler.modified_since (req, l_date.date_time) then
|
||||||
handle_not_modified (req, res)
|
handle_not_modified (req, res, a_handler)
|
||||||
l_failed := True
|
l_failed := True
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -163,7 +170,7 @@ feature {NONE} -- Implementation
|
|||||||
h.add_header_key_value ({HTTP_HEADER_NAMES}.header_vary, l_media_variant)
|
h.add_header_key_value ({HTTP_HEADER_NAMES}.header_vary, l_media_variant)
|
||||||
end
|
end
|
||||||
if not l_media.is_acceptable then
|
if not l_media.is_acceptable then
|
||||||
handle_not_accepted ("None of the requested ContentTypes were acceptable", req, res)
|
handle_not_acceptable ("None of the requested ContentTypes were acceptable", l_mime_types, req, res)
|
||||||
else
|
else
|
||||||
l_langs := a_handler.languages_supported (req)
|
l_langs := a_handler.languages_supported (req)
|
||||||
l_lang := l_conneg.language_preference (l_langs, req.http_accept_language)
|
l_lang := l_conneg.language_preference (l_langs, req.http_accept_language)
|
||||||
@@ -171,7 +178,7 @@ feature {NONE} -- Implementation
|
|||||||
h.add_header_key_value ({HTTP_HEADER_NAMES}.header_vary, l_lang_variant)
|
h.add_header_key_value ({HTTP_HEADER_NAMES}.header_vary, l_lang_variant)
|
||||||
end
|
end
|
||||||
if not l_lang.is_acceptable then
|
if not l_lang.is_acceptable then
|
||||||
handle_not_accepted ("None of the requested languages were acceptable", req, res)
|
handle_not_acceptable ("None of the requested languages were acceptable", l_langs, req, res)
|
||||||
else
|
else
|
||||||
if attached l_lang.language_type as l_language_type then
|
if attached l_lang.language_type as l_language_type then
|
||||||
h.put_content_language (l_language_type)
|
h.put_content_language (l_language_type)
|
||||||
@@ -182,7 +189,7 @@ feature {NONE} -- Implementation
|
|||||||
h.add_header_key_value ({HTTP_HEADER_NAMES}.header_vary, l_charset_variant)
|
h.add_header_key_value ({HTTP_HEADER_NAMES}.header_vary, l_charset_variant)
|
||||||
end
|
end
|
||||||
if not l_charset.is_acceptable then
|
if not l_charset.is_acceptable then
|
||||||
handle_not_accepted ("None of the requested character encodings were acceptable", req, res)
|
handle_not_acceptable ("None of the requested character encodings were acceptable", l_charsets, req, res)
|
||||||
else
|
else
|
||||||
if attached l_media.media_type as l_media_type and attached l_charset.character_type as l_character_type then
|
if attached l_media.media_type as l_media_type and attached l_charset.character_type as l_character_type then
|
||||||
h.put_content_type (l_media_type + "; charset=" + l_character_type)
|
h.put_content_type (l_media_type + "; charset=" + l_character_type)
|
||||||
@@ -193,13 +200,13 @@ feature {NONE} -- Implementation
|
|||||||
h.add_header_key_value ({HTTP_HEADER_NAMES}.header_vary, l_encoding_variant)
|
h.add_header_key_value ({HTTP_HEADER_NAMES}.header_vary, l_encoding_variant)
|
||||||
end
|
end
|
||||||
if not l_encoding.is_acceptable then
|
if not l_encoding.is_acceptable then
|
||||||
handle_not_accepted ("None of the requested transfer encodings were acceptable", req, res)
|
handle_not_acceptable ("None of the requested transfer encodings were acceptable", l_encodings, req, res)
|
||||||
else
|
else
|
||||||
if attached l_encoding.compression_type as l_compression_type then
|
if attached l_encoding.compression_type as l_compression_type then
|
||||||
h.put_content_encoding (l_compression_type)
|
h.put_content_encoding (l_compression_type)
|
||||||
end
|
end
|
||||||
-- We do not support multiple choices, so
|
-- We do not support multiple choices, so
|
||||||
send_get_response (req, res, a_handler, h,
|
send_response (req, res, a_handler, h,
|
||||||
l_media.media_type, l_lang.language_type, l_charset.character_type, l_encoding.compression_type, a_new_resource)
|
l_media.media_type, l_lang.language_type, l_charset.character_type, l_encoding.compression_type, a_new_resource)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -207,7 +214,7 @@ feature {NONE} -- Implementation
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
send_get_response (req: WSF_REQUEST; res: WSF_RESPONSE; a_handler: WSF_SKELETON_HANDLER; a_header: HTTP_HEADER;
|
send_response (req: WSF_REQUEST; res: WSF_RESPONSE; a_handler: WSF_SKELETON_HANDLER; a_header: HTTP_HEADER;
|
||||||
a_media_type, a_language_type, a_character_type, a_compression_type: detachable READABLE_STRING_8; a_new_resource: BOOLEAN)
|
a_media_type, a_language_type, a_character_type, a_compression_type: detachable READABLE_STRING_8; a_new_resource: BOOLEAN)
|
||||||
-- Write response to `req' into `res' in accordance with `a_media_type' etc.
|
-- Write response to `req' into `res' in accordance with `a_media_type' etc.
|
||||||
require
|
require
|
||||||
@@ -219,40 +226,7 @@ feature {NONE} -- Implementation
|
|||||||
a_language_type_attached: a_language_type /= Void
|
a_language_type_attached: a_language_type /= Void
|
||||||
a_character_type_attached: a_character_type /= Void
|
a_character_type_attached: a_character_type /= Void
|
||||||
a_compression_type_attached: a_compression_type /= Void
|
a_compression_type_attached: a_compression_type /= Void
|
||||||
local
|
deferred
|
||||||
l_chunked, l_ok: BOOLEAN
|
|
||||||
l_dt: STRING
|
|
||||||
do
|
|
||||||
a_handler.ensure_content_available (req, a_media_type, a_language_type, a_character_type, a_compression_type)
|
|
||||||
l_chunked := a_handler.is_chunking (req)
|
|
||||||
if l_chunked then
|
|
||||||
a_header.put_transfer_encoding_chunked
|
|
||||||
else
|
|
||||||
a_header.put_content_length (a_handler.content_length (req).as_integer_32)
|
|
||||||
end
|
|
||||||
if attached req.request_time as l_time then
|
|
||||||
l_dt := (create {HTTP_DATE}.make_from_date_time (l_time)).rfc1123_string
|
|
||||||
a_header.put_header_key_value ({HTTP_HEADER_NAMES}.header_date, l_dt)
|
|
||||||
generate_cache_headers (req, a_handler, a_header, l_time)
|
|
||||||
end
|
|
||||||
l_ok := a_handler.response_ok (req)
|
|
||||||
if l_ok then
|
|
||||||
res.set_status_code ({HTTP_STATUS_CODE}.ok)
|
|
||||||
else
|
|
||||||
-- TODO - req.error_handler.has_error = True
|
|
||||||
--handle_internal_server_error (a_handler.last_error (req), req, res)
|
|
||||||
end
|
|
||||||
if attached a_handler.etag (req, a_media_type, a_language_type, a_character_type, a_compression_type) as l_etag then
|
|
||||||
a_header.put_header_key_value ({HTTP_HEADER_NAMES}.header_etag, l_etag)
|
|
||||||
end
|
|
||||||
res.put_header_text (a_header.string)
|
|
||||||
if l_ok then
|
|
||||||
if l_chunked then
|
|
||||||
send_chunked_response (req, res, a_handler, a_header, a_media_type, a_language_type, a_character_type, a_compression_type)
|
|
||||||
else
|
|
||||||
res.put_string (a_handler.content (req, a_media_type, a_language_type, a_character_type, a_compression_type))
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
send_chunked_response (req: WSF_REQUEST; res: WSF_RESPONSE; a_handler: WSF_SKELETON_HANDLER; a_header: HTTP_HEADER;
|
send_chunked_response (req: WSF_REQUEST; res: WSF_RESPONSE; a_handler: WSF_SKELETON_HANDLER; a_header: HTTP_HEADER;
|
||||||
@@ -290,7 +264,7 @@ feature {NONE} -- Implementation
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
if a_handler.finished (req) then
|
if a_handler.finished (req) then
|
||||||
-- TODO - support for trailers
|
-- In future, add support for trailers
|
||||||
res.put_chunk_end
|
res.put_chunk_end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -362,36 +336,139 @@ feature {NONE} -- Implementation
|
|||||||
|
|
||||||
feature -- Basic operations
|
feature -- Basic operations
|
||||||
|
|
||||||
handle_not_accepted (a_message: READABLE_STRING_8; req: WSF_REQUEST; res: WSF_RESPONSE)
|
handle_redirection_error (req: WSF_REQUEST; res: WSF_RESPONSE; a_locations: LIST [URI]; a_status_code: INTEGER)
|
||||||
-- Write a Not Accepted response to `res'.
|
-- Write `a_status_code' error to `res'.
|
||||||
|
-- Include all of `a_locations' in the headers, and hyperlink to the first one in the body.
|
||||||
|
require
|
||||||
|
res_attached: res /= Void
|
||||||
|
req_attached: req /= Void
|
||||||
|
a_locations_attached: a_locations /= Void
|
||||||
|
a_location_not_empty: not a_locations.is_empty
|
||||||
|
a_status_code_code: is_valid_http_status_code (a_status_code)
|
||||||
|
local
|
||||||
|
h: HTTP_HEADER
|
||||||
|
s: STRING
|
||||||
|
do
|
||||||
|
if attached http_status_code_message (a_status_code) as l_msg then
|
||||||
|
create h.make
|
||||||
|
across a_locations as i_location loop
|
||||||
|
h.add_header_key_value ({HTTP_HEADER_NAMES}.header_location, i_location.item.string)
|
||||||
|
end
|
||||||
|
if req.is_content_type_accepted ({HTTP_MIME_TYPES}.text_html) then
|
||||||
|
s := "<html lang=%"en%"><head>"
|
||||||
|
s.append ("<title>")
|
||||||
|
s.append (html_encoder.encoded_string (req.request_uri))
|
||||||
|
s.append ("Error " + a_status_code.out + " (" + l_msg + ")")
|
||||||
|
s.append ("</title>%N")
|
||||||
|
s.append ("[
|
||||||
|
<style type="text/css">
|
||||||
|
div#header {color: #fff; background-color: #000; padding: 20px; text-align: center; font-size: 2em; font-weight: bold;}
|
||||||
|
div#message { margin: 40px; text-align: center; font-size: 1.5em; }
|
||||||
|
div#suggestions { margin: auto; width: 60%;}
|
||||||
|
div#suggestions ul { }
|
||||||
|
div#footer {color: #999; background-color: #eee; padding: 10px; text-align: center; }
|
||||||
|
div#logo { float: right; margin: 20px; width: 60px height: auto; font-size: 0.8em; text-align: center; }
|
||||||
|
div#logo div.outer { padding: 6px; width: 60px; border: solid 3px #500; background-color: #b00;}
|
||||||
|
div#logo div.outer div.inner1 { display: block; margin: 10px 15px; width: 30px; height: 50px; color: #fff; background-color: #fff; border: solid 2px #900; }
|
||||||
|
div#logo div.outer div.inner2 { margin: 10px 15px; width: 30px; height: 15px; color: #fff; background-color: #fff; border: solid 2px #900; }
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
]")
|
||||||
|
s.append ("<div id=%"header%">Error " + a_status_code.out + " (" + l_msg + ")</div>")
|
||||||
|
s.append ("<div id=%"logo%">")
|
||||||
|
s.append ("<div class=%"outer%"> ")
|
||||||
|
s.append ("<div class=%"inner1%"></div>")
|
||||||
|
s.append ("<div class=%"inner2%"></div>")
|
||||||
|
s.append ("</div>")
|
||||||
|
s.append ("The current location for this resource is <a href=%"" + a_locations.first.string + "%">here</a>")
|
||||||
|
s.append ("Error " + a_status_code.out + " (" + l_msg + ")</div>")
|
||||||
|
s.append ("<div id=%"message%">Error " + a_status_code.out + " (" + l_msg + "): <code>" + html_encoder.encoded_string (req.request_uri) + "</code></div>")
|
||||||
|
s.append ("<div id=%"footer%"></div>")
|
||||||
|
s.append ("</body>%N")
|
||||||
|
s.append ("</html>%N")
|
||||||
|
|
||||||
|
h.put_content_type_text_html
|
||||||
|
else
|
||||||
|
s := "Error " + a_status_code.out + " (" + l_msg + "): "
|
||||||
|
s.append (req.request_uri)
|
||||||
|
s.append_character ('%N')
|
||||||
|
s.append ("The current location for this resource is " + a_locations.first.string)
|
||||||
|
h.put_content_type_text_plain
|
||||||
|
end
|
||||||
|
h.put_content_length (s.count)
|
||||||
|
res.put_header_lines (h)
|
||||||
|
res.put_string (s)
|
||||||
|
res.flush
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
handle_not_acceptable (a_message: READABLE_STRING_8; a_supported: LIST [STRING]; req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||||
|
-- Write a Not Acceptable response to `res'.
|
||||||
require
|
require
|
||||||
req_attached: req /= Void
|
req_attached: req /= Void
|
||||||
res_attached: res /= Void
|
res_attached: res /= Void
|
||||||
a_message_attached: a_message /= Void
|
a_message_attached: a_message /= Void
|
||||||
|
a_supported_attached: a_supported /= Void
|
||||||
|
local
|
||||||
|
h: HTTP_HEADER
|
||||||
|
s: STRING
|
||||||
do
|
do
|
||||||
-- TODO: flag this if it gets to code review.
|
create h.make
|
||||||
|
h.put_content_type_text_plain
|
||||||
|
h.put_current_date
|
||||||
|
s := a_message
|
||||||
|
s.append_character ('%N')
|
||||||
|
s.append_character ('%N')
|
||||||
|
s.append_string ("We accept the following:%N%N")
|
||||||
|
across a_supported as i_supported loop
|
||||||
|
s.append_string (i_supported.item)
|
||||||
|
s.append_character ('%N')
|
||||||
|
end
|
||||||
|
h.put_content_length (s.count)
|
||||||
|
res.set_status_code ({HTTP_STATUS_CODE}.not_acceptable)
|
||||||
|
res.put_header_lines (h)
|
||||||
|
res.put_string (s)
|
||||||
|
res.flush
|
||||||
end
|
end
|
||||||
|
|
||||||
handle_if_none_match_failed (req: WSF_REQUEST; res: WSF_RESPONSE)
|
handle_if_none_match_failed (req: WSF_REQUEST; res: WSF_RESPONSE; a_handler: WSF_SKELETON_HANDLER)
|
||||||
-- Write a Precondition Failed response to `res'.
|
-- Write a Not Modified response to `res'.
|
||||||
require
|
require
|
||||||
req_attached: req /= Void
|
req_attached: req /= Void
|
||||||
res_attached: res /= Void
|
res_attached: res /= Void
|
||||||
|
a_handler_attached: a_handler /= Void
|
||||||
do
|
do
|
||||||
-- TODO: flag this if it gets to code review. Why not just handle_precondition_failed?
|
handle_not_modified (req, res, a_handler)
|
||||||
end
|
end
|
||||||
|
|
||||||
handle_not_modified (req: WSF_REQUEST; res: WSF_RESPONSE)
|
handle_not_modified (req: WSF_REQUEST; res: WSF_RESPONSE; a_handler: WSF_SKELETON_HANDLER)
|
||||||
-- Write a Precondition Failed response to `res'.
|
-- Write a Not Modified response to `res'.
|
||||||
require
|
require
|
||||||
req_attached: req /= Void
|
req_attached: req /= Void
|
||||||
res_attached: res /= Void
|
res_attached: res /= Void
|
||||||
|
a_handler_attached: a_handler /= Void
|
||||||
|
local
|
||||||
|
h: HTTP_HEADER
|
||||||
do
|
do
|
||||||
-- TODO: flag this if it gets to code review. Why not just handle_precondition_failed?
|
create h.make
|
||||||
|
h.put_content_type_text_plain
|
||||||
|
h.put_content_length (0)
|
||||||
|
if attached a_handler.etag (req, "", "", "", "") as l_etag then
|
||||||
|
-- FIXME: We aren't strictly conformant here, as we have not conducted content negotiation yet,
|
||||||
|
-- so we might not get an identical etag as for a successful (200 OK) request.
|
||||||
|
-- So we should conduct content negotiation at this point (and if not acceptable, we don't include an etag).
|
||||||
|
-- Add add any Vary header that might result.
|
||||||
|
-- Also, when we add support for the Content-Location header in responses, we need to send that here too.
|
||||||
|
h.put_header_key_value ({HTTP_HEADER_NAMES}.header_etag, l_etag)
|
||||||
|
end
|
||||||
|
generate_cache_headers (req, a_handler, h, create {DATE_TIME}.make_now_utc)
|
||||||
|
res.set_status_code ({HTTP_STATUS_CODE}.not_modified)
|
||||||
|
res.put_header_lines (h)
|
||||||
end
|
end
|
||||||
|
|
||||||
handle_precondition_failed (req: WSF_REQUEST; res: WSF_RESPONSE)
|
handle_precondition_failed (req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||||
-- Write a precondition failed response for `req' to `res'.
|
-- Write a Precondition Failed response for `req' to `res'.
|
||||||
require
|
require
|
||||||
req_attached: req /= Void
|
req_attached: req /= Void
|
||||||
res_attached: res /= Void
|
res_attached: res /= Void
|
||||||
@@ -403,7 +480,59 @@ feature -- Basic operations
|
|||||||
h.put_current_date
|
h.put_current_date
|
||||||
h.put_content_length (0)
|
h.put_content_length (0)
|
||||||
res.set_status_code ({HTTP_STATUS_CODE}.precondition_failed)
|
res.set_status_code ({HTTP_STATUS_CODE}.precondition_failed)
|
||||||
res.put_header_text (h.string)
|
res.put_header_lines (h)
|
||||||
|
end
|
||||||
|
|
||||||
|
handle_unsupported_media_type (req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||||
|
-- Write a Unsupported Media Type response for `req' to `res'.
|
||||||
|
require
|
||||||
|
req_attached: req /= Void
|
||||||
|
res_attached: res /= Void
|
||||||
|
local
|
||||||
|
h: HTTP_HEADER
|
||||||
|
do
|
||||||
|
create h.make
|
||||||
|
h.put_content_type_text_plain
|
||||||
|
h.put_current_date
|
||||||
|
h.put_content_length (0)
|
||||||
|
res.set_status_code ({HTTP_STATUS_CODE}.unsupported_media_type)
|
||||||
|
res.put_header_lines (h)
|
||||||
|
end
|
||||||
|
|
||||||
|
handle_not_implemented (req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||||
|
-- Write a Not Implemented response for `req' to `res'.
|
||||||
|
require
|
||||||
|
req_attached: req /= Void
|
||||||
|
res_attached: res /= Void
|
||||||
|
local
|
||||||
|
h: HTTP_HEADER
|
||||||
|
do
|
||||||
|
create h.make
|
||||||
|
h.put_content_type_text_plain
|
||||||
|
h.put_current_date
|
||||||
|
h.put_content_length (0)
|
||||||
|
res.set_status_code ({HTTP_STATUS_CODE}.not_implemented)
|
||||||
|
res.put_header_lines (h)
|
||||||
|
end
|
||||||
|
|
||||||
|
handle_request_entity_too_large (req: WSF_REQUEST; res: WSF_RESPONSE; a_handler: WSF_SKELETON_HANDLER)
|
||||||
|
-- Write a Request Entity Too Large response for `req' to `res'.
|
||||||
|
require
|
||||||
|
req_attached: req /= Void
|
||||||
|
res_attached: res /= Void
|
||||||
|
a_handler_attached: a_handler /= Void
|
||||||
|
local
|
||||||
|
h: HTTP_HEADER
|
||||||
|
do
|
||||||
|
create h.make
|
||||||
|
h.put_content_type_text_plain
|
||||||
|
h.put_current_date
|
||||||
|
h.put_content_length (0)
|
||||||
|
res.set_status_code ({HTTP_STATUS_CODE}.request_entity_too_large)
|
||||||
|
res.put_header_lines (h)
|
||||||
|
-- FIXME: Need to check if condition is temporary. This needs a new query
|
||||||
|
-- on the handler. For now we can claim compliance by saying the condition
|
||||||
|
-- is always permenent :-) - author's might not like this though.
|
||||||
end
|
end
|
||||||
|
|
||||||
note
|
note
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ feature -- Factory
|
|||||||
do
|
do
|
||||||
if a_method.is_case_insensitive_equal ({HTTP_REQUEST_METHODS}.method_get) or
|
if a_method.is_case_insensitive_equal ({HTTP_REQUEST_METHODS}.method_get) or
|
||||||
a_method.is_case_insensitive_equal ({HTTP_REQUEST_METHODS}.method_head) then
|
a_method.is_case_insensitive_equal ({HTTP_REQUEST_METHODS}.method_head) then
|
||||||
create Result
|
create {WSF_GET_HELPER} Result
|
||||||
elseif a_method.is_case_insensitive_equal ({HTTP_REQUEST_METHODS}.method_put) then
|
elseif a_method.is_case_insensitive_equal ({HTTP_REQUEST_METHODS}.method_put) then
|
||||||
create {WSF_PUT_HELPER} Result
|
create {WSF_PUT_HELPER} Result
|
||||||
elseif a_method.is_case_insensitive_equal ({HTTP_REQUEST_METHODS}.method_post) then
|
elseif a_method.is_case_insensitive_equal ({HTTP_REQUEST_METHODS}.method_post) then
|
||||||
@@ -28,4 +28,14 @@ feature -- Factory
|
|||||||
end
|
end
|
||||||
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
|
end
|
||||||
|
|||||||
@@ -11,11 +11,8 @@ class WSF_POST_HELPER
|
|||||||
inherit
|
inherit
|
||||||
|
|
||||||
WSF_METHOD_HELPER
|
WSF_METHOD_HELPER
|
||||||
rename
|
|
||||||
send_get_response as do_post
|
|
||||||
redefine
|
redefine
|
||||||
execute_new_resource,
|
execute_new_resource
|
||||||
do_post
|
|
||||||
end
|
end
|
||||||
|
|
||||||
feature -- Basic operations
|
feature -- Basic operations
|
||||||
@@ -23,48 +20,54 @@ feature -- Basic operations
|
|||||||
execute_new_resource (req: WSF_REQUEST; res: WSF_RESPONSE; a_handler: WSF_SKELETON_HANDLER)
|
execute_new_resource (req: WSF_REQUEST; res: WSF_RESPONSE; a_handler: WSF_SKELETON_HANDLER)
|
||||||
-- Write response to non-existing resource requested by `req.' into `res'.
|
-- Write response to non-existing resource requested by `req.' into `res'.
|
||||||
-- Policy routines are available in `a_handler'.
|
-- Policy routines are available in `a_handler'.
|
||||||
local
|
|
||||||
l_etags: LIST [READABLE_STRING_32]
|
|
||||||
l_failed: BOOLEAN
|
|
||||||
do
|
do
|
||||||
if a_handler.allow_post_to_missing_resource (req) then
|
if a_handler.allow_post_to_missing_resource (req) then
|
||||||
handle_content_negotiation (req, res, a_handler, True)
|
handle_content_negotiation (req, res, a_handler, True)
|
||||||
else
|
else
|
||||||
-- TODO 404 Not Found
|
res.send (create {WSF_NOT_FOUND_RESPONSE}.make(req))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
feature {NONE} -- Implementation
|
feature {NONE} -- Implementation
|
||||||
|
|
||||||
do_post (req: WSF_REQUEST; res: WSF_RESPONSE; a_handler: WSF_SKELETON_HANDLER; a_header: HTTP_HEADER;
|
send_response (req: WSF_REQUEST; res: WSF_RESPONSE; a_handler: WSF_SKELETON_HANDLER; a_header: HTTP_HEADER;
|
||||||
a_media_type, a_language_type, a_character_type, a_compression_type: detachable READABLE_STRING_8; a_new_resource: BOOLEAN)
|
a_media_type, a_language_type, a_character_type, a_compression_type: detachable READABLE_STRING_8; a_new_resource: BOOLEAN)
|
||||||
-- Write response to `req' into `res' in accordance with `a_media_type' etc. as a new URI.
|
-- Write response to `req' into `res' in accordance with `a_media_type' etc. as a new URI.
|
||||||
|
local
|
||||||
|
l_code: NATURAL
|
||||||
do
|
do
|
||||||
a_handler.read_entity (req)
|
a_handler.read_entity (req)
|
||||||
if a_handler.is_entity_too_large (req) then
|
if a_handler.is_entity_too_large (req) then
|
||||||
handle_request_entity_too_large (req, res, a_handler)
|
handle_request_entity_too_large (req, res, a_handler)
|
||||||
else
|
else
|
||||||
a_handler.check_content_headers (req)
|
a_handler.check_content_headers (req)
|
||||||
if a_handler.content_check_code (req) /= 0 then
|
l_code := a_handler.content_check_code (req)
|
||||||
-- TODO - 415 or 501
|
if l_code /= 0 then
|
||||||
|
if l_code = 415 then
|
||||||
|
handle_unsupported_media_type (req, res)
|
||||||
|
else
|
||||||
|
handle_not_implemented (req, res)
|
||||||
|
end
|
||||||
else
|
else
|
||||||
a_handler.check_request (req, res)
|
a_handler.check_request (req, res)
|
||||||
if a_handler.request_check_code (req) = 0 then
|
if a_handler.request_check_code (req) = 0 then
|
||||||
a_handler.append_resource (req, res)
|
a_handler.append_resource (req, res)
|
||||||
-- 200 or 204 or 303 or 500 (add support for this?)
|
-- 200 or 204 or 303 or 500 (add support for this?)
|
||||||
-- TODO: more support, such as includes_response_entity
|
-- FIXME: more support, such as includes_response_entity
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
handle_request_entity_too_large (req: WSF_REQUEST; res: WSF_RESPONSE; a_handler: WSF_SKELETON_HANDLER)
|
note
|
||||||
-- TODO.
|
copyright: "2011-2013, Jocelyn Fiat, Javier Velilla, Olivier Ligot, Eiffel Software and others"
|
||||||
require
|
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
||||||
-- TODO
|
source: "[
|
||||||
do
|
Eiffel Software
|
||||||
-- Need to check if condition is temporary.
|
5949 Hollister Ave., Goleta, CA 93117 USA
|
||||||
end
|
Telephone 805-685-1006, Fax 805-685-6869
|
||||||
|
Website http://www.eiffel.com
|
||||||
|
Customer support http://support.eiffel.com
|
||||||
|
]"
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -11,11 +11,8 @@ class WSF_PUT_HELPER
|
|||||||
inherit
|
inherit
|
||||||
|
|
||||||
WSF_METHOD_HELPER
|
WSF_METHOD_HELPER
|
||||||
rename
|
|
||||||
send_get_response as do_put
|
|
||||||
redefine
|
redefine
|
||||||
execute_new_resource,
|
execute_new_resource
|
||||||
do_put
|
|
||||||
end
|
end
|
||||||
|
|
||||||
feature -- Basic operations
|
feature -- Basic operations
|
||||||
@@ -25,7 +22,7 @@ feature -- Basic operations
|
|||||||
-- Policy routines are available in `a_handler'.
|
-- Policy routines are available in `a_handler'.
|
||||||
do
|
do
|
||||||
if a_handler.treat_as_moved_permanently (req) then
|
if a_handler.treat_as_moved_permanently (req) then
|
||||||
-- TODO 301 Moved permanently response (single location)
|
handle_redirection_error (req, res, a_handler.previous_location (req), {HTTP_STATUS_CODE}.moved_permanently)
|
||||||
else
|
else
|
||||||
handle_content_negotiation (req, res, a_handler, True)
|
handle_content_negotiation (req, res, a_handler, True)
|
||||||
end
|
end
|
||||||
@@ -34,17 +31,24 @@ feature -- Basic operations
|
|||||||
|
|
||||||
feature {NONE} -- Implementation
|
feature {NONE} -- Implementation
|
||||||
|
|
||||||
do_put (req: WSF_REQUEST; res: WSF_RESPONSE; a_handler: WSF_SKELETON_HANDLER; a_header: HTTP_HEADER;
|
send_response (req: WSF_REQUEST; res: WSF_RESPONSE; a_handler: WSF_SKELETON_HANDLER; a_header: HTTP_HEADER;
|
||||||
a_media_type, a_language_type, a_character_type, a_compression_type: detachable READABLE_STRING_8; a_new_resource: BOOLEAN)
|
a_media_type, a_language_type, a_character_type, a_compression_type: detachable READABLE_STRING_8; a_new_resource: BOOLEAN)
|
||||||
-- Write response to `req' into `res' in accordance with `a_media_type' etc. as a new URI.
|
-- Write response to `req' into `res' in accordance with `a_media_type' etc. as a new URI.
|
||||||
|
local
|
||||||
|
l_code: NATURAL
|
||||||
do
|
do
|
||||||
a_handler.read_entity (req)
|
a_handler.read_entity (req)
|
||||||
if a_handler.is_entity_too_large (req) then
|
if a_handler.is_entity_too_large (req) then
|
||||||
handle_request_entity_too_large (req, res, a_handler)
|
handle_request_entity_too_large (req, res, a_handler)
|
||||||
else
|
else
|
||||||
a_handler.check_content_headers (req)
|
a_handler.check_content_headers (req)
|
||||||
if a_handler.content_check_code (req) /= 0 then
|
l_code := a_handler.content_check_code (req)
|
||||||
-- TODO - 415 or 501
|
if l_code /= 0 then
|
||||||
|
if l_code = 415 then
|
||||||
|
handle_unsupported_media_type (req, res)
|
||||||
|
else
|
||||||
|
handle_not_implemented (req, res)
|
||||||
|
end
|
||||||
else
|
else
|
||||||
a_handler.check_request (req, res)
|
a_handler.check_request (req, res)
|
||||||
if a_handler.request_check_code (req) = 0 then
|
if a_handler.request_check_code (req) = 0 then
|
||||||
@@ -56,7 +60,7 @@ feature {NONE} -- Implementation
|
|||||||
if a_handler.conflict_check_code (req) = 0 then
|
if a_handler.conflict_check_code (req) = 0 then
|
||||||
a_handler.update_resource (req, res)
|
a_handler.update_resource (req, res)
|
||||||
-- 204 or 500 (add support for this?)
|
-- 204 or 500 (add support for this?)
|
||||||
-- TODO: more support, such as includes_response_entity
|
-- FIXME: more support, such as includes_response_entity
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -64,12 +68,4 @@ feature {NONE} -- Implementation
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
handle_request_entity_too_large (req: WSF_REQUEST; res: WSF_RESPONSE; a_handler: WSF_SKELETON_HANDLER)
|
|
||||||
-- TODO.
|
|
||||||
require
|
|
||||||
-- TODO
|
|
||||||
do
|
|
||||||
-- Need to check if condition is temporary.
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -24,6 +24,8 @@ inherit
|
|||||||
|
|
||||||
WSF_METHOD_HELPER_FACTORY
|
WSF_METHOD_HELPER_FACTORY
|
||||||
|
|
||||||
|
WSF_SELF_DOCUMENTED_HANDLER
|
||||||
|
|
||||||
feature -- Access
|
feature -- Access
|
||||||
|
|
||||||
is_chunking (req: WSF_REQUEST): BOOLEAN
|
is_chunking (req: WSF_REQUEST): BOOLEAN
|
||||||
@@ -42,7 +44,7 @@ feature -- Access
|
|||||||
end
|
end
|
||||||
|
|
||||||
conneg (req: WSF_REQUEST): CONNEG_SERVER_SIDE
|
conneg (req: WSF_REQUEST): CONNEG_SERVER_SIDE
|
||||||
-- Content negotiatior for `req';
|
-- Content negotiation for `req';
|
||||||
-- This would normally be a once object, ignoring `req'.
|
-- This would normally be a once object, ignoring `req'.
|
||||||
require
|
require
|
||||||
req_attached: req /= Void
|
req_attached: req /= Void
|
||||||
@@ -161,6 +163,25 @@ feature -- Status report
|
|||||||
deferred
|
deferred
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
feature -- Documentation
|
||||||
|
|
||||||
|
mapping_documentation (m: WSF_ROUTER_MAPPING; a_request_methods: detachable WSF_REQUEST_METHODS): WSF_ROUTER_MAPPING_DOCUMENTATION
|
||||||
|
-- Documentation associated with Current handler, in the context of the mapping `m' and methods `a_request_methods'
|
||||||
|
--| `m' and `a_request_methods' are useful to produce specific documentation when the handler is used for multiple mapping.
|
||||||
|
do
|
||||||
|
create Result.make (m)
|
||||||
|
Result.add_description (description)
|
||||||
|
end
|
||||||
|
|
||||||
|
description: READABLE_STRING_GENERAL
|
||||||
|
-- General description for self-generated documentation;
|
||||||
|
-- The specific URI templates supported will be described automatically
|
||||||
|
deferred
|
||||||
|
ensure
|
||||||
|
description_attached: Result /= Void
|
||||||
|
end
|
||||||
|
|
||||||
feature -- DELETE
|
feature -- DELETE
|
||||||
|
|
||||||
delete (req: WSF_REQUEST)
|
delete (req: WSF_REQUEST)
|
||||||
|
|||||||
@@ -376,6 +376,8 @@ feature -- Helper
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
Result := l_accept.has_substring (a_content_type)
|
Result := l_accept.has_substring (a_content_type)
|
||||||
|
else
|
||||||
|
Result := True
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user