Added advanced settings for standalone connector

- max_concurrent_connections=100
- keep_alive_timeout=15
- max_tcp_clients=100
- socket_timeout=300
- max_keep_alive_requests=300
And then can be set via the options as well, and via .ini file.
Also improved the verbose console output system.
This commit is contained in:
2016-06-15 09:19:23 +02:00
parent af5fc75743
commit 113aa69efc
15 changed files with 347 additions and 94 deletions

View File

@@ -23,11 +23,7 @@ feature {NONE} -- Initialization
-- Specific to `standalone' connector (the EiffelWeb server). -- Specific to `standalone' connector (the EiffelWeb server).
-- See `{WSF_STANDALONE_SERVICE_LAUNCHER}.initialize' -- See `{WSF_STANDALONE_SERVICE_LAUNCHER}.initialize'
set_service_option ("port", 9090) set_service_option ("port", 9090)
set_service_option ("max_concurrent_connections", 10) import_service_options (create {WSF_SERVICE_LAUNCHER_OPTIONS_FROM_INI}.make_from_file ("simple.ini"))
set_service_option ("keep_alive_timeout", 1)
set_service_option ("verbose", True)
end end
end end

View File

@@ -0,0 +1,8 @@
verbose=true
verbose_level=ALERT
port=9090
#max_concurrent_connections=100
#keep_alive_timeout=15
#max_tcp_clients=100
#socket_timeout=300
#max_keep_alive_requests=300

View File

