Compare commits

..

1 Commits

Author SHA1 Message Date
7a182fa02f A few tests with passive region, and expanded objects. 2016-06-14 14:43:26 +02:00
22 changed files with 217 additions and 369 deletions

View File

@@ -22,8 +22,10 @@ feature {NONE} -- Initialization
do do
-- 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)
import_service_options (create {WSF_SERVICE_LAUNCHER_OPTIONS_FROM_INI}.make_from_file ("simple.ini")) set_service_option ("max_concurrent_connections", 10)
set_service_option ("keep_alive_timeout", 1)
set_service_option ("verbose", True)
end end
end end

View File

@@ -18,10 +18,10 @@ feature -- Basic operations
local local
s: STRING s: STRING
dt: HTTP_DATE dt: HTTP_DATE
do do
-- To send a response we need to setup, the status code and -- To send a response we need to setup, the status code and
-- the response headers. -- the response headers.
s := "Hello World!" s := "Hello World!"
create dt.make_now_utc create dt.make_now_utc
s.append (" (UTC time is " + dt.rfc850_string + ").") 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.put_header ({HTTP_STATUS_CODE}.ok, <<["Content-Type", "text/html"], ["Content-Length", s.count.out]>>)

View File

@@ -16,11 +16,19 @@
</target> </target>
<target name="simple_standalone" extends="common"> <target name="simple_standalone" extends="common">
<root class="APPLICATION" feature="make_and_launch"/> <root class="APPLICATION" feature="make_and_launch"/>
<option warning="true" is_attached_by_default="true" void_safety="all" syntax="transitional"> <option warning="true" is_attached_by_default="true" void_safety="transitional" syntax="transitional">
<assertions precondition="true" postcondition="true" check="true" invariant="true" loop="true" supplier_precondition="true"/> <assertions precondition="true" postcondition="true" check="true" invariant="true" loop="true" supplier_precondition="true"/>
</option> </option>
<setting name="concurrency" value="scoop"/> <setting name="concurrency" value="scoop"/>
<library name="default_standalone" location="..\..\library\server\wsf\default\standalone-safe.ecf"/> <library name="default_standalone" location="..\..\library\server\wsf\default\standalone-safe.ecf" readonly="false"/>
<cluster name="simple" location=".\" recursive="true"/>
</target>
<target name="simple_nino" extends="common">
<root class="APPLICATION" feature="make_and_launch"/>
<option warning="true" is_attached_by_default="true" void_safety="transitional" syntax="transitional">
<assertions precondition="true" postcondition="true" check="true" invariant="true" loop="true" supplier_precondition="true"/>
</option>
<library name="default_nino" location="..\..\library\server\wsf\default\nino-safe.ecf"/>
<cluster name="simple" location=".\" recursive="true"/> <cluster name="simple" location=".\" recursive="true"/>
</target> </target>
<target name="simple_cgi" extends="common"> <target name="simple_cgi" extends="common">

View File

@@ -1,8 +0,0 @@
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

@@ -23,7 +23,7 @@ feature {NONE} -- Initialization
local local
n: INTEGER n: INTEGER
p: like pool p: like pool
do do
n := max_concurrent_connections (server).max (1) -- At least one processor! n := max_concurrent_connections (server).max (1) -- At least one processor!
create p.make (n) create p.make (n)
initialize_pool (p, n) initialize_pool (p, n)

View File

