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
17 changed files with 220 additions and 81 deletions

View File

@@ -20,9 +20,12 @@ feature {NONE} -- Initialization
initialize initialize
-- Initialize current service. -- Initialize current service.
do do
-- Specific to `standalone' connector (the EiffelWeb server).
-- See `{WSF_STANDALONE_SERVICE_LAUNCHER}.initialize'
set_service_option ("port", 9090) set_service_option ("port", 9090)
set_service_option ("max_concurrent_connections", 10)
set_service_option ("keep_alive_timeout", 1)
set_service_option ("verbose", True)
end end
end end

View File

@@ -17,10 +17,13 @@ feature -- Basic operations
execute execute
local local
s: STRING s: STRING
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
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]>>)
response.set_status_code ({HTTP_STATUS_CODE}.ok) response.set_status_code ({HTTP_STATUS_CODE}.ok)
response.header.put_content_type_text_html response.header.put_content_type_text_html

View File

@@ -1,14 +1,15 @@
<?xml version="1.0" encoding="ISO-8859-1"?> <?xml version="1.0" encoding="ISO-8859-1"?>
<system xmlns="http://www.eiffel.com/developers/xml/configuration-1-13-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-13-0 http://www.eiffel.com/developers/xml/configuration-1-13-0.xsd" name="simple" uuid="C28C4F53-9963-46C0-A080-8F13E94E7486" library_target="simple"> <system xmlns="http://www.eiffel.com/developers/xml/configuration-1-15-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-15-0 http://www.eiffel.com/developers/xml/configuration-1-15-0.xsd" name="simple" uuid="C28C4F53-9963-46C0-A080-8F13E94E7486" library_target="simple">
<target name="common" abstract="true"> <target name="common" abstract="true">
<file_rule> <file_rule>
<exclude>/EIFGENs$</exclude>
<exclude>/CVS$</exclude>
<exclude>/.svn$</exclude> <exclude>/.svn$</exclude>
<exclude>/CVS$</exclude>
<exclude>/EIFGENs$</exclude>
</file_rule> </file_rule>
<option warning="true" full_class_checking="false" is_attached_by_default="true" void_safety="transitional" syntax="transitional"> <option warning="true" full_class_checking="false" is_attached_by_default="true" is_obsolete_routine_type="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="console_application" value="true"/>
<library name="base" location="$ISE_LIBRARY\library\base\base-safe.ecf"/> <library name="base" location="$ISE_LIBRARY\library\base\base-safe.ecf"/>
<library name="http" location="..\..\library\network\protocol\http\http-safe.ecf"/> <library name="http" location="..\..\library\network\protocol\http\http-safe.ecf"/>
<library name="wsf" location="..\..\library\server\wsf\wsf-safe.ecf"/> <library name="wsf" location="..\..\library\server\wsf\wsf-safe.ecf"/>
@@ -18,8 +19,8 @@
<option warning="true" is_attached_by_default="true" void_safety="transitional" 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="thread"/> <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"/> <cluster name="simple" location=".\" recursive="true"/>
</target> </target>
<target name="simple_nino" extends="common"> <target name="simple_nino" extends="common">

View File

@@ -24,7 +24,7 @@ feature {NONE} -- Initialization
n: INTEGER n: INTEGER
p: like pool p: like pool
do do
n := max_concurrent_connections (server) 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)
pool := p pool := p

View File

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

View File

