From 7a182fa02f951e7a0ffb03ca332ed6cd6cd89769 Mon Sep 17 00:00:00 2001 From: Jocelyn Fiat Date: Tue, 14 Jun 2016 14:43:26 +0200 Subject: [PATCH] A few tests with passive region, and expanded objects. --- examples/simple/application.e | 7 ++- examples/simple/application_execution.e | 3 ++ examples/simple/simple.ecf | 13 ++--- .../scoop/httpd_connection_handler.e | 2 +- .../thread/httpd_connection_handler.e | 2 +- .../configuration/httpd_configuration_i.e | 23 +++++++- .../configuration/httpd_connection_settings.e | 34 ++++++++++++ .../src/httpd/httpd_request_handler_i.e | 49 +++++++++-------- .../standalone/src/httpd/httpd_server_i.e | 2 +- .../wgi_httpd_request_handler.e | 16 +++--- .../wgi_httpd_request_handler_factory.e | 10 ++-- .../standalone/src/wgi_standalone_connector.e | 23 ++++++-- .../src/wgi_standalone_input_stream.e | 2 +- .../wsf_standalone_service_launcher.e | 53 ++++++++++--------- .../wsf/src/service/wsf_service_launcher.e | 6 +-- .../service/wsf_service_launcher_options.e | 36 +++++++++++++ library/server/wsf_html/package.iron | 20 +++++++ 17 files changed, 220 insertions(+), 81 deletions(-) create mode 100644 library/server/ewsgi/connectors/standalone/src/httpd/configuration/httpd_connection_settings.e create mode 100644 library/server/wsf_html/package.iron diff --git a/examples/simple/application.e b/examples/simple/application.e index d1de21d9..b9e39abc 100644 --- a/examples/simple/application.e +++ b/examples/simple/application.e @@ -20,9 +20,12 @@ feature {NONE} -- Initialization initialize -- Initialize current service. do + -- Specific to `standalone' connector (the EiffelWeb server). + -- See `{WSF_STANDALONE_SERVICE_LAUNCHER}.initialize' set_service_option ("port", 9090) + set_service_option ("max_concurrent_connections", 10) + set_service_option ("keep_alive_timeout", 1) + set_service_option ("verbose", True) end - - end diff --git a/examples/simple/application_execution.e b/examples/simple/application_execution.e index b02bdf55..b464d207 100644 --- a/examples/simple/application_execution.e +++ b/examples/simple/application_execution.e @@ -17,10 +17,13 @@ feature -- Basic operations execute local s: STRING + dt: HTTP_DATE do -- To send a response we need to setup, the status code and -- the response headers. s := "Hello World!" + create dt.make_now_utc + s.append (" (UTC time is " + dt.rfc850_string + ").") response.put_header ({HTTP_STATUS_CODE}.ok, <<["Content-Type", "text/html"], ["Content-Length", s.count.out]>>) response.set_status_code ({HTTP_STATUS_CODE}.ok) response.header.put_content_type_text_html diff --git a/examples/simple/simple.ecf b/examples/simple/simple.ecf index f341867d..74fa824a 100644 --- a/examples/simple/simple.ecf +++ b/examples/simple/simple.ecf @@ -1,14 +1,15 @@ - + - /EIFGENs$ - /CVS$ /.svn$ + /CVS$ + /EIFGENs$ - + @@ -18,8 +19,8 @@ - - + + diff --git a/library/server/ewsgi/connectors/standalone/src/httpd/concurrency/scoop/httpd_connection_handler.e b/library/server/ewsgi/connectors/standalone/src/httpd/concurrency/scoop/httpd_connection_handler.e index 9a5f4664..f896d281 100644 --- a/library/server/ewsgi/connectors/standalone/src/httpd/concurrency/scoop/httpd_connection_handler.e +++ b/library/server/ewsgi/connectors/standalone/src/httpd/concurrency/scoop/httpd_connection_handler.e @@ -24,7 +24,7 @@ feature {NONE} -- Initialization n: INTEGER p: like pool do - n := max_concurrent_connections (server) + n := max_concurrent_connections (server).max (1) -- At least one processor! create p.make (n) initialize_pool (p, n) pool := p diff --git a/library/server/ewsgi/connectors/standalone/src/httpd/concurrency/thread/httpd_connection_handler.e b/library/server/ewsgi/connectors/standalone/src/httpd/concurrency/thread/httpd_connection_handler.e index 45b85bd4..75115d3b 100644 --- a/library/server/ewsgi/connectors/standalone/src/httpd/concurrency/thread/httpd_connection_handler.e +++ b/library/server/ewsgi/connectors/standalone/src/httpd/concurrency/thread/httpd_connection_handler.e @@ -23,7 +23,7 @@ feature {NONE} -- Initialization local n: INTEGER do - n := max_concurrent_connections (server) + n := max_concurrent_connections (server).max (1) -- At least one thread! create pool.make (n.to_natural_32) end diff --git a/library/server/ewsgi/connectors/standalone/src/httpd/configuration/httpd_configuration_i.e b/library/server/ewsgi/connectors/standalone/src/httpd/configuration/httpd_configuration_i.e index 8ae522ac..7294d0bf 100644 --- a/library/server/ewsgi/connectors/standalone/src/httpd/configuration/httpd_configuration_i.e +++ b/library/server/ewsgi/connectors/standalone/src/httpd/configuration/httpd_configuration_i.e @@ -15,12 +15,21 @@ feature {NONE} -- Initialization max_tcp_clients := 100 socket_accept_timeout := 1_000 socket_connect_timeout := 5_000 - keep_alive_timeout := 5 + is_secure := False create ca_crt.make_empty create ca_key.make_empty + + connection_settings.keep_alive_timeout := default_keep_alive_timeout end + +feature -- Default values + + default_server_port: INTEGER = 80 + default_max_concurrent_connections: INTEGER = 100 + default_keep_alive_timeout: INTEGER = 5 -- in seconds. + feature -- Access Server_details: STRING_8 @@ -45,6 +54,11 @@ feature -- Access keep_alive_timeout: INTEGER assign set_keep_alive_timeout -- Persistent connection timeout -- Timeout unit in Seconds. + do + Result := connection_settings.keep_alive_timeout + end + + connection_settings: HTTPD_CONNECTION_SETTINGS has_ssl_support: BOOLEAN -- Has SSL support? @@ -126,6 +140,10 @@ feature -- Element change end set_force_single_threaded (v: like force_single_threaded) + -- Force server to handle incoming request in a single thread. + -- i.e set max_concurrent_connections to 0! + obsolete + "Use set_max_concurrent_connections (0) [June/2016]" do if v then set_max_concurrent_connections (0) @@ -139,6 +157,7 @@ feature -- Element change -- Set `is_verbose' to `b' do is_verbose := b + connection_settings.is_verbose := b ensure is_verbose_set: is_verbose = b end @@ -146,7 +165,7 @@ feature -- Element change set_keep_alive_timeout (a_seconds: like keep_alive_timeout) -- Set `keep_alive_timeout' with `a_seconds' do - keep_alive_timeout := a_seconds + connection_settings.keep_alive_timeout := a_seconds ensure keep_alive_timeout_set: keep_alive_timeout = a_seconds end diff --git a/library/server/ewsgi/connectors/standalone/src/httpd/configuration/httpd_connection_settings.e b/library/server/ewsgi/connectors/standalone/src/httpd/configuration/httpd_connection_settings.e new file mode 100644 index 00000000..4303e493 --- /dev/null +++ b/library/server/ewsgi/connectors/standalone/src/httpd/configuration/httpd_connection_settings.e @@ -0,0 +1,34 @@ +note + description: "[ + Connection settings for the standalone HTTPd server. + ]" + author: "$Author$" + date: "$Date$" + revision: "$Revision$" + +expanded class + HTTPD_CONNECTION_SETTINGS + +feature -- Access + + is_verbose: BOOLEAN assign set_is_verbose + -- Is verbose? + + keep_alive_timeout: INTEGER assign set_keep_alive_timeout + -- Keep-alive timeout, also known as persistent-connection timeout. + +feature -- Change + + set_is_verbose (b: BOOLEAN) + -- Set `is_verbose' to `b'. + do + is_verbose := True + end + + set_keep_alive_timeout (a_timeout_in_seconds: INTEGER) + -- Set `keep_alive_timeout' to `a_timeout_in_seconds'. + do + keep_alive_timeout := a_timeout_in_seconds + end + +end diff --git a/library/server/ewsgi/connectors/standalone/src/httpd/httpd_request_handler_i.e b/library/server/ewsgi/connectors/standalone/src/httpd/httpd_request_handler_i.e index 0e195c73..92b588c2 100644 --- a/library/server/ewsgi/connectors/standalone/src/httpd/httpd_request_handler_i.e +++ b/library/server/ewsgi/connectors/standalone/src/httpd/httpd_request_handler_i.e @@ -11,8 +11,9 @@ inherit feature {NONE} -- Initialization - make + make (a_settings: HTTPD_CONNECTION_SETTINGS) do + connection_settings := a_settings reset end @@ -41,6 +42,10 @@ feature {NONE} -- Initialization is_persistent_connection_requested := False end +feature -- Access + + connection_settings: HTTPD_CONNECTION_SETTINGS + feature -- Status report is_connected: BOOLEAN @@ -107,6 +112,9 @@ feature -- Access feature -- Settings is_verbose: BOOLEAN + do + Result := connection_settings.is_verbose + end is_persistent_connection_supported: BOOLEAN -- Is persistent connection supported? @@ -114,24 +122,27 @@ feature -- Settings Result := {HTTPD_SERVER}.is_persistent_connection_supported end - persistent_connection_timeout: INTEGER = 5 -- seconds + persistent_connection_timeout: INTEGER -- seconds -- Number of seconds for persistent connection timeout. -- Default: 5 sec. + do + Result := connection_settings.keep_alive_timeout + end feature -- Status report has_error: BOOLEAN -- Error occurred during `analyze_request_message' -feature -- Change - - set_is_verbose (b: BOOLEAN) - -- Set `is_verbose' with `b'. - do - is_verbose := b - ensure - is_verbose_set: is_verbose = b - end +--feature -- Change +-- +-- set_is_verbose (b: BOOLEAN) +-- -- Set `is_verbose' with `b'. +-- do +-- connection_settings.is_verbose := b +-- ensure +-- is_verbose_set: is_verbose = b +-- end feature -- Execution @@ -210,17 +221,8 @@ feature -- Execution --| TODO: add configuration options for socket timeout. --| set by default 5 seconds. --- l_socket.set_timeout (persistent_connection_timeout) -- 5 seconds! - l_socket.set_timeout (1) -- 1 second! - from - i := persistent_connection_timeout -- * 1 sec - until - l_is_ready or i <= 0 or has_error - loop - l_is_ready := l_socket.ready_for_reading - check not l_socket.is_closed end - i := i - 1 - end + l_socket.set_timeout (persistent_connection_timeout) -- 5 seconds! + l_is_ready := l_socket.ready_for_reading if l_is_ready then create l_remote_info @@ -231,6 +233,9 @@ feature -- Execution remote_info := l_remote_info end analyze_request_message (l_socket) + if is_verbose then + log (request_header) + end else has_error := True debug ("dbglog") diff --git a/library/server/ewsgi/connectors/standalone/src/httpd/httpd_server_i.e b/library/server/ewsgi/connectors/standalone/src/httpd/httpd_server_i.e index d3c236d7..326ed715 100644 --- a/library/server/ewsgi/connectors/standalone/src/httpd/httpd_server_i.e +++ b/library/server/ewsgi/connectors/standalone/src/httpd/httpd_server_i.e @@ -37,7 +37,7 @@ feature {NONE} -- Initialization build_controller -- Build `controller'. do - create controller + create controller end initialize diff --git a/library/server/ewsgi/connectors/standalone/src/implementation/wgi_httpd_request_handler.e b/library/server/ewsgi/connectors/standalone/src/implementation/wgi_httpd_request_handler.e index 3abd5220..51535161 100644 --- a/library/server/ewsgi/connectors/standalone/src/implementation/wgi_httpd_request_handler.e +++ b/library/server/ewsgi/connectors/standalone/src/implementation/wgi_httpd_request_handler.e @@ -19,18 +19,14 @@ inherit SHARED_HTML_ENCODER create - make, make_with_connector feature {NONE} -- Initialization - make_with_connector (conn: like connector) + make_with_connector (a_connection_settings: HTTPD_CONNECTION_SETTINGS; conn: like connector) do - make + make (a_connection_settings) connector := conn --- if conn /= Void then --- set_is_verbose (is_connector_verbose (conn)) --- end end feature -- Access @@ -56,10 +52,10 @@ feature -- SCOOP helpers Result := conn.base end - is_connector_verbose (conn: separate WGI_STANDALONE_CONNECTOR [G]): BOOLEAN - do - Result := conn.is_verbose - end +-- is_connector_verbose (conn: separate WGI_STANDALONE_CONNECTOR [G]): BOOLEAN +-- do +-- Result := conn.is_verbose +-- end feature -- Request processing diff --git a/library/server/ewsgi/connectors/standalone/src/implementation/wgi_httpd_request_handler_factory.e b/library/server/ewsgi/connectors/standalone/src/implementation/wgi_httpd_request_handler_factory.e index 48ea569c..2c9bd545 100644 --- a/library/server/ewsgi/connectors/standalone/src/implementation/wgi_httpd_request_handler_factory.e +++ b/library/server/ewsgi/connectors/standalone/src/implementation/wgi_httpd_request_handler_factory.e @@ -1,5 +1,5 @@ note - description: "Implementation of WGI request handler factory for WGI_STANDALOE_CONNECTOR." + description: "Implementation of WGI request handler factory for WGI_STANDALONE_CONNECTOR." date: "$Date$" revision: "$Revision$" @@ -14,11 +14,15 @@ feature -- Access connector: detachable separate WGI_STANDALONE_CONNECTOR [G] -- httpd solution. + connection_settings: HTTPD_CONNECTION_SETTINGS + -- Connection settings related to httpd solution. + feature -- Element change - set_connector (conn: like connector) + set_connector (a_settings: HTTPD_CONNECTION_SETTINGS; conn: like connector) -- Set `connector' with `conn'. do + connection_settings := a_settings connector := conn end @@ -26,7 +30,7 @@ feature -- Factory new_handler: separate WGI_HTTPD_REQUEST_HANDLER [G] do - create Result.make_with_connector (connector) + create Result.make_with_connector (connection_settings, connector) end note diff --git a/library/server/ewsgi/connectors/standalone/src/wgi_standalone_connector.e b/library/server/ewsgi/connectors/standalone/src/wgi_standalone_connector.e index 9c35e715..7fd84738 100644 --- a/library/server/ewsgi/connectors/standalone/src/wgi_standalone_connector.e +++ b/library/server/ewsgi/connectors/standalone/src/wgi_standalone_connector.e @@ -26,13 +26,18 @@ feature {NONE} -- Initialization create on_launched_actions -- Server - create fac +-- create fac + create fac + request_handler_factory := fac + create server.make (fac) - create observer +-- create server.make (fac) +-- create observer + create observer configuration := server_configuration (server) controller := server_controller (server) - set_factory_connector (Current, fac) initialize_server (server) + set_factory_connector (configuration, Current, fac) end make_with_base (a_base: like base) @@ -51,9 +56,9 @@ feature {NONE} -- Separate helper a_server.set_observer (observer) end - set_factory_connector (conn: detachable separate WGI_STANDALONE_CONNECTOR [G]; fac: separate WGI_HTTPD_REQUEST_HANDLER_FACTORY [G]) + set_factory_connector (a_conf: like configuration; conn: detachable separate WGI_STANDALONE_CONNECTOR [G]; fac: separate WGI_HTTPD_REQUEST_HANDLER_FACTORY [G]) do - fac.set_connector (conn) + fac.set_connector (a_conf.connection_settings, conn) end server_configuration (a_server: like server): like configuration @@ -61,6 +66,9 @@ feature {NONE} -- Separate helper Result := a_server.configuration end + request_handler_factory: separate WGI_HTTPD_REQUEST_HANDLER_FACTORY [G] + -- REQUEST Handler factory. + feature -- Access name: STRING_8 = "httpd" @@ -117,6 +125,11 @@ feature -- Event feature -- Element change + update_configuration (cfg: separate HTTPD_CONFIGURATION) + do + set_factory_connector (cfg, Current, request_handler_factory) + end + set_base (v: like base) -- Set base url `base' to `v'. require diff --git a/library/server/ewsgi/connectors/standalone/src/wgi_standalone_input_stream.e b/library/server/ewsgi/connectors/standalone/src/wgi_standalone_input_stream.e index 2013ad68..d2d8a44f 100644 --- a/library/server/ewsgi/connectors/standalone/src/wgi_standalone_input_stream.e +++ b/library/server/ewsgi/connectors/standalone/src/wgi_standalone_input_stream.e @@ -24,7 +24,7 @@ feature {NONE} -- Initialization set_source (a_source) end -feature {WGI_STANDALONE_CONNECTOR, WGI_SERVICE} -- Nino +feature {WGI_STANDALONE_CONNECTOR, WGI_SERVICE} -- Standalone connector. set_source (i: like source) do diff --git a/library/server/wsf/connector/standalone/wsf_standalone_service_launcher.e b/library/server/wsf/connector/standalone/wsf_standalone_service_launcher.e index 006a23ee..377066bd 100644 --- a/library/server/wsf/connector/standalone/wsf_standalone_service_launcher.e +++ b/library/server/wsf/connector/standalone/wsf_standalone_service_launcher.e @@ -39,33 +39,25 @@ feature {NONE} -- Initialization create on_stopped_actions port_number := 80 --| Default, but quite often, this port is already used ... + keep_alive_timeout := 5_000 -- 5 seconds. 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") + + verbose := opts.option_boolean_value ("verbose", verbose) + port_number := opts.option_integer_value ("port", port_number) + + if opts.option_boolean_value ("force_single_threaded", single_threaded) then + force_single_threaded end + max_concurrent_connections := opts.option_integer_value ("max_concurrent_connections", max_concurrent_connections) + keep_alive_timeout := opts.option_integer_value ("keep_alive_timeout", keep_alive_timeout) end create conn.make @@ -73,21 +65,27 @@ feature {NONE} -- Initialization conn.on_launched_actions.extend (agent on_launched) conn.set_base (base_url) - update_configuration (conn.configuration) + update_configuration (conn, conn.configuration) + end + + force_single_threaded + -- Set `single_threaded' to True. + do + max_concurrent_connections := 0 end feature -- Execution - update_configuration (cfg: like connector.configuration) + update_configuration (conn: like connector; cfg: like connector.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 cfg.http_server_port := port_number + cfg.set_max_concurrent_connections (max_concurrent_connections) + cfg.set_keep_alive_timeout (keep_alive_timeout) + conn.update_configuration (cfg) end launch @@ -98,7 +96,7 @@ feature -- Execution do conn := connector conn.set_base (base_url) - debug ("nino") + debug ("ew_standalone") if verbose then io.error.put_string ("Launching standalone web server on port " + port_number.out) if attached server_name as l_name then @@ -108,7 +106,7 @@ feature -- Execution end end end - update_configuration (conn.configuration) + update_configuration (conn, conn.configuration) conn.launch end @@ -136,6 +134,13 @@ feature {NONE} -- Implementation verbose: BOOLEAN single_threaded: BOOLEAN + do + Result := max_concurrent_connections = 0 + end + + max_concurrent_connections: INTEGER + + keep_alive_timeout: INTEGER feature -- Status report diff --git a/library/server/wsf/src/service/wsf_service_launcher.e b/library/server/wsf/src/service/wsf_service_launcher.e index 2568a5e0..4c4cd271 100644 --- a/library/server/wsf/src/service/wsf_service_launcher.e +++ b/library/server/wsf/src/service/wsf_service_launcher.e @@ -22,11 +22,11 @@ note For instance, you can use create s.make_and_launch_and_options (agent execute, <<["port", 8099]>>) - And if Nino is the default connector it will support: + And if Standalone (the EiffelWeb server) is the default connector it will support: port: numeric such as 8099 (or equivalent string as "8099") base: base_url (very specific to standalone server) - force_single_threaded: use only one thread, useful for Nino - verbose: to display verbose output, useful for Nino + max_concurrent_connections: by default 100 + verbose: to display verbose output, useful for Standalone connector. ]" date: "$Date$" revision: "$Revision$" diff --git a/library/server/wsf/src/service/wsf_service_launcher_options.e b/library/server/wsf/src/service/wsf_service_launcher_options.e index fd690f88..b2827fdc 100644 --- a/library/server/wsf/src/service/wsf_service_launcher_options.e +++ b/library/server/wsf/src/service/wsf_service_launcher_options.e @@ -83,6 +83,42 @@ feature -- Access Result := options.item (a_name) end +feature -- Helpers + + option_integer_value (a_opt_name: READABLE_STRING_GENERAL; a_default: INTEGER): INTEGER + -- INTEGER value associated to option name `a_opt_name', other return `a_default'. + local + s: READABLE_STRING_GENERAL + do + Result := a_default + if attached option (a_opt_name) as opt then + if attached {INTEGER} opt as i then + Result := i + else + s := opt.out + if s.is_integer then + Result := s.to_integer + end + end + end + end + + option_boolean_value (a_opt_name: READABLE_STRING_GENERAL; a_default: BOOLEAN): BOOLEAN + -- BOOLEAN value associated to option name `a_opt_name', other return `a_default'. + local + s: READABLE_STRING_GENERAL + do + Result := a_default + if attached option (a_opt_name) as opt then + if attached {BOOLEAN} opt as b then + Result := b + else + s := opt.out + Result := s.is_case_insensitive_equal ("true") + end + end + end + feature -- Access new_cursor: TABLE_ITERATION_CURSOR [detachable ANY, READABLE_STRING_GENERAL] diff --git a/library/server/wsf_html/package.iron b/library/server/wsf_html/package.iron new file mode 100644 index 00000000..3738eaed --- /dev/null +++ b/library/server/wsf_html/package.iron @@ -0,0 +1,20 @@ +package wsf_html + +project + wsf_html = "wsf_html-safe.ecf" + wsf_html = "wsf_html.ecf" + +note + title: WSF Html widget + description: "[ + HTML widget, such as table, web form, and more based on the WSF interfaces. + ]" + tags: ewf,server,html,form,widget + copyright: 2011-2016, Jocelyn Fiat, Javier Velilla, Eiffel Software and others + license: Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt) + link[license]: http://www.eiffel.com/licensing/forum.txt + link[source]: "Github" https://github.com/EiffelWebFramework/EWF/library/server/wsf_html + link[doc]: "Documentation" http://eiffelwebframework.github.io/EWF/ + +end +