Fixed setting of socket.timeout in httpd (was not currently set before).

Adopted the nanoseconds timeout precision
 - in config file added support for ns, us, ms, s timeout precision (without indication, it uses `seconds` precision).
This commit is contained in:
2018-10-29 11:27:26 +01:00
parent 9fcd30b4e1
commit d3e865cf6c
9 changed files with 267 additions and 81 deletions

View File

@@ -4,10 +4,10 @@ port=9090
max_concurrent_connections=100 max_concurrent_connections=100
max_tcp_clients=100 max_tcp_clients=100
socket_timeout=30 socket_timeout=30
socket_recv_timeout=5 socket_recv_timeout=100 ms
#Persistent connections #Persistent connections
keep_alive_timeout=2 keep_alive_timeout=50 ms
max_keep_alive_requests=-1 max_keep_alive_requests=-1
#SSL #SSL

View File

@@ -11,6 +11,8 @@ inherit
HTTPD_CONSTANTS HTTPD_CONSTANTS
SOCKET_TIMEOUT_UTILITIES
feature {NONE} -- Initialization feature {NONE} -- Initialization
make make
@@ -18,9 +20,9 @@ feature {NONE} -- Initialization
http_server_port := default_http_server_port http_server_port := default_http_server_port
max_concurrent_connections := default_max_concurrent_connections max_concurrent_connections := default_max_concurrent_connections
max_tcp_clients := default_max_tcp_clients max_tcp_clients := default_max_tcp_clients
socket_timeout := default_socket_timeout socket_timeout_ns := seconds_to_nanoseconds (default_socket_timeout)
socket_recv_timeout := default_socket_recv_timeout socket_recv_timeout_ns := seconds_to_nanoseconds (default_socket_recv_timeout)
keep_alive_timeout := default_keep_alive_timeout keep_alive_timeout_ns := seconds_to_nanoseconds (default_keep_alive_timeout)
max_keep_alive_requests := default_max_keep_alive_requests max_keep_alive_requests := default_max_keep_alive_requests
is_secure := False is_secure := False
create secure_certificate.make_empty create secure_certificate.make_empty
@@ -39,12 +41,12 @@ feature -- Access
max_tcp_clients: INTEGER assign set_max_tcp_clients max_tcp_clients: INTEGER assign set_max_tcp_clients
-- Listen on socket for at most `queue' connections. -- Listen on socket for at most `queue' connections.
socket_timeout: INTEGER assign set_socket_timeout socket_timeout_ns: NATURAL_64 assign set_socket_timeout_ns
-- Amount of seconds that the server waits for receipts and transmissions during communications. -- Amount of seconds that the server waits for receipts and transmissions during communications.
-- note: with timeout of 0, socket can wait for ever. -- note: with timeout of 0, socket can wait for ever.
-- By default: 60 seconds, which is appropriate for most situations. -- By default: 60 seconds, which is appropriate for most situations.
socket_recv_timeout: INTEGER assign set_socket_recv_timeout socket_recv_timeout_ns: NATURAL_64 assign set_socket_recv_timeout_ns
-- Amount of seconds that the server waits for receiving data during communications. -- Amount of seconds that the server waits for receiving data during communications.
-- note: with timeout of 0, socket can wait for ever. -- note: with timeout of 0, socket can wait for ever.
-- By default: 5 seconds. -- By default: 5 seconds.
@@ -65,7 +67,7 @@ feature -- Access
verbose_level: INTEGER assign set_verbose_level verbose_level: INTEGER assign set_verbose_level
-- Verbosity of output. -- Verbosity of output.
keep_alive_timeout: INTEGER assign set_keep_alive_timeout keep_alive_timeout_ns: NATURAL_64 assign set_keep_alive_timeout_ns
-- Persistent connection timeout. -- Persistent connection timeout.
-- Number of seconds the server waits after a request has been served before it closes the connection. -- Number of seconds the server waits after a request has been served before it closes the connection.
-- Timeout unit in Seconds. -- Timeout unit in Seconds.
@@ -86,9 +88,9 @@ feature -- Access
do do
Result.is_verbose := is_verbose Result.is_verbose := is_verbose
Result.verbose_level := verbose_level Result.verbose_level := verbose_level
Result.timeout := socket_timeout Result.timeout_ns := socket_timeout_ns
Result.socket_recv_timeout := socket_recv_timeout Result.socket_recv_timeout_ns := socket_recv_timeout_ns
Result.keep_alive_timeout := keep_alive_timeout Result.keep_alive_timeout_ns := keep_alive_timeout_ns
Result.max_keep_alive_requests := max_keep_alive_requests Result.max_keep_alive_requests := max_keep_alive_requests
Result.is_secure := is_secure Result.is_secure := is_secure
end end
@@ -166,28 +168,52 @@ feature -- Element change
max_concurrent_connections_set : max_concurrent_connections = v max_concurrent_connections_set : max_concurrent_connections = v
end end
set_socket_timeout (a_nb_seconds: like socket_timeout) set_socket_timeout_ns (a_nano_seconds: like socket_timeout_ns)
-- Set `socket_timeout_ns' with `a_nano_seconds'.
require
is_valid_timeout_ns: is_valid_timeout_ns (a_nano_seconds)
do
socket_timeout_ns := a_nano_seconds
ensure
socket_timeout_ns_set: socket_timeout_ns = a_nano_seconds
end
set_socket_recv_timeout_ns (a_nano_seconds: like socket_recv_timeout_ns)
-- Set `socket_recv_timeout_ns' with `a_nano_seconds'.
require
is_valid_timeout_ns: is_valid_timeout_ns (a_nano_seconds)
do
socket_recv_timeout_ns := a_nano_seconds
ensure
socket_recv_timeout_ns_set: socket_recv_timeout_ns = a_nano_seconds
end
set_keep_alive_timeout_ns (a_nano_seconds: like keep_alive_timeout_ns)
-- Set `keep_alive_timeout_ns' with `a_nano_seconds'.
require
is_valid_timeout_ns: is_valid_timeout_ns (a_nano_seconds)
do
keep_alive_timeout_ns := a_nano_seconds
ensure
keep_alive_timeout_ns_set: keep_alive_timeout_ns = a_nano_seconds
end
set_socket_timeout (a_nb_seconds: INTEGER)
-- Set `socket_timeout' with `a_nb_seconds'. -- Set `socket_timeout' with `a_nb_seconds'.
do do
socket_timeout := a_nb_seconds set_socket_timeout_ns (seconds_to_nanoseconds (a_nb_seconds))
ensure
socket_timeout_set: socket_timeout = a_nb_seconds
end end
set_socket_recv_timeout (a_nb_seconds: like socket_recv_timeout) set_socket_recv_timeout (a_nb_seconds: INTEGER)
-- Set `socket_recv_timeout' with `a_nb_seconds'. -- Set `socket_recv_timeout' with `a_nb_seconds'.
do do
socket_recv_timeout := a_nb_seconds set_socket_recv_timeout_ns (seconds_to_nanoseconds (a_nb_seconds))
ensure
socket_recv_timeout_set: socket_recv_timeout = a_nb_seconds
end end
set_keep_alive_timeout (a_seconds: like keep_alive_timeout) set_keep_alive_timeout (a_nb_seconds: INTEGER)
-- Set `keep_alive_timeout' with `a_seconds'. -- Set `keep_alive_timeout' with `a_nb_seconds'.
do do
keep_alive_timeout := a_seconds set_keep_alive_timeout_ns (seconds_to_nanoseconds (a_nb_seconds))
ensure
keep_alive_timeout_set: keep_alive_timeout = a_seconds
end end
set_max_keep_alive_requests (nb: like max_keep_alive_requests) set_max_keep_alive_requests (nb: like max_keep_alive_requests)

View File

@@ -9,6 +9,9 @@ note
expanded class expanded class
HTTPD_REQUEST_SETTINGS HTTPD_REQUEST_SETTINGS
inherit
SOCKET_TIMEOUT_UTILITIES
feature -- Access feature -- Access
is_verbose: BOOLEAN assign set_is_verbose is_verbose: BOOLEAN assign set_is_verbose
@@ -20,13 +23,13 @@ feature -- Access
is_secure: BOOLEAN assign set_is_secure is_secure: BOOLEAN assign set_is_secure
-- Is using secure connection? i.e SSL? -- Is using secure connection? i.e SSL?
timeout: INTEGER assign set_timeout timeout_ns: NATURAL_64 assign set_timeout_ns
-- Amount of seconds that the server waits for receipts and transmissions during communications. -- Amount of seconds that the server waits for receipts and transmissions during communications.
socket_recv_timeout: INTEGER assign set_socket_recv_timeout socket_recv_timeout_ns: NATURAL_64 assign set_socket_recv_timeout_ns
-- Amount of seconds that the server waits for receiving data on socket during communications. -- Amount of seconds that the server waits for receiving data on socket during communications.
keep_alive_timeout: INTEGER assign set_keep_alive_timeout keep_alive_timeout_ns: NATURAL_64 assign set_keep_alive_timeout_ns
-- Keep-alive timeout, also known as persistent-connection timeout. -- Keep-alive timeout, also known as persistent-connection timeout.
-- Number of seconds the server waits after a request has been served before it closes the connection. -- Number of seconds the server waits after a request has been served before it closes the connection.
-- Unit in Seconds. -- Unit in Seconds.
@@ -34,6 +37,29 @@ feature -- Access
max_keep_alive_requests: INTEGER assign set_max_keep_alive_requests max_keep_alive_requests: INTEGER assign set_max_keep_alive_requests
-- Maximum number of requests allowed per persistent connection. -- Maximum number of requests allowed per persistent connection.
feature -- Access: obsolete
timeout: INTEGER assign set_timeout
obsolete
"Use `timeout_ns` [2018-10-29]"
do
Result := nanoseconds_to_seconds (timeout_ns)
end
socket_recv_timeout: INTEGER assign set_socket_recv_timeout
obsolete
"Use `socket_recv_timeout_ns` [2018-10-29]"
do
Result := nanoseconds_to_seconds (socket_recv_timeout_ns)
end
keep_alive_timeout: INTEGER assign set_keep_alive_timeout
obsolete
"Use `keep_alive_timeout_ns` [2018-10-29]"
do
Result := nanoseconds_to_seconds (keep_alive_timeout_ns)
end
feature -- Change feature -- Change
set_is_verbose (b: BOOLEAN) set_is_verbose (b: BOOLEAN)
@@ -54,24 +80,48 @@ feature -- Change
is_secure := b is_secure := b
end end
feature -- Timeout change
set_timeout_ns (a_timeout_in_nanoseconds: NATURAL_64)
-- Set `timeout_ns' to `a_timeout_in_nanoseconds'.
do
timeout_ns := a_timeout_in_nanoseconds
end
set_socket_recv_timeout_ns (a_timeout_in_nanoseconds: NATURAL_64)
-- Set `socket_recv_timeout_ns' to `a_timeout_in_nanoseconds'.
do
socket_recv_timeout_ns := a_timeout_in_nanoseconds
end
set_keep_alive_timeout_ns (a_timeout_in_nanoseconds: NATURAL_64)
-- Set `keep_alive_timeout_ns' to `a_timeout_in_nanoseconds'.
do
keep_alive_timeout_ns := a_timeout_in_nanoseconds
end
feature -- Timeout change (in seconds)
set_timeout (a_timeout_in_seconds: INTEGER) set_timeout (a_timeout_in_seconds: INTEGER)
-- Set `timeout' to `a_timeout_in_seconds'. -- Set `timeout' to `a_timeout_in_seconds'.
do do
timeout := a_timeout_in_seconds set_timeout_ns (seconds_to_nanoseconds (a_timeout_in_seconds))
end end
set_socket_recv_timeout (a_timeout_in_seconds: INTEGER) set_socket_recv_timeout (a_timeout_in_seconds: INTEGER)
-- Set `socket_recv_timeout' to `a_timeout_in_seconds'. -- Set `socket_recv_timeout' to `a_timeout_in_seconds'.
do do
socket_recv_timeout := a_timeout_in_seconds set_socket_recv_timeout_ns (seconds_to_nanoseconds (a_timeout_in_seconds))
end end
set_keep_alive_timeout (a_timeout_in_seconds: INTEGER) set_keep_alive_timeout (a_timeout_in_seconds: INTEGER)
-- Set `keep_alive_timeout' to `a_timeout_in_seconds'. -- Set `keep_alive_timeout' to `a_timeout_in_seconds'.
do do
keep_alive_timeout := a_timeout_in_seconds set_keep_alive_timeout_ns (seconds_to_nanoseconds (a_timeout_in_seconds))
end end
feature -- Change
set_max_keep_alive_requests (nb: like max_keep_alive_requests) set_max_keep_alive_requests (nb: like max_keep_alive_requests)
-- Set `max_keep_alive_requests' with `nb' -- Set `max_keep_alive_requests' with `nb'
do do
@@ -79,7 +129,7 @@ feature -- Change
end end
note note
copyright: "2011-2016, Jocelyn Fiat, Javier Velilla, Eiffel Software and others" copyright: "2011-2018, Jocelyn Fiat, Javier Velilla, Eiffel Software and others"
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)" license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
source: "[ source: "[
Eiffel Software Eiffel Software

View File

@@ -19,9 +19,9 @@ feature {NONE} -- Initialization
do do
reset reset
-- Import global request settings. -- Import global request settings.
timeout := a_request_settings.timeout -- seconds timeout_ns := a_request_settings.timeout_ns -- nanoseconds
socket_recv_timeout := a_request_settings.socket_recv_timeout -- seconds socket_recv_timeout_ns := a_request_settings.socket_recv_timeout_ns -- nanoseconds
keep_alive_timeout := a_request_settings.keep_alive_timeout -- seconds keep_alive_timeout_ns := a_request_settings.keep_alive_timeout_ns -- nanoseconds
max_keep_alive_requests := a_request_settings.max_keep_alive_requests max_keep_alive_requests := a_request_settings.max_keep_alive_requests
is_verbose := a_request_settings.is_verbose is_verbose := a_request_settings.is_verbose
@@ -148,16 +148,16 @@ feature -- Settings
-- Is next persistent connection supported? -- Is next persistent connection supported?
-- note: it is relevant only if `is_persistent_connection_supported' is True. -- note: it is relevant only if `is_persistent_connection_supported' is True.
timeout: INTEGER -- seconds timeout_ns: NATURAL_64 -- nanoseconds
-- Amount of seconds that the server waits for receipts and transmissions during communications. -- Amount of seconds that the server waits for receipts and transmissions during communications.
socket_recv_timeout: INTEGER -- seconds socket_recv_timeout_ns: NATURAL_64 -- nanoseconds
-- Amount of seconds that the server waits for receiving data on socket during communications. -- Amount of seconds that the server waits for receiving data on socket during communications.
max_keep_alive_requests: INTEGER max_keep_alive_requests: INTEGER
-- Maximum number of requests allowed per persistent connection. -- Maximum number of requests allowed per persistent connection.
keep_alive_timeout: INTEGER -- seconds keep_alive_timeout_ns: NATURAL_64 -- nanoseconds
-- Number of seconds for persistent connection timeout. -- Number of seconds for persistent connection timeout.
feature -- Status report feature -- Status report
@@ -226,6 +226,10 @@ feature -- Execution
do do
l_socket := client_socket l_socket := client_socket
-- Set to expected `timeout_ns`.
l_socket.set_timeout_ns (timeout_ns)
l_socket.set_recv_timeout_ns (socket_recv_timeout_ns)
-- Compute remote info once for the persistent connection. -- Compute remote info once for the persistent connection.
create l_remote_info create l_remote_info
if attached l_socket.peer_address as l_addr then if attached l_socket.peer_address as l_addr then
@@ -407,9 +411,9 @@ feature -- Parsing
a_socket.readable a_socket.readable
then then
if a_is_reusing_connection then if a_is_reusing_connection then
a_socket.set_recv_timeout (keep_alive_timeout) -- in seconds! a_socket.set_recv_timeout_ns (keep_alive_timeout_ns) -- in nanoseconds!
else else
a_socket.set_recv_timeout (socket_recv_timeout) -- FIXME: return a 408 Request Timeout response .. a_socket.set_recv_timeout_ns (socket_recv_timeout_ns) -- FIXME: return a 408 Request Timeout response ..
end end
if if
@@ -424,7 +428,7 @@ feature -- Parsing
if not has_error then if not has_error then
if a_is_reusing_connection then if a_is_reusing_connection then
-- Restore normal recv timeout! -- Restore normal recv timeout!
a_socket.set_recv_timeout (socket_recv_timeout) -- FIXME: return a 408 Request Timeout response .. a_socket.set_recv_timeout_ns (socket_recv_timeout_ns) -- FIXME: return a 408 Request Timeout response ..
end end
from from
line := next_line (a_socket) line := next_line (a_socket)
@@ -646,7 +650,7 @@ invariant
request_header_attached: request_header /= Void request_header_attached: request_header /= Void
note note
copyright: "2011-2016, Jocelyn Fiat, Javier Velilla, Eiffel Software and others" copyright: "2011-2018, Jocelyn Fiat, Javier Velilla, Eiffel Software and others"
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)" license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
source: "[ source: "[
Eiffel Software Eiffel Software

View File

@@ -109,9 +109,9 @@ feature -- Execution
log (" - port = " + configuration.http_server_port.out) log (" - port = " + configuration.http_server_port.out)
log (" - max_tcp_clients = " + configuration.max_tcp_clients.out) log (" - max_tcp_clients = " + configuration.max_tcp_clients.out)
log (" - max_concurrent_connections = " + configuration.max_concurrent_connections.out) log (" - max_concurrent_connections = " + configuration.max_concurrent_connections.out)
log (" - socket_timeout = " + configuration.socket_timeout.out + " seconds") log (" - socket_timeout = " + timeout_representation (configuration.socket_timeout_ns))
log (" - socket_recv_timeout = " + configuration.socket_recv_timeout.out + " seconds") log (" - socket_recv_timeout = " + timeout_representation (configuration.socket_recv_timeout_ns))
log (" - keep_alive_timeout = " + configuration.keep_alive_timeout.out + " seconds") log (" - keep_alive_timeout = " + timeout_representation (configuration.keep_alive_timeout_ns))
log (" - max_keep_alive_requests = " + configuration.max_keep_alive_requests.out) log (" - max_keep_alive_requests = " + configuration.max_keep_alive_requests.out)
if configuration.has_secure_support then if configuration.has_secure_support then
if configuration.is_secure then if configuration.is_secure then
@@ -366,8 +366,25 @@ feature -- Output
end end
end end
timeout_representation (a_ns: NATURAL_64): STRING
do
if 1_000 * (a_ns // 1_000) = a_ns then
if 1_000_000 * (a_ns // 1_000_000) = a_ns then
if 1_000_000_000 * (a_ns // 1_000_000_000) = a_ns then
Result := (a_ns // 1_000_000_000).out + " seconds"
else
Result := (a_ns // 1_000_000).out + " milliseconds"
end
else
Result := (a_ns // 1_000).out + " microseconds"
end
else
Result := a_ns.out + " nanoseconds"
end
end
note note
copyright: "2011-2016, Jocelyn Fiat, Javier Velilla, Eiffel Software and others" copyright: "2011-2018, Jocelyn Fiat, Javier Velilla, Eiffel Software and others"
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)" license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
source: "[ source: "[
Eiffel Software Eiffel Software

View File

@@ -12,10 +12,10 @@ note
max_concurrent_connections: set to 1, for single threaded behavior max_concurrent_connections: set to 1, for single threaded behavior
max_tcp_clients: max number of open tcp connection max_tcp_clients: max number of open tcp connection
socket_timeout: connection timeout socket_timeout_ns: connection timeout in nanoseconds
socket_recv_timeout: read data timeout socket_recv_timeout_ns: read data timeout in nanoseconds
keep_alive_timeout: amount of time the server will wait for subsequent keep_alive_timeout_ns: amount of nanoseconds the server will wait for subsequent
requests on a persistent connection, requests on a persistent connection,
max_keep_alive_requests: number of requests allowed on a persistent connection, max_keep_alive_requests: number of requests allowed on a persistent connection,
@@ -40,6 +40,8 @@ inherit
WGI_STANDALONE_HTTPD_LOGGER_CONSTANTS WGI_STANDALONE_HTTPD_LOGGER_CONSTANTS
WSF_TIMEOUT_UTILITIES
create create
make, make,
make_and_launch make_and_launch
@@ -57,9 +59,9 @@ feature {NONE} -- Initialization
port_number := {WGI_STANDALONE_CONSTANTS}.default_http_server_port --| Default, but quite often, this port is already used ... port_number := {WGI_STANDALONE_CONSTANTS}.default_http_server_port --| Default, but quite often, this port is already used ...
max_concurrent_connections := {WGI_STANDALONE_CONSTANTS}.default_max_concurrent_connections max_concurrent_connections := {WGI_STANDALONE_CONSTANTS}.default_max_concurrent_connections
max_tcp_clients := {WGI_STANDALONE_CONSTANTS}.default_max_tcp_clients max_tcp_clients := {WGI_STANDALONE_CONSTANTS}.default_max_tcp_clients
socket_timeout := {WGI_STANDALONE_CONSTANTS}.default_socket_timeout -- seconds socket_timeout_ns := seconds_to_nanoseconds ({WGI_STANDALONE_CONSTANTS}.default_socket_timeout) -- default in seconds
socket_recv_timeout := {WGI_STANDALONE_CONSTANTS}.default_socket_recv_timeout -- seconds socket_recv_timeout_ns := seconds_to_nanoseconds ({WGI_STANDALONE_CONSTANTS}.default_socket_recv_timeout) -- default in seconds
keep_alive_timeout := {WGI_STANDALONE_CONSTANTS}.default_keep_alive_timeout -- seconds. keep_alive_timeout_ns := seconds_to_nanoseconds ({WGI_STANDALONE_CONSTANTS}.default_keep_alive_timeout) -- default in seconds.
max_keep_alive_requests := {WGI_STANDALONE_CONSTANTS}.default_max_keep_alive_requests max_keep_alive_requests := {WGI_STANDALONE_CONSTANTS}.default_max_keep_alive_requests
verbose := False verbose := False
verbose_level := notice_level verbose_level := notice_level
@@ -111,9 +113,9 @@ feature {NONE} -- Initialization
end end
max_concurrent_connections := opts.option_integer_value ("max_concurrent_connections", max_concurrent_connections) max_concurrent_connections := opts.option_integer_value ("max_concurrent_connections", max_concurrent_connections)
max_tcp_clients := opts.option_integer_value ("max_tcp_clients", max_tcp_clients) max_tcp_clients := opts.option_integer_value ("max_tcp_clients", max_tcp_clients)
socket_timeout := opts.option_integer_value ("socket_timeout", socket_timeout) socket_timeout_ns := opts.option_timeout_ns_value ("socket_timeout", socket_timeout_ns)
socket_recv_timeout := opts.option_integer_value ("socket_recv_timeout", socket_recv_timeout) socket_recv_timeout_ns := opts.option_timeout_ns_value ("socket_recv_timeout", socket_recv_timeout_ns)
keep_alive_timeout := opts.option_integer_value ("keep_alive_timeout", keep_alive_timeout) keep_alive_timeout_ns := opts.option_timeout_ns_value ("keep_alive_timeout", keep_alive_timeout_ns)
max_keep_alive_requests := opts.option_integer_value ("max_keep_alive_requests", max_keep_alive_requests) max_keep_alive_requests := opts.option_integer_value ("max_keep_alive_requests", max_keep_alive_requests)
if if
@@ -169,9 +171,9 @@ feature -- Execution
cfg.http_server_port := port_number cfg.http_server_port := port_number
cfg.set_max_concurrent_connections (max_concurrent_connections) cfg.set_max_concurrent_connections (max_concurrent_connections)
cfg.set_max_tcp_clients (max_tcp_clients) cfg.set_max_tcp_clients (max_tcp_clients)
cfg.set_socket_timeout (socket_timeout) cfg.set_socket_timeout_ns (socket_timeout_ns)
cfg.set_socket_recv_timeout (socket_recv_timeout) cfg.set_socket_recv_timeout_ns (socket_recv_timeout_ns)
cfg.set_keep_alive_timeout (keep_alive_timeout) cfg.set_keep_alive_timeout_ns (keep_alive_timeout_ns)
cfg.set_max_keep_alive_requests (max_keep_alive_requests) cfg.set_max_keep_alive_requests (max_keep_alive_requests)
end end
@@ -244,10 +246,10 @@ feature {NONE} -- Implementation
end end
max_tcp_clients: INTEGER max_tcp_clients: INTEGER
socket_timeout: INTEGER socket_timeout_ns: NATURAL_64
socket_recv_timeout: INTEGER socket_recv_timeout_ns: NATURAL_64
keep_alive_timeout: INTEGER keep_alive_timeout_ns: NATURAL_64
max_keep_alive_requests: INTEGER max_keep_alive_requests: INTEGER
is_secure_connection_supported: BOOLEAN is_secure_connection_supported: BOOLEAN

View File

@@ -23,6 +23,8 @@ deferred class
inherit inherit
WEB_SOCKET_CONSTANTS WEB_SOCKET_CONSTANTS
WSF_TIMEOUT_UTILITIES
REFACTORING_HELPER REFACTORING_HELPER
feature -- Web Socket Interface feature -- Web Socket Interface
@@ -90,13 +92,18 @@ feature -- Websocket events
feature {WEB_SOCKET} -- Timeout. feature {WEB_SOCKET} -- Timeout.
timer_delay: INTEGER timer_delay_ns: NATURAL_64
-- Maximal duration in seconds between two `on_timeout` event. -- Maximal duration in nanoseconds between two `on_timeout` event.
-- Disable timeout event, by setting it to `0` (default). -- Disable timeout event, by setting it to `0` (default).
set_timer_delay_ns (nb_nanosecs: NATURAL_64)
do
timer_delay_ns := nb_nanosecs
end
set_timer_delay (nb_secs: INTEGER) set_timer_delay (nb_secs: INTEGER)
do do
timer_delay := nb_secs timer_delay_ns := seconds_to_nanoseconds (nb_secs)
end end
on_timer (ws: WEB_SOCKET) on_timer (ws: WEB_SOCKET)
@@ -143,7 +150,7 @@ feature -- Websocket events: implemented
end end
note note
copyright: "2011-2017, Jocelyn Fiat, Javier Velilla, Eiffel Software and others" copyright: "2011-2018, Jocelyn Fiat, Javier Velilla, Eiffel Software and others"
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)" license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
source: "[ source: "[
Eiffel Software Eiffel Software

View File

@@ -42,7 +42,7 @@ feature {NONE} -- Initialization
end end
end end
feature {NONE} -- Access feature {WEB_SOCKET_EVENT_I} -- Access
request: WSF_REQUEST request: WSF_REQUEST
-- Associated request. -- Associated request.
@@ -209,29 +209,30 @@ feature {WEB_SOCKET_HANDLER} -- Networking
wait_for_input (cb: detachable WEB_SOCKET_EVENT_I) wait_for_input (cb: detachable WEB_SOCKET_EVENT_I)
local local
l_timeout, nb: INTEGER nb,
l_cb_timeout: INTEGER l_timeout_ns,
l_cb_timeout_ns: NATURAL_64
do do
has_input := False has_input := False
if cb = Void then if cb = Void then
has_input := socket.ready_for_reading has_input := socket.ready_for_reading
else else
l_cb_timeout := cb.timer_delay l_cb_timeout_ns := cb.timer_delay_ns
l_timeout := socket.timeout l_timeout_ns := socket.timeout_ns
if l_cb_timeout = 0 then if l_cb_timeout_ns = 0 then
-- timeout event not enabled. -- timeout event not enabled.
has_input := socket.ready_for_reading has_input := socket.ready_for_reading
else else
cb.on_timer (Current) cb.on_timer (Current)
if l_cb_timeout > l_timeout then if l_cb_timeout_ns > l_timeout_ns then
-- event timeout duration is bigger than socket timeout -- event timeout duration is bigger than socket timeout
-- thus, no on_timeout before next frame waiting -- thus, no on_timeout before next frame waiting
has_input := socket.ready_for_reading has_input := socket.ready_for_reading
else else
from from
l_timeout := socket.timeout l_timeout_ns := socket.timeout_ns
nb := l_timeout nb := l_timeout_ns
socket.set_timeout (l_cb_timeout) -- FIXME: for now 1 sec is the smaller timeout we can use. socket.set_timeout_ns (l_cb_timeout_ns)
until until
has_input or nb <= 0 has_input or nb <= 0
loop loop
@@ -239,13 +240,13 @@ feature {WEB_SOCKET_HANDLER} -- Networking
if not has_input then if not has_input then
-- Call on_timeout only if there is no input, -- Call on_timeout only if there is no input,
-- otherwise it was called once before the initial wait. -- otherwise it was called once before the initial wait.
socket.set_timeout (l_timeout) socket.set_timeout_ns (l_timeout_ns)
cb.on_timer (Current) cb.on_timer (Current)
socket.set_timeout (l_cb_timeout) socket.set_timeout_ns (l_cb_timeout_ns)
end end
nb := nb - l_cb_timeout nb := nb - l_cb_timeout_ns
end end
socket.set_timeout (l_timeout) socket.set_timeout_ns (l_timeout_ns)
end end
end end
end end
@@ -772,7 +773,7 @@ feature {NONE} -- Debug
end end
note note
copyright: "2011-2017, Jocelyn Fiat, Javier Velilla, Eiffel Software and others" copyright: "2011-2018, Jocelyn Fiat, Javier Velilla, Eiffel Software and others"
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)" license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
source: "[ source: "[
Eiffel Software Eiffel Software

View File

@@ -152,6 +152,80 @@ feature -- Helpers
end end
end end
option_natural_64_value (a_opt_name: READABLE_STRING_GENERAL; a_default: NATURAL_64): NATURAL_64
-- NATURAL_64 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 {NATURAL_64} opt as n then
Result := n
else
s := opt.out
if s.is_natural_64 then
Result := s.to_natural_64
end
end
end
end
option_timeout_ns_value (a_opt_name: READABLE_STRING_GENERAL; a_default: NATURAL_64): NATURAL_64
-- Timeout in nanoseconds associated to option name `a_opt_name', other return `a_default'.
local
v: detachable READABLE_STRING_GENERAL
s: STRING_32
i,l_count: INTEGER
do
if a_opt_name.ends_with ("_ns") then
-- Option use "nanoseconds" convention.
Result := option_natural_64_value (a_opt_name, a_default)
elseif attached option (a_opt_name) as opt then
if attached {READABLE_STRING_GENERAL} opt as str then
from
i := 1
l_count := str.count
until
i > l_count or v /= Void
loop
if str[i].is_space then
-- ignore
elseif str[i].is_digit then
-- Keep it
else
v := str.head (i - 1)
create s.make_from_string_general (str.substring (i, l_count))
s.adjust
end
i := i + 1
end
if v = Void then
v := str
end
if v /= Void then
if s = Void or else s.is_whitespace or else s.is_case_insensitive_equal_general ("s") then
-- Consider as `seconds` for backward compatibility
Result := timeout_utilities.seconds_to_nanoseconds (v.to_integer)
elseif s.is_case_insensitive_equal_general ("ns") then
check v.is_natural_64 end
Result := v.to_natural_64
elseif s.is_case_insensitive_equal_general ("us") then
check v.is_integer end
Result := timeout_utilities.microseconds_to_nanoseconds (v.to_integer)
elseif s.is_case_insensitive_equal_general ("ms") then
check v.is_integer end
Result := timeout_utilities.milliseconds_to_nanoseconds (v.to_integer)
end
else
-- Error!
end
else
-- Backward comptability with timeout in seconds!
Result := timeout_utilities.seconds_to_nanoseconds (option_integer_value (a_opt_name, timeout_utilities.nanoseconds_to_seconds (a_default)))
end
end
end
option_boolean_value (a_opt_name: READABLE_STRING_GENERAL; a_default: BOOLEAN): BOOLEAN 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'. -- BOOLEAN value associated to option name `a_opt_name', other return `a_default'.
local local
@@ -222,6 +296,11 @@ feature {NONE} -- Implementation
options: STRING_TABLE [detachable ANY] options: STRING_TABLE [detachable ANY]
-- Custom options which might be support (or not) by the default service -- Custom options which might be support (or not) by the default service
timeout_utilities: WSF_TIMEOUT_UTILITIES
once
create Result
end
invariant invariant
options_attached: options /= Void options_attached: options /= Void
note note