From bf0eb9a02de2d7faf2d0998a330da363529e46e4 Mon Sep 17 00:00:00 2001 From: Jocelyn Fiat Date: Tue, 24 Mar 2015 23:21:49 +0100 Subject: [PATCH] Added SCOOP support for WSF. WSF_SERVICE is deeply changed, and addition of WSF_EXECUTION. Todo: code cleaning, removing useless things. --- examples/debug/debug.ecf | 14 +- .../debug/launcher/any/application_launcher.e | 4 +- .../launcher/any/application_launcher_i.e | 50 +++-- .../launcher/default/application_launcher.e | 4 +- .../launcher/default/application_launcher_i.e | 8 +- examples/debug/src/ewf_debug_execution.e | 27 +++ examples/debug/src/ewf_debug_server.e | 18 +- examples/simple/simple.ecf | 8 + examples/simple_file/home.html | 10 +- examples/simple_file/service_file.e | 14 +- examples/simple_file/service_file.ecf | 4 +- examples/simple_file/service_file_execution.e | 26 +++ .../connectors/cgi/src/wgi_cgi_connector.e | 26 +-- .../httpd/dev/httpd_connector_dev.e | 31 +-- .../ewsgi/connectors/httpd/httpd-safe.ecf | 11 +- .../none/httpd_connection_handler.e | 2 +- .../httpd/src/httpd/httpd_server_i.e | 2 + .../httpd/src/wgi_httpd_connector.e | 183 ++++++++++++++++++ .../httpd/src/wgi_httpd_input_stream.e | 2 +- .../httpd/src/wgi_httpd_output_stream.e | 2 +- .../wgi_httpd_request_handler.e} | 47 +++-- .../src/wgi_httpd_request_handler_factory.e | 41 ++++ .../libfcgi/src/wgi_libfcgi_connector.e | 26 +-- .../connectors/nino/src/wgi_nino_connector.e | 29 ++- .../connectors/nino/src/wgi_nino_handler.e | 4 +- .../ewsgi/specification/request/wgi_request.e | 2 +- .../ewsgi/specification/service/wgi_service.e | 14 -- .../implementation/wgi_request_from_table.e | 2 +- library/server/ewsgi/src/wgi_execution.e | 54 ++++++ .../connector/cgi/wsf_cgi_service_launcher.e | 20 +- library/server/wsf/connector/httpd-safe.ecf | 22 +++ .../httpd/wsf_httpd_service_launcher.e | 168 ++++++++++++++++ .../libfcgi/wsf_libfcgi_service_launcher.e | 18 +- .../nino/wsf_nino_service_launcher.e | 54 +++--- .../cgi/wsf_default_service_launcher.e | 10 +- library/server/wsf/default/httpd-safe.ecf | 17 ++ .../httpd/wsf_default_response_service.e | 24 +++ .../wsf/default/httpd/wsf_default_service.e | 22 +++ .../httpd/wsf_default_service_launcher.e} | 19 +- .../wsf/default/nino/wsf_default_service.e | 4 +- .../nino/wsf_default_service_launcher.e | 8 +- .../wsf/extension/handler/wsf_debug_handler.e | 16 +- .../wsf/extension/wsf_debug_information.e | 28 ++- .../wsf/src/service/wsf_default_service_i.e | 6 +- .../wsf/src/service/wsf_launchable_service.e | 6 +- library/server/wsf/src/service/wsf_service.e | 20 +- .../wsf/src/service/wsf_service_launcher.e | 24 +-- .../wsf/src/service/wsf_to_wgi_service.e | 41 +--- library/server/wsf/src/wsf_execution.e | 69 ++++++- library/server/wsf/src/wsf_request.e | 4 +- library/server/wsf/src/wsf_response.e | 2 +- 51 files changed, 951 insertions(+), 316 deletions(-) create mode 100644 examples/debug/src/ewf_debug_execution.e create mode 100644 examples/simple_file/service_file_execution.e create mode 100644 library/server/ewsgi/connectors/httpd/src/wgi_httpd_connector.e rename library/server/ewsgi/connectors/httpd/{dev/wsf/wsf_httpd_request_handler.e => src/wgi_httpd_request_handler.e} (88%) create mode 100644 library/server/ewsgi/connectors/httpd/src/wgi_httpd_request_handler_factory.e create mode 100644 library/server/ewsgi/src/wgi_execution.e create mode 100644 library/server/wsf/connector/httpd-safe.ecf create mode 100644 library/server/wsf/connector/httpd/wsf_httpd_service_launcher.e create mode 100644 library/server/wsf/default/httpd-safe.ecf create mode 100644 library/server/wsf/default/httpd/wsf_default_response_service.e create mode 100644 library/server/wsf/default/httpd/wsf_default_service.e rename library/server/{ewsgi/connectors/httpd/dev/wsf/wsf_httpd_request_handler_factory.e => wsf/default/httpd/wsf_default_service_launcher.e} (59%) diff --git a/examples/debug/debug.ecf b/examples/debug/debug.ecf index 7b1f2b7b..26bf2100 100644 --- a/examples/debug/debug.ecf +++ b/examples/debug/debug.ecf @@ -18,12 +18,20 @@ + - - + + + + + + + + + @@ -32,7 +40,7 @@ - + diff --git a/examples/debug/launcher/any/application_launcher.e b/examples/debug/launcher/any/application_launcher.e index 0ef505c3..bb184d0a 100644 --- a/examples/debug/launcher/any/application_launcher.e +++ b/examples/debug/launcher/any/application_launcher.e @@ -8,10 +8,10 @@ note revision: "$Revision: 36 $" class - APPLICATION_LAUNCHER + APPLICATION_LAUNCHER [G -> WSF_EXECUTION create make end] inherit - APPLICATION_LAUNCHER_I + APPLICATION_LAUNCHER_I [G] feature -- Custom diff --git a/examples/debug/launcher/any/application_launcher_i.e b/examples/debug/launcher/any/application_launcher_i.e index 0744c801..22f94cab 100644 --- a/examples/debug/launcher/any/application_launcher_i.e +++ b/examples/debug/launcher/any/application_launcher_i.e @@ -10,24 +10,26 @@ note revision: "$Revision: 36 $" deferred class - APPLICATION_LAUNCHER_I + APPLICATION_LAUNCHER_I [G -> WSF_EXECUTION create make end] inherit SHARED_EXECUTION_ENVIRONMENT feature -- Execution - launch (a_service: WSF_SERVICE; opts: detachable WSF_SERVICE_LAUNCHER_OPTIONS) + launch (opts: detachable WSF_SERVICE_LAUNCHER_OPTIONS) local nature: like launcher_nature do nature := launcher_nature - if nature = Void or else nature = nature_nino then - launch_nino (a_service, opts) + if nature = Void or else nature = nature_httpd then + launch_httpd (opts) + elseif nature = nature_nino then + launch_nino (opts) elseif nature = nature_cgi then - launch_cgi (a_service, opts) + launch_cgi (opts) elseif nature = nature_libfcgi then - launch_libfcgi (a_service, opts) + launch_libfcgi (opts) else -- bye bye (create {EXCEPTIONS}).die (-1) @@ -43,14 +45,16 @@ feature {NONE} -- Access --| and we could use WSF_DEFAULT_SERVICE_LAUNCHER to configure this at compilation time. local p: PATH - l_entry_name: READABLE_STRING_32 ext: detachable READABLE_STRING_32 do create p.make_from_string (execution_environment.arguments.command_name) if attached p.entry as l_entry then - ext := l_entry.extension + ext := l_entry.extension end if ext /= Void then + if ext.same_string (nature_httpd) then + Result := nature_httpd + end if ext.same_string (nature_nino) then Result := nature_nino end @@ -61,39 +65,51 @@ feature {NONE} -- Access Result := nature_libfcgi end end + Result := nature_httpd + end + +feature {NONE} -- nino + + nature_httpd: STRING = "httpd" + + launch_httpd (opts: detachable WSF_SERVICE_LAUNCHER_OPTIONS) + local + launcher: WSF_HTTPD_SERVICE_LAUNCHER [G] + do + create launcher.make_and_launch (opts) end feature {NONE} -- nino nature_nino: STRING = "nino" - launch_nino (a_service: WSF_SERVICE; opts: detachable WSF_SERVICE_LAUNCHER_OPTIONS) + launch_nino (opts: detachable WSF_SERVICE_LAUNCHER_OPTIONS) local - launcher: WSF_NINO_SERVICE_LAUNCHER + launcher: WSF_NINO_SERVICE_LAUNCHER [G] do - create launcher.make_and_launch (a_service, opts) + create launcher.make_and_launch (opts) end feature {NONE} -- cgi nature_cgi: STRING = "cgi" - launch_cgi (a_service: WSF_SERVICE; opts: detachable WSF_SERVICE_LAUNCHER_OPTIONS) + launch_cgi (opts: detachable WSF_SERVICE_LAUNCHER_OPTIONS) local - launcher: WSF_CGI_SERVICE_LAUNCHER + launcher: WSF_CGI_SERVICE_LAUNCHER [G] do - create launcher.make_and_launch (a_service, opts) + create launcher.make_and_launch (opts) end feature {NONE} -- libfcgi nature_libfcgi: STRING = "libfcgi" - launch_libfcgi (a_service: WSF_SERVICE; opts: detachable WSF_SERVICE_LAUNCHER_OPTIONS) + launch_libfcgi (opts: detachable WSF_SERVICE_LAUNCHER_OPTIONS) local - launcher: WSF_LIBFCGI_SERVICE_LAUNCHER + launcher: WSF_LIBFCGI_SERVICE_LAUNCHER [G] do - create launcher.make_and_launch (a_service, opts) + create launcher.make_and_launch (opts) end diff --git a/examples/debug/launcher/default/application_launcher.e b/examples/debug/launcher/default/application_launcher.e index 0ef505c3..bb184d0a 100644 --- a/examples/debug/launcher/default/application_launcher.e +++ b/examples/debug/launcher/default/application_launcher.e @@ -8,10 +8,10 @@ note revision: "$Revision: 36 $" class - APPLICATION_LAUNCHER + APPLICATION_LAUNCHER [G -> WSF_EXECUTION create make end] inherit - APPLICATION_LAUNCHER_I + APPLICATION_LAUNCHER_I [G] feature -- Custom diff --git a/examples/debug/launcher/default/application_launcher_i.e b/examples/debug/launcher/default/application_launcher_i.e index 2cd4a73d..ef8f0037 100644 --- a/examples/debug/launcher/default/application_launcher_i.e +++ b/examples/debug/launcher/default/application_launcher_i.e @@ -10,15 +10,15 @@ note revision: "$Revision: 36 $" deferred class - APPLICATION_LAUNCHER_I + APPLICATION_LAUNCHER_I [G -> WSF_EXECUTION create make end] feature -- Execution - launch (a_service: WSF_SERVICE; opts: detachable WSF_SERVICE_LAUNCHER_OPTIONS) + launch (opts: detachable WSF_SERVICE_LAUNCHER_OPTIONS) local - launcher: WSF_SERVICE_LAUNCHER + launcher: WSF_SERVICE_LAUNCHER [G] do - create {WSF_DEFAULT_SERVICE_LAUNCHER} launcher.make_and_launch (a_service, opts) + create {WSF_DEFAULT_SERVICE_LAUNCHER [G]} launcher.make_and_launch (opts) end end diff --git a/examples/debug/src/ewf_debug_execution.e b/examples/debug/src/ewf_debug_execution.e new file mode 100644 index 00000000..f75c44c2 --- /dev/null +++ b/examples/debug/src/ewf_debug_execution.e @@ -0,0 +1,27 @@ +note + description: "Summary description for {EWF_DEBUG_EXECUTION}." + author: "" + date: "$Date$" + revision: "$Revision$" + +class + EWF_DEBUG_EXECUTION + +inherit + WSF_EXECUTION + +create + make + +feature -- Execution + + execute + local + dbg: WSF_DEBUG_HANDLER + do + response.put_error ("DEBUG uri=" + request.request_uri + "%N") + create dbg.make + dbg.execute_starts_with ("", request, response) + end + +end diff --git a/examples/debug/src/ewf_debug_server.e b/examples/debug/src/ewf_debug_server.e index 3725bfc9..17f6f954 100644 --- a/examples/debug/src/ewf_debug_server.e +++ b/examples/debug/src/ewf_debug_server.e @@ -14,7 +14,7 @@ inherit initialize end - APPLICATION_LAUNCHER + APPLICATION_LAUNCHER [EWF_DEBUG_EXECUTION] create make_and_launch @@ -30,14 +30,14 @@ feature {NONE} -- Initialization -- set_service_option ("base", "/www-debug/debug_service.fcgi/") end - execute (req: WSF_REQUEST; res: WSF_RESPONSE) - local - dbg: WSF_DEBUG_HANDLER - do - res.put_error ("DEBUG" + req.request_uri + "%N") - create dbg.make - dbg.execute_starts_with ("", req, res) - end +-- execute (req: WSF_REQUEST; res: WSF_RESPONSE) +-- local +-- dbg: WSF_DEBUG_HANDLER +-- do +-- res.put_error ("OH NO uri=" + req.request_uri + "%N") +-- create dbg.make +-- dbg.execute_starts_with ("", req, res) +-- end end diff --git a/examples/simple/simple.ecf b/examples/simple/simple.ecf index d0fccfd8..4bf050c9 100644 --- a/examples/simple/simple.ecf +++ b/examples/simple/simple.ecf @@ -13,6 +13,14 @@ + + + + + + - - + + diff --git a/examples/simple_file/service_file_execution.e b/examples/simple_file/service_file_execution.e new file mode 100644 index 00000000..4fc0aacf --- /dev/null +++ b/examples/simple_file/service_file_execution.e @@ -0,0 +1,26 @@ +note + description: "Summary description for {SERVICE_FILE_EXECUTION}." + author: "" + date: "$Date$" + revision: "$Revision$" + +class + SERVICE_FILE_EXECUTION + +inherit + WSF_EXECUTION + +create + make + +feature {NONE} -- Initialization + + execute + local + f: WSF_FILE_RESPONSE + do + create f.make_html ("home.html") + response.send (f) + end + +end 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 f330b4ab..d5c95cf0 100644 --- a/library/server/ewsgi/connectors/cgi/src/wgi_cgi_connector.e +++ b/library/server/ewsgi/connectors/cgi/src/wgi_cgi_connector.e @@ -4,21 +4,11 @@ note revision: "$Revision$" class - WGI_CGI_CONNECTOR + WGI_CGI_CONNECTOR [G -> WGI_EXECUTION create make end] inherit WGI_CONNECTOR -create - make - -feature {NONE} -- Initialization - - make (a_service: like service) - do - service := a_service - end - feature -- Access Name: STRING_8 = "CGI" @@ -27,24 +17,23 @@ feature -- Access Version: STRING_8 = "0.1" -- Version of Current connector -feature {NONE} -- Access - - service: WGI_SERVICE - -- Gateway Service - feature -- Execution launch local req: WGI_REQUEST_FROM_TABLE res: detachable WGI_RESPONSE_STREAM + exec: detachable WGI_EXECUTION rescued: BOOLEAN do if not rescued then create req.make ((create {EXECUTION_ENVIRONMENT}).starting_environment, create {WGI_CGI_INPUT_STREAM}.make, Current) create res.make (create {WGI_CGI_OUTPUT_STREAM}.make, create {WGI_CGI_ERROR_STREAM}.make) - service.execute (req, res) + create {G} exec.make (req, res) + exec.execute + res.flush res.push + exec.clean else if attached (create {EXCEPTION_MANAGER}).last_exception as e and then attached e.exception_trace as l_trace then if res /= Void then @@ -59,6 +48,9 @@ feature -- Execution res.push end end + if exec /= Void then + exec.clean + end end rescue if not rescued then diff --git a/library/server/ewsgi/connectors/httpd/dev/httpd_connector_dev.e b/library/server/ewsgi/connectors/httpd/dev/httpd_connector_dev.e index a12bc301..9353f5c3 100644 --- a/library/server/ewsgi/connectors/httpd/dev/httpd_connector_dev.e +++ b/library/server/ewsgi/connectors/httpd/dev/httpd_connector_dev.e @@ -17,33 +17,16 @@ feature {NONE} -- Initialization make -- Initialize `Current'. local - server: separate HTTPD_SERVER - fac: separate WSF_HTTPD_REQUEST_HANDLER_FACTORY [APP_WSF_EXECUTION] + conn: WGI_HTTPD_CONNECTOR [APP_WSF_EXECUTION] do - print ("Hello%N") - create fac - create server.make (fac) - launch_server (server) + print ("Starting httpd server ...%N") + + create conn.make + conn.set_port_number (9090) + conn.set_max_concurrent_connections (100) + conn.launch end - launch_server (server: separate HTTPD_SERVER) - do - server.configuration.set_max_concurrent_connections (100) - server.configuration.set_http_server_port (9090) - server.launch - end - -feature -- Status - -feature -- Access - -feature -- Change - -feature {NONE} -- Implementation - -invariant --- invariant_clause: True - note copyright: "2011-2015, 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/server/ewsgi/connectors/httpd/httpd-safe.ecf b/library/server/ewsgi/connectors/httpd/httpd-safe.ecf index c308c705..cd28afb9 100644 --- a/library/server/ewsgi/connectors/httpd/httpd-safe.ecf +++ b/library/server/ewsgi/connectors/httpd/httpd-safe.ecf @@ -7,8 +7,9 @@ /\.git$ /\.svn$ - @@ -31,13 +32,12 @@ - - /concurrency$ + /ssl$ /EIFGENs$ /no_ssl$ - /ssl$ + /concurrency$ @@ -73,11 +73,12 @@ - + diff --git a/library/server/ewsgi/connectors/httpd/src/httpd/concurrency/none/httpd_connection_handler.e b/library/server/ewsgi/connectors/httpd/src/httpd/concurrency/none/httpd_connection_handler.e index f420c4d7..54ca8b74 100644 --- a/library/server/ewsgi/connectors/httpd/src/httpd/concurrency/none/httpd_connection_handler.e +++ b/library/server/ewsgi/connectors/httpd/src/httpd/concurrency/none/httpd_connection_handler.e @@ -42,7 +42,7 @@ feature -- Execution cl := h.client_socket a_listening_socket.accept_to (cl) if h.is_connected then - h.execute + h.safe_execute end else check is_not_full: False end diff --git a/library/server/ewsgi/connectors/httpd/src/httpd/httpd_server_i.e b/library/server/ewsgi/connectors/httpd/src/httpd/httpd_server_i.e index c8b0f494..86205296 100644 --- a/library/server/ewsgi/connectors/httpd/src/httpd/httpd_server_i.e +++ b/library/server/ewsgi/connectors/httpd/src/httpd/httpd_server_i.e @@ -16,6 +16,8 @@ feature {NONE} -- Initialization make (a_factory: like factory) -- `a_cfg': server configuration -- `a_factory': connection handler builder + require + fac_is_separated: {PLATFORM}.is_scoop_capable implies not attached {HTTPD_REQUEST_HANDLER_FACTORY} a_factory do make_configured (create {like configuration}.make, a_factory) end diff --git a/library/server/ewsgi/connectors/httpd/src/wgi_httpd_connector.e b/library/server/ewsgi/connectors/httpd/src/wgi_httpd_connector.e new file mode 100644 index 00000000..639f6e21 --- /dev/null +++ b/library/server/ewsgi/connectors/httpd/src/wgi_httpd_connector.e @@ -0,0 +1,183 @@ +note + description: "Summary description for {WGI_HTTPD_CONNECTOR}." + author: "" + todo: "[ + Check if server and configuration has to be 'separate' ? + currently yes, due to WGI_REQUEST.wgi_connector setting. + But we may get rid of this one... + See `{WGI_REQUEST}.wgi_connector' and `{WSF_REQUEST}.wgi_connector' ... + ]" + date: "$Date$" + revision: "$Revision$" + +class + WGI_HTTPD_CONNECTOR [G -> WGI_EXECUTION create make end] + +inherit + WGI_CONNECTOR + +create + make, + make_with_base + +feature {NONE} -- Initialization + + make + local + fac: separate WGI_HTTPD_REQUEST_HANDLER_FACTORY [G] + do + -- Callbacks + create on_launched_actions + create on_stopped_actions + + -- Server + create fac + create server.make (fac) + configuration := server_configuration (server) + + set_factory_connector (Current, fac) + end + + make_with_base (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 ("/") + do + make + set_base (a_base) + end + + set_factory_connector (conn: detachable separate WGI_CONNECTOR; fac: separate WGI_HTTPD_REQUEST_HANDLER_FACTORY [G]) + do + fac.set_connector (conn) + end + +feature -- Access + + name: STRING_8 = "httpd" + -- Name of Current connector + + version: STRING_8 = "0.1" + -- Version of Current connector + +feature -- Access + + server: separate HTTPD_SERVER + + configuration: separate HTTPD_CONFIGURATION + + server_configuration (a_server: like server): like configuration + do + Result := a_server.configuration + end + +feature -- Access + + base: detachable READABLE_STRING_8 + -- Root url base + +feature -- Status report + + launched: BOOLEAN + -- Server launched and listening on `port' + + port: INTEGER + -- Listening port. + --| 0: not launched + +feature -- Callbacks + + on_launched_actions: ACTION_SEQUENCE [TUPLE [WGI_CONNECTOR]] + -- Actions triggered when launched + + on_stopped_actions: ACTION_SEQUENCE [TUPLE [WGI_CONNECTOR]] + -- Actions triggered when stopped + +feature -- Element change + + on_launched (a_port: INTEGER) + -- Server launched + do + launched := True + port := a_port + on_launched_actions.call ([Current]) + end + + on_stopped + -- Server stopped + do + on_stopped_actions.call ([Current]) + launched := False + port := 0 + end + +feature -- Element change + + set_base (b: like base) + require + b_starts_with_slash: (b /= Void and then not b.is_empty) implies b.starts_with ("/") + do + base := b + ensure + valid_base: (attached base as l_base and then not l_base.is_empty) implies l_base.starts_with ("/") + end + + set_port_number (a_port_number: INTEGER) + require + a_port_number_positive_or_zero: a_port_number >= 0 + do + set_port_on_configuration (a_port_number, configuration) + end + + set_max_concurrent_connections (nb: INTEGER) + do + + end + +feature {NONE} -- Implementation + + set_port_on_configuration (a_port_number: INTEGER; cfg: like configuration) + do + cfg.set_http_server_port (a_port_number) + end + + set_max_concurrent_connections_on_configuration (nb: INTEGER; cfg: like configuration) + do + cfg.set_max_concurrent_connections (nb) + end + +feature -- Server + + launch + do + launched := False + port := 0 + launch_server (server) + end + + configure_server (a_configuration: like configuration) + do + if a_configuration.is_verbose then + if attached base as l_base then + io.error.put_string ("Base=" + l_base + "%N") + end + end + end + + launch_server (a_server: like server) + do + configure_server (a_server.configuration) + a_server.launch + end + +note + copyright: "2011-2015, Jocelyn Fiat, Javier Velilla, 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/httpd/src/wgi_httpd_input_stream.e b/library/server/ewsgi/connectors/httpd/src/wgi_httpd_input_stream.e index 878db547..ce34a558 100644 --- a/library/server/ewsgi/connectors/httpd/src/wgi_httpd_input_stream.e +++ b/library/server/ewsgi/connectors/httpd/src/wgi_httpd_input_stream.e @@ -22,7 +22,7 @@ feature {NONE} -- Initialization set_source (a_source) end -feature {WGI_NINO_CONNECTOR, WGI_SERVICE} -- Nino +feature {WGI_HTTPD_CONNECTOR, WGI_SERVICE} -- Nino set_source (i: like source) do diff --git a/library/server/ewsgi/connectors/httpd/src/wgi_httpd_output_stream.e b/library/server/ewsgi/connectors/httpd/src/wgi_httpd_output_stream.e index a57095cf..c581bc79 100644 --- a/library/server/ewsgi/connectors/httpd/src/wgi_httpd_output_stream.e +++ b/library/server/ewsgi/connectors/httpd/src/wgi_httpd_output_stream.e @@ -26,7 +26,7 @@ feature {NONE} -- Initialization set_target (a_target) end -feature {WGI_NINO_CONNECTOR, WGI_SERVICE} -- Nino +feature {WGI_HTTPD_CONNECTOR, WGI_SERVICE} -- Nino set_target (o: like target) do diff --git a/library/server/ewsgi/connectors/httpd/dev/wsf/wsf_httpd_request_handler.e b/library/server/ewsgi/connectors/httpd/src/wgi_httpd_request_handler.e similarity index 88% rename from library/server/ewsgi/connectors/httpd/dev/wsf/wsf_httpd_request_handler.e rename to library/server/ewsgi/connectors/httpd/src/wgi_httpd_request_handler.e index c5730b33..f0bdc24a 100644 --- a/library/server/ewsgi/connectors/httpd/dev/wsf/wsf_httpd_request_handler.e +++ b/library/server/ewsgi/connectors/httpd/src/wgi_httpd_request_handler.e @@ -1,11 +1,11 @@ note - description: "Summary description for {WSF_HTTPD_REQUEST_HANDLER}." + description: "Summary description for {WGI_HTTPD_REQUEST_HANDLER}." author: "" date: "$Date$" revision: "$Revision$" class - WSF_HTTPD_REQUEST_HANDLER [G -> WSF_EXECUTION create make end] + WGI_HTTPD_REQUEST_HANDLER [G -> WGI_EXECUTION create make end] inherit HTTPD_REQUEST_HANDLER @@ -15,7 +15,18 @@ inherit REFACTORING_HELPER create - make + make, + make_with_connector + +feature {NONE} -- Initialization + + make_with_connector (conn: like connector) + do + make + connector := conn + end + + connector: detachable separate WGI_CONNECTOR feature -- Request processing @@ -27,8 +38,7 @@ feature -- Request processing l_error: WGI_ERROR_STREAM req: WGI_REQUEST_FROM_TABLE res: detachable WGI_HTTPD_RESPONSE_STREAM - - exec: WSF_EXECUTION + exec: detachable WGI_EXECUTION retried: BOOLEAN do if not retried then @@ -36,15 +46,33 @@ feature -- Request processing create {WGI_HTTPD_OUTPUT_STREAM} l_output.make (a_socket) create {WGI_HTTPD_ERROR_STREAM} l_error.make_stderr (a_socket.descriptor.out) - create req.make (httpd_environment (a_socket), l_input, Void) + create req.make (httpd_environment (a_socket), l_input, connector) create res.make (l_output, l_error) req.set_meta_string_variable ("RAW_HEADER_DATA", request_header) - exec := new_execution (req, res) + create {G} exec.make (req, res) exec.execute + res.flush res.push + exec.clean 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.set_status_code ({HTTP_STATUS_CODE}.internal_server_error, Void) + end + if res.message_writable then + res.put_string ("
")
+							res.put_string (l_trace)
+							res.put_string ("
") + end + res.push + end + end + if exec /= Void then + exec.clean + end end rescue if not retried then @@ -53,11 +81,6 @@ feature -- Request processing end end - new_execution (req: WGI_REQUEST; res: WGI_RESPONSE): WSF_EXECUTION - do - create {G} Result.make (req, res) - end - base: detachable READABLE_STRING_8 do --TODO diff --git a/library/server/ewsgi/connectors/httpd/src/wgi_httpd_request_handler_factory.e b/library/server/ewsgi/connectors/httpd/src/wgi_httpd_request_handler_factory.e new file mode 100644 index 00000000..c2b2d5ef --- /dev/null +++ b/library/server/ewsgi/connectors/httpd/src/wgi_httpd_request_handler_factory.e @@ -0,0 +1,41 @@ +note + description: "Summary description for {WGI_HTTPD_REQUEST_HANDLER_FACTORY}." + author: "" + date: "$Date$" + revision: "$Revision$" + +class + WGI_HTTPD_REQUEST_HANDLER_FACTORY [G -> WGI_EXECUTION create make end] + +inherit + HTTPD_REQUEST_HANDLER_FACTORY + +feature -- Access + + connector: detachable separate WGI_CONNECTOR + +feature -- Element change + + set_connector (conn: like connector) + do + connector := conn + end + +feature -- Factory + + new_handler: separate WGI_HTTPD_REQUEST_HANDLER [G] + do + create Result.make_with_connector (connector) + end + +note + copyright: "2011-2015, Jocelyn Fiat, Javier Velilla, 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/libfcgi/src/wgi_libfcgi_connector.e b/library/server/ewsgi/connectors/libfcgi/src/wgi_libfcgi_connector.e index 2bb63746..1b994d85 100644 --- a/library/server/ewsgi/connectors/libfcgi/src/wgi_libfcgi_connector.e +++ b/library/server/ewsgi/connectors/libfcgi/src/wgi_libfcgi_connector.e @@ -6,19 +6,19 @@ note revision: "$Revision$" class - WGI_LIBFCGI_CONNECTOR + WGI_LIBFCGI_CONNECTOR [G -> WGI_EXECUTION create make end] inherit WGI_CONNECTOR - -create - make + redefine + default_create + end feature {NONE} -- Initialization - make (a_service: like service) + default_create do - service := a_service + Precursor create fcgi.make create input.make (fcgi) create output.make (fcgi) @@ -32,11 +32,6 @@ feature -- Access Version: STRING_8 = "0.1" -- Version of Current connector -feature {NONE} -- Access - - service: WGI_SERVICE - -- Gateway Service - feature -- Server launch @@ -59,14 +54,18 @@ feature -- Execution local req: WGI_REQUEST_FROM_TABLE res: detachable WGI_RESPONSE_STREAM + exec: detachable WGI_EXECUTION rescued: BOOLEAN do if not rescued then a_input.reset create req.make (vars, a_input, Current) create res.make (a_output, a_output) - service.execute (req, res) + create {G} exec.make (req, res) + exec.execute + res.flush res.push + exec.clean else if attached (create {EXCEPTION_MANAGER}).last_exception as e and then attached e.exception_trace as l_trace then if res /= Void then @@ -81,6 +80,9 @@ feature -- Execution res.push end end + if exec /= Void then + exec.clean + end end rescue if not rescued then 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 431001af..03696fd6 100644 --- a/library/server/ewsgi/connectors/nino/src/wgi_nino_connector.e +++ b/library/server/ewsgi/connectors/nino/src/wgi_nino_connector.e @@ -4,7 +4,7 @@ note revision: "$Revision$" class - WGI_NINO_CONNECTOR + WGI_NINO_CONNECTOR [G -> WGI_EXECUTION create make end] inherit WGI_CONNECTOR @@ -118,7 +118,7 @@ feature -- Server do launched := False port := 0 - create {WGI_NINO_HANDLER} l_http_handler.make_with_callback (server, Current) + create {WGI_NINO_HANDLER [G]} l_http_handler.make_with_callback (server, Current) if configuration.is_verbose then if attached base as l_base then io.error.put_string ("Base=" + l_base + "%N") @@ -128,17 +128,40 @@ feature -- Server end process_request (env: STRING_TABLE [READABLE_STRING_8]; a_headers_text: STRING; a_socket: TCP_STREAM_SOCKET) + -- Process request ... local req: WGI_REQUEST_FROM_TABLE res: detachable WGI_NINO_RESPONSE_STREAM + exec: detachable WGI_EXECUTION retried: BOOLEAN do if not retried then create req.make (env, create {WGI_NINO_INPUT_STREAM}.make (a_socket), Current) create res.make (create {WGI_NINO_OUTPUT_STREAM}.make (a_socket), create {WGI_NINO_ERROR_STREAM}.make_stderr (a_socket.descriptor.out)) req.set_meta_string_variable ("RAW_HEADER_DATA", a_headers_text) - service.execute (req, res) + + create {G} exec.make (req, res) + exec.execute + res.flush res.push + exec.clean + 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.set_status_code ({HTTP_STATUS_CODE}.internal_server_error, Void) + end + if res.message_writable then + res.put_string ("
")
+							res.put_string (l_trace)
+							res.put_string ("
") + end + res.push + end + end + if exec /= Void then + exec.clean + end end rescue if not retried then diff --git a/library/server/ewsgi/connectors/nino/src/wgi_nino_handler.e b/library/server/ewsgi/connectors/nino/src/wgi_nino_handler.e index 528a48c1..d1bd11db 100644 --- a/library/server/ewsgi/connectors/nino/src/wgi_nino_handler.e +++ b/library/server/ewsgi/connectors/nino/src/wgi_nino_handler.e @@ -5,7 +5,7 @@ note revision : "$Revision$" class - WGI_NINO_HANDLER + WGI_NINO_HANDLER [G -> WGI_EXECUTION create make end] inherit HTTP_CONNECTION_HANDLER @@ -27,7 +27,7 @@ feature {NONE} -- Initialization callback := a_callback end - callback: WGI_NINO_CONNECTOR + callback: WGI_NINO_CONNECTOR [G] feature -- Access diff --git a/library/server/ewsgi/specification/request/wgi_request.e b/library/server/ewsgi/specification/request/wgi_request.e index 85a9660e..00c57111 100644 --- a/library/server/ewsgi/specification/request/wgi_request.e +++ b/library/server/ewsgi/specification/request/wgi_request.e @@ -157,7 +157,7 @@ feature -- Eiffel WGI access deferred end - wgi_connector: detachable WGI_CONNECTOR + wgi_connector: detachable separate WGI_CONNECTOR -- Associated Eiffel WGI connector deferred end diff --git a/library/server/ewsgi/specification/service/wgi_service.e b/library/server/ewsgi/specification/service/wgi_service.e index 910bbc42..e13d9468 100644 --- a/library/server/ewsgi/specification/service/wgi_service.e +++ b/library/server/ewsgi/specification/service/wgi_service.e @@ -11,20 +11,6 @@ note deferred class WGI_SERVICE -feature {WGI_CONNECTOR} -- Execution - - execute (req: WGI_REQUEST; res: WGI_RESPONSE) - -- Execute the request - -- See `req.input' for input stream - -- `req.meta_variables' for the CGI meta variable - -- and `res' for output buffer - require - res_status_unset: not res.status_is_set - deferred - ensure - res_status_set: res.status_is_set - 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/server/ewsgi/src/implementation/wgi_request_from_table.e b/library/server/ewsgi/src/implementation/wgi_request_from_table.e index 988d0c99..8a0b30cc 100644 --- a/library/server/ewsgi/src/implementation/wgi_request_from_table.e +++ b/library/server/ewsgi/src/implementation/wgi_request_from_table.e @@ -57,7 +57,7 @@ feature -- EWSGI access wgi_implementation: STRING = "Eiffel Web Framework 0.1" - wgi_connector: detachable WGI_CONNECTOR + wgi_connector: detachable separate WGI_CONNECTOR feature -- Access: CGI meta parameters diff --git a/library/server/ewsgi/src/wgi_execution.e b/library/server/ewsgi/src/wgi_execution.e new file mode 100644 index 00000000..204be494 --- /dev/null +++ b/library/server/ewsgi/src/wgi_execution.e @@ -0,0 +1,54 @@ +note + description: "Summary description for {WGI_EXECUTION}." + author: "" + date: "$Date$" + revision: "$Revision$" + +deferred class + WGI_EXECUTION + +--create +-- make + +feature {NONE} -- Initialization + + make (req: WGI_REQUEST; res: WGI_RESPONSE) + do + request := req + response := res + end + +feature {NONE} -- Access + + request: WGI_REQUEST + + response: WGI_RESPONSE + +feature -- Execution + + execute + -- Execute the request based on `request' and `response'. + deferred + ensure + status_is_set: response.status_is_set + end + +feature -- Cleaning + + clean + -- Clean request data. + do + end + + +note + copyright: "2011-2015, Jocelyn Fiat, Javier Velilla, 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/wsf/connector/cgi/wsf_cgi_service_launcher.e b/library/server/wsf/connector/cgi/wsf_cgi_service_launcher.e index 9d7693af..b82e1680 100644 --- a/library/server/wsf/connector/cgi/wsf_cgi_service_launcher.e +++ b/library/server/wsf/connector/cgi/wsf_cgi_service_launcher.e @@ -18,40 +18,36 @@ note revision: "$Revision$" class - WSF_CGI_SERVICE_LAUNCHER + WSF_CGI_SERVICE_LAUNCHER [G -> WSF_EXECUTION create make end] inherit - WSF_SERVICE_LAUNCHER + WSF_SERVICE_LAUNCHER [G] create make, - make_and_launch, - make_callback, - make_callback_and_launch - + make_and_launch + feature {NONE} -- Initialization initialize do - create connector.make (Current) + create connector end feature -- Execution launch do - if attached connector as conn then - conn.launch - end + connector.launch end feature -- Status report - connector: detachable WGI_CGI_CONNECTOR + connector: WGI_CGI_CONNECTOR [G] -- Default service name ;note - copyright: "2011-2012, Jocelyn Fiat, Javier Velilla, Eiffel Software and others" + copyright: "2011-2015, Jocelyn Fiat, Javier Velilla, 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/wsf/connector/httpd-safe.ecf b/library/server/wsf/connector/httpd-safe.ecf new file mode 100644 index 00000000..c5d577f6 --- /dev/null +++ b/library/server/wsf/connector/httpd-safe.ecf @@ -0,0 +1,22 @@ + + + + + + /EIFGENs$ + /\.git$ + /\.svn$ + + + + + + + + + + + + + diff --git a/library/server/wsf/connector/httpd/wsf_httpd_service_launcher.e b/library/server/wsf/connector/httpd/wsf_httpd_service_launcher.e new file mode 100644 index 00000000..4644ae61 --- /dev/null +++ b/library/server/wsf/connector/httpd/wsf_httpd_service_launcher.e @@ -0,0 +1,168 @@ +note + description: "[ + Component to launch the service using the default connector + + Eiffel Web httpd for this class + + + The httpd default connector support options: + port: numeric such as 8099 (or equivalent string as "8099") + base: base_url (very specific to standalone server) + verbose: to display verbose output, useful for Nino + force_single_threaded: use only one thread, useful for Nino + + check WSF_SERVICE_LAUNCHER for more documentation + ]" + date: "$Date$" + revision: "$Revision$" + +class + WSF_HTTPD_SERVICE_LAUNCHER [G -> WSF_EXECUTION create make end] + +inherit + WSF_SERVICE_LAUNCHER [G] + redefine + launchable + end + +create + make, + make_and_launch + +feature {NONE} -- Initialization + + initialize + local + conn: like connector + do + create on_launched_actions + create on_stopped_actions + + port_number := 80 --| Default, but quite often, this port is already used ... + base_url := "" + + if attached options as opts then + if attached {READABLE_STRING_GENERAL} opts.option ("server_name") as l_server_name then + server_name := l_server_name.to_string_8 + end + if attached {INTEGER} opts.option ("port") as l_port then + port_number := l_port + elseif + attached {READABLE_STRING_GENERAL} opts.option ("port") as l_port_str and then + l_port_str.is_integer + then + port_number := l_port_str.as_string_8.to_integer + end + if attached {READABLE_STRING_GENERAL} opts.option ("base") as l_base_str then + base_url := l_base_str.as_string_8 + end + if attached {BOOLEAN} opts.option ("force_single_threaded") as l_single_threaded then + single_threaded := l_single_threaded + elseif attached {READABLE_STRING_GENERAL} opts.option ("force_single_threaded") as l_single_threaded_str then + single_threaded := l_single_threaded_str.as_lower.same_string ("true") + end + if attached {BOOLEAN} opts.option ("verbose") as l_verbose then + verbose := l_verbose + elseif attached {READABLE_STRING_GENERAL} opts.option ("verbose") as l_verbose_str then + verbose := l_verbose_str.as_lower.same_string ("true") + end + end + + create conn.make + connector := conn + conn.on_launched_actions.extend (agent on_launched) + conn.on_stopped_actions.extend (agent on_stopped) + conn.set_base (base_url) + + update_configuration (conn.configuration) + end + +feature -- Execution + + update_configuration (cfg: separate HTTPD_CONFIGURATION) + do + if single_threaded then + cfg.set_force_single_threaded (True) + end + cfg.set_is_verbose (verbose) + if attached server_name as l_server_name then + cfg.set_http_server_name (l_server_name) + end +-- conn.set_port_number (port_number) + cfg.http_server_port := port_number + end + + launch + -- + -- using `port_number', `base_url', `verbose' and `single_threaded' + local + conn: like connector + do + conn := connector + conn.set_base (base_url) + debug ("nino") + if verbose then + io.error.put_string ("Launching Nino web server on port " + port_number.out) + if attached server_name as l_name then + io.error.put_string ("%N http://" + l_name + ":" + port_number.out + "/" + base_url + "%N") + else + io.error.put_string ("%N http://localhost:" + port_number.out + "/" + base_url + "%N") + end + end + end + update_configuration (conn.configuration) + conn.launch + end + +feature -- Callback + + on_launched_actions: ACTION_SEQUENCE [TUPLE [WGI_CONNECTOR]] + -- Actions triggered when launched + + on_stopped_actions: ACTION_SEQUENCE [TUPLE [WGI_CONNECTOR]] + -- Actions triggered when stopped + +feature {NONE} -- Implementation + + on_launched (conn: WGI_CONNECTOR) + do + on_launched_actions.call ([conn]) + end + + on_stopped (conn: WGI_CONNECTOR) + do + on_stopped_actions.call ([conn]) + end + + port_number: INTEGER + + server_name: detachable READABLE_STRING_8 + + base_url: READABLE_STRING_8 + + verbose: BOOLEAN + + single_threaded: BOOLEAN + +feature -- Status report + + connector: WGI_HTTPD_CONNECTOR [G] + -- Default connector + + launchable: BOOLEAN + do + Result := Precursor and port_number >= 0 + end + +;note + copyright: "2011-2015, Jocelyn Fiat, Javier Velilla, 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/wsf/connector/libfcgi/wsf_libfcgi_service_launcher.e b/library/server/wsf/connector/libfcgi/wsf_libfcgi_service_launcher.e index 5eca65f0..284b3d71 100644 --- a/library/server/wsf/connector/libfcgi/wsf_libfcgi_service_launcher.e +++ b/library/server/wsf/connector/libfcgi/wsf_libfcgi_service_launcher.e @@ -18,40 +18,36 @@ note revision: "$Revision$" class - WSF_LIBFCGI_SERVICE_LAUNCHER + WSF_LIBFCGI_SERVICE_LAUNCHER [G -> WSF_EXECUTION create make end] inherit - WSF_SERVICE_LAUNCHER + WSF_SERVICE_LAUNCHER [G] create make, - make_and_launch, - make_callback, - make_callback_and_launch + make_and_launch feature {NONE} -- Initialization initialize do - create connector.make (Current) + create connector end feature -- Execution launch do - if attached connector as conn then - conn.launch - end + connector.launch end feature -- Status report - connector: detachable WGI_LIBFCGI_CONNECTOR + connector: WGI_LIBFCGI_CONNECTOR [G] -- Default service name ;note - copyright: "2011-2012, Jocelyn Fiat, Javier Velilla, Eiffel Software and others" + copyright: "2011-2015, Jocelyn Fiat, Javier Velilla, 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/wsf/connector/nino/wsf_nino_service_launcher.e b/library/server/wsf/connector/nino/wsf_nino_service_launcher.e index 7fa62a9e..553f20fe 100644 --- a/library/server/wsf/connector/nino/wsf_nino_service_launcher.e +++ b/library/server/wsf/connector/nino/wsf_nino_service_launcher.e @@ -17,19 +17,17 @@ note revision: "$Revision$" class - WSF_NINO_SERVICE_LAUNCHER + WSF_NINO_SERVICE_LAUNCHER [G -> WSF_EXECUTION create make end] inherit - WSF_SERVICE_LAUNCHER + WSF_SERVICE_LAUNCHER [G] redefine launchable end create make, - make_and_launch, - make_callback, - make_callback_and_launch + make_and_launch feature {NONE} -- Initialization @@ -70,9 +68,10 @@ feature {NONE} -- Initialization end end create conn.make (Current) + connector := conn + conn.on_launched_actions.extend (agent on_launched) conn.on_stopped_actions.extend (agent on_stopped) - connector := conn conn.set_base (base_url) if single_threaded then conn.configuration.set_force_single_threaded (True) @@ -85,29 +84,30 @@ feature -- Execution launch -- -- using `port_number', `base_url', `verbose' and `single_threaded' + local + conn: like connector do - if attached connector as conn then - conn.set_base (base_url) - if single_threaded then - conn.configuration.set_force_single_threaded (True) - end - conn.configuration.set_is_verbose (verbose) - debug ("nino") - if verbose then - io.error.put_string ("Launching Nino web server on port " + port_number.out) - if attached server_name as l_name then - io.error.put_string ("%N http://" + l_name + ":" + port_number.out + "/" + base_url + "%N") - else - io.error.put_string ("%N http://localhost:" + port_number.out + "/" + base_url + "%N") - end + conn := connector + conn.set_base (base_url) + if single_threaded then + conn.configuration.set_force_single_threaded (True) + end + conn.configuration.set_is_verbose (verbose) + debug ("nino") + if verbose then + io.error.put_string ("Launching Nino web server on port " + port_number.out) + if attached server_name as l_name then + io.error.put_string ("%N http://" + l_name + ":" + port_number.out + "/" + base_url + "%N") + else + io.error.put_string ("%N http://localhost:" + port_number.out + "/" + base_url + "%N") end end - if attached server_name as l_server_name then - conn.configuration.set_http_server_name (l_server_name) - end - conn.configuration.http_server_port := port_number - conn.launch end + if attached server_name as l_server_name then + conn.configuration.set_http_server_name (l_server_name) + end + conn.configuration.http_server_port := port_number + conn.launch end feature -- Callback @@ -142,7 +142,7 @@ feature {NONE} -- Implementation feature -- Status report - connector: detachable WGI_NINO_CONNECTOR + connector: WGI_NINO_CONNECTOR [G] -- Default connector launchable: BOOLEAN @@ -151,7 +151,7 @@ feature -- Status report end ;note - copyright: "2011-2013, Jocelyn Fiat, Javier Velilla, Eiffel Software and others" + copyright: "2011-2015, Jocelyn Fiat, Javier Velilla, 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/wsf/default/cgi/wsf_default_service_launcher.e b/library/server/wsf/default/cgi/wsf_default_service_launcher.e index 9c2df057..a6ba4e6c 100644 --- a/library/server/wsf/default/cgi/wsf_default_service_launcher.e +++ b/library/server/wsf/default/cgi/wsf_default_service_launcher.e @@ -5,19 +5,17 @@ note revision: "$Revision$" class - WSF_DEFAULT_SERVICE_LAUNCHER + WSF_DEFAULT_SERVICE_LAUNCHER [G -> WSF_EXECUTION create make end] inherit - WSF_CGI_SERVICE_LAUNCHER + WSF_CGI_SERVICE_LAUNCHER [G] create make, - make_and_launch, - make_callback, - make_callback_and_launch + make_and_launch note - copyright: "2011-2012, Jocelyn Fiat, Javier Velilla, Eiffel Software and others" + copyright: "2011-2015, Jocelyn Fiat, Javier Velilla, 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/wsf/default/httpd-safe.ecf b/library/server/wsf/default/httpd-safe.ecf new file mode 100644 index 00000000..c60d7c8e --- /dev/null +++ b/library/server/wsf/default/httpd-safe.ecf @@ -0,0 +1,17 @@ + + + + + + /EIFGENs$ + /\.git$ + /\.svn$ + + + + + + + + diff --git a/library/server/wsf/default/httpd/wsf_default_response_service.e b/library/server/wsf/default/httpd/wsf_default_response_service.e new file mode 100644 index 00000000..0cefc7da --- /dev/null +++ b/library/server/wsf/default/httpd/wsf_default_response_service.e @@ -0,0 +1,24 @@ +note + description: "Summary description for {WSF_DEFAULT_RESPONSE_SERVICE}." + date: "$Date$" + revision: "$Revision$" + +deferred class + WSF_DEFAULT_RESPONSE_SERVICE + +inherit + WSF_DEFAULT_SERVICE + + WSF_RESPONSE_SERVICE + +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)" + 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/wsf/default/httpd/wsf_default_service.e b/library/server/wsf/default/httpd/wsf_default_service.e new file mode 100644 index 00000000..a19fb656 --- /dev/null +++ b/library/server/wsf/default/httpd/wsf_default_service.e @@ -0,0 +1,22 @@ +note + description: "Summary description for {WSF_DEFAULT_SERVICE}." + date: "$Date$" + revision: "$Revision$" + +deferred class + WSF_DEFAULT_SERVICE [G -> WSF_EXECUTION create make end] + +inherit + WSF_DEFAULT_SERVICE_I [WSF_DEFAULT_SERVICE_LAUNCHER [G]] + +note + copyright: "2011-2015, Jocelyn Fiat, Javier Velilla, 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/httpd/dev/wsf/wsf_httpd_request_handler_factory.e b/library/server/wsf/default/httpd/wsf_default_service_launcher.e similarity index 59% rename from library/server/ewsgi/connectors/httpd/dev/wsf/wsf_httpd_request_handler_factory.e rename to library/server/wsf/default/httpd/wsf_default_service_launcher.e index 94b667f4..3a91dafd 100644 --- a/library/server/ewsgi/connectors/httpd/dev/wsf/wsf_httpd_request_handler_factory.e +++ b/library/server/wsf/default/httpd/wsf_default_service_launcher.e @@ -1,21 +1,19 @@ note - description: "Summary description for {WSF_HTTPD_REQUEST_HANDLER_FACTORY}." - author: "" + description: "[ + Default launcher for WSF_SERVICE based on {WSF_HTTPD_SERVICE_LAUNCHER} + ]" date: "$Date$" revision: "$Revision$" class - WSF_HTTPD_REQUEST_HANDLER_FACTORY [G -> WSF_EXECUTION create make end] + WSF_DEFAULT_SERVICE_LAUNCHER [G -> WSF_EXECUTION create make end] inherit - HTTPD_REQUEST_HANDLER_FACTORY + WSF_HTTPD_SERVICE_LAUNCHER [G] -feature -- Factory - - new_handler: separate WSF_HTTPD_REQUEST_HANDLER [G] - do - create Result.make - end +create + make, + make_and_launch note copyright: "2011-2015, Jocelyn Fiat, Javier Velilla, Eiffel Software and others" @@ -27,4 +25,5 @@ note Website http://www.eiffel.com Customer support http://support.eiffel.com ]" + end diff --git a/library/server/wsf/default/nino/wsf_default_service.e b/library/server/wsf/default/nino/wsf_default_service.e index dd76ca78..c29c7047 100644 --- a/library/server/wsf/default/nino/wsf_default_service.e +++ b/library/server/wsf/default/nino/wsf_default_service.e @@ -4,10 +4,10 @@ note revision: "$Revision$" deferred class - WSF_DEFAULT_SERVICE + WSF_DEFAULT_SERVICE [G -> WSF_EXECUTION create make end] inherit - WSF_DEFAULT_SERVICE_I [WSF_DEFAULT_SERVICE_LAUNCHER] + WSF_DEFAULT_SERVICE_I [WSF_DEFAULT_SERVICE_LAUNCHER [G]] note copyright: "2011-2012, Jocelyn Fiat, Javier Velilla, Eiffel Software and others" diff --git a/library/server/wsf/default/nino/wsf_default_service_launcher.e b/library/server/wsf/default/nino/wsf_default_service_launcher.e index aab44c4f..01b0dc35 100644 --- a/library/server/wsf/default/nino/wsf_default_service_launcher.e +++ b/library/server/wsf/default/nino/wsf_default_service_launcher.e @@ -6,16 +6,14 @@ note revision: "$Revision$" class - WSF_DEFAULT_SERVICE_LAUNCHER + WSF_DEFAULT_SERVICE_LAUNCHER [G -> WSF_EXECUTION create make end] inherit - WSF_NINO_SERVICE_LAUNCHER + WSF_NINO_SERVICE_LAUNCHER [G] create make, - make_and_launch, - make_callback, - make_callback_and_launch + make_and_launch note copyright: "2011-2012, Jocelyn Fiat, Javier Velilla, Eiffel Software and others" diff --git a/library/server/wsf/extension/handler/wsf_debug_handler.e b/library/server/wsf/extension/handler/wsf_debug_handler.e index 55ef3cfd..d4b7d954 100644 --- a/library/server/wsf/extension/handler/wsf_debug_handler.e +++ b/library/server/wsf/extension/handler/wsf_debug_handler.e @@ -67,7 +67,11 @@ feature -- Access create p.make_with_body (s) - if {PLATFORM}.is_windows and req.wgi_connector.name.is_case_insensitive_equal ("cgi") then + if + {PLATFORM}.is_windows and then + attached req.wgi_connector as conn and then + is_cgi_connector (conn) + then --| FIXME: the CGI connector add %R for any single %N character, so update the Content-Length accordingly. -- Dirty hack to handle correctly CGI on Windows, since it seems "abc%N" will be sent as "abc%R%N" l_len := 0 @@ -96,9 +100,17 @@ feature -- Access res.send (p) end + is_cgi_connector (conn: separate WGI_CONNECTOR): BOOLEAN + local + s: STRING + do + create s.make_from_separate (conn.name) + Result := s.is_case_insensitive_equal_general ("cgi") + end + note - copyright: "2011-2014, Jocelyn Fiat, Javier Velilla, Olivier Ligot, Colin Adams, Eiffel Software and others" + copyright: "2011-2015, Jocelyn Fiat, Javier Velilla, Olivier Ligot, Colin Adams, 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/wsf/extension/wsf_debug_information.e b/library/server/wsf/extension/wsf_debug_information.e index e320fd2f..5854ca93 100644 --- a/library/server/wsf/extension/wsf_debug_information.e +++ b/library/server/wsf/extension/wsf_debug_information.e @@ -61,12 +61,32 @@ feature -- Execution a_output.append (" version=") a_output.append (req.wgi_version) a_output.append (" connector=%"") - a_output.append (req.wgi_connector.name) - a_output.append (" connector-version=") - a_output.append (req.wgi_connector.version) + if attached req.wgi_connector as conn then + append_connector_name_to (conn, a_output) + a_output.append ("%" connector-version=") + append_connector_version_to (conn, a_output) + else + a_output.append ("none") + end a_output.append (eol) end + append_connector_name_to (conn: separate WGI_CONNECTOR; a_output: STRING) + local + s: STRING + do + create s.make_from_separate (conn.name) + a_output.append (s) + end + + append_connector_version_to (conn: separate WGI_CONNECTOR; a_output: STRING) + local + s: STRING + do + create s.make_from_separate (conn.version) + a_output.append (s) + end + append_cgi_variables_to (req: WSF_REQUEST; res: WSF_RESPONSE; a_output: STRING) do a_output.append ("CGI variables:") @@ -385,7 +405,7 @@ feature -- Constants invariant note - copyright: "2011-2014, Jocelyn Fiat, Javier Velilla, Olivier Ligot, Colin Adams, Eiffel Software and others" + copyright: "2011-2015, Jocelyn Fiat, Javier Velilla, Olivier Ligot, Colin Adams, 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/wsf/src/service/wsf_default_service_i.e b/library/server/wsf/src/service/wsf_default_service_i.e index b54b86d6..6e479586 100644 --- a/library/server/wsf/src/service/wsf_default_service_i.e +++ b/library/server/wsf/src/service/wsf_default_service_i.e @@ -4,18 +4,18 @@ note revision: "$Revision$" deferred class - WSF_DEFAULT_SERVICE_I [G -> WSF_SERVICE_LAUNCHER create make_and_launch end] + WSF_DEFAULT_SERVICE_I [G -> WSF_SERVICE_LAUNCHER [WSF_EXECUTION] create make_and_launch end] inherit WSF_LAUNCHABLE_SERVICE feature {NONE} -- Initialization - launch (a_service: WSF_SERVICE; opts: detachable WSF_SERVICE_LAUNCHER_OPTIONS) + launch (opts: detachable WSF_SERVICE_LAUNCHER_OPTIONS) local l_launcher: G do - create l_launcher.make_and_launch (a_service, opts) + create l_launcher.make_and_launch (opts) end note diff --git a/library/server/wsf/src/service/wsf_launchable_service.e b/library/server/wsf/src/service/wsf_launchable_service.e index fa8aa1d4..cdc8550e 100644 --- a/library/server/wsf/src/service/wsf_launchable_service.e +++ b/library/server/wsf/src/service/wsf_launchable_service.e @@ -14,7 +14,7 @@ feature {NONE} -- Initialization frozen make_and_launch do initialize - launch (Current, service_options) + launch (service_options) end initialize @@ -25,7 +25,7 @@ feature {NONE} -- Initialization service_options: detachable WSF_SERVICE_LAUNCHER_OPTIONS - launch (a_service: WSF_SERVICE; opts: detachable WSF_SERVICE_LAUNCHER_OPTIONS) + launch (opts: detachable WSF_SERVICE_LAUNCHER_OPTIONS) deferred end @@ -47,7 +47,7 @@ feature -- Default service options end note - copyright: "2011-2013, Jocelyn Fiat, Javier Velilla, Olivier Ligot, Eiffel Software and others" + copyright: "2011-2015, Jocelyn Fiat, Javier Velilla, Olivier Ligot, Colin Adams, 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/wsf/src/service/wsf_service.e b/library/server/wsf/src/service/wsf_service.e index 38aef9ac..38b8715e 100644 --- a/library/server/wsf/src/service/wsf_service.e +++ b/library/server/wsf/src/service/wsf_service.e @@ -10,26 +10,8 @@ note deferred class WSF_SERVICE -feature -- Execution - - execute (req: WSF_REQUEST; res: WSF_RESPONSE) - -- Execute the request - -- See `req.input' for input stream - -- `req.meta_variables' for the CGI meta variable - -- and `res' for output buffer - deferred - end - -feature -- Conversion - - to_wgi_service: WGI_SERVICE - -- Adapt Current WSF Service to plug into WGI component - do - create {WSF_TO_WGI_SERVICE} Result.make_from_service (Current) - end - note - copyright: "2011-2012, Jocelyn Fiat, Javier Velilla, Olivier Ligot, Eiffel Software and others" + copyright: "2011-2015, Jocelyn Fiat, Javier Velilla, Olivier Ligot, Colin Adams, 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/wsf/src/service/wsf_service_launcher.e b/library/server/wsf/src/service/wsf_service_launcher.e index bf60ab56..5ac1ed97 100644 --- a/library/server/wsf/src/service/wsf_service_launcher.e +++ b/library/server/wsf/src/service/wsf_service_launcher.e @@ -32,45 +32,31 @@ note revision: "$Revision$" deferred class - WSF_SERVICE_LAUNCHER + WSF_SERVICE_LAUNCHER [G -> WSF_EXECUTION create make end] inherit WSF_TO_WGI_SERVICE feature {NONE} -- Initialization - frozen make (a_service: like service; a_options: like options) + frozen make (a_options: like options) do - make_from_service (a_service) options := a_options initialize ensure - service_set: service = a_service options_set: options = a_options launchable: launchable end - frozen make_and_launch (a_service: like service; a_options: like options) + frozen make_and_launch (a_options: like options) do - make (a_service, a_options) + make (a_options) launch end - frozen make_callback (a_callback: PROCEDURE [ANY, TUPLE [req: WSF_REQUEST; res: WSF_RESPONSE]]; a_options: like options) - do - make (create {WSF_CALLBACK_SERVICE}.make (a_callback), a_options) - end - - frozen make_callback_and_launch (a_callback: PROCEDURE [ANY, TUPLE [req: WSF_REQUEST; res: WSF_RESPONSE]]; a_options: like options) - do - make (create {WSF_CALLBACK_SERVICE}.make (a_callback), a_options) - end - initialize -- Initialize Current using `options' if attached -- and build the connector - require - service_set: service /= Void deferred ensure connector_attached: connector /= Void @@ -120,7 +106,7 @@ invariant connector_attached: connector /= Void note - copyright: "2011-2014, Jocelyn Fiat, Javier Velilla, Olivier Ligot, Colin Adams, Eiffel Software and others" + copyright: "2011-2015, Jocelyn Fiat, Javier Velilla, Olivier Ligot, Colin Adams, 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/wsf/src/service/wsf_to_wgi_service.e b/library/server/wsf/src/service/wsf_to_wgi_service.e index e78a8fa0..10d6d841 100644 --- a/library/server/wsf/src/service/wsf_to_wgi_service.e +++ b/library/server/wsf/src/service/wsf_to_wgi_service.e @@ -13,47 +13,8 @@ class inherit WGI_SERVICE -create - make_from_service - -feature {NONE} -- Make - - make_from_service (a_service: like service) - -- Make from WSF_SERVICE `a_service' - do - service := a_service - end - - service: WSF_SERVICE - -- Associated WSF_SERVICE - -feature {WGI_CONNECTOR} -- Implementation: Execution - - execute (req: WGI_REQUEST; res: WGI_RESPONSE) - -- Delegate the WGI processing to the WSF_SERVICE object - -- - local - w_res: detachable WSF_RESPONSE - w_req: detachable WSF_REQUEST - do - create w_res.make_from_wgi (res) - create w_req.make_from_wgi (req) - service.execute (w_req, w_res) - w_req.destroy - rescue - if w_res /= Void then - if not (w_res.status_committed or w_res.header_committed) then - w_res.set_status_code ({HTTP_STATUS_CODE}.internal_server_error) - end - w_res.flush - end - if w_req /= Void then - w_req.destroy - end - end - note - copyright: "2011-2012, Jocelyn Fiat, Javier Velilla, Olivier Ligot, Eiffel Software and others" + copyright: "2011-2015, Jocelyn Fiat, Javier Velilla, Olivier Ligot, Colin Adams, 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/wsf/src/wsf_execution.e b/library/server/wsf/src/wsf_execution.e index 582fb6d2..b99b89c0 100644 --- a/library/server/wsf/src/wsf_execution.e +++ b/library/server/wsf/src/wsf_execution.e @@ -7,6 +7,17 @@ note deferred class WSF_EXECUTION +inherit + WGI_EXECUTION + rename + request as wgi_request, + response as wgi_response + redefine + make, + execute, + clean + end + --create -- make @@ -14,24 +25,72 @@ feature {NONE} -- Initialization make (req: WGI_REQUEST; res: WGI_RESPONSE) do - create request.make_from_wgi (req) - create response.make_from_wgi (res) + Precursor (req, res) + create request.make_from_wgi (wgi_request) + create response.make_from_wgi (wgi_response) end +feature {NONE} -- Access + request: WSF_REQUEST + -- Access to request data. + -- Header, Query, Post, Input data.. response: WSF_RESPONSE + -- Access to output stream, back to the client. + +feature -- Status report + + message_writable: BOOLEAN + do + Result := response.message_writable + end + +feature -- Helpers + + put_character (c: CHARACTER_8) + require + message_writable: message_writable + do + response.put_character (c) + end + + put_string (s: READABLE_STRING_8) + require + message_writable: message_writable + do + response.put_string (s) + end + + put_error (err: READABLE_STRING_8) + require + message_writable: message_writable + do + response.put_error (err) + end feature -- Execution execute + -- Execute Current `request', + -- getting data from `request' + -- and response to client via `response'. deferred - ensure - response.status_is_set + ensure then + status_is_set: response.status_is_set + end + +feature -- Cleaning + + clean + -- Precursor + do + Precursor + request.destroy end note - copyright: "2011-2015, Jocelyn Fiat, Javier Velilla, Eiffel Software and others" + copyright: "2011-2015, Jocelyn Fiat, Javier Velilla, Olivier Ligot, Colin Adams, 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/wsf/src/wsf_request.e b/library/server/wsf/src/wsf_request.e index 5f17f910..ed082696 100644 --- a/library/server/wsf/src/wsf_request.e +++ b/library/server/wsf/src/wsf_request.e @@ -41,7 +41,7 @@ inherit {NONE} all end -create {WSF_TO_WGI_SERVICE, WSF_EXECUTION} +create {WSF_TO_WGI_SERVICE, WSF_EXECUTION, WGI_EXPORTER} make_from_wgi convert @@ -426,7 +426,7 @@ feature -- Eiffel WGI access Result := wgi_request.wgi_implementation end - wgi_connector: detachable WGI_CONNECTOR + wgi_connector: detachable separate WGI_CONNECTOR -- Associated Eiffel WGI connector do Result := wgi_request.wgi_connector diff --git a/library/server/wsf/src/wsf_response.e b/library/server/wsf/src/wsf_response.e index a158fda3..d7964568 100644 --- a/library/server/wsf/src/wsf_response.e +++ b/library/server/wsf/src/wsf_response.e @@ -19,7 +19,7 @@ note class WSF_RESPONSE -create {WSF_TO_WGI_SERVICE, WSF_EXECUTION} +create {WSF_TO_WGI_SERVICE, WSF_EXECUTION, WGI_EXPORTER} make_from_wgi create {WSF_RESPONSE}