prior to refactoring for WSF_ROUTED_SKELETON_SERVICE
This commit is contained in:
@@ -10,11 +10,16 @@ inherit
|
|||||||
ANY
|
ANY
|
||||||
|
|
||||||
WSF_URI_TEMPLATE_ROUTED_SERVICE
|
WSF_URI_TEMPLATE_ROUTED_SERVICE
|
||||||
|
undefine
|
||||||
|
requires_proxy
|
||||||
|
end
|
||||||
|
|
||||||
WSF_HANDLER_HELPER
|
WSF_HANDLER_HELPER
|
||||||
|
|
||||||
WSF_DEFAULT_SERVICE
|
WSF_DEFAULT_SERVICE
|
||||||
|
|
||||||
|
WSF_NO_PROXY_POLICY
|
||||||
|
|
||||||
create
|
create
|
||||||
make
|
make
|
||||||
|
|
||||||
|
|||||||
35
library/server/wsf/router/wsf_no_proxy_policy.e
Normal file
35
library/server/wsf/router/wsf_no_proxy_policy.e
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
note
|
||||||
|
|
||||||
|
description: "[
|
||||||
|
Policy that no client ever need use a proxy.
|
||||||
|
|
||||||
|
Users of this policy cannot safely use chunked transfer-encoding, or any
|
||||||
|
HTTP/1.1-specific features. So best used only for examples.
|
||||||
|
]"
|
||||||
|
|
||||||
|
date: "$Date$"
|
||||||
|
revision: "$Revision$"
|
||||||
|
|
||||||
|
class WSF_NO_PROXY_POLICY
|
||||||
|
|
||||||
|
inherit
|
||||||
|
|
||||||
|
WSF_PROXY_USE_POLICY
|
||||||
|
redefine
|
||||||
|
requires_proxy
|
||||||
|
end
|
||||||
|
|
||||||
|
feature -- Access
|
||||||
|
|
||||||
|
requires_proxy (req: WSF_REQUEST): BOOLEAN
|
||||||
|
-- Does `req' require use of `proxy_server'?
|
||||||
|
do
|
||||||
|
end
|
||||||
|
|
||||||
|
proxy_server (req: WSF_REQUEST): READABLE_STRING_8 -- We can't currently use UT_URI
|
||||||
|
-- Absolute URI of proxy server which `req' must use
|
||||||
|
do
|
||||||
|
Result := "" -- doesn't meet the postcondition, but the precondition is never true.
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
76
library/server/wsf/router/wsf_proxy_use_policy.e
Normal file
76
library/server/wsf/router/wsf_proxy_use_policy.e
Normal file
@@ -0,0 +1,76 @@
|
|||||||
|
note
|
||||||
|
|
||||||
|
description: "[
|
||||||
|
Policies that determine if the client must use a proxy server
|
||||||
|
to access the resource.
|
||||||
|
|
||||||
|
The default policy implemented here is to require
|
||||||
|
use of the proxy for HTTP/1.0 clients (only) for all requests.
|
||||||
|
]"
|
||||||
|
|
||||||
|
date: "$Date$"
|
||||||
|
revision: "$Revision$"
|
||||||
|
|
||||||
|
deferred class WSF_PROXY_USE_POLICY
|
||||||
|
|
||||||
|
feature -- Access
|
||||||
|
|
||||||
|
requires_proxy (req: WSF_REQUEST): BOOLEAN
|
||||||
|
-- Does `req' require use of `proxy_server'?
|
||||||
|
require
|
||||||
|
req_attached: req /= Void
|
||||||
|
do
|
||||||
|
if is_http_1_0 (req) then
|
||||||
|
Result := True
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
proxy_server (req: WSF_REQUEST): READABLE_STRING_8 -- We can't currently use UT_URI
|
||||||
|
-- Absolute URI of proxy server which `req' must use
|
||||||
|
--| An alternative design would allow a relative URI (relative to the server host),
|
||||||
|
--| which will only work if both the server and the proxy use the default ports.
|
||||||
|
require
|
||||||
|
req_attached: req /= Void
|
||||||
|
proxy_required: requires_proxy (req)
|
||||||
|
deferred
|
||||||
|
ensure
|
||||||
|
absolute_uri: True -- We can't currently use UT_URI to check this. Have we got another class?
|
||||||
|
end
|
||||||
|
|
||||||
|
is_http_1_0 (req: WSF_REQUEST): BOOLEAN
|
||||||
|
-- Does `req' come from an HTTP/1.0 client?
|
||||||
|
require
|
||||||
|
req_attached: req /= Void
|
||||||
|
local
|
||||||
|
l_protocol: READABLE_STRING_8
|
||||||
|
l_tokens: LIST [READABLE_STRING_8]
|
||||||
|
l_protocol_name, l_protocol_version, l_major, l_minor: STRING_8
|
||||||
|
do
|
||||||
|
l_protocol := req.server_protocol
|
||||||
|
l_tokens := l_protocol.split ('/')
|
||||||
|
if l_tokens.count = 2 then
|
||||||
|
l_protocol_name := l_tokens [1].as_string_8
|
||||||
|
l_protocol_name.left_adjust
|
||||||
|
l_protocol_name.right_adjust
|
||||||
|
if l_protocol_name.is_case_insensitive_equal ({HTTP_CONSTANTS}.http_version_1_0.substring (1, 4)) then
|
||||||
|
l_protocol_version := l_tokens [2].as_string_8
|
||||||
|
l_protocol_version.left_adjust
|
||||||
|
l_protocol_version.right_adjust
|
||||||
|
l_tokens := l_protocol_version.split ('.')
|
||||||
|
if l_tokens.count = 2 then
|
||||||
|
l_major := l_tokens [1].as_string_8
|
||||||
|
l_major.left_adjust
|
||||||
|
l_major.right_adjust
|
||||||
|
l_minor := l_tokens [2].as_string_8
|
||||||
|
l_minor.left_adjust
|
||||||
|
l_minor.right_adjust
|
||||||
|
if l_major.is_integer and then l_major.to_integer = 1 and then
|
||||||
|
l_minor.is_integer and then l_minor.to_integer = 0 then
|
||||||
|
Result := True
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
@@ -10,6 +10,8 @@ inherit
|
|||||||
|
|
||||||
WSF_SYSTEM_OPTIONS_ACCESS_POLICY
|
WSF_SYSTEM_OPTIONS_ACCESS_POLICY
|
||||||
|
|
||||||
|
WSF_PROXY_USE_POLICY
|
||||||
|
|
||||||
feature -- Initialization
|
feature -- Initialization
|
||||||
|
|
||||||
initialize_router
|
initialize_router
|
||||||
@@ -50,9 +52,11 @@ feature -- Execution
|
|||||||
--| which is implemented in WSF_REQUEST.make_from_wgi (when it calls `analyze').
|
--| which is implemented in WSF_REQUEST.make_from_wgi (when it calls `analyze').
|
||||||
if unavailable then
|
if unavailable then
|
||||||
handle_unavailable (res)
|
handle_unavailable (res)
|
||||||
|
elseif requires_proxy (req) then
|
||||||
|
handle_use_proxy (req, res)
|
||||||
elseif maximum_uri_length > 0 and then req.request_uri.count.to_natural_32 > maximum_uri_length then
|
elseif maximum_uri_length > 0 and then req.request_uri.count.to_natural_32 > maximum_uri_length then
|
||||||
handle_request_uri_too_long (res)
|
handle_request_uri_too_long (res)
|
||||||
elseif req.request_method.as_upper.same_string ({HTTP_REQUEST_METHODS}.method_options) and then
|
elseif req.is_request_method ({HTTP_REQUEST_METHODS}.method_options) and then
|
||||||
req.request_uri.same_string ("*") then
|
req.request_uri.same_string ("*") then
|
||||||
handle_server_options (req, res)
|
handle_server_options (req, res)
|
||||||
elseif attached router.dispatch_and_return_handler (req, res) as p then
|
elseif attached router.dispatch_and_return_handler (req, res) as p then
|
||||||
@@ -73,7 +77,6 @@ feature -- Execution
|
|||||||
local
|
local
|
||||||
msg: WSF_DEFAULT_ROUTER_RESPONSE
|
msg: WSF_DEFAULT_ROUTER_RESPONSE
|
||||||
do
|
do
|
||||||
--| TODO (colin-adams): update this to distinguish between 501, 403 and 404 results.
|
|
||||||
create msg.make_with_router (req, router)
|
create msg.make_with_router (req, router)
|
||||||
msg.set_documentation_included (True)
|
msg.set_documentation_included (True)
|
||||||
res.send (msg)
|
res.send (msg)
|
||||||
@@ -152,26 +155,23 @@ feature {NONE} -- Implementation
|
|||||||
handle_unavailable (res: WSF_RESPONSE)
|
handle_unavailable (res: WSF_RESPONSE)
|
||||||
-- Write "Service unavailable" response to `res'.
|
-- Write "Service unavailable" response to `res'.
|
||||||
require
|
require
|
||||||
unavailable: unavailable = True
|
unavailable: unavailable
|
||||||
res_attached: res /= Void
|
res_attached: res /= Void
|
||||||
local
|
local
|
||||||
h: HTTP_HEADER
|
h: HTTP_HEADER
|
||||||
do
|
do
|
||||||
create h.make
|
create h.make
|
||||||
h.put_content_type_text_plain
|
h.put_content_type_text_plain
|
||||||
check attached {READABLE_STRING_8} unavailablity_message as m then
|
check attached unavailablity_message as m then
|
||||||
-- invariant
|
-- invariant plus precondition
|
||||||
h.put_content_length (m.count)
|
h.put_content_length (m.count)
|
||||||
h.put_current_date
|
h.put_current_date
|
||||||
res.set_status_code ({HTTP_STATUS_CODE}.service_unavailable)
|
res.set_status_code ({HTTP_STATUS_CODE}.service_unavailable)
|
||||||
if unavailability_duration > 0 then
|
if unavailability_duration > 0 then
|
||||||
h.put_header_key_value ({HTTP_HEADER_NAMES}.header_retry_after, unavailability_duration.out)
|
h.put_header_key_value ({HTTP_HEADER_NAMES}.header_retry_after, unavailability_duration.out)
|
||||||
elseif unavailable_until /= Void then
|
elseif attached unavailable_until as u then
|
||||||
check attached {DATE_TIME} unavailable_until as u then
|
|
||||||
-- $£#$%#! compiler!
|
|
||||||
h.put_header_key_value ({HTTP_HEADER_NAMES}.header_retry_after,
|
h.put_header_key_value ({HTTP_HEADER_NAMES}.header_retry_after,
|
||||||
h.date_to_rfc1123_http_date_format (u))
|
h.date_to_rfc1123_http_date_format (u))
|
||||||
end
|
|
||||||
end
|
end
|
||||||
res.put_header_text (h.string)
|
res.put_header_text (h.string)
|
||||||
res.put_string (m)
|
res.put_string (m)
|
||||||
@@ -210,7 +210,7 @@ feature {NONE} -- Implementation
|
|||||||
require
|
require
|
||||||
req_attached: req /= Void
|
req_attached: req /= Void
|
||||||
res_attached: res /= Void
|
res_attached: res /= Void
|
||||||
method_is_options: req.request_method.as_upper.same_string ({HTTP_REQUEST_METHODS}.method_options)
|
method_is_options: req.is_request_method ({HTTP_REQUEST_METHODS}.method_options)
|
||||||
server_options_requested: req.request_uri.same_string ("*")
|
server_options_requested: req.request_uri.same_string ("*")
|
||||||
do
|
do
|
||||||
--| First check if forbidden.
|
--| First check if forbidden.
|
||||||
@@ -233,7 +233,7 @@ feature {NONE} -- Implementation
|
|||||||
require
|
require
|
||||||
req_attached: req /= Void
|
req_attached: req /= Void
|
||||||
res_attached: res /= Void
|
res_attached: res /= Void
|
||||||
method_is_options: req.request_method.as_upper.same_string ({HTTP_REQUEST_METHODS}.method_options)
|
method_is_options: req.is_request_method ({HTTP_REQUEST_METHODS}.method_options)
|
||||||
server_options_requested: req.request_uri.same_string ("*")
|
server_options_requested: req.request_uri.same_string ("*")
|
||||||
local
|
local
|
||||||
m: detachable READABLE_STRING_8
|
m: detachable READABLE_STRING_8
|
||||||
@@ -270,18 +270,18 @@ feature {NONE} -- Implementation
|
|||||||
require
|
require
|
||||||
req_attached: req /= Void
|
req_attached: req /= Void
|
||||||
res_attached: res /= Void
|
res_attached: res /= Void
|
||||||
method_is_options: req.request_method.as_upper.same_string ({HTTP_REQUEST_METHODS}.method_options)
|
method_is_options: req.is_request_method ({HTTP_REQUEST_METHODS}.method_options)
|
||||||
server_options_requested: req.request_uri.same_string ("*")
|
server_options_requested: req.request_uri.same_string ("*")
|
||||||
local
|
local
|
||||||
h: HTTP_HEADER
|
h: HTTP_HEADER
|
||||||
do
|
do
|
||||||
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
|
||||||
--| TODO - add Allow header for all permitted methods.
|
h.put_allow (router.all_allowed_methods)
|
||||||
h.put_content_length (0)
|
h.put_content_length (0)
|
||||||
res.set_status_code ({HTTP_STATUS_CODE}.ok)
|
res.set_status_code ({HTTP_STATUS_CODE}.ok)
|
||||||
res.put_header_text (h.string)
|
res.put_header_text (h.string)
|
||||||
ensure
|
ensure
|
||||||
response_status_is_set: res.status_is_set
|
response_status_is_set: res.status_is_set
|
||||||
response_code_ok: res.status_code = {HTTP_STATUS_CODE}.ok
|
response_code_ok: res.status_code = {HTTP_STATUS_CODE}.ok
|
||||||
@@ -289,9 +289,30 @@ feature {NONE} -- Implementation
|
|||||||
empty_body: res.transfered_content_length = 0
|
empty_body: res.transfered_content_length = 0
|
||||||
end
|
end
|
||||||
|
|
||||||
|
frozen handle_use_proxy (req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||||
|
-- Write response to OPTIONS * into `res'.
|
||||||
|
require
|
||||||
|
res_attached: res /= Void
|
||||||
|
req_attached: req /= Void
|
||||||
|
proxy_required: requires_proxy (req)
|
||||||
|
local
|
||||||
|
h: HTTP_HEADER
|
||||||
|
do
|
||||||
|
create h.make
|
||||||
|
h.put_content_type_text_plain
|
||||||
|
h.put_current_date
|
||||||
|
h.put_location (proxy_server (req))
|
||||||
|
h.put_content_length (0)
|
||||||
|
res.set_status_code ({HTTP_STATUS_CODE}.use_proxy)
|
||||||
|
ensure
|
||||||
|
response_status_is_set: res.status_is_set
|
||||||
|
response_code_use_proxy: res.status_code = {HTTP_STATUS_CODE}.use_proxy
|
||||||
|
header_sent: res.header_committed and res.message_committed
|
||||||
|
end
|
||||||
|
|
||||||
invariant
|
invariant
|
||||||
|
|
||||||
unavailability_message_attached: unavailable implies attached {READABLE_STRING_8} unavailablity_message as m and then
|
unavailability_message_attached: unavailable implies attached unavailablity_message as m and then
|
||||||
m.count > 0
|
m.count > 0
|
||||||
unavailability_duration_xor_unavailable_until: unavailability_duration > 0 implies unavailable_until = Void
|
unavailability_duration_xor_unavailable_until: unavailability_duration > 0 implies unavailable_until = Void
|
||||||
|
|
||||||
|
|||||||
@@ -277,6 +277,26 @@ feature -- Status report
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
all_allowed_methods: WSF_REQUEST_METHODS
|
||||||
|
-- Methods allowed for ALL requests handled by `Current'
|
||||||
|
local
|
||||||
|
l_mapping: WSF_ROUTER_MAPPING
|
||||||
|
do
|
||||||
|
create Result
|
||||||
|
across
|
||||||
|
mappings as c
|
||||||
|
loop
|
||||||
|
if attached c.item.request_methods as m then
|
||||||
|
Result := Result + m
|
||||||
|
end
|
||||||
|
l_mapping := c.item.mapping
|
||||||
|
if attached {WSF_ROUTING_HANDLER} l_mapping.handler as l_routing then
|
||||||
|
Result := Result + l_routing.router.all_allowed_methods
|
||||||
|
end
|
||||||
|
--| not sure if that covers everything - Jocelyn, please comment
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
feature -- Hook
|
feature -- Hook
|
||||||
|
|
||||||
execute_before (a_mapping: WSF_ROUTER_MAPPING)
|
execute_before (a_mapping: WSF_ROUTER_MAPPING)
|
||||||
|
|||||||
@@ -76,25 +76,44 @@ feature {WSF_RESPONSE} -- Output
|
|||||||
|
|
||||||
send_to (res: WSF_RESPONSE)
|
send_to (res: WSF_RESPONSE)
|
||||||
local
|
local
|
||||||
s: STRING
|
s, l_html_error_code_text: STRING
|
||||||
l_text: detachable READABLE_STRING_GENERAL
|
l_text: detachable READABLE_STRING_GENERAL
|
||||||
l_loc: detachable READABLE_STRING_8
|
l_loc: detachable READABLE_STRING_8
|
||||||
h: like header
|
h: like header
|
||||||
|
l_recognized: BOOLEAN
|
||||||
|
l_messages: HTTP_STATUS_CODE_MESSAGES
|
||||||
do
|
do
|
||||||
|
create l_messages
|
||||||
h := header
|
h := header
|
||||||
res.set_status_code ({HTTP_STATUS_CODE}.method_not_allowed)
|
l_recognized := recognized_methods.has (request.request_method.as_upper)
|
||||||
|
if l_recognized then
|
||||||
|
res.set_status_code (l_messages.method_not_allowed)
|
||||||
|
else
|
||||||
|
res.set_status_code (l_messages.not_implemented)
|
||||||
|
end
|
||||||
|
|
||||||
if attached suggested_methods as lst and then not lst.is_empty then
|
if attached suggested_methods as lst and then not lst.is_empty then
|
||||||
h.put_allow (lst)
|
h.put_allow (lst)
|
||||||
end
|
end
|
||||||
|
|
||||||
s := "Not allowed"
|
if attached l_messages.http_status_code_message (res.status_code) as l_msg then
|
||||||
|
s := l_msg
|
||||||
|
else
|
||||||
|
check
|
||||||
|
impossible: False
|
||||||
|
-- as res.status_code is set to one of the codes that will produce
|
||||||
|
-- a non-void response, even though there is no postcondition to prove it
|
||||||
|
end
|
||||||
|
s := "Bug in server"
|
||||||
|
end
|
||||||
|
|
||||||
|
l_html_error_code_text := html_error_code_text (l_messages, l_recognized)
|
||||||
|
|
||||||
if request.is_content_type_accepted ({HTTP_MIME_TYPES}.text_html) then
|
if request.is_content_type_accepted ({HTTP_MIME_TYPES}.text_html) then
|
||||||
s := "<html lang=%"en%"><head>"
|
s := "<html lang=%"en%"><head>"
|
||||||
s.append ("<title>")
|
s.append ("<title>")
|
||||||
s.append (html_encoder.encoded_string (request.request_uri))
|
s.append (html_encoder.encoded_string (request.request_uri))
|
||||||
s.append ("Error 405 (Method Not Allowed)!!")
|
s.append (l_html_error_code_text + "!!")
|
||||||
s.append ("</title>%N")
|
s.append ("</title>%N")
|
||||||
s.append (
|
s.append (
|
||||||
"[
|
"[
|
||||||
@@ -111,15 +130,15 @@ feature {WSF_RESPONSE} -- Output
|
|||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div id="header">Error 405 (Method Not Allowed)!!</div>
|
<div id="header">]" + l_html_error_code_text + "[!!</div>
|
||||||
]")
|
]")
|
||||||
s.append ("<div id=%"logo%">")
|
s.append ("<div id=%"logo%">")
|
||||||
s.append ("<div class=%"outter%"> ")
|
s.append ("<div class=%"outter%"> ")
|
||||||
s.append ("<div class=%"inner1%"></div>")
|
s.append ("<div class=%"inner1%"></div>")
|
||||||
s.append ("<div class=%"inner2%"></div>")
|
s.append ("<div class=%"inner2%"></div>")
|
||||||
s.append ("</div>")
|
s.append ("</div>")
|
||||||
s.append ("Error 405 (Method Not Allowed)</div>")
|
s.append (l_html_error_code_text + "</div>")
|
||||||
s.append ("<div id=%"message%">Error 405 (Method Not Allowed): the request method <code>")
|
s.append ("<div id=%"message%">" + l_html_error_code_text + ": the request method <code>")
|
||||||
s.append (request.request_method)
|
s.append (request.request_method)
|
||||||
s.append ("</code> is inappropriate for the URL for <code>" + html_encoder.encoded_string (request.request_uri) + "</code>.</div>")
|
s.append ("</code> is inappropriate for the URL for <code>" + html_encoder.encoded_string (request.request_uri) + "</code>.</div>")
|
||||||
if attached suggested_methods as lst and then not lst.is_empty then
|
if attached suggested_methods as lst and then not lst.is_empty then
|
||||||
@@ -180,7 +199,7 @@ feature {WSF_RESPONSE} -- Output
|
|||||||
|
|
||||||
h.put_content_type_text_html
|
h.put_content_type_text_html
|
||||||
else
|
else
|
||||||
s := "Error 405 (Method Not Allowed): the request method "
|
s := l_html_error_code_text + ": the request method "
|
||||||
s.append (request.request_method)
|
s.append (request.request_method)
|
||||||
s.append (" is inappropriate for the URL for '" + html_encoder.encoded_string (request.request_uri) + "'.%N")
|
s.append (" is inappropriate for the URL for '" + html_encoder.encoded_string (request.request_uri) + "'.%N")
|
||||||
if attached suggested_methods as lst and then not lst.is_empty then
|
if attached suggested_methods as lst and then not lst.is_empty then
|
||||||
@@ -239,6 +258,53 @@ feature {WSF_RESPONSE} -- Output
|
|||||||
res.flush
|
res.flush
|
||||||
end
|
end
|
||||||
|
|
||||||
|
feature {NONE} -- Implementation
|
||||||
|
|
||||||
|
recognized_methods: WSF_REQUEST_METHODS
|
||||||
|
-- All methods defined in HTTP/1.1 specification
|
||||||
|
--| Should this include CONNECT? It probably shouldn't be recognized by an origin server,
|
||||||
|
--| We will need a way to extend this for additional methods that the server implements. E.g. PATCH.
|
||||||
|
do
|
||||||
|
create Result.make_from_iterable (<<
|
||||||
|
{HTTP_REQUEST_METHODS}.method_head,
|
||||||
|
{HTTP_REQUEST_METHODS}.method_get,
|
||||||
|
{HTTP_REQUEST_METHODS}.method_trace,
|
||||||
|
{HTTP_REQUEST_METHODS}.method_options,
|
||||||
|
{HTTP_REQUEST_METHODS}.method_post,
|
||||||
|
{HTTP_REQUEST_METHODS}.method_put,
|
||||||
|
{HTTP_REQUEST_METHODS}.method_delete
|
||||||
|
>>)
|
||||||
|
ensure
|
||||||
|
recognized_methods_not_void: Result /= Void
|
||||||
|
end
|
||||||
|
|
||||||
|
html_error_code_text (a_messages: HTTP_STATUS_CODE_MESSAGES; a_recognized: BOOLEAN): READABLE_STRING_8
|
||||||
|
-- Message for including in HTML error text according to `a_recognized'
|
||||||
|
require
|
||||||
|
a_messages_attached: a_messages /= Void
|
||||||
|
local
|
||||||
|
l_code: INTEGER
|
||||||
|
do
|
||||||
|
if a_recognized then
|
||||||
|
l_code := a_messages.method_not_allowed
|
||||||
|
else
|
||||||
|
l_code := a_messages.not_implemented
|
||||||
|
end
|
||||||
|
if attached a_messages.http_status_code_message (l_code) as l_msg then
|
||||||
|
Result := "Error " + l_code.out + " (" + l_msg + ")"
|
||||||
|
else
|
||||||
|
check
|
||||||
|
impossible: False
|
||||||
|
-- as res.status_code is set to one of the codes that will produce
|
||||||
|
-- a non-void response, even though there is no postcondition to prove it.
|
||||||
|
-- The postcondition wouldn't be needed if there was a precondition using is_valid_http_status_code
|
||||||
|
end
|
||||||
|
Result := "Bug in server"
|
||||||
|
end
|
||||||
|
ensure
|
||||||
|
html_error_code_text_attached: Result /= Void
|
||||||
|
end
|
||||||
|
|
||||||
note
|
note
|
||||||
copyright: "2011-2012, Jocelyn Fiat, Javier Velilla, Olivier Ligot, Eiffel Software and others"
|
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)"
|
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
||||||
|
|||||||
Reference in New Issue
Block a user