@@ -10,17 +10,26 @@ feature {NONE} -- Initialization
make make
do do
http_server_port := 80 http_server_port := default_http_server_port
max_concurrent_connections := 100 max_concurrent_connections := default_max_concurrent_connections
max_tcp_clients := 100 max_tcp_clients := default_max_tcp_clients
socket_accept_timeout := 1_000 socket_timeout := default_socket_timeout
socket_connect_timeout := 5_000 keep_alive_timeout := default_keep_alive_timeout
keep_alive_timeout := 5 max_keep_alive_requests := default_max_keep_alive_requests
is_secure := False is_secure := False
create ca_crt.make_empty create ca_crt.make_empty
create ca_key.make_empty create ca_key.make_empty
end end
feature -- Defaults
default_http_server_port: INTEGER = 80
default_max_concurrent_connections: INTEGER = 100
default_max_tcp_clients: INTEGER = 100
default_socket_timeout: INTEGER = 300 -- seconds
default_keep_alive_timeout: INTEGER = 15 -- seconds
default_max_keep_alive_requests: INTEGER = 100
feature -- Access feature -- Access
Server_details: STRING_8 Server_details: STRING_8
@@ -31,9 +40,15 @@ feature -- Access
http_server_name: detachable READABLE_STRING_8 assign set_http_server_name http_server_name: detachable READABLE_STRING_8 assign set_http_server_name
http_server_port: INTEGER assign set_http_server_port http_server_port: INTEGER assign set_http_server_port
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.
socket_timeout: INTEGER assign set_socket_timeout
-- Amount of seconds that the server waits for receipts and transmissions during communications.
-- note: with timeout of 0, socket can wait for ever.
-- By default: 300 seconds, which is appropriate for most situations.
max_concurrent_connections: INTEGER assign set_max_concurrent_connections max_concurrent_connections: INTEGER assign set_max_concurrent_connections
socket_accept_timeout: INTEGER assign set_socket_accept_timeout -- Max number of concurrent connections.
socket_connect_timeout: INTEGER assign set_socket_connect_timeout
force_single_threaded: BOOLEAN assign set_force_single_threaded force_single_threaded: BOOLEAN assign set_force_single_threaded
do do
@@ -43,15 +58,35 @@ feature -- Access
is_verbose: BOOLEAN assign set_is_verbose is_verbose: BOOLEAN assign set_is_verbose
-- Display verbose message to the output? -- Display verbose message to the output?
verbose_level: INTEGER assign set_verbose_level
-- Verbosity of output.
keep_alive_timeout: INTEGER assign set_keep_alive_timeout keep_alive_timeout: INTEGER assign set_keep_alive_timeout
-- Persistent connection timeout -- Persistent connection timeout.
-- 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.
-- By default: 5 seconds.
max_keep_alive_requests: INTEGER assign set_max_keep_alive_requests
-- Maximum number of requests allowed per persistent connection.
-- Recommended a high setting.
-- To disable KeepAlive, set `max_keep_alive_requests' to 0.
-- By default: 100 .
has_ssl_support: BOOLEAN has_ssl_support: BOOLEAN
-- Has SSL support? -- Has SSL support?
deferred deferred
end end
request_settings: HTTPD_REQUEST_SETTINGS
do
Result.is_verbose := is_verbose
Result.verbose_level := verbose_level
Result.timeout := socket_timeout
Result.keep_alive_timeout := keep_alive_timeout
Result.max_keep_alive_requests := max_keep_alive_requests
end
feature -- Access: SSL feature -- Access: SSL
is_secure: BOOLEAN is_secure: BOOLEAN
@@ -75,7 +110,6 @@ feature -- Element change
else else
create {IMMUTABLE_STRING_8} http_server_name.make_from_separate (v) create {IMMUTABLE_STRING_8} http_server_name.make_from_separate (v)
end end
--| Missing postcondition.
end end
unset_http_server_name unset_http_server_name
@@ -110,27 +144,35 @@ feature -- Element change
max_concurrent_connections_set : max_concurrent_connections = v max_concurrent_connections_set : max_concurrent_connections = v
end end
set_socket_accept_timeout (v: like socket_accept_timeout) set_socket_timeout (a_nb_seconds: like socket_timeout)
-- Set `socket_accept_timeout' with `v' -- Set `socket_timeout' with `a_nb_seconds'
do do
socket_accept_timeout := v socket_timeout := a_nb_seconds
ensure ensure
socket_accept_timeout_set: socket_accept_timeout = v socket_timeout_set: socket_timeout = a_nb_seconds
end end
set_socket_connect_timeout (v: like socket_connect_timeout) set_keep_alive_timeout (a_seconds: like keep_alive_timeout)
-- Set `socket_connect_timeout' with `v' -- Set `keep_alive_timeout' with `a_seconds'
do do
socket_connect_timeout := v keep_alive_timeout := a_seconds
ensure ensure
socket_connect_timeout_set: socket_connect_timeout = v keep_alive_timeout_set: keep_alive_timeout = a_seconds
end
set_max_keep_alive_requests (nb: like max_keep_alive_requests)
-- Set `max_keep_alive_requests' with `nb'
do
max_keep_alive_requests := nb
ensure
max_keep_alive_requests_set: max_keep_alive_requests = nb
end end
set_force_single_threaded (v: like force_single_threaded) set_force_single_threaded (v: like force_single_threaded)
-- Force server to handle incoming request in a single thread. -- Force server to handle incoming request in a single thread.
-- i.e set max_concurrent_connections to 0! -- i.e set max_concurrent_connections to 0!
obsolete obsolete
"Use set_max_concurrent_connections (0) [June/2016]" "Use set_max_concurrent_connections (0) [June/2016]"
do do
if v then if v then
set_max_concurrent_connections (0) set_max_concurrent_connections (0)
@@ -148,12 +190,12 @@ feature -- Element change
is_verbose_set: is_verbose = b is_verbose_set: is_verbose = b
end end
set_keep_alive_timeout (a_seconds: like keep_alive_timeout) set_verbose_level (lev: INTEGER)
-- Set `keep_alive_timeout' with `a_seconds' -- Set `verbose_level' to `lev'.
do do
keep_alive_timeout := a_seconds verbose_level := lev
ensure ensure
keep_alive_timeout_set: keep_alive_timeout = a_seconds verbose_level_set: verbose_level = lev
end end
mark_secure mark_secure

View File

@@ -0,0 +1,64 @@
note
description: "[
Request settings for the standalone HTTPd server.
]"
author: "$Author$"
date: "$Date$"
revision: "$Revision$"
expanded class
HTTPD_REQUEST_SETTINGS
feature -- Access
is_verbose: BOOLEAN assign set_is_verbose
-- Is verbose?
verbose_level: INTEGER assign set_verbose_level
-- Verbosity of output.
timeout: INTEGER assign set_timeout
-- Amount of seconds that the server waits for receipts and transmissions during communications.
keep_alive_timeout: INTEGER assign set_keep_alive_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.
-- Unit in Seconds.
max_keep_alive_requests: INTEGER assign set_max_keep_alive_requests
-- Maximum number of requests allowed per persistent connection.
feature -- Change
set_is_verbose (b: BOOLEAN)
-- Set `is_verbose' to `b'.
do
is_verbose := b
end
set_verbose_level (lev: INTEGER)
-- Set `verbose_level' to `lev'.
do
verbose_level := lev
end
set_timeout (a_timeout_in_seconds: INTEGER)
-- Set `timeout' to `a_timeout_in_seconds'.
do
timeout := a_timeout_in_seconds
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
set_max_keep_alive_requests (nb: like max_keep_alive_requests)
-- Set `max_keep_alive_requests' with `nb'
do
max_keep_alive_requests := nb
end
end

