diff --git a/examples/simple_ssl/application.e b/examples/simple_ssl/application.e
new file mode 100644
index 00000000..e890c187
--- /dev/null
+++ b/examples/simple_ssl/application.e
@@ -0,0 +1,29 @@
+note
+ description : "simple application root class"
+ date : "$Date$"
+ revision : "$Revision$"
+
+class
+ APPLICATION
+
+inherit
+ WSF_DEFAULT_SERVICE [APPLICATION_EXECUTION]
+ redefine
+ initialize
+ end
+
+create
+ make_and_launch
+
+feature {NONE} -- Initialization
+
+ initialize
+ -- Initialize current service.
+ do
+ -- Specific to `standalone' connector (the EiffelWeb server).
+ -- See `{WSF_STANDALONE_SERVICE_LAUNCHER}.initialize'
+ set_service_option ("port", 9090)
+ import_service_options (create {WSF_SERVICE_LAUNCHER_OPTIONS_FROM_INI}.make_from_file ("simple.ini"))
+ end
+
+end
diff --git a/examples/simple_ssl/application_execution.e b/examples/simple_ssl/application_execution.e
new file mode 100644
index 00000000..2d6d0a75
--- /dev/null
+++ b/examples/simple_ssl/application_execution.e
@@ -0,0 +1,41 @@
+note
+ description : "simple application execution"
+ date : "$Date$"
+ revision : "$Revision$"
+
+class
+ APPLICATION_EXECUTION
+
+inherit
+ WSF_EXECUTION
+
+create
+ make
+
+feature -- Basic operations
+
+ execute
+ local
+ s: STRING
+ dt: HTTP_DATE
+ do
+ -- To send a response we need to setup, the status code and
+ -- the response headers.
+ s := "Hello World!"
+ create dt.make_now_utc
+ s.append (" (UTC time is " + dt.rfc850_string + ").")
+ if request.is_https then
+ s.append ("
This is a secured connection! (https)
%N")
+ end
+
+ 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.header.put_content_type_text_html
+ response.header.put_content_length (s.count)
+ if attached request.http_connection as l_connection and then l_connection.is_case_insensitive_equal_general ("keep-alive") then
+ response.header.put_header_key_value ("Connection", "keep-alive")
+ end
+ response.put_string (s)
+ end
+
+end
diff --git a/examples/simple_ssl/simple.crt b/examples/simple_ssl/simple.crt
new file mode 100644
index 00000000..6147c200
--- /dev/null
+++ b/examples/simple_ssl/simple.crt
@@ -0,0 +1,15 @@
+-----BEGIN CERTIFICATE-----
+MIICWDCCAcGgAwIBAgIJAJnXGtV+PtiYMA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNV
+BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBX
+aWRnaXRzIFB0eSBMdGQwHhcNMTUwNDAzMjIxNTA0WhcNMTYwNDAyMjIxNTA0WjBF
+MQswCQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50
+ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKB
+gQDFMK6ojzg+KlklhTossR13c51izMgGc3B0z9ttfHIcx2kxra3HtHcKIl5wSUvn
+G8zmSyFAyQTs5LUv65q46FM9qU8tP+vTeFCfNXvjRcIEpouta3J53K0xuUlxz4d4
+4D6qvdDWAez/0AkI4y5etW5zXtg7IQorJhsI9TmfGuruzwIDAQABo1AwTjAdBgNV
+HQ4EFgQUbWpk2HoHa0YqpEwr7CGEatBFTMkwHwYDVR0jBBgwFoAUbWpk2HoHa0Yq
+pEwr7CGEatBFTMkwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQUFAAOBgQAi+h4/
+IgEocWkdRZBKHEcTrRxz5WhEDJMoVo9LhnXvCfn1G/4p6Un6sYv7Xzpi9NuSY8uV
+cjfJJXhtF3AtyZ70iTAxWaRWjGaZ03PYOjlledJ5rqJEt6CCn8m+JsfznduZvbxQ
+zQ6jCLXfyD/tvemB+yYEI3NntvRKx5/zt6Q26Q==
+-----END CERTIFICATE-----
diff --git a/examples/simple_ssl/simple.ini b/examples/simple_ssl/simple.ini
new file mode 100644
index 00000000..2ec39e14
--- /dev/null
+++ b/examples/simple_ssl/simple.ini
@@ -0,0 +1,28 @@
+##########################################################
+### EiffelWeb settings for related connector ###
+### Mostly for EiffelWeb standalone connector ###
+### See {WGI_STANDALONE_CONSTANTS} for default values. ###
+##########################################################
+
+### Connection settings
+port=9090
+#max_concurrent_connections=100
+#max_tcp_clients=100
+
+### Timeout settings
+#socket_timeout=60
+#socket_recv_timeout=5
+
+### Persistent connection settings
+#keep_alive_timeout=15
+#max_keep_alive_requests=100
+
+### SSL settings
+# enable SSL, with file certificate.
+ssl_enabled=true
+ssl_ca_key=simple.key
+ssl_ca_crt=simple.crt
+
+### App settings
+verbose=true
+verbose_level=ALERT
diff --git a/examples/simple_ssl/simple.key b/examples/simple_ssl/simple.key
new file mode 100644
index 00000000..e5e22a52
--- /dev/null
+++ b/examples/simple_ssl/simple.key
@@ -0,0 +1,15 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIICXAIBAAKBgQDFMK6ojzg+KlklhTossR13c51izMgGc3B0z9ttfHIcx2kxra3H
+tHcKIl5wSUvnG8zmSyFAyQTs5LUv65q46FM9qU8tP+vTeFCfNXvjRcIEpouta3J5
+3K0xuUlxz4d44D6qvdDWAez/0AkI4y5etW5zXtg7IQorJhsI9TmfGuruzwIDAQAB
+AoGAR5efMg+dieRyLU8rieJcImxVbfOPg9gRsjdtIVkXTR+RL7ow59q7hXBo/Td/
+WU8cm1gXoJ/bK+71YYqWyB+BaLRIWvRWb7Gdw203tu4e136Ca5uuY+71qdbVTVcl
+NQ7J+T+eAQFP+a+DdT3ZQxu9eze87SMbu6i5YSpIk2kusOECQQDunv/DQ+nc+NgR
+DF+Td3sNYUVRT9a1CWi6abAG6reXwp8MS4NobWDf+Ps4JODhEEwlIdq5qL7qqYBZ
+Gc1TJJ53AkEA0404Fn6vAzzegBcS4RLlYTK7nMr0m4pMmDMCI6YzAYdMmKHp1e6f
+IwxSmQrmwyAgwcT01bc0+A8yipcC2BWQaQJBAJ01QZm635OGmos41KsKF5bsE8gL
+SpBBH69Yu/ECqGwie7iU84FUNnO4zIHjwghlPVVlZX3Vz9o4S+fn2N9DC+cCQGyZ
+QyCxGdC0r5fbwHJQS/ZQn+UGfvlVzqoXDVMVn3t6ZES6YZrT61eHnOM5qGqklIxE
+Old3vDZXPt/MU8Zvk3kCQBOgUx2VxvTrHN37hk9/QIDiM62+RenBm1M3ah8xTosf
+1mSeEb6d9Kwb3TgPBmA7YXzJuAQfRIvEPMPxT5SSr6Q=
+-----END RSA PRIVATE KEY-----
diff --git a/examples/simple_ssl/simple_ssl.ecf b/examples/simple_ssl/simple_ssl.ecf
new file mode 100644
index 00000000..51e2b9a8
--- /dev/null
+++ b/examples/simple_ssl/simple_ssl.ecf
@@ -0,0 +1,27 @@
+
+
+
+ Simple EiffelWeb standalone server with SSL support (Concurrent connection supported thanks to SCOOP).
+
+
+ /.svn$
+ /CVS$
+ /EIFGENs$
+
+
+
+
+
+
+
+
+
+
+
+
+ Simple EiffelWeb standalone server with SSL support (Single threaded, thus no concurrent connection.)
+
+
+
diff --git a/library/server/ewsgi/connectors/standalone/lib/httpd/concurrency/scoop/httpd_request_handler.e b/library/server/ewsgi/connectors/standalone/lib/httpd/concurrency/scoop/httpd_request_handler.e
index 9335e76f..2defb093 100644
--- a/library/server/ewsgi/connectors/standalone/lib/httpd/concurrency/scoop/httpd_request_handler.e
+++ b/library/server/ewsgi/connectors/standalone/lib/httpd/concurrency/scoop/httpd_request_handler.e
@@ -25,20 +25,27 @@ feature {CONCURRENT_POOL, HTTPD_CONNECTION_HANDLER_I} -- Basic operation
release
--
local
- d: STRING
+ d: detachable STRING
do
- if attached internal_client_socket as l_socket then
- d := l_socket.descriptor.out
- else
- d := "N/A"
- end
debug ("dbglog")
+ if
+ attached internal_client_socket as l_socket and then
+ l_socket.descriptor_available
+ then
+ d := l_socket.descriptor.out
+ else
+ d := "N/A"
+ end
dbglog (generator + ".release: ENTER {" + d + "}")
end
Precursor {HTTPD_REQUEST_HANDLER_I}
release_pool_item
debug ("dbglog")
- dbglog (generator + ".release: LEAVE {" + d + "}")
+ if d /= Void then
+ dbglog (generator + ".release: LEAVE {" + d + "}")
+ else
+ dbglog (generator + ".release: LEAVE {N/A}")
+ end
end
end
diff --git a/library/server/ewsgi/connectors/standalone/lib/httpd/concurrency/thread/httpd_request_handler.e b/library/server/ewsgi/connectors/standalone/lib/httpd/concurrency/thread/httpd_request_handler.e
index e053bfe7..57c6ecd6 100644
--- a/library/server/ewsgi/connectors/standalone/lib/httpd/concurrency/thread/httpd_request_handler.e
+++ b/library/server/ewsgi/connectors/standalone/lib/httpd/concurrency/thread/httpd_request_handler.e
@@ -18,21 +18,28 @@ inherit
feature {HTTPD_CONNECTION_HANDLER_I} -- Basic operation
release
+ --
local
- d: STRING
+ d: detachable STRING
do
- -- FIXME: for log purpose
- if attached internal_client_socket as l_socket then
- d := l_socket.descriptor.out
- else
- d := "N/A"
- end
debug ("dbglog")
+ if
+ attached internal_client_socket as l_socket and then
+ l_socket.descriptor_available
+ then
+ d := l_socket.descriptor.out
+ else
+ d := "N/A"
+ end
dbglog (generator + ".release: ENTER {" + d + "}")
end
Precursor {HTTPD_REQUEST_HANDLER_I}
debug ("dbglog")
- dbglog (generator + ".release: LEAVE {" + d + "}")
+ if d /= Void then
+ dbglog (generator + ".release: LEAVE {" + d + "}")
+ else
+ dbglog (generator + ".release: LEAVE {N/A}")
+ end
end
end
diff --git a/library/server/ewsgi/connectors/standalone/lib/httpd/configuration/httpd_configuration_i.e b/library/server/ewsgi/connectors/standalone/lib/httpd/configuration/httpd_configuration_i.e
index 48bdff7a..7c06b59f 100644
--- a/library/server/ewsgi/connectors/standalone/lib/httpd/configuration/httpd_configuration_i.e
+++ b/library/server/ewsgi/connectors/standalone/lib/httpd/configuration/httpd_configuration_i.e
@@ -6,6 +6,11 @@ note
deferred class
HTTPD_CONFIGURATION_I
+inherit
+ ANY
+
+ HTTPD_CONSTANTS
+
feature {NONE} -- Initialization
make
@@ -14,6 +19,7 @@ feature {NONE} -- Initialization
max_concurrent_connections := default_max_concurrent_connections
max_tcp_clients := default_max_tcp_clients
socket_timeout := default_socket_timeout
+ socket_recv_timeout := default_socket_recv_timeout
keep_alive_timeout := default_keep_alive_timeout
max_keep_alive_requests := default_max_keep_alive_requests
is_secure := False
@@ -21,15 +27,6 @@ feature {NONE} -- Initialization
create ca_key.make_empty
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
Server_details: STRING_8
@@ -45,7 +42,12 @@ feature -- Access
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.
+ -- By default: 60 seconds, which is appropriate for most situations.
+
+ socket_recv_timeout: INTEGER assign set_socket_recv_timeout
+ -- Amount of seconds that the server waits for receiving data during communications.
+ -- note: with timeout of 0, socket can wait for ever.
+ -- By default: 5 seconds.
max_concurrent_connections: INTEGER assign set_max_concurrent_connections
-- Max number of concurrent connections.
@@ -83,8 +85,10 @@ feature -- Access
Result.is_verbose := is_verbose
Result.verbose_level := verbose_level
Result.timeout := socket_timeout
+ Result.socket_recv_timeout := socket_recv_timeout
Result.keep_alive_timeout := keep_alive_timeout
Result.max_keep_alive_requests := max_keep_alive_requests
+ Result.is_secure := is_secure
end
feature -- Access: SSL
@@ -92,10 +96,10 @@ feature -- Access: SSL
is_secure: BOOLEAN
-- Is SSL/TLS session?.
- ca_crt: IMMUTABLE_STRING_8
+ ca_crt: detachable IMMUTABLE_STRING_32
-- the signed certificate.
- ca_key: IMMUTABLE_STRING_8
+ ca_key: detachable IMMUTABLE_STRING_32
-- private key to the certificate.
ssl_protocol: NATURAL
@@ -103,6 +107,22 @@ feature -- Access: SSL
feature -- Element change
+ set_ssl_settings (v: detachable separate TUPLE [protocol: separate READABLE_STRING_GENERAL; ca_crt, ca_key: detachable separate READABLE_STRING_GENERAL])
+ local
+ prot: STRING_32
+ do
+ is_secure := False
+ ca_crt := Void
+ ca_key := Void
+ if v /= Void then
+ is_secure := True
+ create prot.make_from_separate (v.protocol)
+ set_ssl_protocol_from_string (prot)
+ set_ca_crt (v.ca_crt)
+ set_ca_key (v.ca_key)
+ end
+ end
+
set_http_server_name (v: detachable separate READABLE_STRING_8)
do
if v = Void then
@@ -152,6 +172,14 @@ feature -- Element change
socket_timeout_set: socket_timeout = a_nb_seconds
end
+ set_socket_recv_timeout (a_nb_seconds: like socket_recv_timeout)
+ -- Set `socket_recv_timeout' with `a_nb_seconds'
+ do
+ socket_recv_timeout := a_nb_seconds
+ ensure
+ socket_recv_timeout_set: socket_recv_timeout = a_nb_seconds
+ end
+
set_keep_alive_timeout (a_seconds: like keep_alive_timeout)
-- Set `keep_alive_timeout' with `a_seconds'
do
@@ -198,17 +226,33 @@ feature -- Element change
verbose_level_set: verbose_level = lev
end
- mark_secure
- -- Set is_secure in True
+ set_is_secure (b: BOOLEAN)
+ -- Set `is_secure' to `b'.
do
- if has_ssl_support then
+ if b and has_ssl_support then
is_secure := True
- if http_server_port = 80 then
+ if
+ http_server_port = 80
+ then
set_http_server_port (443)
end
else
is_secure := False
+ if
+ http_server_port = 443
+ then
+ set_http_server_port (80)
+ end
end
+ ensure
+ is_secure_set: has_ssl_support implies is_secure
+ is_not_secure: not has_ssl_support implies not is_secure
+ end
+
+ mark_secure
+ -- Set is_secure in True
+ do
+ set_is_secure (True)
ensure
is_secure_set: has_ssl_support implies is_secure
-- http_server_port_set: has_ssl_support implies http_server_port = 443
@@ -218,16 +262,24 @@ feature -- Element change
feature -- Element change
- set_ca_crt (a_value: separate READABLE_STRING_8)
+ set_ca_crt (a_value: detachable separate READABLE_STRING_GENERAL)
-- Set `ca_crt' from `a_value'.
do
- create ca_crt.make_from_separate (a_value)
+ if a_value /= Void then
+ create ca_crt.make_from_separate (a_value)
+ else
+ ca_crt := Void
+ end
end
- set_ca_key (a_value: separate READABLE_STRING_8)
+ set_ca_key (a_value: detachable separate READABLE_STRING_GENERAL)
-- Set `ca_key' with `a_value'.
do
- create ca_key.make_from_separate (a_value)
+ if a_value /= Void then
+ create ca_key.make_from_separate (a_value)
+ else
+ ca_key := Void
+ end
end
set_ssl_protocol (a_version: NATURAL)
@@ -238,6 +290,24 @@ feature -- Element change
ssl_protocol_set: ssl_protocol = a_version
end
+ set_ssl_protocol_from_string (a_ssl_version: READABLE_STRING_GENERAL)
+ -- Set `ssl_protocol' with `a_ssl_version'
+ do
+ if a_ssl_version.is_case_insensitive_equal ("ssl_2_3") then
+ set_ssl_protocol_to_ssl_2_or_3
+ elseif a_ssl_version.is_case_insensitive_equal ("tls_1_0") then
+ set_ssl_protocol_to_tls_1_0
+ elseif a_ssl_version.is_case_insensitive_equal ("tls_1_1") then
+ set_ssl_protocol_to_tls_1_1
+ elseif a_ssl_version.is_case_insensitive_equal ("tls_1_2") then
+ set_ssl_protocol_to_tls_1_2
+ elseif a_ssl_version.is_case_insensitive_equal ("dtls_1_0") then
+ set_ssl_protocol_to_dtls_1_0
+ else -- Default
+ set_ssl_protocol_to_tls_1_2
+ end
+ end
+
feature -- SSL Helpers
set_ssl_protocol_to_ssl_2_or_3
diff --git a/library/server/ewsgi/connectors/standalone/lib/httpd/configuration/httpd_constants.e b/library/server/ewsgi/connectors/standalone/lib/httpd/configuration/httpd_constants.e
new file mode 100644
index 00000000..71e4dcc1
--- /dev/null
+++ b/library/server/ewsgi/connectors/standalone/lib/httpd/configuration/httpd_constants.e
@@ -0,0 +1,28 @@
+note
+ description: "[
+ Various constant values used in httpd settings.
+ ]"
+ author: "$Author$"
+ date: "$Date$"
+ revision: "$Revision$"
+
+deferred class
+ HTTPD_CONSTANTS
+
+feature -- Default connection settings
+
+ default_http_server_port: INTEGER = 80
+ default_max_concurrent_connections: INTEGER = 100
+ default_max_tcp_clients: INTEGER = 100
+
+feature -- Default timeout settings
+
+ default_socket_timeout: INTEGER = 60 -- seconds
+ default_socket_recv_timeout: INTEGER = 5 -- seconds
+
+feature -- Default persistent connection settings
+
+ default_keep_alive_timeout: INTEGER = 15 -- seconds
+ default_max_keep_alive_requests: INTEGER = 100
+
+end
diff --git a/library/server/ewsgi/connectors/standalone/lib/httpd/configuration/httpd_request_settings.e b/library/server/ewsgi/connectors/standalone/lib/httpd/configuration/httpd_request_settings.e
index 146b193a..a591cac3 100644
--- a/library/server/ewsgi/connectors/standalone/lib/httpd/configuration/httpd_request_settings.e
+++ b/library/server/ewsgi/connectors/standalone/lib/httpd/configuration/httpd_request_settings.e
@@ -17,9 +17,15 @@ feature -- Access
verbose_level: INTEGER assign set_verbose_level
-- Verbosity of output.
+ is_secure: BOOLEAN assign set_is_secure
+ -- Is using secure connection? i.e SSL?
+
timeout: INTEGER assign set_timeout
-- Amount of seconds that the server waits for receipts and transmissions during communications.
+ socket_recv_timeout: INTEGER assign set_socket_recv_timeout
+ -- Amount of seconds that the server waits for receiving data on socket during communications.
+
keep_alive_timeout: INTEGER assign set_keep_alive_timeout
-- Keep-alive timeout, also known as persistent-connection timeout.
-- Number of seconds the server waits after a request has been served before it closes the connection.
@@ -42,12 +48,24 @@ feature -- Change
verbose_level := lev
end
+ set_is_secure (b: BOOLEAN)
+ -- Set `is_secure' to `b'.
+ do
+ is_secure := b
+ end
+
set_timeout (a_timeout_in_seconds: INTEGER)
-- Set `timeout' to `a_timeout_in_seconds'.
do
timeout := a_timeout_in_seconds
end
+ set_socket_recv_timeout (a_timeout_in_seconds: INTEGER)
+ -- Set `socket_recv_timeout' to `a_timeout_in_seconds'.
+ do
+ socket_recv_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
diff --git a/library/server/ewsgi/connectors/standalone/lib/httpd/http_network-safe.ecf b/library/server/ewsgi/connectors/standalone/lib/httpd/http_network-safe.ecf
index 20a62c0c..faea6dd5 100644
--- a/library/server/ewsgi/connectors/standalone/lib/httpd/http_network-safe.ecf
+++ b/library/server/ewsgi/connectors/standalone/lib/httpd/http_network-safe.ecf
@@ -10,20 +10,29 @@
-
-
+
-
-
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/library/server/ewsgi/connectors/standalone/lib/httpd/http_network.ecf b/library/server/ewsgi/connectors/standalone/lib/httpd/http_network.ecf
index 18719f75..25cc31ea 100644
--- a/library/server/ewsgi/connectors/standalone/lib/httpd/http_network.ecf
+++ b/library/server/ewsgi/connectors/standalone/lib/httpd/http_network.ecf
@@ -24,6 +24,16 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/library/server/ewsgi/connectors/standalone/lib/httpd/httpd-safe.ecf b/library/server/ewsgi/connectors/standalone/lib/httpd/httpd-safe.ecf
index b29b1277..d25947d3 100644
--- a/library/server/ewsgi/connectors/standalone/lib/httpd/httpd-safe.ecf
+++ b/library/server/ewsgi/connectors/standalone/lib/httpd/httpd-safe.ecf
@@ -30,6 +30,16 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/library/server/ewsgi/connectors/standalone/lib/httpd/httpd.ecf b/library/server/ewsgi/connectors/standalone/lib/httpd/httpd.ecf
index 982378fa..9d62c604 100644
--- a/library/server/ewsgi/connectors/standalone/lib/httpd/httpd.ecf
+++ b/library/server/ewsgi/connectors/standalone/lib/httpd/httpd.ecf
@@ -29,6 +29,16 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/library/server/ewsgi/connectors/standalone/lib/httpd/httpd_request_handler_i.e b/library/server/ewsgi/connectors/standalone/lib/httpd/httpd_request_handler_i.e
index 1c38a3ff..439d9122 100644
--- a/library/server/ewsgi/connectors/standalone/lib/httpd/httpd_request_handler_i.e
+++ b/library/server/ewsgi/connectors/standalone/lib/httpd/httpd_request_handler_i.e
@@ -11,6 +11,8 @@ inherit
HTTPD_LOGGER_CONSTANTS
+ HTTPD_SOCKET_FACTORY
+
feature {NONE} -- Initialization
make (a_request_settings: HTTPD_REQUEST_SETTINGS)
@@ -18,11 +20,13 @@ feature {NONE} -- Initialization
reset
-- Import global request settings.
timeout := a_request_settings.timeout -- seconds
+ socket_recv_timeout := a_request_settings.socket_recv_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
+ is_secure := a_request_settings.is_secure
end
reset
@@ -68,7 +72,7 @@ feature -- Access
do
s := internal_client_socket
if s = Void then
- create s.make_empty
+ s := new_client_socket (is_secure)
internal_client_socket := s
end
Result := s
@@ -121,6 +125,10 @@ feature -- Settings
verbose_level: INTEGER
-- Output verbosity.
+ is_secure: BOOLEAN
+ -- Is secure socket?
+ -- i.e: SSL?
+
is_persistent_connection_supported: BOOLEAN
-- Is persistent connection supported?
do
@@ -134,6 +142,9 @@ feature -- Settings
timeout: INTEGER -- seconds
-- Amount of seconds that the server waits for receipts and transmissions during communications.
+ socket_recv_timeout: INTEGER -- seconds
+ -- Amount of seconds that the server waits for receiving data on socket during communications.
+
max_keep_alive_requests: INTEGER
-- Maximum number of requests allowed per persistent connection.
@@ -187,6 +198,7 @@ feature -- Execution
n,m: INTEGER
do
l_socket := client_socket
+ l_socket.set_recv_timeout (socket_recv_timeout)
check
socket_attached: l_socket /= Void
socket_valid: l_socket.is_open_read and then l_socket.is_open_write
@@ -206,18 +218,24 @@ feature -- Execution
log ("Reuse connection (" + n.out + ")", information_level)
end
-- FIXME: it seems to be called one more time, mostly to see this is done.
- execute_request
+ execute_request (n > 1)
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
reset_request
end
+ if l_exit and has_error and not l_socket.is_closed then
+ l_socket.close
+ end
end
- execute_request
+ execute_request (a_is_reusing_connection: BOOLEAN)
+ -- Execute http request, and if `a_is_reusing_connection' is True
+ -- the execution is reusing the persistent connection.
require
is_connected: is_connected
+ reuse_connection_when_possible: a_is_reusing_connection implies is_persistent_connection_supported
local
l_remote_info: detachable like remote_info
l_socket: like client_socket
@@ -237,13 +255,16 @@ feature -- Execution
dbglog (generator + ".execute_request socket=" + l_socket.descriptor.out + " ENTER")
end
- --| TODO: add configuration options for socket timeout.
- --| set by default 5 seconds.
- l_socket.set_timeout (keep_alive_timeout) -- 5 seconds!
- l_is_ready := l_socket.ready_for_reading
+ if a_is_reusing_connection then
+ --| set by default 5 seconds.
+ l_socket.set_recv_timeout (keep_alive_timeout) -- in seconds!
+ l_is_ready := l_socket.ready_for_reading
+ else
+ l_is_ready := True
+ end
if l_is_ready then
- l_socket.set_timeout (timeout) -- FIXME: return a 408 Request Timeout response ..
+ l_socket.set_recv_timeout (socket_recv_timeout) -- FIXME: return a 408 Request Timeout response ..
create l_remote_info
if attached l_socket.peer_address as l_addr then
l_remote_info.addr := l_addr.host_address.host_address
@@ -326,8 +347,7 @@ feature -- Parsing
has_error := True
end
l_is_verbose := is_verbose
- if not has_error or l_is_verbose then
- -- if `is_verbose' we can try to print the request, even if it is a bad HTTP request
+ if not has_error then
from
line := next_line (a_socket)
until
diff --git a/library/server/ewsgi/connectors/standalone/lib/httpd/httpd_server_i.e b/library/server/ewsgi/connectors/standalone/lib/httpd/httpd_server_i.e
index ec02bd07..a5935aa1 100644
--- a/library/server/ewsgi/connectors/standalone/lib/httpd/httpd_server_i.e
+++ b/library/server/ewsgi/connectors/standalone/lib/httpd/httpd_server_i.e
@@ -108,6 +108,7 @@ feature -- Execution
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 (" - socket_recv_timeout = " + configuration.socket_recv_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
diff --git a/library/server/ewsgi/connectors/standalone/lib/httpd/network/from_16_11/tcp_stream_socket_ext.e b/library/server/ewsgi/connectors/standalone/lib/httpd/network/from_16_11/tcp_stream_socket_ext.e
new file mode 100644
index 00000000..65d4d70a
--- /dev/null
+++ b/library/server/ewsgi/connectors/standalone/lib/httpd/network/from_16_11/tcp_stream_socket_ext.e
@@ -0,0 +1,9 @@
+note
+ description: "[
+ Since 16.11, the EiffelNet socket interface has recv_timeout and send_timeout.
+ ]"
+
+deferred class
+ TCP_STREAM_SOCKET_EXT
+
+end
diff --git a/library/server/ewsgi/connectors/standalone/lib/httpd/network/httpd_stream_socket.e b/library/server/ewsgi/connectors/standalone/lib/httpd/network/httpd_stream_socket.e
index f3f3209d..76c0bb34 100644
--- a/library/server/ewsgi/connectors/standalone/lib/httpd/network/httpd_stream_socket.e
+++ b/library/server/ewsgi/connectors/standalone/lib/httpd/network/httpd_stream_socket.e
@@ -62,6 +62,7 @@ feature {NONE} -- Initialization
feature -- Change
set_timeout (n: INTEGER)
+ -- Set timeout to `n' seconds.
do
if attached {NETWORK_STREAM_SOCKET} socket as l_socket then
l_socket.set_timeout (n)
@@ -82,6 +83,22 @@ feature -- Change
end
end
+ set_recv_timeout (a_timeout_seconds: INTEGER)
+ -- Set the receive timeout in seconds on Current socket.
+ do
+ if attached {TCP_STREAM_SOCKET} socket as l_socket then
+ l_socket.set_recv_timeout (a_timeout_seconds)
+ end
+ end
+
+ set_send_timeout (a_timeout_seconds: INTEGER)
+ -- Set the send timeout in seconds on Current socket.
+ do
+ if attached {TCP_STREAM_SOCKET} socket as l_socket then
+ l_socket.set_send_timeout (a_timeout_seconds)
+ end
+ end
+
feature -- Access
last_string: STRING
diff --git a/library/server/ewsgi/connectors/standalone/lib/httpd/network/ssl/httpd_stream_ssl_socket.e b/library/server/ewsgi/connectors/standalone/lib/httpd/network/ssl/httpd_stream_ssl_socket.e
index 8b0be0da..1217d0d1 100644
--- a/library/server/ewsgi/connectors/standalone/lib/httpd/network/ssl/httpd_stream_ssl_socket.e
+++ b/library/server/ewsgi/connectors/standalone/lib/httpd/network/ssl/httpd_stream_ssl_socket.e
@@ -17,58 +17,66 @@ inherit
ready_for_writing,
ready_for_reading,
try_ready_for_reading,
- put_readable_string_8
+ put_readable_string_8,
+ make_empty
end
create
make_ssl_server_by_address_and_port, make_ssl_server_by_port,
make_server_by_address_and_port, make_server_by_port,
make_ssl_client_by_address_and_port, make_ssl_client_by_port,
- make_client_by_address_and_port, make_client_by_port
+ make_client_by_address_and_port, make_client_by_port,
+ make_empty
create {HTTPD_STREAM_SOCKET}
make
feature {NONE} -- Initialization
- make_ssl_server_by_address_and_port (an_address: INET_ADDRESS; a_port: INTEGER; a_ssl_protocol: NATURAL; a_crt: STRING; a_key: STRING)
+ make_ssl_server_by_address_and_port (an_address: INET_ADDRESS; a_port: INTEGER; a_ssl_protocol: NATURAL; a_crt_fn, a_key_fn: detachable READABLE_STRING_GENERAL)
local
l_socket: SSL_TCP_STREAM_SOCKET
do
create l_socket.make_server_by_address_and_port (an_address, a_port)
l_socket.set_tls_protocol (a_ssl_protocol)
socket := l_socket
- set_certificates (a_crt, a_key)
+ set_certificates (a_crt_fn, a_key_fn)
end
- make_ssl_server_by_port (a_port: INTEGER; a_ssl_protocol: NATURAL; a_crt: STRING; a_key: STRING)
+ make_ssl_server_by_port (a_port: INTEGER; a_ssl_protocol: NATURAL; a_crt_fn, a_key_fn: detachable READABLE_STRING_GENERAL)
local
l_socket: SSL_TCP_STREAM_SOCKET
do
create l_socket.make_server_by_port (a_port)
l_socket.set_tls_protocol (a_ssl_protocol)
socket := l_socket
- set_certificates (a_crt, a_key)
+ set_certificates (a_crt_fn, a_key_fn)
end
- make_ssl_client_by_address_and_port (an_address: INET_ADDRESS; a_port: INTEGER; a_ssl_protocol: NATURAL; a_crt: STRING; a_key: STRING)
+ make_ssl_client_by_address_and_port (an_address: INET_ADDRESS; a_port: INTEGER; a_ssl_protocol: NATURAL; a_crt_fn, a_key_fn: detachable READABLE_STRING_GENERAL)
local
l_socket: SSL_TCP_STREAM_SOCKET
do
create l_socket.make_client_by_address_and_port (an_address, a_port)
l_socket.set_tls_protocol (a_ssl_protocol)
socket := l_socket
- set_certificates (a_crt, a_key)
+ set_certificates (a_crt_fn, a_key_fn)
end
- make_ssl_client_by_port (a_peer_port: INTEGER; a_peer_host: STRING; a_ssl_protocol: NATURAL; a_crt: STRING; a_key: STRING)
+ make_ssl_client_by_port (a_peer_port: INTEGER; a_peer_host: STRING; a_ssl_protocol: NATURAL; a_crt_fn, a_key_fn: detachable READABLE_STRING_GENERAL)
local
l_socket: SSL_TCP_STREAM_SOCKET
do
create l_socket.make_client_by_port (a_peer_port, a_peer_host)
l_socket.set_tls_protocol (a_ssl_protocol)
socket := l_socket
- set_certificates (a_crt, a_key)
+ set_certificates (a_crt_fn, a_key_fn)
+ end
+
+ make_empty
+ -- .
+ do
+ create {SSL_TCP_STREAM_SOCKET} socket.make_empty
end
feature -- Output
@@ -136,15 +144,15 @@ feature -- Status Report
feature {HTTPD_STREAM_SOCKET} -- Implementation
- set_certificates (a_crt: STRING; a_key: STRING)
- local
- a_file_name: FILE_NAME
+ set_certificates (a_crt_filename, a_key_filename: detachable READABLE_STRING_GENERAL)
do
if attached {SSL_NETWORK_STREAM_SOCKET} socket as l_socket then
- create a_file_name.make_from_string (a_crt)
- l_socket.set_certificate_file_name (a_file_name)
- create a_file_name.make_from_string (a_key)
- l_socket.set_key_file_name (a_file_name)
+ if a_crt_filename /= Void then
+ l_socket.set_certificate_file_name (a_crt_filename)
+ end
+ if a_key_filename /= Void then
+ l_socket.set_key_file_name (a_key_filename)
+ end
end
end
diff --git a/library/server/ewsgi/connectors/standalone/lib/httpd/network/tcp_stream_socket.e b/library/server/ewsgi/connectors/standalone/lib/httpd/network/tcp_stream_socket.e
index 774b3bb5..6961a777 100644
--- a/library/server/ewsgi/connectors/standalone/lib/httpd/network/tcp_stream_socket.e
+++ b/library/server/ewsgi/connectors/standalone/lib/httpd/network/tcp_stream_socket.e
@@ -12,6 +12,8 @@ inherit
make
end
+ TCP_STREAM_SOCKET_EXT
+
create
make_server_by_address_and_port,
make_server_by_port,
diff --git a/library/server/ewsgi/connectors/standalone/lib/httpd/network/until_16_05/tcp_stream_socket_ext.e b/library/server/ewsgi/connectors/standalone/lib/httpd/network/until_16_05/tcp_stream_socket_ext.e
new file mode 100644
index 00000000..73480ca3
--- /dev/null
+++ b/library/server/ewsgi/connectors/standalone/lib/httpd/network/until_16_05/tcp_stream_socket_ext.e
@@ -0,0 +1,104 @@
+note
+ description: "[
+ Until 16.05, the EiffelNet socket interface DOES NOT have recv_timeout and send_timeout.
+ ]"
+
+deferred class
+ TCP_STREAM_SOCKET_EXT
+
+feature -- Access
+
+ descriptor: INTEGER
+ -- Socket descriptor of current socket
+ deferred
+ end
+
+feature -- Socket Recv and Send timeout.
+
+-- recv_timeout: INTEGER
+-- -- Receive timeout in seconds on Current socket.
+-- do
+-- Result := c_get_sock_recv_timeout (descriptor, level_sol_socket)
+-- ensure
+-- result_not_negative: Result >= 0
+-- end
+--
+-- send_timeout: INTEGER
+-- -- Send timeout in seconds on Current socket.
+-- do
+-- Result := c_get_sock_send_timeout (descriptor, level_sol_socket)
+-- ensure
+-- result_not_negative: Result >= 0
+-- end
+
+ set_recv_timeout (a_timeout_seconds: INTEGER)
+ -- Set the receive timeout in seconds on Current socket.
+ -- if `0' the related operations will never timeout.
+ require
+ positive_timeout: a_timeout_seconds >= 0
+ do
+ c_set_sock_recv_timeout (descriptor, level_sol_socket, a_timeout_seconds)
+ end
+
+ set_send_timeout (a_timeout_seconds: INTEGER)
+ -- Set the send timeout in milliseconds on Current socket.
+ -- if `0' the related operations will never timeout.
+ require
+ positive_timeout: a_timeout_seconds >= 0
+ do
+ c_set_sock_send_timeout (descriptor, level_sol_socket, a_timeout_seconds)
+ end
+
+feature {NONE} -- Externals
+
+ level_sol_socket: INTEGER
+ -- SOL_SOCKET level of options
+ deferred
+ end
+
+-- set_so_rcvtimeo (a_timeout_seconds: INTEGER)
+-- -- Set the receive timeout in seconds on Current socket.
+-- -- if `0' the related operations will never timeout.
+-- require
+-- positive_timeout: a_timeout_seconds >= 0
+-- do
+-- c_set_sock_recv_timeout (descriptor, level_sol_socket, a_timeout_seconds)
+-- end
+
+ c_set_sock_recv_timeout (a_fd, a_level: INTEGER; a_timeout_seconds: INTEGER)
+ -- C routine to set socket option `SO_RCVTIMEO' with `a_timeout_seconds' seconds.
+ external
+ "C inline"
+ alias
+ "[
+#ifdef EIF_WINDOWS
+ int arg = (int) 1000 * $a_timeout_seconds; /* Timeout in milliseconds */
+ setsockopt((SOCKET) $a_fd, (int) $a_level, (int) SO_RCVTIMEO, (char *) &arg, sizeof(arg));
+#else
+ struct timeval tv;
+ tv.tv_sec = $a_timeout_seconds; /* Timeout in seconds */
+
+ setsockopt((int) $a_fd, (int) $a_level, (int) SO_RCVTIMEO, (struct timeval *)&tv, sizeof(struct timeval));
+#endif
+ ]"
+ end
+
+ c_set_sock_send_timeout (a_fd, a_level: INTEGER; a_timeout_seconds: INTEGER)
+ -- C routine to set socket option `SO_SNDTIMEO' with `a_timeout_seconds' seconds.
+ external
+ "C inline"
+ alias
+ "[
+#ifdef EIF_WINDOWS
+ int arg = (int) 1000 * $a_timeout_seconds; /* Timeout in milliseconds */
+ setsockopt((SOCKET) $a_fd, (int) $a_level, (int) SO_SNDTIMEO, (char *) &arg, sizeof(arg));
+#else
+ struct timeval tv;
+ tv.tv_sec = $a_timeout_seconds; /* Timeout in seconds */
+
+ setsockopt((int) $a_fd, (int) $a_level, (int) SO_SNDTIMEO, (struct timeval *)&tv, sizeof(struct timeval));
+#endif
+ ]"
+ end
+
+end
diff --git a/library/server/ewsgi/connectors/standalone/lib/httpd/no_ssl/httpd_socket_factory.e b/library/server/ewsgi/connectors/standalone/lib/httpd/no_ssl/httpd_socket_factory.e
new file mode 100644
index 00000000..6c08bc32
--- /dev/null
+++ b/library/server/ewsgi/connectors/standalone/lib/httpd/no_ssl/httpd_socket_factory.e
@@ -0,0 +1,17 @@
+note
+ description: "Summary description for {HTTPD_SOCKET_FACTORY}."
+ date: "$Date$"
+ revision: "$Revision$"
+
+deferred class
+ HTTPD_SOCKET_FACTORY
+
+feature -- Access
+
+ new_client_socket (a_is_secure: BOOLEAN): HTTPD_STREAM_SOCKET
+ do
+ check not_secure: not a_is_secure end
+ create Result.make_empty
+ end
+
+end
diff --git a/library/server/ewsgi/connectors/standalone/lib/httpd/ssl/httpd_socket_factory.e b/library/server/ewsgi/connectors/standalone/lib/httpd/ssl/httpd_socket_factory.e
new file mode 100644
index 00000000..ff410db5
--- /dev/null
+++ b/library/server/ewsgi/connectors/standalone/lib/httpd/ssl/httpd_socket_factory.e
@@ -0,0 +1,20 @@
+note
+ description: "Summary description for {HTTPD_SOCKET_FACTORY}."
+ date: "$Date$"
+ revision: "$Revision$"
+
+deferred class
+ HTTPD_SOCKET_FACTORY
+
+feature -- Access
+
+ new_client_socket (a_is_secure: BOOLEAN): HTTPD_STREAM_SOCKET
+ do
+ if a_is_secure then
+ create {HTTPD_STREAM_SSL_SOCKET} Result.make_empty
+ else
+ create Result.make_empty
+ end
+ end
+
+end
diff --git a/library/server/ewsgi/connectors/standalone/src/implementation/wgi_httpd_request_handler.e b/library/server/ewsgi/connectors/standalone/src/implementation/wgi_httpd_request_handler.e
index dc95fb21..4ff9ac89 100644
--- a/library/server/ewsgi/connectors/standalone/src/implementation/wgi_httpd_request_handler.e
+++ b/library/server/ewsgi/connectors/standalone/src/implementation/wgi_httpd_request_handler.e
@@ -230,6 +230,9 @@ feature -- Request processing
set_environment_variable (l_server_port, "SERVER_PORT", Result)
set_environment_variable (version, "SERVER_PROTOCOL", Result)
set_environment_variable ({HTTPD_CONFIGURATION}.Server_details, "SERVER_SOFTWARE", Result)
+ if is_secure then
+ set_environment_variable ("on", "HTTPS", Result)
+ end
--| Apply `base' value
l_base := base
diff --git a/library/server/ewsgi/connectors/standalone/src/wgi_standalone_connector.e b/library/server/ewsgi/connectors/standalone/src/wgi_standalone_connector.e
index 8efd1910..0d227df9 100644
--- a/library/server/ewsgi/connectors/standalone/src/wgi_standalone_connector.e
+++ b/library/server/ewsgi/connectors/standalone/src/wgi_standalone_connector.e
@@ -2,8 +2,8 @@ note
description: "[
Standalone Web Server connector.
]"
- date: "$Date$"
- revision: "$Revision$"
+ date: "$Date: 2016-08-06 13:34:52 +0200 (sam., 06 août 2016) $"
+ revision: "$Revision: 99106 $"
class
WGI_STANDALONE_CONNECTOR [G -> WGI_EXECUTION create make end]
@@ -155,6 +155,12 @@ feature -- Element change
set_is_verbose_on_configuration (b, configuration)
end
+ set_is_secure (b: BOOLEAN)
+ -- Set is_secure connection mode.
+ -- i.e: using SSL.
+ do
+ set_is_secure_on_configuration (b, configuration)
+ end
feature -- Server
@@ -242,6 +248,11 @@ feature {NONE} -- Implementation: element change
cfg.set_is_verbose (b)
end
+ set_is_secure_on_configuration (b: BOOLEAN; cfg: like configuration)
+ do
+ cfg.set_is_secure (b)
+ end
+
note
copyright: "2011-2016, Jocelyn Fiat, Javier Velilla, Eiffel Software and others"
diff --git a/library/server/ewsgi/connectors/standalone/src/wgi_standalone_constants.e b/library/server/ewsgi/connectors/standalone/src/wgi_standalone_constants.e
new file mode 100644
index 00000000..dd5914c9
--- /dev/null
+++ b/library/server/ewsgi/connectors/standalone/src/wgi_standalone_constants.e
@@ -0,0 +1,18 @@
+note
+ description: "[
+ Constants value related to Standalone connector,
+ and indirectly to `httpd' component.
+ ]"
+ author: "$Author$"
+ date: "$Date$"
+ revision: "$Revision$"
+
+deferred class
+ WGI_STANDALONE_CONSTANTS
+
+inherit
+ ANY
+
+ HTTPD_CONSTANTS
+
+end
diff --git a/library/server/wsf/connector/standalone/wsf_standalone_service_launcher.e b/library/server/wsf/connector/standalone/wsf_standalone_service_launcher.e
index 3ce801f4..e4169605 100644
--- a/library/server/wsf/connector/standalone/wsf_standalone_service_launcher.e
+++ b/library/server/wsf/connector/standalone/wsf_standalone_service_launcher.e
@@ -2,14 +2,27 @@ note
description: "[
Component to launch the service using the default connector
- Eiffel Web httpd for this class
+ EiffelWeb httpd for this class
+ The httpd default connector support options:
+ verbose: to display verbose output
+ port: numeric such as 8099 (or equivalent string as "8099")
+ base: base_url (very specific to standalone server)
+
+ max_concurrent_connections: set one, for single threaded behavior
+ max_tcp_clients: max number of open tcp connection
+
+ socket_timeout: connection timeout
+ socket_recv_timeout: read data timeout
+
+ keep_alive_timeout: amount of time the server will wait for subsequent
+ requests on a persistent connection,
+ max_keep_alive_requests: number of requests allowed on a persistent connection,
+
+ ssl_enabled: set to True for https support.
+ ssl_ca_crt: path to the certificat crt file (relevant when ssl_enabled is True)
+ ssl_ca_key: path to the certificat key file (relevant when ssl_enabled is True)
- The httpd default connector support options:
- port: numeric such as 8099 (or equivalent string as "8099")
- base: base_url (very specific to standalone server)
- verbose: to display verbose output, useful for standalone connector
- force_single_threaded: use only one thread, useful for standalone connector
check WSF_SERVICE_LAUNCHER for more documentation
]"
@@ -41,12 +54,13 @@ feature {NONE} -- Initialization
create on_launched_actions
create on_stopped_actions
- port_number := 80 --| Default, but quite often, this port is already used ...
- max_concurrent_connections := 100
- max_tcp_clients := 100
- socket_timeout := 300 -- 300 seconds
- keep_alive_timeout := 15 -- 15 seconds.
- max_keep_alive_requests := 100
+ port_number := {WGI_STANDALONE_CONSTANTS}.default_http_server_port --| Default, but quite often, this port is already used ...
+ max_concurrent_connections := {WGI_STANDALONE_CONSTANTS}.default_max_concurrent_connections
+ max_tcp_clients := {WGI_STANDALONE_CONSTANTS}.default_max_tcp_clients
+ socket_timeout := {WGI_STANDALONE_CONSTANTS}.default_socket_timeout -- seconds
+ socket_recv_timeout := {WGI_STANDALONE_CONSTANTS}.default_socket_recv_timeout -- seconds
+ keep_alive_timeout := {WGI_STANDALONE_CONSTANTS}.default_keep_alive_timeout -- seconds.
+ max_keep_alive_requests := {WGI_STANDALONE_CONSTANTS}.default_max_keep_alive_requests
verbose := False
verbose_level := notice_level
@@ -59,6 +73,7 @@ feature {NONE} -- Initialization
if attached {READABLE_STRING_GENERAL} opts.option ("base") as l_base_str then
base_url := l_base_str.as_string_8
end
+
verbose := opts.option_boolean_value ("verbose", verbose)
-- See `{HTTPD_REQUEST_HANDLER_I}.*_verbose_level`
@@ -96,8 +111,16 @@ feature {NONE} -- Initialization
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)
+ socket_recv_timeout := opts.option_integer_value ("socket_recv_timeout", socket_recv_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)
+
+ if
+ opts.option_boolean_value ("ssl_enabled", ssl_enabled) and then
+ attached opts.option_string_32_value ("ssl_protocol", "tls_1_2") as ssl_prot
+ then
+ ssl_settings := [ssl_prot, opts.option_string_32_value ("ssl_ca_crt", Void), opts.option_string_32_value ("ssl_ca_key", Void)]
+ end
end
create conn.make
@@ -120,11 +143,13 @@ feature -- Execution
do
cfg.set_is_verbose (verbose)
cfg.set_verbose_level (verbose_level)
+ cfg.set_ssl_settings (ssl_settings)
cfg.set_http_server_name (server_name)
cfg.http_server_port := port_number
cfg.set_max_concurrent_connections (max_concurrent_connections)
cfg.set_max_tcp_clients (max_tcp_clients)
cfg.set_socket_timeout (socket_timeout)
+ cfg.set_socket_recv_timeout (socket_recv_timeout)
cfg.set_keep_alive_timeout (keep_alive_timeout)
cfg.set_max_keep_alive_requests (max_keep_alive_requests)
end
@@ -140,11 +165,17 @@ feature -- Execution
debug ("ew_standalone")
if verbose then
io.error.put_string ("Launching standalone web server on port " + port_number.out)
- if attached server_name as l_name then
- io.error.put_string ("%N http://" + l_name + ":" + port_number.out + "/" + base_url + "%N")
+ if ssl_enabled then
+ io.error.put_string ("%N https://")
else
- io.error.put_string ("%N http://localhost:" + port_number.out + "/" + base_url + "%N")
+ io.error.put_string ("%N http://")
end
+ if attached server_name as l_name then
+ io.error.put_string (l_name)
+ else
+ io.error.put_string ("localhost")
+ end
+ io.error.put_string (":" + port_number.out + "/" + base_url + "%N")
end
end
update_configuration (conn.configuration)
@@ -177,9 +208,18 @@ feature {NONE} -- Implementation
-- Help defining the verbosity.
-- The higher, the more output.
+ ssl_settings: detachable TUPLE [protocol: READABLE_STRING_GENERAL; ca_crt, ca_key: detachable READABLE_STRING_GENERAL]
+
+ ssl_enabled: BOOLEAN
+ -- Is secure server? i.e using SSL?
+ do
+ Result := attached ssl_settings as ssl and then attached ssl.protocol as prot and then not prot.is_whitespace
+ end
+
max_concurrent_connections: INTEGER
max_tcp_clients: INTEGER
socket_timeout: INTEGER
+ socket_recv_timeout: INTEGER
keep_alive_timeout: INTEGER
max_keep_alive_requests: INTEGER
diff --git a/library/server/wsf/src/service/wsf_service_launcher.e b/library/server/wsf/src/service/wsf_service_launcher.e
index 2568a5e0..86c41a75 100644
--- a/library/server/wsf/src/service/wsf_service_launcher.e
+++ b/library/server/wsf/src/service/wsf_service_launcher.e
@@ -22,11 +22,11 @@ note
For instance, you can use
create s.make_and_launch_and_options (agent execute, <<["port", 8099]>>)
- And if Nino is the default connector it will support:
+ And if the connector is the Standalone connector,
+ check {WSF_STANDALONE_SERVICE_LAUNCHER} for options description, such as:
port: numeric such as 8099 (or equivalent string as "8099")
base: base_url (very specific to standalone server)
- force_single_threaded: use only one thread, useful for Nino
- verbose: to display verbose output, useful for Nino
+ verbose: to display verbose output.
]"
date: "$Date$"
revision: "$Revision$"
diff --git a/library/server/wsf/src/service/wsf_service_launcher_options.e b/library/server/wsf/src/service/wsf_service_launcher_options.e
index 82e65a6f..1394c17d 100644
--- a/library/server/wsf/src/service/wsf_service_launcher_options.e
+++ b/library/server/wsf/src/service/wsf_service_launcher_options.e
@@ -8,8 +8,8 @@ note
force_single_threaded: use only one thread, useful for Nino
verbose: to display verbose output, useful for Nino
]"
- date: "$Date$"
- revision: "$Revision$"
+ date: "$Date: 2016-08-06 13:34:52 +0200 (sam., 06 août 2016) $"
+ revision: "$Revision: 99106 $"
class
WSF_SERVICE_LAUNCHER_OPTIONS
@@ -85,6 +85,12 @@ feature -- Access
feature -- Helpers
+ has_option (a_opt_name: READABLE_STRING_GENERAL): BOOLEAN
+ -- Is there any value associated to option name `a_opt_name'?
+ do
+ Result := attached option (a_opt_name)
+ end
+
has_integer_option (a_opt_name: READABLE_STRING_GENERAL): BOOLEAN
-- Is there any INTEGER value associated to option name `a_opt_name'?
local
@@ -100,6 +106,29 @@ feature -- Helpers
end
end
+ has_string_32_option (a_opt_name: READABLE_STRING_GENERAL): BOOLEAN
+ -- Is there any string 32 value associated to option name `a_opt_name'?
+ do
+ if attached option (a_opt_name) as opt then
+ Result := attached {READABLE_STRING_GENERAL} opt
+ end
+ end
+
+ option_string_32_value (a_opt_name: READABLE_STRING_GENERAL; a_default: detachable READABLE_STRING_GENERAL): detachable IMMUTABLE_STRING_32
+ -- Unicode String value associated to option name `a_opt_name', other return `a_default'.
+ do
+ if attached option (a_opt_name) as opt then
+ if attached {READABLE_STRING_32} opt as s32 then
+ create Result.make_from_string (s32)
+ elseif attached {READABLE_STRING_GENERAL} opt as s then
+ create Result.make_from_string_general (s)
+ end
+ end
+ if Result = Void and a_default /= Void then
+ create Result.make_from_string_general (a_default)
+ end
+ end
+
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