@@ -10,25 +10,25 @@ feature {NONE} -- Initialization
make make
do do
http_server_port := default_http_server_port http_server_port := 80
max_concurrent_connections := default_max_concurrent_connections max_concurrent_connections := 100
max_tcp_clients := default_max_tcp_clients max_tcp_clients := 100
socket_timeout := default_socket_timeout socket_accept_timeout := 1_000
keep_alive_timeout := default_keep_alive_timeout socket_connect_timeout := 5_000
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
connection_settings.keep_alive_timeout := default_keep_alive_timeout
end end
feature -- Defaults
default_http_server_port: INTEGER = 80 feature -- Default values
default_server_port: INTEGER = 80
default_max_concurrent_connections: INTEGER = 100 default_max_concurrent_connections: INTEGER = 100
default_max_tcp_clients: INTEGER = 100 default_keep_alive_timeout: INTEGER = 5 -- in seconds.
default_socket_timeout: INTEGER = 300 -- seconds
default_keep_alive_timeout: INTEGER = 15 -- seconds
default_max_keep_alive_requests: INTEGER = 100
feature -- Access feature -- Access
@@ -40,53 +40,31 @@ 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
-- Max number of concurrent connections. socket_accept_timeout: INTEGER assign set_socket_accept_timeout
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
Result := max_concurrent_connections = 0 Result := (max_concurrent_connections = 0)
end end
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. do
Result := connection_settings.keep_alive_timeout
end
max_keep_alive_requests: INTEGER assign set_max_keep_alive_requests connection_settings: HTTPD_CONNECTION_SETTINGS
-- 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
@@ -110,6 +88,7 @@ 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
@@ -144,28 +123,20 @@ 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_accept_timeout (v: like socket_accept_timeout)
-- Set `socket_timeout' with `a_nb_seconds' -- Set `socket_accept_timeout' with `v'
do do
socket_timeout := a_nb_seconds socket_accept_timeout := v
ensure ensure
socket_timeout_set: socket_timeout = a_nb_seconds socket_accept_timeout_set: socket_accept_timeout = v
end end
set_keep_alive_timeout (a_seconds: like keep_alive_timeout) set_socket_connect_timeout (v: like socket_connect_timeout)
-- Set `keep_alive_timeout' with `a_seconds' -- Set `socket_connect_timeout' with `v'
do do
keep_alive_timeout := a_seconds socket_connect_timeout := v
ensure ensure
keep_alive_timeout_set: keep_alive_timeout = a_seconds socket_connect_timeout_set: socket_connect_timeout = v
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)
@@ -186,16 +157,17 @@ feature -- Element change
-- Set `is_verbose' to `b' -- Set `is_verbose' to `b'
do do
is_verbose := b is_verbose := b
connection_settings.is_verbose := b
ensure ensure
is_verbose_set: is_verbose = b is_verbose_set: is_verbose = b
end end
set_verbose_level (lev: INTEGER) set_keep_alive_timeout (a_seconds: like keep_alive_timeout)
-- Set `verbose_level' to `lev'. -- Set `keep_alive_timeout' with `a_seconds'
do do
verbose_level := lev connection_settings.keep_alive_timeout := a_seconds
ensure ensure
verbose_level_set: verbose_level = lev keep_alive_timeout_set: keep_alive_timeout = a_seconds
end end
mark_secure mark_secure

View File

@@ -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

View File

@@ -1,64 +0,0 @@
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