View File

@@ -0,0 +1,22 @@
note
description: "[
Constant value to define the logging level.
]"
date: "$Date$"
revision: "$Revision$"
deferred class
HTTPD_LOGGER_CONSTANTS
feature -- Access
alert_level: INTEGER = 1 -- 0000 0001
critical_level: INTEGER = 2 -- 0000 0010
error_level: INTEGER = 4 -- 0000 0100
warning_level: INTEGER = 8 -- 0000 1000
notice_level: INTEGER = 16 -- 0001 0000
information_level: INTEGER = 32 -- 0010 0000
debug_level: INTEGER = 64 -- 0100 0000
end

View File

@@ -9,12 +9,20 @@ deferred class
inherit inherit
HTTPD_DEBUG_FACILITIES HTTPD_DEBUG_FACILITIES
HTTPD_LOGGER_CONSTANTS
feature {NONE} -- Initialization feature {NONE} -- Initialization
make make (a_request_settings: HTTPD_REQUEST_SETTINGS)
do do
reset reset
persistent_connection_timeout := 5 -- seconds -- Import global request settings.
timeout := a_request_settings.timeout -- seconds
keep_alive_timeout := a_request_settings.keep_alive_timeout -- seconds
max_keep_alive_requests := a_request_settings.max_keep_alive_requests
is_verbose := a_request_settings.is_verbose
verbose_level := a_request_settings.verbose_level
end end
reset reset
@@ -108,16 +116,29 @@ feature -- Access
feature -- Settings feature -- Settings
is_verbose: BOOLEAN is_verbose: BOOLEAN
-- Output messages?
verbose_level: INTEGER
-- Output verbosity.
is_persistent_connection_supported: BOOLEAN is_persistent_connection_supported: BOOLEAN
-- Is persistent connection supported? -- Is persistent connection supported?
do do
Result := {HTTPD_SERVER}.is_persistent_connection_supported Result := {HTTPD_SERVER}.is_persistent_connection_supported and then max_keep_alive_requests > 0
end end
persistent_connection_timeout: INTEGER -- seconds is_next_persistent_connection_supported: BOOLEAN
-- Is next persistent connection supported?
-- note: it is relevant only if `is_persistent_connection_supported' is True.
timeout: INTEGER -- seconds
-- Amount of seconds that the server waits for receipts and transmissions during communications.
max_keep_alive_requests: INTEGER
-- Maximum number of requests allowed per persistent connection.
keep_alive_timeout: INTEGER -- seconds
-- Number of seconds for persistent connection timeout. -- Number of seconds for persistent connection timeout.
-- Default: 5 sec.
feature -- Status report feature -- Status report
@@ -163,7 +184,7 @@ feature -- Execution
local local
l_socket: like client_socket l_socket: like client_socket
l_exit: BOOLEAN l_exit: BOOLEAN
n: INTEGER n,m: INTEGER
do do
l_socket := client_socket l_socket := client_socket
check check
@@ -173,15 +194,21 @@ feature -- Execution
from from
-- Process persistent connection as long the socket is not closed. -- Process persistent connection as long the socket is not closed.
n := 0 n := 0
m := max_keep_alive_requests
is_next_persistent_connection_supported := True
until until
l_exit l_exit
loop loop
n := n + 1 n := n + 1
if n >= m then
is_next_persistent_connection_supported := False
end
-- FIXME: it seems to be called one more time, mostly to see this is done. -- FIXME: it seems to be called one more time, mostly to see this is done.
execute_request execute_request
l_exit := not is_persistent_connection_supported l_exit := not is_persistent_connection_supported
or has_error or l_socket.is_closed or not l_socket.is_open_read or not is_next_persistent_connection_supported -- related to `max_keep_alive_requests'
or not is_persistent_connection_requested or not is_persistent_connection_requested
or has_error or l_socket.is_closed or not l_socket.is_open_read
reset_request reset_request
end end
end end
@@ -193,7 +220,6 @@ feature -- Execution
l_remote_info: detachable like remote_info l_remote_info: detachable like remote_info
l_socket: like client_socket l_socket: like client_socket
l_is_ready: BOOLEAN l_is_ready: BOOLEAN
i: INTEGER
do do
l_socket := client_socket l_socket := client_socket
check check
@@ -211,10 +237,11 @@ feature -- Execution
--| TODO: add configuration options for socket timeout. --| TODO: add configuration options for socket timeout.
--| set by default 5 seconds. --| set by default 5 seconds.
l_socket.set_timeout (persistent_connection_timeout) -- 5 seconds! l_socket.set_timeout (keep_alive_timeout) -- 5 seconds!
l_is_ready := l_socket.ready_for_reading l_is_ready := l_socket.ready_for_reading
if l_is_ready then if l_is_ready then
l_socket.set_timeout (timeout) -- FIXME: return a 408 Request Timeout response ..
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
l_remote_info.addr := l_addr.host_address.host_address l_remote_info.addr := l_addr.host_address.host_address
@@ -234,10 +261,13 @@ feature -- Execution
if l_is_ready then if l_is_ready then
-- check catch_bad_incoming_connection: False end -- check catch_bad_incoming_connection: False end
if is_verbose then if is_verbose then
log ("ERROR: invalid HTTP incoming request") log (request_header + "%NWARNING: invalid HTTP incoming request", warning_level)
end end
end end
else else
if is_verbose then
log (request_header, information_level)
end
process_request (l_socket) process_request (l_socket)
end end
debug ("dbglog") debug ("dbglog")
@@ -281,11 +311,11 @@ feature -- Parsing
do do
create txt.make (64) create txt.make (64)
request_header := txt request_header := txt
if if
not has_error and then not has_error and then
a_socket.is_readable and then a_socket.is_readable and then
attached next_line (a_socket) as l_request_line and then attached next_line (a_socket) as l_request_line and then
not l_request_line.is_empty not l_request_line.is_empty
then then
txt.append (l_request_line) txt.append (l_request_line)
txt.append_character ('%N') txt.append_character ('%N')
@@ -302,8 +332,10 @@ feature -- Parsing
line = Void or end_of_stream or has_error line = Void or end_of_stream or has_error
loop loop
n := line.count n := line.count
if l_is_verbose then debug ("ew_standalone")
log (line) if l_is_verbose then
log (line, debug_level)
end
end end
pos := line.index_of (':', 1) pos := line.index_of (':', 1)
if pos > 0 then if pos > 0 then
@@ -350,9 +382,11 @@ feature -- Parsing
local local
n, pos, next_pos: INTEGER n, pos, next_pos: INTEGER
do do
if is_verbose then debug ("ew_standalone")
log ("%N## Parse HTTP request line ##") if is_verbose then
log (line) log ("%N## Parse HTTP request line ##", debug_level)
log (line, debug_level)
end
end end
pos := line.index_of (' ', 1) pos := line.index_of (' ', 1)
method := line.substring (1, pos - 1) method := line.substring (1, pos - 1)
@@ -369,7 +403,7 @@ feature -- Parsing
next_line (a_socket: HTTPD_STREAM_SOCKET): detachable STRING next_line (a_socket: HTTPD_STREAM_SOCKET): detachable STRING
-- Next line fetched from `a_socket' is available. -- Next line fetched from `a_socket' is available.
require require
not_has_error: not has_error not_has_error: not has_error or is_verbose
is_readable: a_socket.is_open_read is_readable: a_socket.is_open_read
local local
retried: BOOLEAN retried: BOOLEAN
@@ -380,19 +414,19 @@ feature -- Parsing
elseif a_socket.readable then elseif a_socket.readable then
a_socket.read_line_thread_aware a_socket.read_line_thread_aware
Result := a_socket.last_string Result := a_socket.last_string
-- Do no check `socket_ok' before socket operation, -- Do no check `socket_ok' before socket operation,
-- otherwise it may be False, due to error during other socket operation in same thread. -- otherwise it may be False, due to error during other socket operation in same thread.
if not a_socket.socket_ok then if not a_socket.socket_ok then
has_error := True has_error := True
if is_verbose then if is_verbose then
log ("%N## Socket is not ok! ##") log (request_header +"%N" + Result + "%N## socket_ok=False! ##", debug_level)
end end
end end
else else
-- Error with socket... -- Error with socket...
has_error := True has_error := True
if is_verbose then if is_verbose then
log ("%N## Socket is not readable! ##") log (request_header + "%N## Socket is not readable! ##", debug_level)
end end
end end
rescue rescue
@@ -412,13 +446,17 @@ feature -- Output
logger_set: logger = a_logger logger_set: logger = a_logger
end end
log (m: STRING) log (m: STRING; a_level: INTEGER)
-- Log message `m'. -- Log message `m'.
require
is_verbose: is_verbose
do do
if attached logger as l_logger then if is_verbose and (verbose_level & a_level) = a_level then
l_logger.log (m) if attached logger as l_logger then
else l_logger.log (m)
io.put_string (m + "%N") else
io.put_string (m + "%N")
end
end end
end end

