From fd0912904c38bd77050abd41f86f2b4178d7f61c Mon Sep 17 00:00:00 2001 From: Jocelyn Fiat Date: Fri, 25 Nov 2011 14:39:48 +0100 Subject: [PATCH] Simplified EWSGI interfaces Renamed WGI_RESPONSE_BUFFER as WGI_RESPONSE to avoid confusion Removed EWF_HEADER and removed related caller from WGI implementation, now this is only part of WSF library Added wgi_version, wgi_implementation and wgi_connector to the WGI_REQUEST interface to give more information to the user Added back WGI_CONNECTOR to WGI specification, mainly because of `{WGI_REQUEST}.wgi_connector' simplified WGI_CONNECTOR to contain for now only `name' and `version' if the implementation of connector inherit from WGI_CONNECTOR (recommended) this might gives more access to the user using a reverse assignment for specific needs (but this usage is not recommended due to portability issue on other connector) Removed useless connector.ecf since now EWF/WGI library provides the helper classes --- .../server/ewsgi/connectors/cgi/cgi-safe.ecf | 1 - library/server/ewsgi/connectors/cgi/cgi.ecf | 1 - .../connectors/cgi/src/wgi_cgi_connector.e | 29 +- .../ewsgi/connectors/common/wgi_connector.e | 44 -- .../ewsgi/connectors/connector-safe.ecf | 16 - library/server/ewsgi/connectors/connector.ecf | 16 - .../ewsgi/connectors/libfcgi/libfcgi-safe.ecf | 1 - .../ewsgi/connectors/libfcgi/libfcgi.ecf | 1 - .../libfcgi/src/wgi_libfcgi_connector.e | 25 +- .../ewsgi/connectors/nino/nino-safe.ecf | 1 - library/server/ewsgi/connectors/nino/nino.ecf | 1 - .../connectors/nino/src/wgi_nino_connector.e | 38 +- library/server/ewsgi/ewsgi-safe.ecf | 1 + library/server/ewsgi/ewsgi.ecf | 1 + .../ewsgi/specification/request/wgi_request.e | 19 + .../{wgi_response_buffer.e => wgi_response.e} | 19 +- .../ewsgi/src/helper/wgi_request_from_table.e | 11 +- ..._stream_buffer.e => wgi_response_stream.e} | 31 +- library/server/ewsgi/src/support/ewf_header.e | 465 ------------------ library/server/ewsgi/src/wgi_agent_service.e | 4 +- library/server/ewsgi/src/wgi_service.e | 2 +- library/server/wsf/src/support/wsf_header.e | 424 +++++++++++++++- library/server/wsf/src/wsf_response.e | 27 +- library/server/wsf/src/wsf_service.e | 2 +- 24 files changed, 553 insertions(+), 627 deletions(-) delete mode 100644 library/server/ewsgi/connectors/common/wgi_connector.e delete mode 100644 library/server/ewsgi/connectors/connector-safe.ecf delete mode 100644 library/server/ewsgi/connectors/connector.ecf rename library/server/ewsgi/specification/response/{wgi_response_buffer.e => wgi_response.e} (80%) rename library/server/ewsgi/src/helper/{wgi_response_stream_buffer.e => wgi_response_stream.e} (73%) delete mode 100644 library/server/ewsgi/src/support/ewf_header.e diff --git a/library/server/ewsgi/connectors/cgi/cgi-safe.ecf b/library/server/ewsgi/connectors/cgi/cgi-safe.ecf index 6ddc9af7..512dd955 100644 --- a/library/server/ewsgi/connectors/cgi/cgi-safe.ecf +++ b/library/server/ewsgi/connectors/cgi/cgi-safe.ecf @@ -10,7 +10,6 @@ - diff --git a/library/server/ewsgi/connectors/cgi/cgi.ecf b/library/server/ewsgi/connectors/cgi/cgi.ecf index 0e8b4361..d6c265ec 100644 --- a/library/server/ewsgi/connectors/cgi/cgi.ecf +++ b/library/server/ewsgi/connectors/cgi/cgi.ecf @@ -10,7 +10,6 @@ - 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 5b30cc66..f798f271 100644 --- a/library/server/ewsgi/connectors/cgi/src/wgi_cgi_connector.e +++ b/library/server/ewsgi/connectors/cgi/src/wgi_cgi_connector.e @@ -1,6 +1,5 @@ note description: "Summary description for {WGI_CGI_CONNECTOR}." - author: "" date: "$Date$" revision: "$Revision$" @@ -13,23 +12,43 @@ inherit create make +feature {NONE} -- Initialization + + make (a_app: like application) + do + application := a_app + end + +feature -- Access + + Name: STRING_8 = "CGI" + -- Name of Current connector + + Version: STRING_8 = "0.1" + -- Version of Current connector + +feature {NONE} -- Access + + application: WGI_SERVICE + -- Gateway Service + feature -- Execution launch local req: WGI_REQUEST_FROM_TABLE - res: detachable WGI_RESPONSE_STREAM_BUFFER + res: detachable WGI_RESPONSE_STREAM rescued: BOOLEAN do if not rescued then - create req.make ((create {EXECUTION_ENVIRONMENT}).starting_environment_variables, create {WGI_CGI_INPUT_STREAM}.make) + create req.make ((create {EXECUTION_ENVIRONMENT}).starting_environment_variables, create {WGI_CGI_INPUT_STREAM}.make, Current) create res.make (create {WGI_CGI_OUTPUT_STREAM}.make) application.execute (req, res) else 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.write_header ({HTTP_STATUS_CODE}.internal_server_error, Void) + res.set_status_code ({HTTP_STATUS_CODE}.internal_server_error) end if res.message_writable then res.write_string ("
" + l_trace + "
") @@ -41,7 +60,7 @@ feature -- Execution rescued := True retry end - + note copyright: "2011-2011, Eiffel Software and others" license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)" diff --git a/library/server/ewsgi/connectors/common/wgi_connector.e b/library/server/ewsgi/connectors/common/wgi_connector.e deleted file mode 100644 index 87d345b5..00000000 --- a/library/server/ewsgi/connectors/common/wgi_connector.e +++ /dev/null @@ -1,44 +0,0 @@ -note - description: "Summary description for {WGI_CONNECTOR}." - specification: "EWSGI/connector specification https://github.com/Eiffel-World/Eiffel-Web-Framework/wiki/EWSGI-specification" - date: "$Date$" - revision: "$Revision$" - -deferred class - WGI_CONNECTOR - -feature {NONE} -- Initialization - - make (a_app: like application) - do - application := a_app - initialize - end - - initialize - -- Initialize connector - do - end - -feature {NONE} -- Access - - application: WGI_SERVICE - -- Gateway Service - -feature -- Server - - launch - deferred - end - -note - copyright: "2011-2011, 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 diff --git a/library/server/ewsgi/connectors/connector-safe.ecf b/library/server/ewsgi/connectors/connector-safe.ecf deleted file mode 100644 index 1361b1c6..00000000 --- a/library/server/ewsgi/connectors/connector-safe.ecf +++ /dev/null @@ -1,16 +0,0 @@ - - - - - - /.git$ - /EIFGENs$ - /.svn$ - - - - - - - diff --git a/library/server/ewsgi/connectors/connector.ecf b/library/server/ewsgi/connectors/connector.ecf deleted file mode 100644 index 0a591f8f..00000000 --- a/library/server/ewsgi/connectors/connector.ecf +++ /dev/null @@ -1,16 +0,0 @@ - - - - - - /.git$ - /EIFGENs$ - /.svn$ - - - - - - - diff --git a/library/server/ewsgi/connectors/libfcgi/libfcgi-safe.ecf b/library/server/ewsgi/connectors/libfcgi/libfcgi-safe.ecf index 1dd35651..cc3d47bc 100644 --- a/library/server/ewsgi/connectors/libfcgi/libfcgi-safe.ecf +++ b/library/server/ewsgi/connectors/libfcgi/libfcgi-safe.ecf @@ -10,7 +10,6 @@ - diff --git a/library/server/ewsgi/connectors/libfcgi/libfcgi.ecf b/library/server/ewsgi/connectors/libfcgi/libfcgi.ecf index 5240dad5..bf084003 100644 --- a/library/server/ewsgi/connectors/libfcgi/libfcgi.ecf +++ b/library/server/ewsgi/connectors/libfcgi/libfcgi.ecf @@ -10,7 +10,6 @@ - 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 49838b2a..4aab9a02 100644 --- a/library/server/ewsgi/connectors/libfcgi/src/wgi_libfcgi_connector.e +++ b/library/server/ewsgi/connectors/libfcgi/src/wgi_libfcgi_connector.e @@ -10,22 +10,33 @@ class inherit WGI_CONNECTOR - redefine - initialize - end create make feature {NONE} -- Initialization - initialize + make (a_app: like application) do + application := a_app create fcgi.make create {WGI_LIBFCGI_INPUT_STREAM} input.make (fcgi) create {WGI_LIBFCGI_OUTPUT_STREAM} output.make (fcgi) end +feature -- Access + + Name: STRING_8 = "libFCGI" + -- Name of Current connector + + Version: STRING_8 = "0.1" + -- Version of Current connector + +feature {NONE} -- Access + + application: WGI_SERVICE + -- Gateway Service + feature -- Server launch @@ -47,18 +58,18 @@ feature -- Execution process_fcgi_request (vars: HASH_TABLE [STRING, STRING]; a_input: like input; a_output: like output) local req: WGI_REQUEST_FROM_TABLE - res: detachable WGI_RESPONSE_STREAM_BUFFER + res: detachable WGI_RESPONSE_STREAM rescued: BOOLEAN do if not rescued then - create req.make (vars, a_input) + create req.make (vars, a_input, Current) create res.make (a_output) application.execute (req, res) else 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.write_header ({HTTP_STATUS_CODE}.internal_server_error, Void) + res.set_status_code ({HTTP_STATUS_CODE}.internal_server_error) end if res.message_writable then res.write_string ("
" + l_trace + "
") diff --git a/library/server/ewsgi/connectors/nino/nino-safe.ecf b/library/server/ewsgi/connectors/nino/nino-safe.ecf index 06dc298e..7926cb48 100644 --- a/library/server/ewsgi/connectors/nino/nino-safe.ecf +++ b/library/server/ewsgi/connectors/nino/nino-safe.ecf @@ -10,7 +10,6 @@ - diff --git a/library/server/ewsgi/connectors/nino/nino.ecf b/library/server/ewsgi/connectors/nino/nino.ecf index 0e051988..e22c084e 100644 --- a/library/server/ewsgi/connectors/nino/nino.ecf +++ b/library/server/ewsgi/connectors/nino/nino.ecf @@ -10,7 +10,6 @@ - diff --git a/library/server/ewsgi/connectors/nino/src/wgi_nino_connector.e b/library/server/ewsgi/connectors/nino/src/wgi_nino_connector.e index d12df62e..7dae16a0 100644 --- a/library/server/ewsgi/connectors/nino/src/wgi_nino_connector.e +++ b/library/server/ewsgi/connectors/nino/src/wgi_nino_connector.e @@ -9,9 +9,6 @@ class inherit WGI_CONNECTOR - redefine - initialize - end create make, @@ -19,6 +16,16 @@ create feature {NONE} -- Initialization + make (a_app: like application) + local + cfg: HTTP_SERVER_CONFIGURATION + do + application := a_app + + create cfg.make + create server.make (cfg) + end + make_with_base (a_app: like application; a_base: like base) require a_base_starts_with_slash: (a_base /= Void and then not a_base.is_empty) implies a_base.starts_with ("/") @@ -27,15 +34,18 @@ feature {NONE} -- Initialization set_base (a_base) end -feature {NONE} -- Initialization +feature -- Access - initialize - local - cfg: HTTP_SERVER_CONFIGURATION - do - create cfg.make - create server.make (cfg) - end + name: STRING_8 = "Nino" + -- Name of Current connector + + version: STRING_8 = "0.1" + -- Version of Current connector + +feature {NONE} -- Access + + application: WGI_SERVICE + -- Gateway Service feature -- Access @@ -107,11 +117,11 @@ feature -- Server process_request (env: HASH_TABLE [STRING, STRING]; a_headers_text: STRING; a_socket: TCP_STREAM_SOCKET) local req: WGI_REQUEST_FROM_TABLE - res: detachable WGI_RESPONSE_STREAM_BUFFER + res: detachable WGI_RESPONSE_STREAM rescued: BOOLEAN do if not rescued then - create req.make (env, create {WGI_NINO_INPUT_STREAM}.make (a_socket)) + create req.make (env, create {WGI_NINO_INPUT_STREAM}.make (a_socket), Current) create res.make (create {WGI_NINO_OUTPUT_STREAM}.make (a_socket)) req.set_meta_string_variable ("RAW_HEADER_DATA", a_headers_text) application.execute (req, res) @@ -119,7 +129,7 @@ feature -- Server 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.write_header ({HTTP_STATUS_CODE}.internal_server_error, Void) + res.set_status_code ({HTTP_STATUS_CODE}.internal_server_error) end if res.message_writable then res.write_string ("
" + l_trace + "
") diff --git a/library/server/ewsgi/ewsgi-safe.ecf b/library/server/ewsgi/ewsgi-safe.ecf index f4127fbf..ec9e40bf 100644 --- a/library/server/ewsgi/ewsgi-safe.ecf +++ b/library/server/ewsgi/ewsgi-safe.ecf @@ -17,5 +17,6 @@ + diff --git a/library/server/ewsgi/ewsgi.ecf b/library/server/ewsgi/ewsgi.ecf index 94a0499c..964539f5 100644 --- a/library/server/ewsgi/ewsgi.ecf +++ b/library/server/ewsgi/ewsgi.ecf @@ -17,5 +17,6 @@ + diff --git a/library/server/ewsgi/specification/request/wgi_request.e b/library/server/ewsgi/specification/request/wgi_request.e index cf169bf5..db01dfb6 100644 --- a/library/server/ewsgi/specification/request/wgi_request.e +++ b/library/server/ewsgi/specification/request/wgi_request.e @@ -129,6 +129,25 @@ feature -- Access: CGI meta variables deferred end +feature -- EWSGI access + + wgi_version: READABLE_STRING_8 + -- Eiffel WGI version + --| example: "1.0" + deferred + end + + wgi_implementation: READABLE_STRING_8 + -- Information about Eiffel WGI implementation + --| example: "Eiffel Web Framework 1.0" + deferred + end + + wgi_connector: WGI_CONNECTOR + -- Associated Eiffel WGI connector + deferred + end + feature -- Common Gateway Interface - 1.1 8 January 1996 auth_type: detachable READABLE_STRING_8 diff --git a/library/server/ewsgi/specification/response/wgi_response_buffer.e b/library/server/ewsgi/specification/response/wgi_response.e similarity index 80% rename from library/server/ewsgi/specification/response/wgi_response_buffer.e rename to library/server/ewsgi/specification/response/wgi_response.e index 50b5aaf0..993be799 100644 --- a/library/server/ewsgi/specification/response/wgi_response_buffer.e +++ b/library/server/ewsgi/specification/response/wgi_response.e @@ -1,11 +1,10 @@ note - description: "Summary description for {WGI_RESPONSE_BUFFER}." - author: "" + description: "Summary description for {WGI_RESPONSE}." date: "$Date$" revision: "$Revision$" deferred class - WGI_RESPONSE_BUFFER + WGI_RESPONSE feature {WGI_SERVICE} -- Commit @@ -69,7 +68,7 @@ feature -- Status setting feature -- Header output operation - write_headers_string (a_headers: READABLE_STRING_8) + write_headers (a_headers: READABLE_STRING_8) require status_set: status_is_set header_not_committed: not header_committed @@ -80,18 +79,6 @@ feature -- Header output operation message_writable: message_writable end - write_header (a_status_code: INTEGER; a_headers: detachable ARRAY [TUPLE [key: READABLE_STRING_8; value: READABLE_STRING_8]]) - -- Send headers with status `a_status', and headers from `a_headers' - require - status_not_set: not status_is_set - header_not_committed: not header_committed - deferred - ensure - header_committed: header_committed - status_set: status_is_set - message_writable: message_writable - end - feature -- Output operation write_string (s: READABLE_STRING_8) diff --git a/library/server/ewsgi/src/helper/wgi_request_from_table.e b/library/server/ewsgi/src/helper/wgi_request_from_table.e index 6024236c..d170438d 100644 --- a/library/server/ewsgi/src/helper/wgi_request_from_table.e +++ b/library/server/ewsgi/src/helper/wgi_request_from_table.e @@ -19,10 +19,11 @@ create feature {NONE} -- Initialization - make (a_vars: HASH_TABLE [READABLE_STRING_8, READABLE_STRING_8]; a_input: like input) + make (a_vars: HASH_TABLE [READABLE_STRING_8, READABLE_STRING_8]; a_input: like input; a_wgi_connector: like wgi_connector) require vars_attached: a_vars /= Void do + wgi_connector := a_wgi_connector input := a_input set_meta_variables (a_vars) @@ -34,6 +35,14 @@ feature -- Access: Input input: WGI_INPUT_STREAM -- Server input channel +feature -- EWSGI access + + wgi_version: STRING = "0.1" + + wgi_implementation: STRING = "Eiffel Web Framework 0.1" + + wgi_connector: WGI_CONNECTOR + feature -- Access: CGI meta parameters meta_variables: HASH_TABLE [READABLE_STRING_8, READABLE_STRING_8] diff --git a/library/server/ewsgi/src/helper/wgi_response_stream_buffer.e b/library/server/ewsgi/src/helper/wgi_response_stream.e similarity index 73% rename from library/server/ewsgi/src/helper/wgi_response_stream_buffer.e rename to library/server/ewsgi/src/helper/wgi_response_stream.e index 5de3610f..8ada8a12 100644 --- a/library/server/ewsgi/src/helper/wgi_response_stream_buffer.e +++ b/library/server/ewsgi/src/helper/wgi_response_stream.e @@ -1,17 +1,16 @@ note description: "[ - Response buffer + WGI Response implemented using stream buffer ]" - specification: "EWSGI specification https://github.com/Eiffel-World/Eiffel-Web-Framework/wiki/EWSGI-specification" date: "$Date$" revision: "$Revision$" class - WGI_RESPONSE_STREAM_BUFFER + WGI_RESPONSE_STREAM inherit - WGI_RESPONSE_BUFFER + WGI_RESPONSE create make @@ -76,34 +75,12 @@ feature -- Status setting feature -- Header output operation - write_headers_string (a_headers: READABLE_STRING_8) + write_headers (a_headers: READABLE_STRING_8) do write (a_headers) header_committed := True end - write_header (a_status_code: INTEGER; a_headers: detachable ARRAY [TUPLE [key: READABLE_STRING_8; value: READABLE_STRING_8]]) - -- Send headers with status `a_status', and headers from `a_headers' - local - h: EWF_HEADER - i,n: INTEGER - do - set_status_code (a_status_code) - create h.make - if a_headers /= Void then - from - i := a_headers.lower - n := a_headers.upper - until - i > n - loop - h.put_header_key_value (a_headers[i].key, a_headers[i].value) - i := i + 1 - end - end - write_headers_string (h.string) - end - feature -- Output operation write_string (s: READABLE_STRING_8) diff --git a/library/server/ewsgi/src/support/ewf_header.e b/library/server/ewsgi/src/support/ewf_header.e deleted file mode 100644 index b2bc0bbb..00000000 --- a/library/server/ewsgi/src/support/ewf_header.e +++ /dev/null @@ -1,465 +0,0 @@ -note - description: "[ - The class provides an easy way to build HTTP header. - - You will also find some helper feature to help coding most common usage - - Please, have a look at constants classes such as - HTTP_MIME_TYPES - HTTP_HEADER_NAMES - HTTP_STATUS_CODE - HTTP_REQUEST_METHODS - (or HTTP_CONSTANTS which groups them for convenience) - - Note the return status code is not part of the HTTP header - However you can set the "Status: " header line if you want - ]" - legal: "See notice at end of class." - status: "See notice at end of class." - date: "$Date$" - revision: "$Revision$" - -class - EWF_HEADER - -inherit - ANY - - HTTP_STATUS_CODE_MESSAGES --| useful for `put_status' - export - {NONE} all - end - -create - make, - make_with_count - -feature {NONE} -- Initialization - - make - -- Initialize current - do - make_with_count (3) - end - - make_with_count (n: INTEGER) - -- Make with a capacity of `n' header entries - do - create {ARRAYED_LIST [READABLE_STRING_8]} headers.make (n) - end - -feature -- Recycle - - recycle - -- Recycle current object - do - headers.wipe_out - end - -feature -- Access - - headers: LIST [READABLE_STRING_8] - -- Header's lines - - string: STRING - -- String representation of the headers - local - l_headers: like headers - do - create Result.make (32) - l_headers := headers - if l_headers.is_empty then - put_content_type_text_html -- See if this make sense to define a default content-type - else - from - l_headers.start - until - l_headers.after - loop - append_line_to (l_headers.item, Result) - l_headers.forth - end - end - append_end_of_line_to (Result) - end - -feature -- Header change: general - - add_header (h: READABLE_STRING_8) - -- Add header `h' - -- if it already exists, there will be multiple header with same name - -- which can also be valid - require - h_not_empty: not h.is_empty - do - headers.force (h) - end - - put_header (h: READABLE_STRING_8) - -- Add header `h' or replace existing header of same header name - require - h_not_empty: not h.is_empty - do - force_header_by_name (header_name (h), h) - end - - add_header_key_value (k,v: READABLE_STRING_8) - -- Add header `k:v', or replace existing header of same header name/key - do - add_header (k + colon_space + v) - end - - put_header_key_value (k,v: READABLE_STRING_8) - -- Add header `k:v', or replace existing header of same header name/key - do - put_header (k + colon_space + v) - end - -feature -- Status related - - put_status (c: INTEGER) - -- Put "Status: " header - -- Rarely used - local - s: STRING - do - create s.make_from_string (c.out) - if attached http_status_code_message (c) as msg then - s.append_character (' ') - s.append (msg) - end - put_header_key_value ("Status", s) - end - -feature -- Content related header - - put_content_type (t: READABLE_STRING_8) - do - put_header_key_value ({HTTP_HEADER_NAMES}.header_content_type, t) - end - - add_content_type (t: READABLE_STRING_8) - -- same as `put_content_type', but allow multiple definition of "Content-Type" - do - add_header_key_value ({HTTP_HEADER_NAMES}.header_content_type, t) - end - - put_content_type_with_charset (t: READABLE_STRING_8; c: READABLE_STRING_8) - do - put_header_key_value ({HTTP_HEADER_NAMES}.header_content_type, t + "; charset=" + c + "") - end - - add_content_type_with_charset (t: READABLE_STRING_8; c: READABLE_STRING_8) - -- same as `put_content_type_with_charset', but allow multiple definition of "Content-Type" - do - add_header_key_value ({HTTP_HEADER_NAMES}.header_content_type, t + "; charset=" + c + "") - end - - put_content_type_with_name (t: READABLE_STRING_8; n: READABLE_STRING_8) - do - put_header_key_value ({HTTP_HEADER_NAMES}.header_content_type, t + "; name=%"" + n + "%"") - end - - add_content_type_with_name (t: READABLE_STRING_8; n: READABLE_STRING_8) - -- same as `put_content_type_with_name', but allow multiple definition of "Content-Type" - do - add_header_key_value ({HTTP_HEADER_NAMES}.header_content_type, t + "; name=%"" + n + "%"") - end - - put_content_length (n: INTEGER) - do - put_header_key_value ({HTTP_HEADER_NAMES}.header_content_length, n.out) - end - - put_content_transfer_encoding (a_mechanism: READABLE_STRING_8) - -- Put "Content-Transfer-Encoding" header with for instance "binary" - --| encoding := "Content-Transfer-Encoding" ":" mechanism - --| - --| mechanism := "7bit" ; case-insensitive - --| / "quoted-printable" - --| / "base64" - --| / "8bit" - --| / "binary" - --| / x-token - - do - put_header_key_value ({HTTP_HEADER_NAMES}.header_content_transfer_encoding, a_mechanism) - end - - put_transfer_encoding (a_enc: READABLE_STRING_8) - -- Put "Transfer-Encoding" header with for instance "chunked" - do - put_header_key_value ({HTTP_HEADER_NAMES}.header_transfer_encoding, a_enc) - end - - put_transfer_encoding_chunked - -- Put "Transfer-Encoding: chunked" header - do - put_transfer_encoding ("chunked") - end - - put_content_disposition (a_type: READABLE_STRING_8; a_params: detachable READABLE_STRING_8) - -- Put "Content-Disposition" header - --| See RFC2183 - --| disposition := "Content-Disposition" ":" - --| disposition-type - --| *(";" disposition-parm) - --| disposition-type := "inline" - --| / "attachment" - --| / extension-token - --| ; values are not case-sensitive - --| disposition-parm := filename-parm - --| / creation-date-parm - --| / modification-date-parm - --| / read-date-parm - --| / size-parm - --| / parameter - --| filename-parm := "filename" "=" value - --| creation-date-parm := "creation-date" "=" quoted-date-time - --| modification-date-parm := "modification-date" "=" quoted-date-time - --| read-date-parm := "read-date" "=" quoted-date-time - --| size-parm := "size" "=" 1*DIGIT - --| quoted-date-time := quoted-string - --| ; contents MUST be an RFC 822 `date-time' - --| ; numeric timezones (+HHMM or -HHMM) MUST be used - do - if a_params /= Void then - put_header_key_value ({HTTP_HEADER_NAMES}.header_content_disposition, a_type + semi_colon_space + a_params) - else - put_header_key_value ({HTTP_HEADER_NAMES}.header_content_disposition, a_type) - end - end - -feature -- Content-type helpers - - put_content_type_text_css do put_content_type ({HTTP_MIME_TYPES}.text_css) end - put_content_type_text_csv do put_content_type ({HTTP_MIME_TYPES}.text_csv) end - put_content_type_text_html do put_content_type ({HTTP_MIME_TYPES}.text_html) end - put_content_type_text_javascript do put_content_type ({HTTP_MIME_TYPES}.text_javascript) end - put_content_type_text_json do put_content_type ({HTTP_MIME_TYPES}.text_json) end - put_content_type_text_plain do put_content_type ({HTTP_MIME_TYPES}.text_plain) end - put_content_type_text_xml do put_content_type ({HTTP_MIME_TYPES}.text_xml) end - - put_content_type_application_json do put_content_type ({HTTP_MIME_TYPES}.application_json) end - put_content_type_application_javascript do put_content_type ({HTTP_MIME_TYPES}.application_javascript) end - put_content_type_application_zip do put_content_type ({HTTP_MIME_TYPES}.application_zip) end - - put_content_type_image_gif do put_content_type ({HTTP_MIME_TYPES}.image_gif) end - put_content_type_image_png do put_content_type ({HTTP_MIME_TYPES}.image_png) end - put_content_type_image_jpg do put_content_type ({HTTP_MIME_TYPES}.image_jpg) end - put_content_type_image_svg_xml do put_content_type ({HTTP_MIME_TYPES}.image_svg_xml) end - - put_content_type_message_http do put_content_type ({HTTP_MIME_TYPES}.message_http) end - - put_content_type_multipart_mixed do put_content_type ({HTTP_MIME_TYPES}.multipart_mixed) end - put_content_type_multipart_alternative do put_content_type ({HTTP_MIME_TYPES}.multipart_alternative) end - put_content_type_multipart_related do put_content_type ({HTTP_MIME_TYPES}.multipart_related) end - put_content_type_multipart_form_data do put_content_type ({HTTP_MIME_TYPES}.multipart_form_data) end - put_content_type_multipart_signed do put_content_type ({HTTP_MIME_TYPES}.multipart_signed) end - put_content_type_multipart_encrypted do put_content_type ({HTTP_MIME_TYPES}.multipart_encrypted) end - -feature -- Date - - put_date (s: READABLE_STRING_8) - -- Put "Date: " header - do - put_header_key_value ({HTTP_HEADER_NAMES}.header_date, s) - end - - put_current_date - -- Put current date time with "Date" header - do - put_utc_date (create {DATE_TIME}.make_now_utc) - end - - put_utc_date (dt: DATE_TIME) - -- Put UTC date time `dt' with "Date" header - do - put_date (dt.formatted_out ("ddd,[0]dd mmm yyyy [0]hh:[0]mi:[0]ss.ff2") + " GMT") - end - -feature -- Others - - put_expires (n: INTEGER) - do - put_header_key_value ("Expires", n.out) - end - - put_cache_control (s: READABLE_STRING_8) - -- `s' could be for instance "no-cache, must-revalidate" - do - put_header_key_value ("Cache-Control", s) - end - - put_pragma (s: READABLE_STRING_8) - do - put_header_key_value ("Pragma", s) - end - - put_pragma_no_cache - do - put_pragma ("no-cache") - end - -feature -- Redirection - - put_location (a_location: READABLE_STRING_8) - -- Tell the client the new location `a_location' - require - a_location_valid: not a_location.is_empty - do - put_header_key_value ({HTTP_HEADER_NAMES}.header_location, a_location) - end - - put_refresh (a_location: READABLE_STRING_8; a_timeout_in_seconds: INTEGER) - -- Tell the client to refresh page with `a_location' after `a_timeout_in_seconds' in seconds - require - a_location_valid: not a_location.is_empty - do - put_header_key_value ({HTTP_HEADER_NAMES}.header_refresh, a_timeout_in_seconds.out + "; url=" + a_location) - end - -feature -- Cookie - - put_cookie (key, value: READABLE_STRING_8; expiration, path, domain, secure: detachable READABLE_STRING_8) - -- Set a cookie on the client's machine - -- with key 'key' and value 'value'. - require - make_sense: (key /= Void and value /= Void) and then (not key.is_empty and not value.is_empty) - local - s: STRING - do - s := {HTTP_HEADER_NAMES}.header_set_cookie + colon_space + key + "=" + value - if expiration /= Void then - s.append ("; expires=" + expiration) - end - if path /= Void then - s.append ("; path=" + path) - end - if domain /= Void then - s.append ("; domain=" + domain) - end - if secure /= Void then - s.append ("; secure=" + secure) - end - add_header (s) - end - -feature -- Status report - - has_header_named (a_name: READABLE_STRING_8): BOOLEAN - -- Has header item for `n'? - local - c: like headers.new_cursor - n: INTEGER - l_line: READABLE_STRING_8 - do - from - n := a_name.count - c := headers.new_cursor - until - c.after or Result - loop - l_line := c.item - if l_line.starts_with (a_name) then - if l_line.valid_index (n + 1) then - Result := l_line [n + 1] = ':' - end - end - c.forth - end - end - - has_content_length: BOOLEAN - -- Has header "content_length" - do - Result := has_header_named ({HTTP_HEADER_NAMES}.header_content_length) - end - -feature {NONE} -- Implementation: Header - - force_header_by_name (n: detachable READABLE_STRING_8; h: READABLE_STRING_8) - -- Add header `h' or replace existing header of same header name `n' - require - h_has_name_n: (n /= Void and attached header_name (h) as hn) implies n.same_string (hn) - local - l_headers: like headers - do - if n /= Void then - from - l_headers := headers - l_headers.start - until - l_headers.after or l_headers.item.starts_with (n) - loop - l_headers.forth - end - if not l_headers.after then - l_headers.replace (h) - else - add_header (h) - end - else - add_header (h) - end - end - - header_name (h: READABLE_STRING_8): detachable READABLE_STRING_8 - -- If any, header's name with colon - --| ex: for "Foo-bar: something", this will return "Foo-bar:" - local - s: detachable STRING_8 - i,n: INTEGER - c: CHARACTER - do - from - i := 1 - n := h.count - create s.make (10) - until - i > n or c = ':' or s = Void - loop - c := h[i] - inspect c - when ':' then - s.extend (c) - when '-', 'a' .. 'z', 'A' .. 'Z' then - s.extend (c) - else - s := Void - end - i := i + 1 - end - Result := s - end - -feature {NONE} -- Implementation - - append_line_to (s: READABLE_STRING_8; h: like string) - do - h.append_string (s) - append_end_of_line_to (h) - end - - append_end_of_line_to (h: like string) - do - h.append_character ('%R') - h.append_character ('%N') - end - -feature {NONE} -- Constants - - colon_space: STRING = ": " - semi_colon_space: STRING = "; " - -note - copyright: "2011-2011, 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 diff --git a/library/server/ewsgi/src/wgi_agent_service.e b/library/server/ewsgi/src/wgi_agent_service.e index 7635771e..3abdbeb0 100644 --- a/library/server/ewsgi/src/wgi_agent_service.e +++ b/library/server/ewsgi/src/wgi_agent_service.e @@ -23,10 +23,10 @@ feature {NONE} -- Implementation feature {NONE} -- Implementation - callback: PROCEDURE [ANY, TUPLE [req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER]] + callback: PROCEDURE [ANY, TUPLE [req: WGI_REQUEST; res: WGI_RESPONSE]] -- Procedure called on `execute' - execute (req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER) + execute (req: WGI_REQUEST; res: WGI_RESPONSE) -- Execute the request do callback.call ([req, res]) diff --git a/library/server/ewsgi/src/wgi_service.e b/library/server/ewsgi/src/wgi_service.e index e9adf6a0..a71cdb48 100644 --- a/library/server/ewsgi/src/wgi_service.e +++ b/library/server/ewsgi/src/wgi_service.e @@ -13,7 +13,7 @@ deferred class feature -- Execution - execute (req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER) + execute (req: WGI_REQUEST; res: WGI_RESPONSE) -- Execute the request -- See `req.input' for input stream -- `req.meta_variables' for the CGI meta variable diff --git a/library/server/wsf/src/support/wsf_header.e b/library/server/wsf/src/support/wsf_header.e index 5d333cdb..139be662 100644 --- a/library/server/wsf/src/support/wsf_header.e +++ b/library/server/wsf/src/support/wsf_header.e @@ -23,12 +23,434 @@ class WSF_HEADER inherit - EWF_HEADER + ANY + + HTTP_STATUS_CODE_MESSAGES --| useful for `put_status' + export + {NONE} all + end create make, make_with_count +feature {NONE} -- Initialization + + make + -- Initialize current + do + make_with_count (3) + end + + make_with_count (n: INTEGER) + -- Make with a capacity of `n' header entries + do + create {ARRAYED_LIST [READABLE_STRING_8]} headers.make (n) + end + +feature -- Recycle + + recycle + -- Recycle current object + do + headers.wipe_out + end + +feature -- Access + + headers: LIST [READABLE_STRING_8] + -- Header's lines + + string: STRING + -- String representation of the headers + local + l_headers: like headers + do + create Result.make (32) + l_headers := headers + if l_headers.is_empty then + put_content_type_text_html -- See if this make sense to define a default content-type + else + from + l_headers.start + until + l_headers.after + loop + append_line_to (l_headers.item, Result) + l_headers.forth + end + end + append_end_of_line_to (Result) + end + +feature -- Header change: general + + add_header (h: READABLE_STRING_8) + -- Add header `h' + -- if it already exists, there will be multiple header with same name + -- which can also be valid + require + h_not_empty: not h.is_empty + do + headers.force (h) + end + + put_header (h: READABLE_STRING_8) + -- Add header `h' or replace existing header of same header name + require + h_not_empty: not h.is_empty + do + force_header_by_name (header_name (h), h) + end + + add_header_key_value (k,v: READABLE_STRING_8) + -- Add header `k:v', or replace existing header of same header name/key + do + add_header (k + colon_space + v) + end + + put_header_key_value (k,v: READABLE_STRING_8) + -- Add header `k:v', or replace existing header of same header name/key + do + put_header (k + colon_space + v) + end + +feature -- Status related + + put_status (c: INTEGER) + -- Put "Status: " header + -- Rarely used + local + s: STRING + do + create s.make_from_string (c.out) + if attached http_status_code_message (c) as msg then + s.append_character (' ') + s.append (msg) + end + put_header_key_value ("Status", s) + end + +feature -- Content related header + + put_content_type (t: READABLE_STRING_8) + do + put_header_key_value ({HTTP_HEADER_NAMES}.header_content_type, t) + end + + add_content_type (t: READABLE_STRING_8) + -- same as `put_content_type', but allow multiple definition of "Content-Type" + do + add_header_key_value ({HTTP_HEADER_NAMES}.header_content_type, t) + end + + put_content_type_with_charset (t: READABLE_STRING_8; c: READABLE_STRING_8) + do + put_header_key_value ({HTTP_HEADER_NAMES}.header_content_type, t + "; charset=" + c + "") + end + + add_content_type_with_charset (t: READABLE_STRING_8; c: READABLE_STRING_8) + -- same as `put_content_type_with_charset', but allow multiple definition of "Content-Type" + do + add_header_key_value ({HTTP_HEADER_NAMES}.header_content_type, t + "; charset=" + c + "") + end + + put_content_type_with_name (t: READABLE_STRING_8; n: READABLE_STRING_8) + do + put_header_key_value ({HTTP_HEADER_NAMES}.header_content_type, t + "; name=%"" + n + "%"") + end + + add_content_type_with_name (t: READABLE_STRING_8; n: READABLE_STRING_8) + -- same as `put_content_type_with_name', but allow multiple definition of "Content-Type" + do + add_header_key_value ({HTTP_HEADER_NAMES}.header_content_type, t + "; name=%"" + n + "%"") + end + + put_content_length (n: INTEGER) + do + put_header_key_value ({HTTP_HEADER_NAMES}.header_content_length, n.out) + end + + put_content_transfer_encoding (a_mechanism: READABLE_STRING_8) + -- Put "Content-Transfer-Encoding" header with for instance "binary" + --| encoding := "Content-Transfer-Encoding" ":" mechanism + --| + --| mechanism := "7bit" ; case-insensitive + --| / "quoted-printable" + --| / "base64" + --| / "8bit" + --| / "binary" + --| / x-token + do + put_header_key_value ({HTTP_HEADER_NAMES}.header_content_transfer_encoding, a_mechanism) + end + + put_transfer_encoding (a_enc: READABLE_STRING_8) + -- Put "Transfer-Encoding" header with for instance "chunked" + do + put_header_key_value ({HTTP_HEADER_NAMES}.header_transfer_encoding, a_enc) + end + + put_transfer_encoding_chunked + -- Put "Transfer-Encoding: chunked" header + do + put_transfer_encoding ("chunked") + end + + put_content_disposition (a_type: READABLE_STRING_8; a_params: detachable READABLE_STRING_8) + -- Put "Content-Disposition" header + --| See RFC2183 + --| disposition := "Content-Disposition" ":" + --| disposition-type + --| *(";" disposition-parm) + --| disposition-type := "inline" + --| / "attachment" + --| / extension-token + --| ; values are not case-sensitive + --| disposition-parm := filename-parm + --| / creation-date-parm + --| / modification-date-parm + --| / read-date-parm + --| / size-parm + --| / parameter + --| filename-parm := "filename" "=" value + --| creation-date-parm := "creation-date" "=" quoted-date-time + --| modification-date-parm := "modification-date" "=" quoted-date-time + --| read-date-parm := "read-date" "=" quoted-date-time + --| size-parm := "size" "=" 1*DIGIT + --| quoted-date-time := quoted-string + --| ; contents MUST be an RFC 822 `date-time' + --| ; numeric timezones (+HHMM or -HHMM) MUST be used + do + if a_params /= Void then + put_header_key_value ({HTTP_HEADER_NAMES}.header_content_disposition, a_type + semi_colon_space + a_params) + else + put_header_key_value ({HTTP_HEADER_NAMES}.header_content_disposition, a_type) + end + end + +feature -- Content-type helpers + + put_content_type_text_css do put_content_type ({HTTP_MIME_TYPES}.text_css) end + put_content_type_text_csv do put_content_type ({HTTP_MIME_TYPES}.text_csv) end + put_content_type_text_html do put_content_type ({HTTP_MIME_TYPES}.text_html) end + put_content_type_text_javascript do put_content_type ({HTTP_MIME_TYPES}.text_javascript) end + put_content_type_text_json do put_content_type ({HTTP_MIME_TYPES}.text_json) end + put_content_type_text_plain do put_content_type ({HTTP_MIME_TYPES}.text_plain) end + put_content_type_text_xml do put_content_type ({HTTP_MIME_TYPES}.text_xml) end + + put_content_type_application_json do put_content_type ({HTTP_MIME_TYPES}.application_json) end + put_content_type_application_javascript do put_content_type ({HTTP_MIME_TYPES}.application_javascript) end + put_content_type_application_zip do put_content_type ({HTTP_MIME_TYPES}.application_zip) end + + put_content_type_image_gif do put_content_type ({HTTP_MIME_TYPES}.image_gif) end + put_content_type_image_png do put_content_type ({HTTP_MIME_TYPES}.image_png) end + put_content_type_image_jpg do put_content_type ({HTTP_MIME_TYPES}.image_jpg) end + put_content_type_image_svg_xml do put_content_type ({HTTP_MIME_TYPES}.image_svg_xml) end + + put_content_type_message_http do put_content_type ({HTTP_MIME_TYPES}.message_http) end + + put_content_type_multipart_mixed do put_content_type ({HTTP_MIME_TYPES}.multipart_mixed) end + put_content_type_multipart_alternative do put_content_type ({HTTP_MIME_TYPES}.multipart_alternative) end + put_content_type_multipart_related do put_content_type ({HTTP_MIME_TYPES}.multipart_related) end + put_content_type_multipart_form_data do put_content_type ({HTTP_MIME_TYPES}.multipart_form_data) end + put_content_type_multipart_signed do put_content_type ({HTTP_MIME_TYPES}.multipart_signed) end + put_content_type_multipart_encrypted do put_content_type ({HTTP_MIME_TYPES}.multipart_encrypted) end + +feature -- Date + + put_date (s: READABLE_STRING_8) + -- Put "Date: " header + do + put_header_key_value ({HTTP_HEADER_NAMES}.header_date, s) + end + + put_current_date + -- Put current date time with "Date" header + do + put_utc_date (create {DATE_TIME}.make_now_utc) + end + + put_utc_date (dt: DATE_TIME) + -- Put UTC date time `dt' with "Date" header + do + put_date (dt.formatted_out ("ddd,[0]dd mmm yyyy [0]hh:[0]mi:[0]ss.ff2") + " GMT") + end + +feature -- Others + + put_expires (n: INTEGER) + do + put_header_key_value ("Expires", n.out) + end + + put_cache_control (s: READABLE_STRING_8) + -- `s' could be for instance "no-cache, must-revalidate" + do + put_header_key_value ("Cache-Control", s) + end + + put_pragma (s: READABLE_STRING_8) + do + put_header_key_value ("Pragma", s) + end + + put_pragma_no_cache + do + put_pragma ("no-cache") + end + +feature -- Redirection + + put_location (a_location: READABLE_STRING_8) + -- Tell the client the new location `a_location' + require + a_location_valid: not a_location.is_empty + do + put_header_key_value ({HTTP_HEADER_NAMES}.header_location, a_location) + end + + put_refresh (a_location: READABLE_STRING_8; a_timeout_in_seconds: INTEGER) + -- Tell the client to refresh page with `a_location' after `a_timeout_in_seconds' in seconds + require + a_location_valid: not a_location.is_empty + do + put_header_key_value ({HTTP_HEADER_NAMES}.header_refresh, a_timeout_in_seconds.out + "; url=" + a_location) + end + +feature -- Cookie + + put_cookie (key, value: READABLE_STRING_8; expiration, path, domain, secure: detachable READABLE_STRING_8) + -- Set a cookie on the client's machine + -- with key 'key' and value 'value'. + require + make_sense: (key /= Void and value /= Void) and then (not key.is_empty and not value.is_empty) + local + s: STRING + do + s := {HTTP_HEADER_NAMES}.header_set_cookie + colon_space + key + "=" + value + if expiration /= Void then + s.append ("; expires=" + expiration) + end + if path /= Void then + s.append ("; path=" + path) + end + if domain /= Void then + s.append ("; domain=" + domain) + end + if secure /= Void then + s.append ("; secure=" + secure) + end + add_header (s) + end + +feature -- Status report + + has_header_named (a_name: READABLE_STRING_8): BOOLEAN + -- Has header item for `n'? + local + c: like headers.new_cursor + n: INTEGER + l_line: READABLE_STRING_8 + do + from + n := a_name.count + c := headers.new_cursor + until + c.after or Result + loop + l_line := c.item + if l_line.starts_with (a_name) then + if l_line.valid_index (n + 1) then + Result := l_line [n + 1] = ':' + end + end + c.forth + end + end + + has_content_length: BOOLEAN + -- Has header "content_length" + do + Result := has_header_named ({HTTP_HEADER_NAMES}.header_content_length) + end + +feature {NONE} -- Implementation: Header + + force_header_by_name (n: detachable READABLE_STRING_8; h: READABLE_STRING_8) + -- Add header `h' or replace existing header of same header name `n' + require + h_has_name_n: (n /= Void and attached header_name (h) as hn) implies n.same_string (hn) + local + l_headers: like headers + do + if n /= Void then + from + l_headers := headers + l_headers.start + until + l_headers.after or l_headers.item.starts_with (n) + loop + l_headers.forth + end + if not l_headers.after then + l_headers.replace (h) + else + add_header (h) + end + else + add_header (h) + end + end + + header_name (h: READABLE_STRING_8): detachable READABLE_STRING_8 + -- If any, header's name with colon + --| ex: for "Foo-bar: something", this will return "Foo-bar:" + local + s: detachable STRING_8 + i,n: INTEGER + c: CHARACTER + do + from + i := 1 + n := h.count + create s.make (10) + until + i > n or c = ':' or s = Void + loop + c := h[i] + inspect c + when ':' then + s.extend (c) + when '-', 'a' .. 'z', 'A' .. 'Z' then + s.extend (c) + else + s := Void + end + i := i + 1 + end + Result := s + end + +feature {NONE} -- Implementation + + append_line_to (s: READABLE_STRING_8; h: like string) + do + h.append_string (s) + append_end_of_line_to (h) + end + + append_end_of_line_to (h: like string) + do + h.append_character ('%R') + h.append_character ('%N') + end + +feature {NONE} -- Constants + + colon_space: STRING = ": " + semi_colon_space: STRING = "; " + note copyright: "2011-2011, Eiffel Software and others" license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)" diff --git a/library/server/wsf/src/wsf_response.e b/library/server/wsf/src/wsf_response.e index e74ecb31..effeefee 100644 --- a/library/server/wsf/src/wsf_response.e +++ b/library/server/wsf/src/wsf_response.e @@ -12,16 +12,17 @@ create {WSF_SERVICE} make_from_wgi convert - make_from_wgi ({WGI_RESPONSE_BUFFER}) + make_from_wgi ({WGI_RESPONSE}) feature {NONE} -- Initialization - make_from_wgi (r: WGI_RESPONSE_BUFFER) + make_from_wgi (r: WGI_RESPONSE) do wgi_response := r end - wgi_response: WGI_RESPONSE_BUFFER + wgi_response: WGI_RESPONSE + -- Associated WGI_RESPONSE feature -- Status report @@ -77,7 +78,7 @@ feature -- Header output operation status_set: status_is_set header_not_committed: not header_committed do - wgi_response.write_headers_string (a_headers) + wgi_response.write_headers (a_headers) ensure status_set: status_is_set header_committed: header_committed @@ -89,8 +90,24 @@ feature -- Header output operation require status_not_set: not status_is_set header_not_committed: not header_committed + local + h: WSF_HEADER + i,n: INTEGER do - wgi_response.write_header (a_status_code, a_headers) + set_status_code (a_status_code) + create h.make + if a_headers /= Void then + from + i := a_headers.lower + n := a_headers.upper + until + i > n + loop + h.put_header_key_value (a_headers[i].key, a_headers[i].value) + i := i + 1 + end + end + wgi_response.write_headers (h.string) ensure header_committed: header_committed status_set: status_is_set diff --git a/library/server/wsf/src/wsf_service.e b/library/server/wsf/src/wsf_service.e index a42fcfb6..cb1a1733 100644 --- a/library/server/wsf/src/wsf_service.e +++ b/library/server/wsf/src/wsf_service.e @@ -28,7 +28,7 @@ feature -- Execution feature -- WGI Execution - wgi_execute (req: WGI_REQUEST; res: WGI_RESPONSE_BUFFER) + wgi_execute (req: WGI_REQUEST; res: WGI_RESPONSE) do execute (create {WSF_REQUEST}.make_from_wgi (req), create {WSF_RESPONSE}.make_from_wgi (res)) end