@@ -1,22 +0,0 @@
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,20 +9,12 @@ deferred class
inherit inherit
HTTPD_DEBUG_FACILITIES HTTPD_DEBUG_FACILITIES
HTTPD_LOGGER_CONSTANTS
feature {NONE} -- Initialization feature {NONE} -- Initialization
make (a_request_settings: HTTPD_REQUEST_SETTINGS) make (a_settings: HTTPD_CONNECTION_SETTINGS)
do do
connection_settings := a_settings
reset reset
-- 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
@@ -50,6 +42,10 @@ feature {NONE} -- Initialization
is_persistent_connection_requested := False is_persistent_connection_requested := False
end end
feature -- Access
connection_settings: HTTPD_CONNECTION_SETTINGS
feature -- Status report feature -- Status report
is_connected: BOOLEAN is_connected: BOOLEAN
@@ -116,44 +112,37 @@ feature -- Access
feature -- Settings feature -- Settings
is_verbose: BOOLEAN is_verbose: BOOLEAN
-- Output messages? do
Result := connection_settings.is_verbose
verbose_level: INTEGER end
-- 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 and then max_keep_alive_requests > 0 Result := {HTTPD_SERVER}.is_persistent_connection_supported
end end
is_next_persistent_connection_supported: BOOLEAN persistent_connection_timeout: INTEGER -- seconds
-- 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.
do
Result := connection_settings.keep_alive_timeout
end
feature -- Status report feature -- Status report
has_error: BOOLEAN has_error: BOOLEAN
-- Error occurred during `analyze_request_message' -- Error occurred during `analyze_request_message'
feature -- Change --feature -- Change
--
set_is_verbose (b: BOOLEAN) -- set_is_verbose (b: BOOLEAN)
-- Set `is_verbose' with `b'. -- -- Set `is_verbose' with `b'.
do -- do
is_verbose := b -- connection_settings.is_verbose := b
ensure -- ensure
is_verbose_set: is_verbose = b -- is_verbose_set: is_verbose = b
end -- end
feature -- Execution feature -- Execution
@@ -184,7 +173,7 @@ feature -- Execution
local local
l_socket: like client_socket l_socket: like client_socket
l_exit: BOOLEAN l_exit: BOOLEAN
n,m: INTEGER n: INTEGER
do do
l_socket := client_socket l_socket := client_socket
check check
@@ -194,21 +183,15 @@ 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 not is_next_persistent_connection_supported -- related to `max_keep_alive_requests'
or not is_persistent_connection_requested
or has_error or l_socket.is_closed or not l_socket.is_open_read or has_error or l_socket.is_closed or not l_socket.is_open_read
or not is_persistent_connection_requested
reset_request reset_request
end end
end end
@@ -220,6 +203,7 @@ 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
@@ -237,11 +221,10 @@ 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 (keep_alive_timeout) -- 5 seconds! l_socket.set_timeout (persistent_connection_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
@@ -250,6 +233,9 @@ feature -- Execution
remote_info := l_remote_info remote_info := l_remote_info
end end
analyze_request_message (l_socket) analyze_request_message (l_socket)
if is_verbose then
log (request_header)
end
else else
has_error := True has_error := True
debug ("dbglog") debug ("dbglog")
@@ -261,13 +247,10 @@ 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 (request_header + "%NWARNING: invalid HTTP incoming request", warning_level) log ("ERROR: invalid HTTP incoming request")
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")
@@ -311,11 +294,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')
@@ -332,10 +315,8 @@ 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
debug ("ew_standalone") if l_is_verbose then
if l_is_verbose then log (line)
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
@@ -382,11 +363,9 @@ feature -- Parsing
local local
n, pos, next_pos: INTEGER n, pos, next_pos: INTEGER
do do
debug ("ew_standalone") if is_verbose then
if is_verbose then log ("%N## Parse HTTP request line ##")
log ("%N## Parse HTTP request line ##", debug_level) log (line)
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)
@@ -403,7 +382,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 or is_verbose not_has_error: not has_error
is_readable: a_socket.is_open_read is_readable: a_socket.is_open_read
local local
retried: BOOLEAN retried: BOOLEAN
@@ -414,19 +393,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 (request_header +"%N" + Result + "%N## socket_ok=False! ##", debug_level) log ("%N## Socket is not ok! ##")
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 (request_header + "%N## Socket is not readable! ##", debug_level) log ("%N## Socket is not readable! ##")
end end
end end
rescue rescue
@@ -446,17 +425,13 @@ feature -- Output
logger_set: logger = a_logger logger_set: logger = a_logger
end end
log (m: STRING; a_level: INTEGER) log (m: STRING)
-- Log message `m'. -- Log message `m'.
require
is_verbose: is_verbose
do do
if is_verbose and (verbose_level & a_level) = a_level then if attached logger as l_logger then
if attached logger as l_logger then l_logger.log (m)
l_logger.log (m) else
else io.put_string (m + "%N")
io.put_string (m + "%N")
end
end end
end end