View File

@@ -51,6 +51,9 @@ feature -- Access
is_verbose: BOOLEAN is_verbose: BOOLEAN
-- Is verbose for output messages. -- Is verbose for output messages.
verbose_level: INTEGER
-- Verbosity of output.
configuration: HTTPD_CONFIGURATION configuration: HTTPD_CONFIGURATION
-- Associated server configuration. -- Associated server configuration.
@@ -100,7 +103,16 @@ feature -- Execution
apply_configuration apply_configuration
is_terminated := False is_terminated := False
if is_verbose then if is_verbose then
log ("%N%NStarting Web Application Server (port=" + configuration.http_server_port.out + "):%N") log ("%N%NStarting Web Application Server ...")
log (" - port = " + configuration.http_server_port.out)
log (" - max_tcp_clients = " + configuration.max_tcp_clients.out)
log (" - max_concurrent_connections = " + configuration.max_concurrent_connections.out)
log (" - socket_timeout = " + configuration.socket_timeout.out + " seconds")
log (" - keep_alive_timeout = " + configuration.keep_alive_timeout.out + " seconds")
log (" - max_keep_alive_requests = " + configuration.max_keep_alive_requests.out)
if configuration.verbose_level > 0 then
log (" - verbose_level = " + configuration.verbose_level.out)
end
end end
is_shutdown_requested := False is_shutdown_requested := False
listen listen
@@ -150,7 +162,7 @@ feature -- Listening
if not l_listening_socket.is_bound then if not l_listening_socket.is_bound then
if is_verbose then if is_verbose then
log ("Socket could not be bound on port " + l_http_port.out) log ("Socket could not be bound on port " + l_http_port.out + " !")
end end
else else
l_http_port := l_listening_socket.port l_http_port := l_listening_socket.port
@@ -159,9 +171,9 @@ feature -- Listening
l_listening_socket.listen (configuration.max_tcp_clients) l_listening_socket.listen (configuration.max_tcp_clients)
if is_verbose then if is_verbose then
if configuration.is_secure then if configuration.is_secure then
log ("%NHTTP Connection Server ready on port " + l_http_port.out +" : https://localhost:" + l_http_port.out + "/") log ("%NListening on port " + l_http_port.out +" : https://localhost:" + l_http_port.out + "/")
else else
log ("%NHTTP Connection Server ready on port " + l_http_port.out +" : http://localhost:" + l_http_port.out + "/") log ("%NListening on port " + l_http_port.out +" : http://localhost:" + l_http_port.out + "/")
end end
end end
on_launched (l_http_port) on_launched (l_http_port)
@@ -312,6 +324,7 @@ feature -- Configuration change
is_not_launched: not is_launched is_not_launched: not is_launched
do do
is_verbose := configuration.is_verbose is_verbose := configuration.is_verbose
verbose_level := configuration.verbose_level
end end
feature -- Output feature -- Output

