Migrated most of the example and library to new design.
This commit is contained in:
@@ -26,23 +26,6 @@ feature {NONE} -- Implementation
|
||||
create connector.make_with_base (a_base_url)
|
||||
end
|
||||
|
||||
-- make_with_callback (a_callback: PROCEDURE [ANY, TUPLE [req: WGI_REQUEST; res: WGI_RESPONSE]])
|
||||
-- -- Initialize `Current'.
|
||||
-- do
|
||||
-- make_custom_with_callback (a_callback, Void)
|
||||
-- end
|
||||
|
||||
-- make_custom_with_callback (a_callback: PROCEDURE [ANY, TUPLE [req: WGI_REQUEST; res: WGI_RESPONSE]]; a_base_url: detachable STRING)
|
||||
-- -- Initialize `Current'.
|
||||
-- require
|
||||
-- base_url_starts_with_slash: (a_base_url /= Void and then not a_base_url.is_empty) implies a_base_url.starts_with ("/")
|
||||
-- local
|
||||
-- app: WGI_AGENT_SERVICE
|
||||
-- do
|
||||
-- create app.make (a_callback)
|
||||
-- make_custom (app, a_base_url)
|
||||
-- end
|
||||
|
||||
feature -- Access
|
||||
|
||||
connector: WGI_NINO_CONNECTOR [G]
|
||||
|
||||
@@ -17,16 +17,27 @@ feature {NONE} -- Initialization
|
||||
make
|
||||
-- Initialize `Current'.
|
||||
local
|
||||
conn: WGI_HTTPD_CONNECTOR [APP_WSF_EXECUTION]
|
||||
conn: WGI_STANDALONE_CONNECTOR [APP_WSF_EXECUTION]
|
||||
do
|
||||
print ("Starting httpd server ...%N")
|
||||
|
||||
create conn.make
|
||||
conn.on_launched_actions.extend (agent on_launched)
|
||||
conn.set_port_number (9090)
|
||||
conn.set_max_concurrent_connections (100)
|
||||
conn.launch
|
||||
end
|
||||
|
||||
on_launched (conn: WGI_STANDALONE_CONNECTOR [WGI_EXECUTION])
|
||||
do
|
||||
print ("Server listening on port " + conn.port.out + "%N")
|
||||
end
|
||||
|
||||
on_stopped (conn: WGI_STANDALONE_CONNECTOR [WGI_EXECUTION])
|
||||
do
|
||||
print ("Server terminated%N")
|
||||
end
|
||||
|
||||
note
|
||||
copyright: "2011-2015, Jocelyn Fiat, Javier Velilla, Eiffel Software and others"
|
||||
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
||||
@@ -19,14 +19,19 @@ feature {NONE} -- Initialization
|
||||
|
||||
reset
|
||||
do
|
||||
has_error := False
|
||||
version := Void
|
||||
remote_info := Void
|
||||
reset_request
|
||||
|
||||
has_error := False
|
||||
if attached internal_client_socket as l_sock then
|
||||
l_sock.cleanup
|
||||
end
|
||||
internal_client_socket := Void
|
||||
end
|
||||
|
||||
reset_request
|
||||
do
|
||||
version := Void
|
||||
remote_info := Void
|
||||
|
||||
-- FIXME: optimize to just wipe_out if needed
|
||||
create method.make_empty
|
||||
@@ -34,6 +39,7 @@ feature {NONE} -- Initialization
|
||||
create request_header.make_empty
|
||||
create request_header_map.make (10)
|
||||
|
||||
keep_alive_enabled := False
|
||||
end
|
||||
|
||||
feature -- Status report
|
||||
@@ -79,6 +85,24 @@ feature -- Access
|
||||
remote_info: detachable TUPLE [addr: STRING; hostname: STRING; port: INTEGER]
|
||||
-- Information related to remote client
|
||||
|
||||
keep_alive_enabled: BOOLEAN
|
||||
-- Inside a persistent connection?
|
||||
|
||||
is_http_version_1_0: BOOLEAN
|
||||
do
|
||||
Result := not attached version as v or else v.same_string ("HTTP/1.0")
|
||||
end
|
||||
|
||||
is_http_version_1_1: BOOLEAN
|
||||
do
|
||||
Result := not attached version as v or else v.same_string ("HTTP/1.1")
|
||||
end
|
||||
|
||||
is_http_version_2: BOOLEAN
|
||||
do
|
||||
Result := not attached version as v or else v.same_string ("HTTP/2.0")
|
||||
end
|
||||
|
||||
feature -- Settings
|
||||
|
||||
is_verbose: BOOLEAN
|
||||
@@ -93,6 +117,7 @@ feature -- Change
|
||||
set_is_verbose (b: BOOLEAN)
|
||||
do
|
||||
is_verbose := b
|
||||
print ("set_is_verbose " + b.out + "%N")
|
||||
end
|
||||
|
||||
feature -- Execution
|
||||
@@ -118,6 +143,33 @@ feature -- Execution
|
||||
end
|
||||
|
||||
execute
|
||||
require
|
||||
is_connected: is_connected
|
||||
local
|
||||
l_socket: like client_socket
|
||||
l_exit: BOOLEAN
|
||||
n: INTEGER
|
||||
do
|
||||
l_socket := client_socket
|
||||
check
|
||||
socket_attached: l_socket /= Void
|
||||
socket_valid: l_socket.is_open_read and then l_socket.is_open_write
|
||||
end
|
||||
from
|
||||
-- Process persistent connection as long the socket is not closed.
|
||||
n := 0
|
||||
until
|
||||
l_exit
|
||||
loop
|
||||
n := n + 1
|
||||
-- FIXME: it seems to be called one more time, mostly to see this is done.
|
||||
execute_request
|
||||
l_exit := has_error or l_socket.is_closed or not l_socket.is_open_read or not keep_alive_enabled
|
||||
reset_request
|
||||
end
|
||||
end
|
||||
|
||||
execute_request
|
||||
require
|
||||
is_connected: is_connected
|
||||
local
|
||||
@@ -132,14 +184,15 @@ feature -- Execution
|
||||
end
|
||||
if l_socket.is_closed then
|
||||
debug ("dbglog")
|
||||
dbglog (generator + ".execute {socket is Closed!}")
|
||||
dbglog (generator + ".execute_request {socket is Closed!}")
|
||||
end
|
||||
else
|
||||
debug ("dbglog")
|
||||
dbglog (generator + ".execute socket=" + l_socket.descriptor.out + " ENTER")
|
||||
dbglog (generator + ".execute_request socket=" + l_socket.descriptor.out + " ENTER")
|
||||
end
|
||||
from until l_continue loop
|
||||
if l_socket.ready_for_reading then
|
||||
if l_socket.try_ready_for_reading then
|
||||
-- ready_for_reading then
|
||||
l_continue := True
|
||||
create l_remote_info
|
||||
if attached l_socket.peer_address as l_addr then
|
||||
@@ -150,7 +203,11 @@ feature -- Execution
|
||||
end
|
||||
analyze_request_message (l_socket)
|
||||
else
|
||||
log (generator + ".execute socket=" + l_socket.descriptor.out + "} WAITING")
|
||||
has_error := True
|
||||
l_continue := True
|
||||
debug ("dbglog")
|
||||
dbglog (generator + ".execute_request socket=" + l_socket.descriptor.out + "} WAITING")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -164,7 +221,7 @@ feature -- Execution
|
||||
process_request (l_socket)
|
||||
end
|
||||
debug ("dbglog")
|
||||
dbglog (generator + ".execute {" + l_socket.descriptor.out + "} LEAVE")
|
||||
dbglog (generator + ".execute_request {" + l_socket.descriptor.out + "} LEAVE")
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -243,6 +300,22 @@ feature -- Parsing
|
||||
line := next_line (a_socket)
|
||||
end
|
||||
end
|
||||
if not {HTTPD_SERVER}.is_persistent_connection_supported then
|
||||
keep_alive_enabled := False
|
||||
elseif is_http_version_1_0 then
|
||||
keep_alive_enabled := attached request_header_map.item ("Connection") as l_connection and then
|
||||
l_connection.is_case_insensitive_equal_general ("keep-alive")
|
||||
else
|
||||
-- By default HTTP:1/1 support persistent connection.
|
||||
if
|
||||
attached request_header_map.item ("Connection") as l_connection and then
|
||||
l_connection.is_case_insensitive_equal_general ("close")
|
||||
then
|
||||
keep_alive_enabled := False
|
||||
else
|
||||
keep_alive_enabled := True
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -251,7 +324,7 @@ feature -- Parsing
|
||||
require
|
||||
valid_line: line /= Void and then not line.is_empty
|
||||
local
|
||||
pos, next_pos: INTEGER
|
||||
n, pos, next_pos: INTEGER
|
||||
do
|
||||
if is_verbose then
|
||||
log ("%N## Parse HTTP request line ##")
|
||||
@@ -261,7 +334,11 @@ feature -- Parsing
|
||||
method := line.substring (1, pos - 1)
|
||||
next_pos := line.index_of (' ', pos + 1)
|
||||
uri := line.substring (pos + 1, next_pos - 1)
|
||||
version := line.substring (next_pos + 1, line.count)
|
||||
n := line.count
|
||||
if line[n] = '%R' then
|
||||
n := n - 1
|
||||
end
|
||||
version := line.substring (next_pos + 1, n)
|
||||
has_error := method.is_empty
|
||||
end
|
||||
|
||||
@@ -269,11 +346,18 @@ feature -- Parsing
|
||||
-- Next line fetched from `a_socket' is available.
|
||||
require
|
||||
is_readable: a_socket.is_open_read
|
||||
local
|
||||
retried: BOOLEAN
|
||||
do
|
||||
if a_socket.socket_ok then
|
||||
if retried then
|
||||
Result := Void
|
||||
elseif a_socket.socket_ok then
|
||||
a_socket.read_line_thread_aware
|
||||
Result := a_socket.last_string
|
||||
end
|
||||
rescue
|
||||
retried := True
|
||||
retry
|
||||
end
|
||||
|
||||
feature -- Output
|
||||
@@ -58,6 +58,19 @@ feature -- Access
|
||||
|
||||
factory: separate HTTPD_REQUEST_HANDLER_FACTORY
|
||||
|
||||
is_persistent_connection_supported: BOOLEAN = False
|
||||
-- Is persistent connection supported?
|
||||
--| For now, disabled during dev.
|
||||
|
||||
feature -- Callbacks
|
||||
|
||||
observer: detachable separate HTTPD_SERVER_OBSERVER
|
||||
|
||||
set_observer (obs: like observer)
|
||||
do
|
||||
observer := obs
|
||||
end
|
||||
|
||||
feature -- Access: listening
|
||||
|
||||
port: INTEGER
|
||||
@@ -91,22 +104,10 @@ feature -- Execution
|
||||
end
|
||||
is_shutdown_requested := False
|
||||
listen
|
||||
is_terminated := True
|
||||
on_terminated
|
||||
end
|
||||
|
||||
on_terminated
|
||||
require
|
||||
is_terminated
|
||||
do
|
||||
if is_terminated then
|
||||
log ("%N%NTerminating Web Application Server (port="+ port.out +"):%N")
|
||||
end
|
||||
if attached output as o then
|
||||
o.flush
|
||||
o.close
|
||||
end
|
||||
end
|
||||
|
||||
shutdown_server
|
||||
do
|
||||
debug ("dbglog")
|
||||
@@ -251,8 +252,12 @@ feature -- Event
|
||||
require
|
||||
not_launched: not is_launched
|
||||
do
|
||||
-- print ("port=" + a_port.out + "%N")
|
||||
is_launched := True
|
||||
port := a_port
|
||||
if attached observer as obs then
|
||||
observer_on_launched (obs, a_port)
|
||||
end
|
||||
ensure
|
||||
is_launched: is_launched
|
||||
end
|
||||
@@ -262,10 +267,43 @@ feature -- Event
|
||||
require
|
||||
is_launched: is_launched
|
||||
do
|
||||
is_launched := False
|
||||
is_terminated := True
|
||||
ensure
|
||||
stopped: not is_launched
|
||||
if attached observer as obs then
|
||||
observer_on_stopped (obs)
|
||||
end
|
||||
end
|
||||
|
||||
on_terminated
|
||||
-- Server terminated
|
||||
require
|
||||
is_terminated
|
||||
do
|
||||
if is_terminated and is_verbose then
|
||||
log ("%N%NTerminating Web Application Server (port="+ port.out +"):%N")
|
||||
end
|
||||
if attached output as o then
|
||||
o.flush
|
||||
o.close
|
||||
end
|
||||
if attached observer as obs then
|
||||
observer_on_terminated (obs)
|
||||
end
|
||||
end
|
||||
|
||||
feature {NONE} -- Separate event
|
||||
|
||||
observer_on_launched (obs: attached like observer; a_port: INTEGER)
|
||||
do
|
||||
obs.on_launched (a_port)
|
||||
end
|
||||
|
||||
observer_on_stopped (obs: attached like observer)
|
||||
do
|
||||
obs.on_stopped
|
||||
end
|
||||
|
||||
observer_on_terminated (obs: attached like observer)
|
||||
do
|
||||
obs.on_terminated
|
||||
end
|
||||
|
||||
feature -- Configuration change
|
||||
@@ -0,0 +1,24 @@
|
||||
note
|
||||
description: "Summary description for {HTTPD_SERVER_OBSERVER}."
|
||||
author: ""
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
deferred class
|
||||
HTTPD_SERVER_OBSERVER
|
||||
|
||||
feature -- Event
|
||||
|
||||
on_launched (a_port: INTEGER)
|
||||
deferred
|
||||
end
|
||||
|
||||
on_stopped
|
||||
deferred
|
||||
end
|
||||
|
||||
on_terminated
|
||||
deferred
|
||||
end
|
||||
|
||||
end
|
||||
@@ -26,9 +26,14 @@ feature {NONE} -- Initialization
|
||||
do
|
||||
make
|
||||
connector := conn
|
||||
-- if conn /= Void then
|
||||
-- set_is_verbose (is_connector_verbose (conn))
|
||||
-- end
|
||||
end
|
||||
|
||||
connector: detachable separate WGI_HTTPD_CONNECTOR [G]
|
||||
feature -- Access
|
||||
|
||||
connector: detachable separate WGI_STANDALONE_CONNECTOR [G]
|
||||
|
||||
base: detachable IMMUTABLE_STRING_8
|
||||
do
|
||||
@@ -39,11 +44,18 @@ feature {NONE} -- Initialization
|
||||
end
|
||||
end
|
||||
|
||||
connector_base (conn: separate WGI_HTTPD_CONNECTOR [G]): detachable separate READABLE_STRING_8
|
||||
feature -- SCOOP helpers
|
||||
|
||||
connector_base (conn: separate WGI_STANDALONE_CONNECTOR [G]): detachable separate READABLE_STRING_8
|
||||
do
|
||||
Result := conn.base
|
||||
end
|
||||
|
||||
is_connector_verbose (conn: separate WGI_STANDALONE_CONNECTOR [G]): BOOLEAN
|
||||
do
|
||||
Result := conn.is_verbose
|
||||
end
|
||||
|
||||
feature -- Request processing
|
||||
|
||||
process_request (a_socket: HTTPD_STREAM_SOCKET)
|
||||
@@ -53,14 +65,14 @@ feature -- Request processing
|
||||
l_output: WGI_OUTPUT_STREAM
|
||||
l_error: WGI_ERROR_STREAM
|
||||
req: WGI_REQUEST_FROM_TABLE
|
||||
res: detachable WGI_HTTPD_RESPONSE_STREAM
|
||||
res: detachable WGI_STANDALONE_RESPONSE_STREAM
|
||||
exec: detachable WGI_EXECUTION
|
||||
retried: BOOLEAN
|
||||
do
|
||||
if not retried then
|
||||
create {WGI_HTTPD_INPUT_STREAM} l_input.make (a_socket)
|
||||
create {WGI_HTTPD_OUTPUT_STREAM} l_output.make (a_socket)
|
||||
create {WGI_HTTPD_ERROR_STREAM} l_error.make_stderr (a_socket.descriptor.out)
|
||||
create {WGI_STANDALONE_INPUT_STREAM} l_input.make (a_socket)
|
||||
create {WGI_STANDALONE_OUTPUT_STREAM} l_output.make (a_socket)
|
||||
create {WGI_STANDALONE_ERROR_STREAM} l_error.make_stderr (a_socket.descriptor.out)
|
||||
|
||||
create req.make (httpd_environment (a_socket), l_input, connector)
|
||||
create res.make (l_output, l_error)
|
||||
@@ -12,7 +12,7 @@ inherit
|
||||
|
||||
feature -- Access
|
||||
|
||||
connector: detachable separate WGI_HTTPD_CONNECTOR [G]
|
||||
connector: detachable separate WGI_STANDALONE_CONNECTOR [G]
|
||||
|
||||
feature -- Element change
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
note
|
||||
description: "Summary description for {WGI_HTTPD_CONNECTOR}."
|
||||
description: "Summary description for {WGI_STANDALONE_CONNECTOR}."
|
||||
author: ""
|
||||
todo: "[
|
||||
Check if server and configuration has to be 'separate' ?
|
||||
@@ -11,7 +11,7 @@ note
|
||||
revision: "$Revision$"
|
||||
|
||||
class
|
||||
WGI_HTTPD_CONNECTOR [G -> WGI_EXECUTION create make end]
|
||||
WGI_STANDALONE_CONNECTOR [G -> WGI_EXECUTION create make end]
|
||||
|
||||
inherit
|
||||
WGI_CONNECTOR
|
||||
@@ -28,14 +28,15 @@ feature {NONE} -- Initialization
|
||||
do
|
||||
-- Callbacks
|
||||
create on_launched_actions
|
||||
create on_stopped_actions
|
||||
|
||||
-- Server
|
||||
create fac
|
||||
create server.make (fac)
|
||||
create observer
|
||||
configuration := server_configuration (server)
|
||||
|
||||
controller := server_controller (server)
|
||||
set_factory_connector (Current, fac)
|
||||
initialize_server (server)
|
||||
end
|
||||
|
||||
make_with_base (a_base: like base)
|
||||
@@ -46,11 +47,23 @@ feature {NONE} -- Initialization
|
||||
set_base (a_base)
|
||||
end
|
||||
|
||||
set_factory_connector (conn: detachable separate WGI_HTTPD_CONNECTOR [G]; fac: separate WGI_HTTPD_REQUEST_HANDLER_FACTORY [G])
|
||||
initialize_server (a_server: like server)
|
||||
do
|
||||
a_server.set_observer (observer)
|
||||
end
|
||||
|
||||
feature {NONE} -- Separate helper
|
||||
|
||||
set_factory_connector (conn: detachable separate WGI_STANDALONE_CONNECTOR [G]; fac: separate WGI_HTTPD_REQUEST_HANDLER_FACTORY [G])
|
||||
do
|
||||
fac.set_connector (conn)
|
||||
end
|
||||
|
||||
server_configuration (a_server: like server): like configuration
|
||||
do
|
||||
Result := a_server.configuration
|
||||
end
|
||||
|
||||
feature -- Access
|
||||
|
||||
name: STRING_8 = "httpd"
|
||||
@@ -63,12 +76,11 @@ feature -- Access
|
||||
|
||||
server: separate HTTPD_SERVER
|
||||
|
||||
configuration: separate HTTPD_CONFIGURATION
|
||||
controller: separate HTTPD_CONTROLLER
|
||||
|
||||
server_configuration (a_server: like server): like configuration
|
||||
do
|
||||
Result := a_server.configuration
|
||||
end
|
||||
observer: separate WGI_STANDALONE_SERVER_OBSERVER
|
||||
|
||||
configuration: separate HTTPD_CONFIGURATION
|
||||
|
||||
feature -- Access
|
||||
|
||||
@@ -82,17 +94,17 @@ feature -- Status report
|
||||
|
||||
port: INTEGER
|
||||
-- Listening port.
|
||||
--| 0: not launched
|
||||
--| 0: not launched
|
||||
|
||||
is_verbose: BOOLEAN
|
||||
-- Is verbose?
|
||||
|
||||
feature -- Callbacks
|
||||
|
||||
on_launched_actions: ACTION_SEQUENCE [TUPLE [WGI_CONNECTOR]]
|
||||
on_launched_actions: ACTION_SEQUENCE [TUPLE [WGI_STANDALONE_CONNECTOR [WGI_EXECUTION]]]
|
||||
-- Actions triggered when launched
|
||||
|
||||
on_stopped_actions: ACTION_SEQUENCE [TUPLE [WGI_CONNECTOR]]
|
||||
-- Actions triggered when stopped
|
||||
|
||||
feature -- Element change
|
||||
feature -- Event
|
||||
|
||||
on_launched (a_port: INTEGER)
|
||||
-- Server launched
|
||||
@@ -102,14 +114,6 @@ feature -- Element change
|
||||
on_launched_actions.call ([Current])
|
||||
end
|
||||
|
||||
on_stopped
|
||||
-- Server stopped
|
||||
do
|
||||
on_stopped_actions.call ([Current])
|
||||
launched := False
|
||||
port := 0
|
||||
end
|
||||
|
||||
feature -- Element change
|
||||
|
||||
set_base (b: like base)
|
||||
@@ -154,6 +158,7 @@ feature {NONE} -- Implementation
|
||||
|
||||
set_is_verbose_on_configuration (b: BOOLEAN; cfg: like configuration)
|
||||
do
|
||||
is_verbose := b
|
||||
cfg.set_is_verbose (b)
|
||||
end
|
||||
|
||||
@@ -164,6 +169,29 @@ feature -- Server
|
||||
launched := False
|
||||
port := 0
|
||||
launch_server (server)
|
||||
on_server_started (observer)
|
||||
end
|
||||
|
||||
shutdown_server
|
||||
do
|
||||
if launched then
|
||||
-- FIXME jfiat [2015/03/27] : prevent multiple calls (otherwise it hangs)
|
||||
separate_shutdown_server_on_controller (controller)
|
||||
end
|
||||
end
|
||||
|
||||
server_controller (a_server: like server): separate HTTPD_CONTROLLER
|
||||
do
|
||||
Result := a_server.controller
|
||||
end
|
||||
|
||||
on_server_started (obs: like observer)
|
||||
require
|
||||
obs.started
|
||||
do
|
||||
if obs.port > 0 then
|
||||
on_launched (obs.port)
|
||||
end
|
||||
end
|
||||
|
||||
configure_server (a_configuration: like configuration)
|
||||
@@ -181,6 +209,19 @@ feature -- Server
|
||||
a_server.launch
|
||||
end
|
||||
|
||||
feature {NONE} -- Implementation
|
||||
|
||||
separate_server_terminated (a_server: like server): BOOLEAN
|
||||
do
|
||||
Result := a_server.is_terminated
|
||||
end
|
||||
|
||||
separate_shutdown_server_on_controller (a_controller: separate HTTPD_CONTROLLER)
|
||||
do
|
||||
a_controller.shutdown
|
||||
end
|
||||
|
||||
|
||||
note
|
||||
copyright: "2011-2015, Jocelyn Fiat, Javier Velilla, Eiffel Software and others"
|
||||
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
||||
@@ -1,12 +1,12 @@
|
||||
note
|
||||
description: "Summary description for WGI_HTTPD_ERROR_STREAM."
|
||||
description: "Summary description for WGI_STANDALONE_ERROR_STREAM."
|
||||
legal: "See notice at end of class."
|
||||
status: "See notice at end of class."
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
class
|
||||
WGI_HTTPD_ERROR_STREAM
|
||||
WGI_STANDALONE_ERROR_STREAM
|
||||
|
||||
inherit
|
||||
WGI_ERROR_STREAM
|
||||
@@ -58,7 +58,7 @@ feature -- Error
|
||||
end
|
||||
|
||||
note
|
||||
copyright: "2011-2011, Eiffel Software and others"
|
||||
copyright: "2011-2015, Jocelyn Fiat, Javier Velilla, Eiffel Software and others"
|
||||
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
||||
source: "[
|
||||
Eiffel Software
|
||||
@@ -1,12 +1,12 @@
|
||||
note
|
||||
description: "Summary description for {WGI_HTTPD_INPUT_STREAM}."
|
||||
description: "Summary description for {WGI_STANDALONE_INPUT_STREAM}."
|
||||
legal: "See notice at end of class."
|
||||
status: "See notice at end of class."
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
class
|
||||
WGI_HTTPD_INPUT_STREAM
|
||||
WGI_STANDALONE_INPUT_STREAM
|
||||
|
||||
inherit
|
||||
WGI_INPUT_STREAM
|
||||
@@ -22,7 +22,7 @@ feature {NONE} -- Initialization
|
||||
set_source (a_source)
|
||||
end
|
||||
|
||||
feature {WGI_HTTPD_CONNECTOR, WGI_SERVICE} -- Nino
|
||||
feature {WGI_STANDALONE_CONNECTOR, WGI_SERVICE} -- Nino
|
||||
|
||||
set_source (i: like source)
|
||||
do
|
||||
@@ -1,12 +1,12 @@
|
||||
note
|
||||
description: "Summary description for {WGI_HTTPD_OUTPUT_STREAM}."
|
||||
description: "Summary description for {WGI_STANDALONE_OUTPUT_STREAM}."
|
||||
legal: "See notice at end of class."
|
||||
status: "See notice at end of class."
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
class
|
||||
WGI_HTTPD_OUTPUT_STREAM
|
||||
WGI_STANDALONE_OUTPUT_STREAM
|
||||
|
||||
inherit
|
||||
WGI_OUTPUT_STREAM
|
||||
@@ -26,7 +26,7 @@ feature {NONE} -- Initialization
|
||||
set_target (a_target)
|
||||
end
|
||||
|
||||
feature {WGI_HTTPD_CONNECTOR, WGI_SERVICE} -- Nino
|
||||
feature {WGI_STANDALONE_CONNECTOR, WGI_SERVICE} -- Nino
|
||||
|
||||
set_target (o: like target)
|
||||
do
|
||||
@@ -7,7 +7,7 @@ note
|
||||
revision: "$Revision$"
|
||||
|
||||
class
|
||||
WGI_HTTPD_RESPONSE_STREAM
|
||||
WGI_STANDALONE_RESPONSE_STREAM
|
||||
|
||||
inherit
|
||||
WGI_RESPONSE_STREAM
|
||||
@@ -27,9 +27,11 @@ feature -- Header output operation
|
||||
o := output
|
||||
o.put_string (a_text)
|
||||
|
||||
-- Nino does not support persistent connection for now
|
||||
o.put_string ("Connection: close")
|
||||
o.put_crlf
|
||||
if not {HTTPD_SERVER}.is_persistent_connection_supported then
|
||||
-- standalone does not support persistent connection for now
|
||||
o.put_string ("Connection: close")
|
||||
o.put_crlf
|
||||
end
|
||||
|
||||
-- end of headers
|
||||
o.put_crlf
|
||||
@@ -38,7 +40,7 @@ feature -- Header output operation
|
||||
end
|
||||
|
||||
;note
|
||||
copyright: "2011-2012, Jocelyn Fiat, Javier Velilla, Eiffel Software and others"
|
||||
copyright: "2011-2015, Jocelyn Fiat, Javier Velilla, Eiffel Software and others"
|
||||
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
||||
source: "[
|
||||
Eiffel Software
|
||||
@@ -0,0 +1,53 @@
|
||||
note
|
||||
description: "Summary description for {WGI_STANDALONE_SERVER_OBSERVER}."
|
||||
author: ""
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
class
|
||||
WGI_STANDALONE_SERVER_OBSERVER
|
||||
|
||||
inherit
|
||||
HTTPD_SERVER_OBSERVER
|
||||
|
||||
feature -- Access
|
||||
|
||||
started: BOOLEAN
|
||||
|
||||
stopped: BOOLEAN
|
||||
|
||||
terminated: BOOLEAN
|
||||
|
||||
port: INTEGER
|
||||
|
||||
feature -- Event
|
||||
|
||||
on_launched (a_port: INTEGER)
|
||||
do
|
||||
started := True
|
||||
port := a_port
|
||||
end
|
||||
|
||||
on_stopped
|
||||
do
|
||||
stopped := True
|
||||
end
|
||||
|
||||
on_terminated
|
||||
do
|
||||
port := 0
|
||||
terminated := True
|
||||
end
|
||||
|
||||
|
||||
note
|
||||
copyright: "2011-2015, Jocelyn Fiat, Javier Velilla, Eiffel Software and others"
|
||||
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
||||
source: "[
|
||||
Eiffel Software
|
||||
5949 Hollister Ave., Goleta, CA 93117 USA
|
||||
Telephone 805-685-1006, Fax 805-685-6869
|
||||
Website http://www.eiffel.com
|
||||
Customer support http://support.eiffel.com
|
||||
]"
|
||||
end
|
||||
@@ -1,13 +1,13 @@
|
||||
<?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="connector_httpd" uuid="49C99A6E-CCC1-4015-81F6-D7C43B592034" library_target="connector_httpd">
|
||||
<target name="connector_httpd">
|
||||
<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="connector_standalone" uuid="49C99A6E-CCC1-4015-81F6-D7C43B592034" library_target="connector_standalone">
|
||||
<target name="connector_standalone">
|
||||
<root all_classes="true"/>
|
||||
<file_rule>
|
||||
<exclude>/EIFGENs$</exclude>
|
||||
<exclude>/\.git$</exclude>
|
||||
<exclude>/\.svn$</exclude>
|
||||
</file_rule>
|
||||
<option debug="false" warning="true" full_class_checking="true" is_attached_by_default="true" void_safety="all" syntax="transitional">
|
||||
<option debug="true" warning="true" full_class_checking="true" is_attached_by_default="true" void_safety="all" syntax="transitional">
|
||||
<debug name="dbglog" enabled="true"/>
|
||||
<assertions precondition="true"/>
|
||||
</option>
|
||||
@@ -16,16 +16,14 @@
|
||||
<library name="encoder" location="..\..\..\..\text\encoder\encoder-safe.ecf"/>
|
||||
<library name="ewsgi" location="..\..\ewsgi-safe.ecf" readonly="false"/>
|
||||
<library name="http" location="..\..\..\..\network\protocol\http\http-safe.ecf"/>
|
||||
<library name="httpd" location="src\httpd\httpd-safe.ecf"/>
|
||||
<cluster name="src" location=".\src\" recursive="true">
|
||||
<file_rule>
|
||||
<exclude>/httpd$</exclude>
|
||||
</file_rule>
|
||||
<library name="httpd" location="src\httpd\httpd-safe.ecf" readonly="false"/>
|
||||
<cluster name="src" location=".\src\">
|
||||
<cluster name="implementation" location="$|implementation\" hidden="true"/>
|
||||
</cluster>
|
||||
</target>
|
||||
<target name="dev" extends="connector_httpd">
|
||||
<target name="dev_scoop" extends="connector_standalone">
|
||||
<root class="HTTPD_CONNECTOR_DEV" feature="make"/>
|
||||
<option debug="false">
|
||||
<option debug="true">
|
||||
<debug name="dbglog" enabled="true"/>
|
||||
<assertions precondition="true" postcondition="true" check="true" supplier_precondition="true"/>
|
||||
</option>
|
||||
@@ -33,10 +31,10 @@
|
||||
<library name="wsf" location="..\..\..\wsf\wsf-safe.ecf" readonly="false"/>
|
||||
<cluster name="dev" location="dev\" recursive="true"/>
|
||||
</target>
|
||||
<target name="dev_mt" extends="dev">
|
||||
<target name="dev_mt" extends="dev_scoop">
|
||||
<setting name="concurrency" value="thread"/>
|
||||
</target>
|
||||
<target name="dev_none" extends="dev">
|
||||
<target name="dev_none" extends="dev_scoop">
|
||||
<setting name="concurrency" value="none"/>
|
||||
</target>
|
||||
</system>
|
||||
23
library/server/ewsgi/connectors/standalone/standalone.ecf
Normal file
23
library/server/ewsgi/connectors/standalone/standalone.ecf
Normal file
@@ -0,0 +1,23 @@
|
||||
<?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="connector_standalone" uuid="49C99A6E-CCC1-4015-81F6-D7C43B592034" library_target="connector_standalone">
|
||||
<target name="connector_standalone">
|
||||
<root all_classes="true"/>
|
||||
<file_rule>
|
||||
<exclude>/EIFGENs$</exclude>
|
||||
<exclude>/\.git$</exclude>
|
||||
<exclude>/\.svn$</exclude>
|
||||
</file_rule>
|
||||
<option warning="true" full_class_checking="true" void_safety="none" syntax="transitional">
|
||||
<assertions precondition="true"/>
|
||||
</option>
|
||||
<setting name="concurrency" value="scoop"/>
|
||||
<library name="base" location="$ISE_LIBRARY\library\base\base.ecf"/>
|
||||
<library name="encoder" location="..\..\..\..\text\encoder\encoder.ecf"/>
|
||||
<library name="ewsgi" location="..\..\ewsgi.ecf" readonly="false"/>
|
||||
<library name="http" location="..\..\..\..\network\protocol\http\http.ecf"/>
|
||||
<library name="httpd" location="src\httpd\httpd.ecf" readonly="false"/>
|
||||
<cluster name="src" location=".\src\">
|
||||
<cluster name="implementation" location="$|implementation\" hidden="true"/>
|
||||
</cluster>
|
||||
</target>
|
||||
</system>
|
||||
@@ -18,20 +18,13 @@ feature {NONE} -- Initialization
|
||||
make
|
||||
do
|
||||
print ("Example: start a Nino web server on port " + port_number.out + ", %Nand reply Hello World for any request such as http://localhost:8123/%N")
|
||||
(create {NINO_SERVICE}.make_custom (Current, "")).listen (port_number)
|
||||
end
|
||||
|
||||
execute (req: WGI_REQUEST; res: WGI_RESPONSE)
|
||||
do
|
||||
res.set_status_code (200, Void)
|
||||
res.put_header_text ("Content-Type: text/plain%R%N")
|
||||
res.put_string ("Hello World!%N")
|
||||
(create {NINO_SERVICE [HELLO_WORLD_EXECUTION]}.make_custom ("")).listen (port_number)
|
||||
end
|
||||
|
||||
port_number: INTEGER = 8123
|
||||
|
||||
note
|
||||
copyright: "2011-2012, Eiffel Software and others"
|
||||
copyright: "2011-2015, Eiffel Software and others"
|
||||
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
||||
source: "[
|
||||
Eiffel Software
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
note
|
||||
description: "Summary description for {HELLO_WORLD_EXECUTION}."
|
||||
author: ""
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
class
|
||||
HELLO_WORLD_EXECUTION
|
||||
|
||||
inherit
|
||||
WGI_EXECUTION
|
||||
|
||||
create
|
||||
make
|
||||
|
||||
feature {NONE} -- Initialization
|
||||
|
||||
execute
|
||||
do
|
||||
response.set_status_code (200, Void)
|
||||
response.put_header_text ("Content-Type: text/plain%R%N")
|
||||
response.put_string ("Hello World!%N")
|
||||
end
|
||||
|
||||
note
|
||||
copyright: "2011-2015, Eiffel Software and others"
|
||||
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
||||
source: "[
|
||||
Eiffel Software
|
||||
5949 Hollister Ave., Goleta, CA 93117 USA
|
||||
Telephone 805-685-1006, Fax 805-685-6869
|
||||
Website http://www.eiffel.com
|
||||
Customer support http://support.eiffel.com
|
||||
]"
|
||||
end
|
||||
|
||||
@@ -1,26 +1,16 @@
|
||||
note
|
||||
description: "Summary description for {APP_WSF_HTTPD_REQUEST_HANDLER}."
|
||||
description: "Summary description for {WGI_EXECUTION_FACTORY}."
|
||||
author: ""
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
class
|
||||
APP_WSF_HTTPD_REQUEST_HANDLER
|
||||
deferred class
|
||||
WGI_EXECUTION_FACTORY
|
||||
|
||||
inherit
|
||||
WSF_HTTPD_REQUEST_HANDLER
|
||||
feature -- Factory
|
||||
|
||||
create
|
||||
make
|
||||
|
||||
feature -- Execute
|
||||
|
||||
do_more (req: WGI_REQUEST; res: WGI_RESPONSE)
|
||||
local
|
||||
exec: WSF_EXECUTION
|
||||
do
|
||||
create {APP_WSF_EXECUTION} exec.make (req, res)
|
||||
exec.execute
|
||||
execution (req: WGI_REQUEST; res: WGI_RESPONSE): WGI_EXECUTION
|
||||
deferred
|
||||
end
|
||||
|
||||
note
|
||||
@@ -22,13 +22,13 @@ feature {NONE} -- Initialization
|
||||
local
|
||||
utf: UTF_CONVERTER
|
||||
do
|
||||
auth_type := req.auth_type
|
||||
content_length := req.content_length
|
||||
if attached req.content_type as ct then
|
||||
content_type := ct.string
|
||||
else
|
||||
content_type := Void
|
||||
end
|
||||
auth_type := req.auth_type
|
||||
gateway_interface := req.gateway_interface
|
||||
path_info := req.path_info
|
||||
path_translated := req.path_translated
|
||||
|
||||
Reference in New Issue
Block a user