@@ -15,12 +15,21 @@ feature {NONE} -- Initialization
max_tcp_clients := 100 max_tcp_clients := 100
socket_accept_timeout := 1_000 socket_accept_timeout := 1_000
socket_connect_timeout := 5_000 socket_connect_timeout := 5_000
keep_alive_timeout := 5
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 -- Default values
default_server_port: INTEGER = 80
default_max_concurrent_connections: INTEGER = 100
default_keep_alive_timeout: INTEGER = 5 -- in seconds.
feature -- Access feature -- Access
Server_details: STRING_8 Server_details: STRING_8
@@ -45,6 +54,11 @@ feature -- Access
keep_alive_timeout: INTEGER assign set_keep_alive_timeout keep_alive_timeout: INTEGER assign set_keep_alive_timeout
-- Persistent connection timeout -- Persistent connection timeout
-- Timeout unit in Seconds. -- Timeout unit in Seconds.
do
Result := connection_settings.keep_alive_timeout
end
connection_settings: HTTPD_CONNECTION_SETTINGS
has_ssl_support: BOOLEAN has_ssl_support: BOOLEAN
-- Has SSL support? -- Has SSL support?
@@ -126,6 +140,10 @@ feature -- Element change
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.
-- i.e set max_concurrent_connections to 0!
obsolete
"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)
@@ -139,6 +157,7 @@ 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
@@ -146,7 +165,7 @@ feature -- Element change
set_keep_alive_timeout (a_seconds: like keep_alive_timeout) set_keep_alive_timeout (a_seconds: like keep_alive_timeout)
-- Set `keep_alive_timeout' with `a_seconds' -- Set `keep_alive_timeout' with `a_seconds'
do do
keep_alive_timeout := a_seconds connection_settings.keep_alive_timeout := a_seconds
ensure ensure
keep_alive_timeout_set: keep_alive_timeout = a_seconds keep_alive_timeout_set: keep_alive_timeout = a_seconds
end end

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

@@ -11,8 +11,9 @@ inherit
feature {NONE} -- Initialization feature {NONE} -- Initialization
make make (a_settings: HTTPD_CONNECTION_SETTINGS)
do do
connection_settings := a_settings
reset reset
end end
@@ -41,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
@@ -107,6 +112,9 @@ feature -- Access
feature -- Settings feature -- Settings
is_verbose: BOOLEAN is_verbose: BOOLEAN
do
Result := connection_settings.is_verbose
end
is_persistent_connection_supported: BOOLEAN is_persistent_connection_supported: BOOLEAN
-- Is persistent connection supported? -- Is persistent connection supported?
@@ -114,24 +122,27 @@ feature -- Settings
Result := {HTTPD_SERVER}.is_persistent_connection_supported Result := {HTTPD_SERVER}.is_persistent_connection_supported
end end
persistent_connection_timeout: INTEGER = 5 -- seconds persistent_connection_timeout: INTEGER -- seconds
-- Number of seconds for persistent connection timeout. -- Number of seconds for persistent connection timeout.
-- Default: 5 sec. -- 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
@@ -210,17 +221,8 @@ 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 (persistent_connection_timeout) -- 5 seconds!
l_socket.set_timeout (1) -- 1 second!
from
i := persistent_connection_timeout -- * 1 sec
until
l_is_ready or i <= 0 or has_error
loop
l_is_ready := l_socket.ready_for_reading l_is_ready := l_socket.ready_for_reading
check not l_socket.is_closed end
i := i - 1
end
if l_is_ready then if l_is_ready then
create l_remote_info create l_remote_info
@@ -231,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")

View File

@@ -37,7 +37,7 @@ feature {NONE} -- Initialization
build_controller build_controller
-- Build `controller'. -- Build `controller'.
do do
create controller create <NONE> controller
end end
initialize initialize

View File

@@ -19,18 +19,14 @@ 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 (conn: like connector) make_with_connector (a_connection_settings: HTTPD_CONNECTION_SETTINGS; conn: like connector)
do do
make make (a_connection_settings)
connector := conn connector := conn
-- if conn /= Void then
-- set_is_verbose (is_connector_verbose (conn))
-- end
end end
feature -- Access feature -- Access
@@ -56,10 +52,10 @@ feature -- SCOOP helpers
Result := conn.base Result := conn.base
end end
is_connector_verbose (conn: separate WGI_STANDALONE_CONNECTOR [G]): BOOLEAN -- is_connector_verbose (conn: separate WGI_STANDALONE_CONNECTOR [G]): BOOLEAN
do -- do
Result := conn.is_verbose -- Result := conn.is_verbose
end -- end
feature -- Request processing feature -- Request processing

View File

@@ -1,5 +1,5 @@
note note
description: "Implementation of WGI request handler factory for WGI_STANDALOE_CONNECTOR." description: "Implementation of WGI request handler factory for WGI_STANDALONE_CONNECTOR."
date: "$Date$" date: "$Date$"
revision: "$Revision$" revision: "$Revision$"
@@ -14,11 +14,15 @@ feature -- Access
connector: detachable separate WGI_STANDALONE_CONNECTOR [G] connector: detachable separate WGI_STANDALONE_CONNECTOR [G]
-- httpd solution. -- httpd solution.
connection_settings: HTTPD_CONNECTION_SETTINGS
-- Connection settings related to httpd solution.
feature -- Element change feature -- Element change
set_connector (conn: like connector) 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
end end
@@ -26,7 +30,7 @@ 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 (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 fac
create <NONE> fac
request_handler_factory := fac
create server.make (fac) create server.make (fac)
create observer -- create <NONE> server.make (fac)
-- create 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)
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
set_factory_connector (conn: detachable separate WGI_STANDALONE_CONNECTOR [G]; fac: separate WGI_HTTPD_REQUEST_HANDLER_FACTORY [G]) set_factory_connector (a_conf: like configuration; conn: detachable separate WGI_STANDALONE_CONNECTOR [G]; fac: separate WGI_HTTPD_REQUEST_HANDLER_FACTORY [G])
do do
fac.set_connector (conn) 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"
@@ -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

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