View File

@@ -24,13 +24,10 @@ create
feature {NONE} -- Initialization feature {NONE} -- Initialization
make_with_connector (conn: like connector) make_with_connector (a_request_settings: HTTPD_REQUEST_SETTINGS; conn: like connector)
do do
make make (a_request_settings)
connector := conn connector := conn
-- if conn /= Void then
-- set_is_verbose (is_connector_verbose (conn))
-- end
end end
feature -- Access feature -- Access
@@ -56,11 +53,6 @@ feature -- SCOOP helpers
Result := conn.base Result := conn.base
end end
is_connector_verbose (conn: separate WGI_STANDALONE_CONNECTOR [G]): BOOLEAN
do
Result := conn.is_verbose
end
feature -- Request processing feature -- Request processing
process_request (a_socket: HTTPD_STREAM_SOCKET) process_request (a_socket: HTTPD_STREAM_SOCKET)
@@ -87,7 +79,7 @@ feature -- Request processing
else else
l_output.set_http_version (version) l_output.set_http_version (version)
end end
res.set_is_persistent_connection_supported ({HTTPD_SERVER}.is_persistent_connection_supported) res.set_is_persistent_connection_supported (is_persistent_connection_supported and is_next_persistent_connection_supported)
res.set_is_persistent_connection_requested (is_persistent_connection_requested) res.set_is_persistent_connection_requested (is_persistent_connection_requested)
req.set_meta_string_variable ("RAW_HEADER_DATA", request_header) req.set_meta_string_variable ("RAW_HEADER_DATA", request_header)

