Now WGI_RESPONSE.set_status_code (..) has a new argument to pass optional custom reason phrase.
This is a minor breaking change (but prior to the first release, so acceptable) And then it is now possible to precise a custom reason phrase (useful for 4xx and 5xx response) At the WSF_RESPONSE level, the status code is now sent only when the header are sent. thus, it is possible to change the status code as long as no header is sent. (in the future, we should also try to delay the sending of headers) Removed WGI_RESPONSE.put_header_lines (..) which was not used, and WGI is not meant to provide such user friendly features Now this is available directly on WSF_RESPONSE
This commit is contained in:
@@ -92,6 +92,11 @@ feature -- Authentication
|
||||
Result := session.credentials
|
||||
end
|
||||
|
||||
proxy: detachable TUPLE [host: READABLE_STRING_8; port: INTEGER]
|
||||
do
|
||||
Result := session.proxy
|
||||
end
|
||||
|
||||
feature -- Settings
|
||||
|
||||
timeout: INTEGER
|
||||
@@ -131,6 +136,12 @@ feature -- Settings
|
||||
Result := session.default_response_charset
|
||||
end
|
||||
|
||||
is_insecure: BOOLEAN
|
||||
-- Allow connections to SSL sites without certs
|
||||
do
|
||||
Result := session.is_insecure
|
||||
end
|
||||
|
||||
feature {NONE} -- Utilities
|
||||
|
||||
append_parameters_to_url (a_url: STRING; a_parameters: detachable ARRAY [detachable TUPLE [name: READABLE_STRING_8; value: READABLE_STRING_8]])
|
||||
|
||||
@@ -105,6 +105,12 @@ feature -- Settings
|
||||
default_response_charset: detachable READABLE_STRING_8
|
||||
-- Default encoding of responses. Used if no charset is provided by the host.
|
||||
|
||||
is_insecure: BOOLEAN
|
||||
-- Allow connections to SSL sites without certs
|
||||
|
||||
proxy: detachable TUPLE [host: READABLE_STRING_8; port: INTEGER]
|
||||
-- Proxy information [`host' and `port']
|
||||
|
||||
feature -- Access
|
||||
|
||||
base_url: READABLE_STRING_8
|
||||
@@ -132,9 +138,9 @@ feature -- Change
|
||||
base_url := u
|
||||
end
|
||||
|
||||
set_timeout (n: like timeout)
|
||||
set_timeout (n_seconds: like timeout)
|
||||
do
|
||||
timeout := n
|
||||
timeout := n_seconds
|
||||
end
|
||||
|
||||
set_connect_timeout (n: like connect_timeout)
|
||||
@@ -147,6 +153,11 @@ feature -- Change
|
||||
add_header ("User-Agent", v)
|
||||
end
|
||||
|
||||
set_is_insecure (b: BOOLEAN)
|
||||
do
|
||||
is_insecure := b
|
||||
end
|
||||
|
||||
add_header (k: READABLE_STRING_8; v: READABLE_STRING_8)
|
||||
do
|
||||
headers.force (v, k)
|
||||
@@ -203,6 +214,15 @@ feature -- Change
|
||||
max_redirects := n
|
||||
end
|
||||
|
||||
set_proxy (a_host: detachable READABLE_STRING_8; a_port: INTEGER)
|
||||
do
|
||||
if a_host = Void then
|
||||
proxy := Void
|
||||
else
|
||||
proxy := [a_host, a_port]
|
||||
end
|
||||
end
|
||||
|
||||
note
|
||||
copyright: "2011-2012, Jocelyn Fiat, Javier Velilla, Eiffel Software and others"
|
||||
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
||||
|
||||
@@ -54,6 +54,7 @@ feature -- Execution
|
||||
curl_easy: CURL_EASY_EXTERNALS
|
||||
curl_handle: POINTER
|
||||
ctx: like context
|
||||
l_proxy: like proxy
|
||||
do
|
||||
ctx := context
|
||||
curl := session.curl
|
||||
@@ -83,7 +84,14 @@ feature -- Execution
|
||||
curl_easy.setopt_integer (curl_handle, {CURL_OPT_CONSTANTS}.curlopt_header, 1)
|
||||
|
||||
--| PROXY ...
|
||||
if ctx /= Void and then attached ctx.proxy as l_proxy then
|
||||
|
||||
if ctx /= Void then
|
||||
l_proxy := ctx.proxy
|
||||
end
|
||||
if l_proxy = Void then
|
||||
l_proxy := proxy
|
||||
end
|
||||
if l_proxy /= Void then
|
||||
curl_easy.setopt_integer (curl_handle, {CURL_OPT_CONSTANTS}.curlopt_proxyport, l_proxy.port)
|
||||
curl_easy.setopt_string (curl_handle, {CURL_OPT_CONSTANTS}.curlopt_proxy, l_proxy.host)
|
||||
end
|
||||
@@ -104,6 +112,12 @@ feature -- Execution
|
||||
curl_easy.setopt_integer (curl_handle, {CURL_OPT_CONSTANTS}.curlopt_followlocation, 0)
|
||||
end
|
||||
|
||||
--| SSL
|
||||
if is_insecure then
|
||||
curl_easy.setopt_integer (curl_handle, {CURL_OPT_CONSTANTS}.curlopt_ssl_verifyhost, 0)
|
||||
curl_easy.setopt_integer (curl_handle, {CURL_OPT_CONSTANTS}.curlopt_ssl_verifypeer, 0)
|
||||
end
|
||||
|
||||
if request_method.is_case_insensitive_equal ("GET") then
|
||||
curl_easy.setopt_integer (curl_handle, {CURL_OPT_CONSTANTS}.curlopt_httpget, 1)
|
||||
elseif request_method.is_case_insensitive_equal ("POST") then
|
||||
|
||||
@@ -80,7 +80,7 @@ feature {NONE} -- Initialization
|
||||
loop
|
||||
line := c.item
|
||||
if not line.is_empty then
|
||||
if line[line.count] = '%R' then
|
||||
if line [line.count] = '%R' then
|
||||
line.remove_tail (1)
|
||||
end
|
||||
add_header (line)
|
||||
|
||||
@@ -231,6 +231,9 @@ feature -- Request or Response header name
|
||||
-- Implementation-specific headers that may have various effects anywhere along the request-response chain.
|
||||
--| Example: Pragma: no-cache
|
||||
|
||||
header_status: STRING = "Status"
|
||||
-- CGI program can use this to return the HTTP status code to the client.
|
||||
|
||||
header_via: STRING = "Via"
|
||||
-- Request: Informs the server of proxies through which the request was sent.
|
||||
-- Response: Informs the client of proxies through which the response was sent.
|
||||
@@ -245,7 +248,7 @@ feature -- MIME related
|
||||
header_content_transfer_encoding: STRING = "Content-Transfer-Encoding"
|
||||
|
||||
note
|
||||
copyright: "2011-2011, Eiffel Software and others"
|
||||
copyright: "2011-2012, Jocelyn Fiat, Eiffel Software and others"
|
||||
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
||||
source: "[
|
||||
Eiffel Software
|
||||
|
||||
@@ -48,7 +48,7 @@ feature -- Execution
|
||||
if attached (create {EXCEPTION_MANAGER}).last_exception as e and then attached e.exception_trace as l_trace then
|
||||
if res /= Void then
|
||||
if not res.status_is_set then
|
||||
res.set_status_code ({HTTP_STATUS_CODE}.internal_server_error)
|
||||
res.set_status_code ({HTTP_STATUS_CODE}.internal_server_error, Void)
|
||||
end
|
||||
if res.message_writable then
|
||||
res.put_string ("<pre>" + l_trace + "</pre>")
|
||||
|
||||
@@ -36,21 +36,24 @@ feature {NONE} -- Initialization
|
||||
|
||||
feature -- Status writing
|
||||
|
||||
put_status_line (a_code: INTEGER)
|
||||
-- Put status code line for `a_code'
|
||||
--| Note this is a default implementation, and could be redefined
|
||||
--| for instance in relation to NPH CGI script
|
||||
put_status_line (a_code: INTEGER; a_reason_phrase: detachable READABLE_STRING_8)
|
||||
-- <Precursor>
|
||||
local
|
||||
s: STRING
|
||||
m: detachable READABLE_STRING_8
|
||||
do
|
||||
if a_code /= 200 then
|
||||
create s.make (16)
|
||||
s.append ("Status:")
|
||||
s.append_character (' ')
|
||||
s.append_integer (a_code)
|
||||
if attached http_status_code_message (a_code) as l_status_message then
|
||||
m := a_reason_phrase
|
||||
if m = Void then
|
||||
m := http_status_code_message (a_code)
|
||||
end
|
||||
if m /= Void then
|
||||
s.append_character (' ')
|
||||
s.append_string (l_status_message)
|
||||
s.append_string (m)
|
||||
end
|
||||
put_header_line (s)
|
||||
end
|
||||
|
||||
@@ -69,7 +69,7 @@ feature -- Execution
|
||||
if attached (create {EXCEPTION_MANAGER}).last_exception as e and then attached e.exception_trace as l_trace then
|
||||
if res /= Void then
|
||||
if not res.status_is_set then
|
||||
res.set_status_code ({HTTP_STATUS_CODE}.internal_server_error)
|
||||
res.set_status_code ({HTTP_STATUS_CODE}.internal_server_error, Void)
|
||||
end
|
||||
if res.message_writable then
|
||||
res.put_string ("<pre>" + l_trace + "</pre>")
|
||||
|
||||
@@ -40,23 +40,24 @@ feature -- Status report
|
||||
|
||||
feature -- Status writing
|
||||
|
||||
put_status_line (a_code: INTEGER)
|
||||
-- Put status code line for `a_code'
|
||||
--| Note this is a default implementation, and could be redefined
|
||||
--| for instance in relation to NPH CGI script
|
||||
put_status_line (a_code: INTEGER; a_reason_phrase: detachable READABLE_STRING_8)
|
||||
-- <Precursor>
|
||||
local
|
||||
s: STRING
|
||||
m: detachable READABLE_STRING_8
|
||||
do
|
||||
--| Do not send any Status line back to the FastCGI client
|
||||
--| According to http://www.fastcgi.com/docs/faq.html#httpstatus
|
||||
if a_code /= 200 then
|
||||
create s.make (16)
|
||||
s.append ("Status:")
|
||||
s.append_character (' ')
|
||||
s.append_integer (a_code)
|
||||
if attached http_status_code_message (a_code) as l_status_message then
|
||||
m := a_reason_phrase
|
||||
if m = Void then
|
||||
m := http_status_code_message (a_code)
|
||||
end
|
||||
if m /= Void then
|
||||
s.append_character (' ')
|
||||
s.append_string (l_status_message)
|
||||
s.append_string (m)
|
||||
end
|
||||
put_header_line (s)
|
||||
end
|
||||
|
||||
@@ -37,20 +37,23 @@ feature {WGI_NINO_CONNECTOR, WGI_SERVICE} -- Nino
|
||||
|
||||
feature -- Status writing
|
||||
|
||||
put_status_line (a_code: INTEGER)
|
||||
-- Put status code line for `a_code'
|
||||
--| Note this is a default implementation, and could be redefined
|
||||
--| for instance in relation to NPH CGI script
|
||||
put_status_line (a_code: INTEGER; a_reason_phrase: detachable READABLE_STRING_8)
|
||||
-- <Precursor>
|
||||
local
|
||||
s: STRING
|
||||
m: detachable READABLE_STRING_8
|
||||
do
|
||||
create s.make (16)
|
||||
s.append ({HTTP_CONSTANTS}.http_version_1_1)
|
||||
s.append_character (' ')
|
||||
s.append_integer (a_code)
|
||||
if attached http_status_code_message (a_code) as l_status_message then
|
||||
m := a_reason_phrase
|
||||
if m = Void then
|
||||
m := http_status_code_message (a_code)
|
||||
end
|
||||
if m /= Void then
|
||||
s.append_character (' ')
|
||||
s.append_string (l_status_message)
|
||||
s.append_string (m)
|
||||
end
|
||||
put_header_line (s)
|
||||
end
|
||||
|
||||
@@ -49,15 +49,17 @@ feature -- Status setting
|
||||
deferred
|
||||
end
|
||||
|
||||
set_status_code (a_code: INTEGER)
|
||||
-- Set response status code
|
||||
set_status_code (a_code: INTEGER; a_reason_phrase: detachable READABLE_STRING_8)
|
||||
-- Set response status code with custom `a_reason_phrase' if precised
|
||||
-- Should be done before sending any data back to the client
|
||||
require
|
||||
a_code_positive: a_code > 0
|
||||
status_not_set: not status_committed
|
||||
header_not_committed: not header_committed
|
||||
deferred
|
||||
ensure
|
||||
status_code_set: status_code = a_code
|
||||
status_reason_phrase_set: status_reason_phrase = a_reason_phrase
|
||||
status_set: status_is_set
|
||||
end
|
||||
|
||||
@@ -66,6 +68,13 @@ feature -- Status setting
|
||||
deferred
|
||||
end
|
||||
|
||||
status_reason_phrase: detachable READABLE_STRING_8
|
||||
-- Custom status reason phrase for the Response (optional)
|
||||
deferred
|
||||
ensure
|
||||
Result /= Void implies status_is_set
|
||||
end
|
||||
|
||||
feature -- Header output operation
|
||||
|
||||
put_header_text (a_text: READABLE_STRING_8)
|
||||
@@ -79,17 +88,7 @@ feature -- Header output operation
|
||||
deferred
|
||||
ensure
|
||||
status_set: status_is_set
|
||||
header_committed: header_committed
|
||||
message_writable: message_writable
|
||||
end
|
||||
|
||||
put_header_lines (a_lines: ITERABLE [TUPLE [name: READABLE_STRING_8; value: READABLE_STRING_8]])
|
||||
require
|
||||
status_set: status_is_set
|
||||
header_not_committed: not header_committed
|
||||
deferred
|
||||
ensure
|
||||
status_set: status_is_set
|
||||
status_committed: status_committed
|
||||
header_committed: header_committed
|
||||
message_writable: message_writable
|
||||
end
|
||||
|
||||
@@ -62,10 +62,13 @@ feature -- Specific output
|
||||
|
||||
feature -- Status writing
|
||||
|
||||
put_status_line (a_code: INTEGER)
|
||||
put_status_line (a_code: INTEGER; a_reason_phrase: detachable READABLE_STRING_8)
|
||||
-- Put status code line for `a_code'
|
||||
-- with custom `a_reason_phrase' if precised
|
||||
--| Note this is a default implementation, and could be redefined
|
||||
--| for instance in relation to NPH CGI script
|
||||
require
|
||||
a_code_positive: a_code > 0
|
||||
deferred
|
||||
end
|
||||
|
||||
|
||||
@@ -54,21 +54,25 @@ feature -- Status setting
|
||||
status_is_set: BOOLEAN
|
||||
-- Is status set?
|
||||
do
|
||||
Result := status_code /= 0
|
||||
Result := status_code > 0
|
||||
end
|
||||
|
||||
set_status_code (a_code: INTEGER)
|
||||
set_status_code (a_code: INTEGER; a_reason_phrase: detachable READABLE_STRING_8)
|
||||
-- Set response status code
|
||||
-- Should be done before sending any data back to the client
|
||||
do
|
||||
status_code := a_code
|
||||
output.put_status_line (a_code)
|
||||
status_reason_phrase := a_reason_phrase
|
||||
output.put_status_line (a_code, a_reason_phrase)
|
||||
status_committed := True
|
||||
end
|
||||
|
||||
status_code: INTEGER
|
||||
-- Response status
|
||||
|
||||
status_reason_phrase: detachable READABLE_STRING_8
|
||||
-- Custom status reason phrase for the Response (optional)
|
||||
|
||||
feature -- Header output operation
|
||||
|
||||
put_header_text (a_text: READABLE_STRING_8)
|
||||
@@ -78,24 +82,6 @@ feature -- Header output operation
|
||||
header_committed := True
|
||||
end
|
||||
|
||||
put_header_lines (a_lines: ITERABLE [TUPLE [name: READABLE_STRING_8; value: READABLE_STRING_8]])
|
||||
local
|
||||
h: STRING_8
|
||||
do
|
||||
create h.make (256)
|
||||
across
|
||||
a_lines as c
|
||||
loop
|
||||
h.append (c.item.name)
|
||||
h.append_character (':')
|
||||
h.append_character (' ')
|
||||
h.append (c.item.value)
|
||||
h.append_character ('%R')
|
||||
h.append_character ('%N')
|
||||
end
|
||||
put_header_text (h)
|
||||
end
|
||||
|
||||
feature -- Output operation
|
||||
|
||||
put_character (c: CHARACTER_8)
|
||||
|
||||
@@ -56,35 +56,57 @@ feature -- Status setting
|
||||
status_is_set: BOOLEAN
|
||||
-- Is status set?
|
||||
do
|
||||
Result := wgi_response.status_is_set
|
||||
Result := status_code > 0
|
||||
end
|
||||
|
||||
set_status_code (a_code: INTEGER)
|
||||
-- Set response status code
|
||||
-- Should be done before sending any data back to the client
|
||||
--| note: the status is really sent when the header are set
|
||||
require
|
||||
a_code_valid: a_code > 0
|
||||
status_not_set: not status_committed
|
||||
header_not_committed: not header_committed
|
||||
do
|
||||
wgi_response.set_status_code (a_code)
|
||||
status_code := a_code
|
||||
status_reason_phrase := Void
|
||||
ensure
|
||||
status_code_set: status_code = a_code
|
||||
status_set: status_is_set
|
||||
end
|
||||
|
||||
set_status_code_with_reason_phrase (a_code: INTEGER; a_reason_phrase: READABLE_STRING_8)
|
||||
-- Set response status code
|
||||
-- Should be done before sending any data back to the client
|
||||
--| note: the status is really sent when the header are set
|
||||
require
|
||||
a_code_valid: a_code > 0
|
||||
status_not_set: not status_committed
|
||||
header_not_committed: not header_committed
|
||||
do
|
||||
set_status_code (a_code)
|
||||
status_reason_phrase := a_reason_phrase
|
||||
ensure
|
||||
status_code_set: status_code = a_code
|
||||
status_reason_phrase_set: status_reason_phrase = a_reason_phrase
|
||||
status_set: status_is_set
|
||||
end
|
||||
|
||||
status_code: INTEGER
|
||||
-- Response status
|
||||
do
|
||||
Result := wgi_response.status_code
|
||||
end
|
||||
|
||||
status_reason_phrase: detachable READABLE_STRING_8
|
||||
-- Custom status reason phrase (optional)
|
||||
|
||||
feature -- Header output operation
|
||||
|
||||
put_header_text (a_headers: READABLE_STRING_8)
|
||||
-- Sent `a_headers' and just before send the status code
|
||||
require
|
||||
status_set: status_is_set
|
||||
header_not_committed: not header_committed
|
||||
do
|
||||
wgi_response.set_status_code (status_code, status_reason_phrase)
|
||||
wgi_response.put_header_text (a_headers)
|
||||
ensure
|
||||
status_set: status_is_set
|
||||
@@ -93,7 +115,7 @@ feature -- Header output operation
|
||||
message_writable: message_writable
|
||||
end
|
||||
|
||||
put_header (a_status_code: INTEGER; a_headers: detachable ARRAY [TUPLE [key: READABLE_STRING_8; value: READABLE_STRING_8]])
|
||||
put_header (a_status_code: INTEGER; a_headers: detachable ARRAY [TUPLE [name: READABLE_STRING_8; value: READABLE_STRING_8]])
|
||||
-- Send headers with status `a_status', and headers from `a_headers'
|
||||
require
|
||||
status_not_committed: not status_committed
|
||||
@@ -107,14 +129,28 @@ feature -- Header output operation
|
||||
put_header_text (h.string)
|
||||
end
|
||||
ensure
|
||||
header_committed: header_committed
|
||||
status_set: status_is_set
|
||||
header_committed: header_committed
|
||||
message_writable: message_writable
|
||||
end
|
||||
|
||||
put_header_lines (a_lines: ITERABLE [TUPLE [name: READABLE_STRING_8; value: READABLE_STRING_8]])
|
||||
-- Send headers from `a_lines'
|
||||
local
|
||||
h: STRING_8
|
||||
do
|
||||
wgi_response.put_header_lines (a_lines)
|
||||
create h.make (256)
|
||||
across
|
||||
a_lines as c
|
||||
loop
|
||||
h.append (c.item.name)
|
||||
h.append_character (':')
|
||||
h.append_character (' ')
|
||||
h.append (c.item.value)
|
||||
h.append_character ('%R')
|
||||
h.append_character ('%N')
|
||||
end
|
||||
put_header_text (h)
|
||||
end
|
||||
|
||||
feature -- Output report
|
||||
|
||||
Reference in New Issue
Block a user