View File

@@ -51,9 +51,6 @@ 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.
@@ -103,16 +100,7 @@ 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 ...") log ("%N%NStarting Web Application Server (port=" + configuration.http_server_port.out + "):%N")
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
@@ -162,7 +150,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
@@ -171,9 +159,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 ("%NListening on port " + l_http_port.out +" : https://localhost:" + l_http_port.out + "/") log ("%NHTTP Connection Server ready on port " + l_http_port.out +" : https://localhost:" + l_http_port.out + "/")
else else
log ("%NListening on port " + l_http_port.out +" : http://localhost:" + l_http_port.out + "/") log ("%NHTTP Connection Server ready 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)
@@ -324,7 +312,6 @@ 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

@@ -19,14 +19,13 @@ inherit
SHARED_HTML_ENCODER SHARED_HTML_ENCODER
create create
make,
make_with_connector make_with_connector
feature {NONE} -- Initialization feature {NONE} -- Initialization
make_with_connector (a_request_settings: HTTPD_REQUEST_SETTINGS; conn: like connector) make_with_connector (a_connection_settings: HTTPD_CONNECTION_SETTINGS; conn: like connector)
do do
make (a_request_settings) make (a_connection_settings)
connector := conn connector := conn
end end
@@ -53,6 +52,11 @@ 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)
@@ -79,7 +83,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 (is_persistent_connection_supported and is_next_persistent_connection_supported) res.set_is_persistent_connection_supported ({HTTPD_SERVER}.is_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,23 +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 connection_settings: HTTPD_CONNECTION_SETTINGS
-- Settings specific to request handling. -- Connection settings related to httpd solution.
feature -- Element change feature -- Element change
update_with (conn: like connector; a_conf: separate HTTPD_CONFIGURATION) set_connector (a_settings: HTTPD_CONNECTION_SETTINGS; conn: like connector)
-- Set `connector' with `conn'. -- Set `connector' with `conn'.
do do
connection_settings := a_settings
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 (request_settings, connector) create Result.make_with_connector (connection_settings, connector)
end end
note note

View File

@@ -26,13 +26,18 @@ feature {NONE} -- Initialization
create on_launched_actions create on_launched_actions
-- Server -- Server
-- create fac
create <NONE> fac create <NONE> fac
request_handler_factory := fac request_handler_factory := fac
create server.make (fac) create server.make (fac)
-- create <NONE> server.make (fac)
-- create observer
create <NONE> observer create <NONE> observer
configuration := server_configuration (server) configuration := server_configuration (server)
controller := server_controller (server) controller := server_controller (server)
initialize_server (server) initialize_server (server)
set_factory_connector (configuration, Current, fac)
end end
make_with_base (a_base: like base) make_with_base (a_base: like base)
@@ -51,9 +56,9 @@ feature {NONE} -- Separate helper
a_server.set_observer (observer) a_server.set_observer (observer)
end end
update_factory (conn: detachable separate WGI_STANDALONE_CONNECTOR [G]; fac: separate WGI_HTTPD_REQUEST_HANDLER_FACTORY [G]; a_conf: separate HTTPD_CONFIGURATION) set_factory_connector (a_conf: like configuration; conn: detachable separate WGI_STANDALONE_CONNECTOR [G]; fac: separate WGI_HTTPD_REQUEST_HANDLER_FACTORY [G])
do do
fac.update_with (conn, a_conf) fac.set_connector (a_conf.connection_settings, conn)
end end
server_configuration (a_server: like server): like configuration server_configuration (a_server: like server): like configuration
@@ -61,6 +66,9 @@ feature {NONE} -- Separate helper
Result := a_server.configuration Result := a_server.configuration
end end
request_handler_factory: separate WGI_HTTPD_REQUEST_HANDLER_FACTORY [G]
-- REQUEST Handler factory.
feature -- Access feature -- Access
name: STRING_8 = "httpd" name: STRING_8 = "httpd"
@@ -74,9 +82,6 @@ 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.
@@ -100,6 +105,9 @@ 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]]]
@@ -117,6 +125,11 @@ feature -- Event
feature -- Element change 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 (v: like base)
-- Set base url `base' to `v'. -- Set base url `base' to `v'.
require require
@@ -190,22 +203,18 @@ feature {NONE} -- Implementation
Result := a_server.controller Result := a_server.controller
end end
apply_configuration (a_configuration: like configuration) configure_server (a_configuration: like configuration)
local
v: BOOLEAN
do do
v := a_configuration.is_verbose if a_configuration.is_verbose then
if v then if attached base as l_base 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
apply_configuration (a_server.configuration) configure_server (a_server.configuration)
a_server.launch a_server.launch
end end
@@ -233,6 +242,7 @@ 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

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

View File

@@ -24,7 +24,7 @@ feature {NONE} -- Initialization
set_source (a_source) set_source (a_source)
end end
feature {WGI_STANDALONE_CONNECTOR, WGI_SERVICE} -- Nino feature {WGI_STANDALONE_CONNECTOR, WGI_SERVICE} -- Standalone connector.
set_source (i: like source) set_source (i: like source)
do do

View File

@@ -108,6 +108,7 @@ 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,8 +25,6 @@ inherit
launchable launchable
end end
WGI_STANDALONE_HTTPD_LOGGER_CONSTANTS
create create
make, make,
make_and_launch make_and_launch
@@ -36,20 +34,12 @@ 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 ...
max_concurrent_connections := 100 keep_alive_timeout := 5_000 -- 5 seconds.
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
@@ -59,45 +49,15 @@ feature {NONE} -- Initialization
if attached {READABLE_STRING_GENERAL} opts.option ("base") as l_base_str then if attached {READABLE_STRING_GENERAL} opts.option ("base") as l_base_str then
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", False) then if opts.option_boolean_value ("force_single_threaded", single_threaded) 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
@@ -105,28 +65,27 @@ feature {NONE} -- Initialization
conn.on_launched_actions.extend (agent on_launched) conn.on_launched_actions.extend (agent on_launched)
conn.set_base (base_url) conn.set_base (base_url)
update_configuration (conn.configuration) update_configuration (conn, conn.configuration)
end end
force_single_threaded force_single_threaded
-- Set `single_threaded' to True. -- Set `single_threaded' to True.
do do
max_concurrent_connections := 1 max_concurrent_connections := 0
end end
feature -- Execution feature -- Execution
update_configuration (cfg: like connector.configuration) update_configuration (conn: like connector; cfg: like connector.configuration)
do do
cfg.set_is_verbose (verbose) cfg.set_is_verbose (verbose)
cfg.set_verbose_level (verbose_level) if attached server_name as l_server_name then
cfg.set_http_server_name (server_name) cfg.set_http_server_name (l_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)
cfg.set_max_keep_alive_requests (max_keep_alive_requests) conn.update_configuration (cfg)
end end
launch launch
@@ -147,7 +106,7 @@ feature -- Execution
end end
end end
end end
update_configuration (conn.configuration) update_configuration (conn, conn.configuration)
conn.launch conn.launch
end end
@@ -173,21 +132,16 @@ 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

@@ -22,11 +22,11 @@ note
For instance, you can use For instance, you can use
create s.make_and_launch_and_options (agent execute, <<["port", 8099]>>) 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") port: numeric such as 8099 (or equivalent string as "8099")
base: base_url (very specific to standalone server) base: base_url (very specific to standalone server)
force_single_threaded: use only one thread, useful for Nino max_concurrent_connections: by default 100
verbose: to display verbose output, useful for Nino verbose: to display verbose output, useful for Standalone connector.
]" ]"
date: "$Date$" date: "$Date$"
revision: "$Revision$" revision: "$Revision$"

View File

@@ -85,21 +85,6 @@ 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

View File

@@ -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