@@ -39,33 +39,25 @@ feature {NONE} -- Initialization
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.
base_url := "" base_url := ""
if attached options as opts then if attached options as opts then
if attached {READABLE_STRING_GENERAL} opts.option ("server_name") as l_server_name then if attached {READABLE_STRING_GENERAL} opts.option ("server_name") as l_server_name then
server_name := l_server_name.to_string_8 server_name := l_server_name.to_string_8
end end
if attached {INTEGER} opts.option ("port") as l_port then
port_number := l_port
elseif
attached {READABLE_STRING_GENERAL} opts.option ("port") as l_port_str and then
l_port_str.is_integer
then
port_number := l_port_str.as_string_8.to_integer
end
if attached {READABLE_STRING_GENERAL} opts.option ("base") as l_base_str then 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
if attached {BOOLEAN} opts.option ("force_single_threaded") as l_single_threaded then
single_threaded := l_single_threaded verbose := opts.option_boolean_value ("verbose", verbose)
elseif attached {READABLE_STRING_GENERAL} opts.option ("force_single_threaded") as l_single_threaded_str then port_number := opts.option_integer_value ("port", port_number)
single_threaded := l_single_threaded_str.as_lower.same_string ("true")
end if opts.option_boolean_value ("force_single_threaded", single_threaded) then
if attached {BOOLEAN} opts.option ("verbose") as l_verbose then force_single_threaded
verbose := l_verbose
elseif attached {READABLE_STRING_GENERAL} opts.option ("verbose") as l_verbose_str then
verbose := l_verbose_str.as_lower.same_string ("true")
end end
max_concurrent_connections := opts.option_integer_value ("max_concurrent_connections", max_concurrent_connections)
keep_alive_timeout := opts.option_integer_value ("keep_alive_timeout", keep_alive_timeout)
end end
create conn.make create conn.make
@@ -73,21 +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
force_single_threaded
-- Set `single_threaded' to True.
do
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
if single_threaded then
cfg.set_force_single_threaded (True)
end
cfg.set_is_verbose (verbose) cfg.set_is_verbose (verbose)
if attached server_name as l_server_name then if attached server_name as l_server_name then
cfg.set_http_server_name (l_server_name) cfg.set_http_server_name (l_server_name)
end end
cfg.http_server_port := port_number cfg.http_server_port := port_number
cfg.set_max_concurrent_connections (max_concurrent_connections)
cfg.set_keep_alive_timeout (keep_alive_timeout)
conn.update_configuration (cfg)
end end
launch launch
@@ -98,7 +96,7 @@ feature -- Execution
do do
conn := connector conn := connector
conn.set_base (base_url) conn.set_base (base_url)
debug ("nino") debug ("ew_standalone")
if verbose then if verbose then
io.error.put_string ("Launching standalone web server on port " + port_number.out) io.error.put_string ("Launching standalone web server on port " + port_number.out)
if attached server_name as l_name then if attached server_name as l_name then
@@ -108,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
@@ -136,6 +134,13 @@ feature {NONE} -- Implementation
verbose: BOOLEAN verbose: BOOLEAN
single_threaded: BOOLEAN single_threaded: BOOLEAN
do
Result := max_concurrent_connections = 0
end
max_concurrent_connections: INTEGER
keep_alive_timeout: INTEGER
feature -- Status report feature -- Status report

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

@@ -83,6 +83,42 @@ feature -- Access
Result := options.item (a_name) Result := options.item (a_name)
end end
feature -- Helpers
option_integer_value (a_opt_name: READABLE_STRING_GENERAL; a_default: INTEGER): INTEGER
-- INTEGER value associated to option name `a_opt_name', other return `a_default'.
local
s: READABLE_STRING_GENERAL
do
Result := a_default
if attached option (a_opt_name) as opt then
if attached {INTEGER} opt as i then
Result := i
else
s := opt.out
if s.is_integer then
Result := s.to_integer
end
end
end
end
option_boolean_value (a_opt_name: READABLE_STRING_GENERAL; a_default: BOOLEAN): BOOLEAN
-- BOOLEAN value associated to option name `a_opt_name', other return `a_default'.
local
s: READABLE_STRING_GENERAL
do
Result := a_default
if attached option (a_opt_name) as opt then
if attached {BOOLEAN} opt as b then
Result := b
else
s := opt.out
Result := s.is_case_insensitive_equal ("true")
end
end
end
feature -- Access feature -- Access
new_cursor: TABLE_ITERATION_CURSOR [detachable ANY, READABLE_STRING_GENERAL] new_cursor: TABLE_ITERATION_CURSOR [detachable ANY, READABLE_STRING_GENERAL]

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