diff --git a/library/client/http_client/src/http_client_request.e b/library/client/http_client/src/http_client_request.e index ab331fd0..fbdc8b92 100644 --- a/library/client/http_client/src/http_client_request.e +++ b/library/client/http_client/src/http_client_request.e @@ -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]]) diff --git a/library/client/http_client/src/http_client_session.e b/library/client/http_client/src/http_client_session.e index 24e17b32..24060d6f 100644 --- a/library/client/http_client/src/http_client_session.e +++ b/library/client/http_client/src/http_client_session.e @@ -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)" diff --git a/library/client/http_client/src/spec/libcurl/libcurl_http_client_request.e b/library/client/http_client/src/spec/libcurl/libcurl_http_client_request.e index 52d7602f..e346b3b3 100644 --- a/library/client/http_client/src/spec/libcurl/libcurl_http_client_request.e +++ b/library/client/http_client/src/spec/libcurl/libcurl_http_client_request.e @@ -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 diff --git a/library/protocol/http/src/http_header.e b/library/protocol/http/src/http_header.e index d78e63f3..6ea26e1a 100644 --- a/library/protocol/http/src/http_header.e +++ b/library/protocol/http/src/http_header.e @@ -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) diff --git a/library/protocol/http/src/http_header_names.e b/library/protocol/http/src/http_header_names.e index 73f037fd..8d679ea9 100644 --- a/library/protocol/http/src/http_header_names.e +++ b/library/protocol/http/src/http_header_names.e @@ -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 diff --git a/library/server/ewsgi/connectors/cgi/src/wgi_cgi_connector.e b/library/server/ewsgi/connectors/cgi/src/wgi_cgi_connector.e index 0384343f..b237ef81 100644 --- a/library/server/ewsgi/connectors/cgi/src/wgi_cgi_connector.e +++ b/library/server/ewsgi/connectors/cgi/src/wgi_cgi_connector.e @@ -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 ("
" + l_trace + "
") diff --git a/library/server/ewsgi/connectors/cgi/src/wgi_cgi_output_stream.e b/library/server/ewsgi/connectors/cgi/src/wgi_cgi_output_stream.e index 7fac392c..323927d3 100644 --- a/library/server/ewsgi/connectors/cgi/src/wgi_cgi_output_stream.e +++ b/library/server/ewsgi/connectors/cgi/src/wgi_cgi_output_stream.e @@ -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) + -- 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 diff --git a/library/server/ewsgi/connectors/libfcgi/src/wgi_libfcgi_connector.e b/library/server/ewsgi/connectors/libfcgi/src/wgi_libfcgi_connector.e index 93f70dab..08efc4a4 100644 --- a/library/server/ewsgi/connectors/libfcgi/src/wgi_libfcgi_connector.e +++ b/library/server/ewsgi/connectors/libfcgi/src/wgi_libfcgi_connector.e @@ -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 ("
" + l_trace + "
") diff --git a/library/server/ewsgi/connectors/libfcgi/src/wgi_libfcgi_output_stream.e b/library/server/ewsgi/connectors/libfcgi/src/wgi_libfcgi_output_stream.e index 349d2dab..d3b67676 100644 --- a/library/server/ewsgi/connectors/libfcgi/src/wgi_libfcgi_output_stream.e +++ b/library/server/ewsgi/connectors/libfcgi/src/wgi_libfcgi_output_stream.e @@ -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) + -- 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 diff --git a/library/server/ewsgi/connectors/nino/src/wgi_nino_output_stream.e b/library/server/ewsgi/connectors/nino/src/wgi_nino_output_stream.e index 1b84c0ad..9e95b69e 100644 --- a/library/server/ewsgi/connectors/nino/src/wgi_nino_output_stream.e +++ b/library/server/ewsgi/connectors/nino/src/wgi_nino_output_stream.e @@ -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) + -- 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 diff --git a/library/server/ewsgi/specification/response/wgi_response.e b/library/server/ewsgi/specification/response/wgi_response.e index b9b9c7f1..3822fc82 100644 --- a/library/server/ewsgi/specification/response/wgi_response.e +++ b/library/server/ewsgi/specification/response/wgi_response.e @@ -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 diff --git a/library/server/ewsgi/specification/stream/wgi_output_stream.e b/library/server/ewsgi/specification/stream/wgi_output_stream.e index 871de1d9..39d8dcd7 100644 --- a/library/server/ewsgi/specification/stream/wgi_output_stream.e +++ b/library/server/ewsgi/specification/stream/wgi_output_stream.e @@ -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 diff --git a/library/server/ewsgi/src/implementation/wgi_response_stream.e b/library/server/ewsgi/src/implementation/wgi_response_stream.e index 82c07f3b..a7610d42 100644 --- a/library/server/ewsgi/src/implementation/wgi_response_stream.e +++ b/library/server/ewsgi/src/implementation/wgi_response_stream.e @@ -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) diff --git a/library/server/wsf/src/wsf_response.e b/library/server/wsf/src/wsf_response.e index 9d7f8461..17ed25c1 100644 --- a/library/server/wsf/src/wsf_response.e +++ b/library/server/wsf/src/wsf_response.e @@ -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