From 74121be470c3ca4d682e4eab2e28c428f62df537 Mon Sep 17 00:00:00 2001 From: Jocelyn Fiat Date: Wed, 18 Oct 2017 23:29:16 +0200 Subject: [PATCH 1/3] Support persistent connection, even in single thread mode (i.e concurrency=none). Warning: as there is no concurrent request handling in single threaded mode, it is recommended to either set the keep_alive_timeout to a small value, or disable persistent connection by setting max_keep_alive_requests to 0. Change the default keep_alive_timeout from 15 to 5 seconds. Accept -1 as value of max_keep_alive_requests to have unlimited number of request in the same persistent connection. --- examples/websocket/websocket_app.ecf | 10 +++++++- examples/websocket/ws.ini | 4 +-- .../concurrency/none/httpd_request_handler.e | 12 +-------- .../httpd/configuration/httpd_constants.e | 2 +- .../server/httpd/httpd_request_handler_i.e | 6 +++-- .../wsf_standalone_service_options.e | 25 +++++++++++++++++++ 6 files changed, 42 insertions(+), 17 deletions(-) diff --git a/examples/websocket/websocket_app.ecf b/examples/websocket/websocket_app.ecf index d14ca0d8..6126f6cb 100644 --- a/examples/websocket/websocket_app.ecf +++ b/examples/websocket/websocket_app.ecf @@ -3,9 +3,9 @@ - /\.svn$ /CVS$ /EIFGENs$ + /\.svn$ + + Single thread solution. + Warning: as it can not handle concurrent request, it is recommended to set Keep-Alive-Timeout to very low value, as browser will keep persistent connection open too long. + + + + + diff --git a/examples/websocket/ws.ini b/examples/websocket/ws.ini index 29179920..af39b45d 100644 --- a/examples/websocket/ws.ini +++ b/examples/websocket/ws.ini @@ -2,11 +2,11 @@ verbose=true verbose_level=INFORMATION port=9090 max_concurrent_connections=100 -keep_alive_timeout=35 +keep_alive_timeout=2 +max_keep_alive_requests=-1 max_tcp_clients=100 socket_timeout=30 socket_recv_timeout=5 -max_keep_alive_requests=300 is_secure=false secure_certificate=ca.crt diff --git a/library/server/httpd/concurrency/none/httpd_request_handler.e b/library/server/httpd/concurrency/none/httpd_request_handler.e index c033de78..808fb033 100644 --- a/library/server/httpd/concurrency/none/httpd_request_handler.e +++ b/library/server/httpd/concurrency/none/httpd_request_handler.e @@ -8,19 +8,9 @@ deferred class inherit HTTPD_REQUEST_HANDLER_I - redefine - is_persistent_connection_supported - end - -feature -- Status report - - is_persistent_connection_supported: BOOLEAN = False - -- - -- When there is no concurrency support, do not try to support - -- persistent connection! note - copyright: "2011-2015, Jocelyn Fiat, Javier Velilla, Eiffel Software and others" + copyright: "2011-2017, 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/httpd/configuration/httpd_constants.e b/library/server/httpd/configuration/httpd_constants.e index 80fbef03..2475a0b1 100644 --- a/library/server/httpd/configuration/httpd_constants.e +++ b/library/server/httpd/configuration/httpd_constants.e @@ -25,7 +25,7 @@ feature -- Default timeout settings feature -- Default persistent connection settings - default_keep_alive_timeout: INTEGER = 15 -- seconds + default_keep_alive_timeout: INTEGER = 5 -- seconds default_max_keep_alive_requests: INTEGER = 100 note diff --git a/library/server/httpd/httpd_request_handler_i.e b/library/server/httpd/httpd_request_handler_i.e index d2598206..c61a1759 100644 --- a/library/server/httpd/httpd_request_handler_i.e +++ b/library/server/httpd/httpd_request_handler_i.e @@ -140,7 +140,8 @@ feature -- Settings is_persistent_connection_supported: BOOLEAN -- Is persistent connection supported? do - Result := {HTTPD_SERVER}.is_persistent_connection_supported and then max_keep_alive_requests > 0 + Result := {HTTPD_SERVER}.is_persistent_connection_supported and then + max_keep_alive_requests /= 0 --| `-1` no limit end is_next_persistent_connection_supported: BOOLEAN @@ -247,7 +248,8 @@ feature -- Execution l_exit loop n := n + 1 - if n >= m then + -- If `m` is `-1`, no limit for the number of keep_alive requests. + if m >= 0 and n >= m then is_next_persistent_connection_supported := False elseif n > 1 and is_verbose then log ("Reuse connection (" + n.out + ")", information_level) diff --git a/library/server/wsf/connector/standalone/wsf_standalone_service_options.e b/library/server/wsf/connector/standalone/wsf_standalone_service_options.e index b537ecf2..6cf35895 100644 --- a/library/server/wsf/connector/standalone/wsf_standalone_service_options.e +++ b/library/server/wsf/connector/standalone/wsf_standalone_service_options.e @@ -104,11 +104,26 @@ feature -- Access: persistent connection -- Maximum number of requests allowed per persistent connection. -- Recommended a high setting. -- To disable KeepAlive, set `max_keep_alive_requests' to 0. + -- To have no limit, set `max_keep_alive_requests' to -1. -- By default: {HTTPD_CONFIGURATION_I}.default_max_keep_alive_requests . do Result := option_integer_value ("max_keep_alive_requests", 0) end + persistent_connection_disabled: BOOLEAN + -- Persistent connection disabled? + -- (or Keep-Alive disabled). + do + Result := max_keep_alive_requests = 0 + end + + has_unlimited_keep_alive_requests: BOOLEAN + -- Has unlimited count of keep alive requests. + -- i.e no limit of number of requests allowed per persistent connection. + do + Result := max_keep_alive_requests < 0 + end + feature -- Access: SSL is_secure: BOOLEAN assign set_is_secure @@ -205,6 +220,16 @@ feature -- Element change set_numeric_option ("max_keep_alive_requests", nb) end + set_unlimited_keep_alive_requests + do + set_max_keep_alive_requests (-1) + end + + disable_persistent_connection + do + set_max_keep_alive_requests (0) + end + set_is_secure (b: BOOLEAN) -- Set secured connection enabled to `b'. -- i.e if connection is using SSL/TLS. From a1b43374388dc5c3a7925371dfb86aecf680374a Mon Sep 17 00:00:00 2001 From: Jocelyn Fiat Date: Wed, 18 Oct 2017 23:41:03 +0200 Subject: [PATCH 2/3] Set keep_alive_timeout to 2, this way for single threaded case, browser does not wait too much to start the websocket connection. Set max_keep_alive_requests to -1, to allow unlimited number of requests within a same websocket connection. --- examples/websocket/ws.ini | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/examples/websocket/ws.ini b/examples/websocket/ws.ini index af39b45d..87dcb630 100644 --- a/examples/websocket/ws.ini +++ b/examples/websocket/ws.ini @@ -1,13 +1,20 @@ -verbose=true -verbose_level=INFORMATION port=9090 + +#Socket and timeout max_concurrent_connections=100 -keep_alive_timeout=2 -max_keep_alive_requests=-1 max_tcp_clients=100 socket_timeout=30 socket_recv_timeout=5 +#Persistent connections +keep_alive_timeout=2 +max_keep_alive_requests=-1 + +#SSL is_secure=false secure_certificate=ca.crt secure_certificate_key=ca.key + +#Debug +verbose=true +verbose_level=INFORMATION From db39068ceb395412de50f9de0b40442c4efbd27c Mon Sep 17 00:00:00 2001 From: Jocelyn Fiat Date: Thu, 19 Oct 2017 00:14:23 +0200 Subject: [PATCH 3/3] Updated documentation for standalone connector. Changed `default_max_keep_alive_requests` from 100 to 300. --- docs/workbook/basics/basics.md | 4 ++- docs/workbook/connectors/standalone.md | 27 +++++++++++++++++++ .../httpd/configuration/httpd_constants.e | 2 +- .../wsf_standalone_service_options.e | 2 +- 4 files changed, 32 insertions(+), 3 deletions(-) create mode 100644 docs/workbook/connectors/standalone.md diff --git a/docs/workbook/basics/basics.md b/docs/workbook/basics/basics.md index 2fc0e40f..f8b41b1b 100644 --- a/docs/workbook/basics/basics.md +++ b/docs/workbook/basics/basics.md @@ -59,7 +59,7 @@ feature -- Basic operations end ``` -When using the "standalone" connector (or the deprecated "nino" connector), by default the service listens on port 80, but often this port is already used by other applications, so it is recommended to use another port. +When using the [standalone](../connectors/standalone.md) connector (or the deprecated "nino" connector), by default the service listens on port 80, but often this port is already used by other applications, so it is recommended to use another port. To define another port, redefine the feature `initialize` and set up a new port number using the service options (see below). @@ -86,6 +86,8 @@ feature {NONE} -- Initialization end ``` +Learn more about the [Standalone](../connectors/standalone.md) connector. + The **WSF_REQUEST** gives access to the incoming data; the class provides features to get information such as request method, form data, query parameters, uploaded files, HTTP request headers, and hostname of the client among others. The **WSF_RESPONSE** provides features to define the response with information such as HTTP status codes (10x,20x, 30x, 40x, and 50x), response headers (Content-Type, Content-Length, etc.) and obviously the body of the message itself. diff --git a/docs/workbook/connectors/standalone.md b/docs/workbook/connectors/standalone.md new file mode 100644 index 00000000..4dd0ff46 --- /dev/null +++ b/docs/workbook/connectors/standalone.md @@ -0,0 +1,27 @@ +Nav: [Workbook](../workbook.md) + +## The EiffelWeb standalone connector + +It provides a standalone httpd server for the EiffelWeb framework. +It implements HTTP/1.1 with persistent connection, concurrent connection, ... + +To easily set the standalone connector, see class `WSF_STANDALONE_SERVICE_OPTIONS`. + +### Main settings: + +* `port`: Listening port number (defaut: 80). +* `max_concurrent_connections`: maximum of concurrent connections (default: 100) +* `max_tcp_clients`: Listen on socket for at most `max_tcp_clients` connections (default: 100) +* `socket_timeout`: Amount of seconds the server waits for receipts and transmissions during communications. With timeout of 0, socket can wait for ever. (default: 60) +* `socket_recv_timeout`: Amount of seconds the server waits for receiving data during communications. With timeout of 0, socket can waits for ever. (default: 5) +* `keep_alive_timeout`: Persistent connection timeout. Number of seconds the server waits after a request has been served before it closes the connection (default: 5) +* `max_keep_alive_requests`: Maximum number of requests allowed per persistent connection. To disable KeepAlive, set `max_keep_alive_requests` to `0`. To have no limit, set `max_keep_alive_requests` to `-1` (default: 300). + +* `is_secure`: check SSL certificate? +* `secure_certificate`: path to SSL certificate. +* `secure_certificate_key`: certificate key + +* `verbose`: display verbose output (Default: false) + +See also `WGI_STANDALONE_CONSTANTS` for default values. + diff --git a/library/server/httpd/configuration/httpd_constants.e b/library/server/httpd/configuration/httpd_constants.e index 2475a0b1..2a0ed315 100644 --- a/library/server/httpd/configuration/httpd_constants.e +++ b/library/server/httpd/configuration/httpd_constants.e @@ -26,7 +26,7 @@ feature -- Default timeout settings feature -- Default persistent connection settings default_keep_alive_timeout: INTEGER = 5 -- seconds - default_max_keep_alive_requests: INTEGER = 100 + default_max_keep_alive_requests: INTEGER = 300 note copyright: "2011-2016, Jocelyn Fiat, Javier Velilla, Eiffel Software and others" diff --git a/library/server/wsf/connector/standalone/wsf_standalone_service_options.e b/library/server/wsf/connector/standalone/wsf_standalone_service_options.e index 6cf35895..c3fa0c20 100644 --- a/library/server/wsf/connector/standalone/wsf_standalone_service_options.e +++ b/library/server/wsf/connector/standalone/wsf_standalone_service_options.e @@ -66,7 +66,7 @@ feature -- Access: connection end max_tcp_clients: INTEGER assign set_max_tcp_clients - -- Listen on socket for at most `queue' connections. + -- Listen on socket for at most `max_tcp_clients' connections. do Result := option_integer_value ("max_tcp_clients", 0) end