This commit is contained in:
@@ -113,6 +113,27 @@ feature -- Element change
|
||||
headers.force (v, k)
|
||||
end
|
||||
|
||||
add_header_line (s: READABLE_STRING_8)
|
||||
local
|
||||
i: INTEGER
|
||||
do
|
||||
i := s.index_of (':', 1)
|
||||
if i > 0 then
|
||||
add_header (s.substring (1, i - 1), s.substring (i + 1, s.count))
|
||||
end
|
||||
end
|
||||
|
||||
add_header_lines (lst: ITERABLE [READABLE_STRING_8])
|
||||
local
|
||||
i: INTEGER
|
||||
do
|
||||
across
|
||||
lst as c
|
||||
loop
|
||||
add_header_line (c.item)
|
||||
end
|
||||
end
|
||||
|
||||
add_query_parameter (k: READABLE_STRING_32; v: READABLE_STRING_32)
|
||||
do
|
||||
query_parameters.force (v, k)
|
||||
|
||||
@@ -76,6 +76,11 @@ feature -- Basic operation
|
||||
end
|
||||
end
|
||||
|
||||
custom (a_method: READABLE_STRING_8; a_path: READABLE_STRING_8; ctx: detachable HTTP_CLIENT_REQUEST_CONTEXT): HTTP_CLIENT_RESPONSE
|
||||
-- Response for `a_method' request based on Current, `a_path' and `ctx'.
|
||||
deferred
|
||||
end
|
||||
|
||||
get (a_path: READABLE_STRING_8; ctx: detachable HTTP_CLIENT_REQUEST_CONTEXT): HTTP_CLIENT_RESPONSE
|
||||
-- Response for GET request based on Current, `a_path' and `ctx'.
|
||||
deferred
|
||||
@@ -124,7 +129,7 @@ feature -- Status report
|
||||
-- Is interface usable?
|
||||
deferred
|
||||
end
|
||||
|
||||
|
||||
feature -- Settings
|
||||
|
||||
timeout: INTEGER
|
||||
|
||||
@@ -33,20 +33,22 @@ feature -- Status report
|
||||
|
||||
feature -- Basic operation
|
||||
|
||||
get (a_path: READABLE_STRING_8; ctx: detachable HTTP_CLIENT_REQUEST_CONTEXT): HTTP_CLIENT_RESPONSE
|
||||
custom (a_method: READABLE_STRING_8; a_path: READABLE_STRING_8; ctx: detachable HTTP_CLIENT_REQUEST_CONTEXT): HTTP_CLIENT_RESPONSE
|
||||
local
|
||||
req: HTTP_CLIENT_REQUEST
|
||||
do
|
||||
create {LIBCURL_HTTP_CLIENT_REQUEST} req.make (base_url + a_path, "GET", Current, ctx)
|
||||
create {LIBCURL_HTTP_CLIENT_REQUEST} req.make (base_url + a_path, a_method, Current, ctx)
|
||||
Result := req.execute
|
||||
end
|
||||
|
||||
head (a_path: READABLE_STRING_8; ctx: detachable HTTP_CLIENT_REQUEST_CONTEXT): HTTP_CLIENT_RESPONSE
|
||||
local
|
||||
req: HTTP_CLIENT_REQUEST
|
||||
get (a_path: READABLE_STRING_8; ctx: detachable HTTP_CLIENT_REQUEST_CONTEXT): HTTP_CLIENT_RESPONSE
|
||||
do
|
||||
create {LIBCURL_HTTP_CLIENT_REQUEST} req.make (base_url + a_path, "HEAD", Current, ctx)
|
||||
Result := req.execute
|
||||
Result := custom ("GET", a_path, ctx)
|
||||
end
|
||||
|
||||
head (a_path: READABLE_STRING_8; ctx: detachable HTTP_CLIENT_REQUEST_CONTEXT): HTTP_CLIENT_RESPONSE
|
||||
do
|
||||
Result := custom ("HEAD", a_path, ctx)
|
||||
end
|
||||
|
||||
post (a_path: READABLE_STRING_8; a_ctx: detachable HTTP_CLIENT_REQUEST_CONTEXT; data: detachable READABLE_STRING_8): HTTP_CLIENT_RESPONSE
|
||||
@@ -87,8 +89,7 @@ feature -- Basic operation
|
||||
ctx.set_upload_filename (f.name)
|
||||
end
|
||||
end
|
||||
create {LIBCURL_HTTP_CLIENT_REQUEST} req.make (base_url + a_path, "PUT", Current, ctx)
|
||||
Result := req.execute
|
||||
Result := custom ("PUT", a_path, ctx)
|
||||
if f /= Void then
|
||||
f.delete
|
||||
end
|
||||
@@ -100,7 +101,6 @@ feature -- Basic operation
|
||||
|
||||
put_file (a_path: READABLE_STRING_8; a_ctx: detachable HTTP_CLIENT_REQUEST_CONTEXT; fn: detachable READABLE_STRING_8): HTTP_CLIENT_RESPONSE
|
||||
local
|
||||
req: HTTP_CLIENT_REQUEST
|
||||
ctx: detachable HTTP_CLIENT_REQUEST_CONTEXT
|
||||
do
|
||||
ctx := a_ctx
|
||||
@@ -110,16 +110,12 @@ feature -- Basic operation
|
||||
end
|
||||
ctx.set_upload_filename (fn)
|
||||
end
|
||||
create {LIBCURL_HTTP_CLIENT_REQUEST} req.make (base_url + a_path, "PUT", Current, ctx)
|
||||
Result := req.execute
|
||||
Result := custom ("PUT", a_path, ctx)
|
||||
end
|
||||
|
||||
delete (a_path: READABLE_STRING_8; ctx: detachable HTTP_CLIENT_REQUEST_CONTEXT): HTTP_CLIENT_RESPONSE
|
||||
local
|
||||
req: HTTP_CLIENT_REQUEST
|
||||
do
|
||||
create {LIBCURL_HTTP_CLIENT_REQUEST} req.make (base_url + a_path, "DELETE", Current, ctx)
|
||||
Result := req.execute
|
||||
Result := custom ("DELETE", a_path, ctx)
|
||||
end
|
||||
|
||||
feature {NONE} -- Implementation
|
||||
|
||||
@@ -52,6 +52,8 @@ feature -- Access
|
||||
|
||||
http_access_control_request_headers: STRING = "HTTP_ACCESS_CONTROL_REQUEST_HEADERS"
|
||||
|
||||
http_if_match: STRING = "HTTP_IF_MATCH"
|
||||
|
||||
gateway_interface: STRING = "GATEWAY_INTERFACE"
|
||||
|
||||
auth_type: STRING = "AUTH_TYPE"
|
||||
|
||||
@@ -604,6 +604,11 @@ feature -- HTTP_*
|
||||
deferred
|
||||
end
|
||||
|
||||
http_if_match: detachable READABLE_STRING_8
|
||||
-- Existence check on resource
|
||||
deferred
|
||||
end
|
||||
|
||||
feature -- Extra CGI environment variables
|
||||
|
||||
request_uri: READABLE_STRING_8
|
||||
|
||||
@@ -248,6 +248,12 @@ feature -- Access: HTTP_* CGI meta parameters - 1.1
|
||||
Result := meta_string_variable ({WGI_META_NAMES}.http_access_control_request_headers)
|
||||
end
|
||||
|
||||
http_if_match: detachable READABLE_STRING_8
|
||||
-- Existence check on resource
|
||||
do
|
||||
Result := meta_string_variable ({WGI_META_NAMES}.http_if_match)
|
||||
end
|
||||
|
||||
feature -- Access: Extension to CGI meta parameters - 1.1
|
||||
|
||||
request_uri: READABLE_STRING_8
|
||||
|
||||
@@ -256,6 +256,7 @@ feature {NONE} -- Implementation
|
||||
h.put_current_date
|
||||
h.put_location (proxy_server (req).string)
|
||||
h.put_content_length (0)
|
||||
res.put_header_lines (h)
|
||||
res.set_status_code ({HTTP_STATUS_CODE}.use_proxy)
|
||||
ensure
|
||||
response_status_is_set: res.status_is_set
|
||||
|
||||
@@ -58,8 +58,20 @@ feature {WSF_RESPONSE} -- Output
|
||||
if req.is_request_method ({HTTP_REQUEST_METHODS}.method_trace) then
|
||||
msg := trace_message (req)
|
||||
elseif attached method_not_allowed_message (req) as not_allowed then
|
||||
--| We give this precedence over 412 Precondition Failed or 404 Not Found,
|
||||
--| as we assume the existence of a handler for at least one method
|
||||
--| indicates existence of the resource. This is obviously not the
|
||||
--| case if the only method allowed is POST, but the handler ought
|
||||
--| to handle the 404 Not Found and 412 Precondition Failed cases in that case.
|
||||
--| Ditto for template URI handlers where not all template variable
|
||||
--| values map to existing resources.
|
||||
msg := not_allowed
|
||||
elseif attached req.http_if_match as l_match and then l_match.same_string ("*") then
|
||||
msg := precondition_failed_message (req)
|
||||
else
|
||||
--| Other response codes are possible, such as 301 Moved permananently,
|
||||
--| 302 Found and 410 Gone. But these require handlers to implement,
|
||||
--| so no other code can be given at this point.
|
||||
msg := not_found_message (req)
|
||||
end
|
||||
res.send (msg)
|
||||
@@ -67,7 +79,17 @@ feature {WSF_RESPONSE} -- Output
|
||||
|
||||
feature {NONE} -- Implementation
|
||||
|
||||
precondition_failed_message (req: WSF_REQUEST): WSF_PRECONDITION_FAILED_MESSAGE
|
||||
-- Automatically generated response for 412 Precondition Failed response
|
||||
require
|
||||
req_attached: req /= Void
|
||||
do
|
||||
create Result.make (req)
|
||||
end
|
||||
|
||||
method_not_allowed_message (req: WSF_REQUEST): detachable WSF_METHOD_NOT_ALLOWED_RESPONSE
|
||||
require
|
||||
req_attached: req /= Void
|
||||
local
|
||||
vis: WSF_ROUTER_AGENT_ITERATOR
|
||||
do
|
||||
|
||||
@@ -45,6 +45,7 @@ feature {NONE} -- Initialization
|
||||
initialize
|
||||
local
|
||||
h: like header
|
||||
d: HTTP_DATE
|
||||
do
|
||||
create h.make
|
||||
header := h
|
||||
@@ -52,6 +53,9 @@ feature {NONE} -- Initialization
|
||||
h.put_transfer_encoding_binary
|
||||
h.put_content_length (filesize (file_name))
|
||||
h.put_content_disposition ("attachment", "filename=%""+ base_name +"%"")
|
||||
if attached filedate (file_name) as dt then
|
||||
h.put_last_modified (dt)
|
||||
end
|
||||
end
|
||||
|
||||
feature -- Element change
|
||||
@@ -138,6 +142,19 @@ feature {NONE} -- Implementation: file system helper
|
||||
end
|
||||
end
|
||||
|
||||
filedate (fn: STRING): detachable DATE_TIME
|
||||
-- Size of the file `fn'.
|
||||
local
|
||||
f: RAW_FILE
|
||||
d: HTTP_DATE
|
||||
do
|
||||
create f.make (fn)
|
||||
if f.exists then
|
||||
create d.make_from_timestamp (f.date)
|
||||
Result := d.date_time
|
||||
end
|
||||
end
|
||||
|
||||
file_extension (fn: STRING): STRING
|
||||
-- Extension of file `fn'.
|
||||
local
|
||||
|
||||
@@ -0,0 +1,130 @@
|
||||
note
|
||||
description: "[
|
||||
This class is used to report a 412 Precondition Failed page
|
||||
]"
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
class WSF_PRECONDITION_FAILED_MESSAGE
|
||||
|
||||
inherit
|
||||
|
||||
WSF_RESPONSE_MESSAGE
|
||||
|
||||
SHARED_HTML_ENCODER
|
||||
|
||||
create
|
||||
|
||||
make
|
||||
|
||||
feature {NONE} -- Initialization
|
||||
|
||||
make (req: WSF_REQUEST)
|
||||
-- Initialize setting `request' from `req'.
|
||||
do
|
||||
request := req
|
||||
create header.make
|
||||
ensure
|
||||
req_aliased: 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
|
||||
l_text: detachable READABLE_STRING_GENERAL
|
||||
l_loc: detachable READABLE_STRING_8
|
||||
h: like header
|
||||
do
|
||||
h := header
|
||||
res.set_status_code ({HTTP_STATUS_CODE}.precondition_failed)
|
||||
|
||||
if request.is_content_type_accepted ({HTTP_MIME_TYPES}.text_html) then
|
||||
s := "<html lang=%"en%"><head>"
|
||||
s.append ("<title>")
|
||||
s.append (html_encoder.encoded_string (request.request_uri))
|
||||
s.append ("Error 412 (Precondition Failed)")
|
||||
s.append ("</title>%N")
|
||||
s.append ("[
|
||||
<style type="text/css">
|
||||
div#header {color: #fff; background-color: #000; padding: 20px; width: 100%; text-align: center; font-size: 2em; font-weight: bold;}
|
||||
div#message { margin: 40px; width: 100%; text-align: center; font-size: 1.5em; }
|
||||
div#footer {color: #999; background-color: #eee; padding: 10px; width: 100%; text-align: center; }
|
||||
div#logo { float: right; margin: 20px; width: 60px height: auto; font-size: 0.8em; text-align: center; }
|
||||
div#logo div.outter { padding: 6px; width: 60px; border: solid 3px #500; background-color: #b00;}
|
||||
div#logo div.outter div.inner1 { display: block; margin: 10px 15px; width: 30px; height: 50px; color: #fff; background-color: #fff; border: solid 2px #900; }
|
||||
div#logo div.outter div.inner2 { margin: 10px 15px; width: 30px; height: 15px; color: #fff; background-color: #fff; border: solid 2px #900; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="header">Error 412 (Precondition Failed)</div>
|
||||
]")
|
||||
s.append ("<div id=%"logo%">")
|
||||
s.append ("<div class=%"outter%"> ")
|
||||
s.append ("<div class=%"inner1%"></div>")
|
||||
s.append ("<div class=%"inner2%"></div>")
|
||||
s.append ("</div>")
|
||||
s.append ("Error 412 (Precondition Failed)</div>")
|
||||
s.append ("<div id=%"message%">Error 412 (Precondition Failed): <code>" + html_encoder.encoded_string (request.request_uri) + "</code></div>")
|
||||
if attached body as b then
|
||||
s.append ("<div>")
|
||||
s.append (b)
|
||||
s.append ("</div>%N")
|
||||
end
|
||||
|
||||
s.append ("<div id=%"footer%"></div>")
|
||||
s.append ("</body>%N")
|
||||
s.append ("</html>%N")
|
||||
|
||||
h.put_content_type_text_html
|
||||
else
|
||||
s := "Error 412 (Precondition Failed): "
|
||||
s.append (request.request_uri)
|
||||
s.append_character ('%N')
|
||||
if attached body as b then
|
||||
s.append ("%N")
|
||||
s.append (b)
|
||||
s.append ("%N")
|
||||
end
|
||||
|
||||
h.put_content_type_text_plain
|
||||
end
|
||||
h.put_content_length (s.count)
|
||||
res.put_header_text (h.string)
|
||||
res.put_string (s)
|
||||
res.flush
|
||||
end
|
||||
|
||||
note
|
||||
|
||||
copyright: "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
|
||||
@@ -1042,6 +1042,12 @@ feature -- HTTP_*
|
||||
Result := wgi_request.http_access_control_request_headers
|
||||
end
|
||||
|
||||
http_if_match: detachable READABLE_STRING_8
|
||||
-- Existence check on resource
|
||||
do
|
||||
Result := wgi_request.http_if_match
|
||||
end
|
||||
|
||||
feature -- Extra CGI environment variables
|
||||
|
||||
request_uri: READABLE_STRING_8
|
||||
|
||||
@@ -207,7 +207,7 @@ feature -- Header output operation
|
||||
if header_committed then
|
||||
report_content_already_sent_and_header_ignored
|
||||
else
|
||||
header.append_raw_header_data (a_text)
|
||||
header.put_raw_header_data (a_text)
|
||||
end
|
||||
ensure
|
||||
message_writable: message_writable
|
||||
|
||||
Reference in New Issue
Block a user