View File

@@ -14,19 +14,23 @@ feature -- Access
connector: detachable separate WGI_STANDALONE_CONNECTOR [G] connector: detachable separate WGI_STANDALONE_CONNECTOR [G]
-- httpd solution. -- httpd solution.
request_settings: HTTPD_REQUEST_SETTINGS
-- Settings specific to request handling.
feature -- Element change feature -- Element change
update_with (conn: like connector) update_with (conn: like connector; a_conf: separate HTTPD_CONFIGURATION)
-- Set `connector' with `conn'. -- Set `connector' with `conn'.
do do
connector := conn connector := conn
request_settings := a_conf.request_settings
end end
feature -- Factory feature -- Factory
new_handler: separate WGI_HTTPD_REQUEST_HANDLER [G] new_handler: separate WGI_HTTPD_REQUEST_HANDLER [G]
do do
create Result.make_with_connector (connector) create Result.make_with_connector (request_settings, connector)
end end
note note

View File

@@ -27,11 +27,11 @@ feature {NONE} -- Initialization
-- Server -- Server
create <NONE> fac create <NONE> fac
request_handler_factory := fac
create server.make (fac) create server.make (fac)
create <NONE> observer create <NONE> observer
configuration := server_configuration (server) configuration := server_configuration (server)
controller := server_controller (server) controller := server_controller (server)
set_factory_connector (Current, fac)
initialize_server (server) initialize_server (server)
end end
@@ -51,9 +51,9 @@ feature {NONE} -- Separate helper
a_server.set_observer (observer) a_server.set_observer (observer)
end end
set_factory_connector (conn: detachable separate WGI_STANDALONE_CONNECTOR [G]; fac: separate WGI_HTTPD_REQUEST_HANDLER_FACTORY [G]) update_factory (conn: detachable separate WGI_STANDALONE_CONNECTOR [G]; fac: separate WGI_HTTPD_REQUEST_HANDLER_FACTORY [G]; a_conf: separate HTTPD_CONFIGURATION)
do do
fac.update_with (conn) fac.update_with (conn, a_conf)
end end
server_configuration (a_server: like server): like configuration server_configuration (a_server: like server): like configuration
@@ -74,6 +74,9 @@ feature -- Access
server: separate HTTPD_SERVER server: separate HTTPD_SERVER
-- HTTPd server object. -- HTTPd server object.
request_handler_factory: separate WGI_HTTPD_REQUEST_HANDLER_FACTORY [G]
-- Factory for request handlers.
controller: separate HTTPD_CONTROLLER controller: separate HTTPD_CONTROLLER
-- Controller used to shutdown server. -- Controller used to shutdown server.
@@ -97,9 +100,6 @@ feature -- Status report
-- Listening port. -- Listening port.
--| 0: not launched --| 0: not launched
is_verbose: BOOLEAN
-- Is verbose?
feature -- Callbacks feature -- Callbacks
on_launched_actions: ACTION_SEQUENCE [TUPLE [WGI_STANDALONE_CONNECTOR [WGI_EXECUTION]]] on_launched_actions: ACTION_SEQUENCE [TUPLE [WGI_STANDALONE_CONNECTOR [WGI_EXECUTION]]]
@@ -190,18 +190,22 @@ feature {NONE} -- Implementation
Result := a_server.controller Result := a_server.controller
end end
configure_server (a_configuration: like configuration) apply_configuration (a_configuration: like configuration)
local
v: BOOLEAN
do do
if a_configuration.is_verbose then v := a_configuration.is_verbose
if attached base as l_base then if v then
if attached base as l_base and then not l_base.is_whitespace then
io.error.put_string ("Base=" + l_base + "%N") io.error.put_string ("Base=" + l_base + "%N")
end end
end end
update_factory (Current, request_handler_factory, a_configuration)
end end
launch_server (a_server: like server) launch_server (a_server: like server)
do do
configure_server (a_server.configuration) apply_configuration (a_server.configuration)
a_server.launch a_server.launch
end end
@@ -229,7 +233,6 @@ feature {NONE} -- Implementation: element change
set_is_verbose_on_configuration (b: BOOLEAN; cfg: like configuration) set_is_verbose_on_configuration (b: BOOLEAN; cfg: like configuration)
do do
is_verbose := b
cfg.set_is_verbose (b) cfg.set_is_verbose (b)
end end

View File

@@ -0,0 +1,10 @@
note
description: "Export HTTPD_LOGGER_CONSTANTS to Standlone connector interfaces."
class
WGI_STANDALONE_HTTPD_LOGGER_CONSTANTS
inherit
HTTPD_LOGGER_CONSTANTS
end

View File

@@ -108,7 +108,6 @@ feature -- Header output operation
l_connection := s.substring (i + 12, j - 1) l_connection := s.substring (i + 12, j - 1)
l_connection.adjust l_connection.adjust
if if
not is_http_version_1_0 and
not l_connection.is_case_insensitive_equal_general ("close") not l_connection.is_case_insensitive_equal_general ("close")
then then
s.replace_substring ("Connection: close", i + 1, j - 1) s.replace_substring ("Connection: close", i + 1, j - 1)

View File

@@ -25,6 +25,8 @@ inherit
launchable launchable
end end
WGI_STANDALONE_HTTPD_LOGGER_CONSTANTS
create create
make, make,
make_and_launch make_and_launch
@@ -34,12 +36,20 @@ feature {NONE} -- Initialization
initialize initialize
local local
conn: like connector conn: like connector
s: READABLE_STRING_GENERAL
do do
create on_launched_actions create on_launched_actions
create on_stopped_actions create on_stopped_actions
port_number := 80 --| Default, but quite often, this port is already used ... port_number := 80 --| Default, but quite often, this port is already used ...
keep_alive_timeout := 5_000 -- 5 seconds. max_concurrent_connections := 100
max_tcp_clients := 100
socket_timeout := 300 -- 300 seconds
keep_alive_timeout := 15 -- 15 seconds.
max_keep_alive_requests := 100
verbose := False
verbose_level := notice_level
base_url := "" base_url := ""
if attached options as opts then if attached options as opts then
@@ -50,13 +60,44 @@ feature {NONE} -- Initialization
base_url := l_base_str.as_string_8 base_url := l_base_str.as_string_8
end end
verbose := opts.option_boolean_value ("verbose", verbose) verbose := opts.option_boolean_value ("verbose", verbose)
-- See `{HTTPD_REQUEST_HANDLER_I}.*_verbose_level`
if opts.has_integer_option ("verbose_level") then
verbose_level := opts.option_integer_value ("verbose_level", verbose_level)
elseif attached {READABLE_STRING_GENERAL} opts.option ("verbose_level") as s_verbose_level then
verbose_level := 0 -- Reset
across
s_verbose_level.split ('+') as ic
loop
s := ic.item
if s.is_case_insensitive_equal ("alert") then
verbose_level := verbose_level | alert_level
elseif s.is_case_insensitive_equal ("critical") then
verbose_level := verbose_level | critical_level
elseif s.is_case_insensitive_equal ("error") then
verbose_level := verbose_level | error_level
elseif s.is_case_insensitive_equal ("warning") then
verbose_level := verbose_level | warning_level
elseif s.is_case_insensitive_equal ("notice") then
verbose_level := verbose_level | notice_level
elseif s.is_case_insensitive_equal ("information") then
verbose_level := verbose_level | information_level
elseif s.is_case_insensitive_equal ("debug") then
verbose_level := verbose_level | debug_level
else
end
end
end
port_number := opts.option_integer_value ("port", port_number) port_number := opts.option_integer_value ("port", port_number)
if opts.option_boolean_value ("force_single_threaded", single_threaded) then if opts.option_boolean_value ("force_single_threaded", False) then
force_single_threaded force_single_threaded
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)
socket_timeout := opts.option_integer_value ("socket_timeout", socket_timeout)
keep_alive_timeout := opts.option_integer_value ("keep_alive_timeout", keep_alive_timeout) keep_alive_timeout := opts.option_integer_value ("keep_alive_timeout", keep_alive_timeout)
max_keep_alive_requests := opts.option_integer_value ("max_keep_alive_requests", max_keep_alive_requests)
end end
create conn.make create conn.make
@@ -78,13 +119,14 @@ feature -- Execution
update_configuration (cfg: like connector.configuration) update_configuration (cfg: like connector.configuration)
do do
cfg.set_is_verbose (verbose) cfg.set_is_verbose (verbose)
if attached server_name as l_server_name then cfg.set_verbose_level (verbose_level)
cfg.set_http_server_name (l_server_name) cfg.set_http_server_name (server_name)
end
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_socket_timeout (socket_timeout)
cfg.set_keep_alive_timeout (keep_alive_timeout) cfg.set_keep_alive_timeout (keep_alive_timeout)
-- conn.update_configuration (cfg) cfg.set_max_keep_alive_requests (max_keep_alive_requests)
end end
launch launch
@@ -131,16 +173,21 @@ feature {NONE} -- Implementation
base_url: READABLE_STRING_8 base_url: READABLE_STRING_8
verbose: BOOLEAN verbose: BOOLEAN
verbose_level: INTEGER
-- Help defining the verbosity.
-- The higher, the more output.
max_concurrent_connections: INTEGER
max_tcp_clients: INTEGER
socket_timeout: INTEGER
keep_alive_timeout: INTEGER
max_keep_alive_requests: INTEGER
single_threaded: BOOLEAN single_threaded: BOOLEAN
do do
Result := max_concurrent_connections = 0 Result := max_concurrent_connections = 0
end end
max_concurrent_connections: INTEGER
keep_alive_timeout: INTEGER
feature -- Status report feature -- Status report
connector: WGI_STANDALONE_CONNECTOR [G] connector: WGI_STANDALONE_CONNECTOR [G]

View File

@@ -85,6 +85,21 @@ feature -- Access
feature -- Helpers feature -- Helpers
has_integer_option (a_opt_name: READABLE_STRING_GENERAL): BOOLEAN
-- Is there any INTEGER value associated to option name `a_opt_name'?
local
s: READABLE_STRING_GENERAL
do
if attached option (a_opt_name) as opt then
if attached {INTEGER} opt as i then
Result := True
else
s := opt.out
Result := s.is_integer
end
end
end
option_integer_value (a_opt_name: READABLE_STRING_GENERAL; a_default: INTEGER): INTEGER 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'. -- INTEGER value associated to option name `a_opt_name', other return `a_default'.
local local

Binary file not shown.