First attempt to use `{NETWORK_STREAM_SOCKET}.accept_to'
This commit is contained in:
@@ -57,45 +57,33 @@ feature {HTTPD_SERVER_I} -- Execution
|
|||||||
p.gracefull_stop
|
p.gracefull_stop
|
||||||
end
|
end
|
||||||
|
|
||||||
process_incoming_connection (a_socket: HTTPD_STREAM_SOCKET)
|
accept_incoming_connection (a_listening_socket: HTTPD_STREAM_SOCKET)
|
||||||
-- <Precursor>
|
|
||||||
do
|
do
|
||||||
debug ("dbglog")
|
accept_connection_on_pool (a_listening_socket, pool) -- Wait on not pool.is_full or is_stop_requested
|
||||||
dbglog (generator + ".before process_incoming_connection {"+ a_socket.descriptor.out +"} -- SCOOP WAIT!")
|
|
||||||
end
|
|
||||||
-- if is_shutdown_requested then
|
|
||||||
-- a_socket.cleanup
|
|
||||||
-- else
|
|
||||||
process_connection_on_pool (a_socket, pool) -- Wait on not pool.is_full or is_stop_requested
|
|
||||||
-- end
|
|
||||||
debug ("dbglog")
|
|
||||||
dbglog (generator + ".after process_incoming_connection {"+ a_socket.descriptor.out +"}")
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
process_connection_on_pool (a_socket: HTTPD_STREAM_SOCKET; a_pool: like pool)
|
accept_connection_on_pool (a_listening_socket: HTTPD_STREAM_SOCKET; a_pool: like pool)
|
||||||
-- Process incoming connection
|
-- Process accept connection
|
||||||
-- note that the precondition matters for scoop synchronization.
|
-- note that the precondition matters for scoop synchronization.
|
||||||
require
|
require
|
||||||
concurrency: not a_pool.is_full or is_shutdown_requested or a_pool.stop_requested
|
concurrency: not a_pool.is_full or is_shutdown_requested or a_pool.stop_requested
|
||||||
do
|
do
|
||||||
debug ("dbglog")
|
debug ("dbglog")
|
||||||
dbglog (generator + ".ENTER process_connection {"+ a_socket.descriptor.out +"}")
|
dbglog (generator + ".ENTER accept_connection_on_pool")
|
||||||
end
|
end
|
||||||
if is_shutdown_requested then
|
if is_shutdown_requested then
|
||||||
a_socket.cleanup
|
-- Cancel
|
||||||
elseif attached a_pool.separate_item (factory) as h then
|
elseif attached a_pool.separate_item (factory) as h then
|
||||||
process_request_handler (h, a_socket)
|
process_request_handler_on_accept (h, a_listening_socket)
|
||||||
else
|
else
|
||||||
check is_not_full: False end
|
check is_not_full: False end
|
||||||
a_socket.cleanup
|
|
||||||
end
|
end
|
||||||
debug ("dbglog")
|
debug ("dbglog")
|
||||||
dbglog (generator + ".LEAVE process_connection {"+ a_socket.descriptor.out +"}")
|
dbglog (generator + ".LEAVE accept_connection_on_pool")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
process_request_handler (hdl: separate HTTPD_REQUEST_HANDLER; a_socket: HTTPD_STREAM_SOCKET)
|
process_request_handler_on_accept (hdl: separate HTTPD_REQUEST_HANDLER; a_listening_socket: HTTPD_STREAM_SOCKET)
|
||||||
require
|
require
|
||||||
not hdl.has_error
|
not hdl.has_error
|
||||||
do
|
do
|
||||||
@@ -103,20 +91,21 @@ feature {HTTPD_SERVER_I} -- Execution
|
|||||||
--| also handle permanent connection...?
|
--| also handle permanent connection...?
|
||||||
|
|
||||||
debug ("dbglog")
|
debug ("dbglog")
|
||||||
dbglog (generator + ".ENTER process_request_handler {"+ a_socket.descriptor.out +"}")
|
dbglog (generator + ".ENTER process_request_handler_on_accept")
|
||||||
end
|
end
|
||||||
|
|
||||||
hdl.set_client_socket (a_socket)
|
hdl.accept_from_listening_socket (a_listening_socket)
|
||||||
if hdl.has_error then
|
if hdl.has_error then
|
||||||
log ("Internal error (set_client_socket failed)")
|
log ("Internal error (accept_from_listening_socket failed)")
|
||||||
else
|
else
|
||||||
-- hdl.set_logger (server)
|
-- hdl.set_logger (server)
|
||||||
if attached hdl.separate_execution as l_result then
|
if attached hdl.separate_execution as l_result then
|
||||||
|
|
||||||
end
|
end
|
||||||
hdl.separate_release
|
hdl.separate_release
|
||||||
end
|
end
|
||||||
debug ("dbglog")
|
debug ("dbglog")
|
||||||
dbglog (generator + ".LEAVE process_request_handler {"+ a_socket.descriptor.out +"}")
|
dbglog (generator + ".LEAVE process_request_handler_on_accept")
|
||||||
end
|
end
|
||||||
rescue
|
rescue
|
||||||
log ("Releasing handler after exception!")
|
log ("Releasing handler after exception!")
|
||||||
|
|||||||
@@ -12,9 +12,7 @@ deferred class
|
|||||||
inherit
|
inherit
|
||||||
HTTPD_REQUEST_HANDLER_I
|
HTTPD_REQUEST_HANDLER_I
|
||||||
redefine
|
redefine
|
||||||
-- set_client_socket,
|
release
|
||||||
release,
|
|
||||||
reset
|
|
||||||
end
|
end
|
||||||
|
|
||||||
CONCURRENT_POOL_ITEM
|
CONCURRENT_POOL_ITEM
|
||||||
@@ -22,42 +20,23 @@ inherit
|
|||||||
release as release_pool_item
|
release as release_pool_item
|
||||||
end
|
end
|
||||||
|
|
||||||
feature {NONE} -- Initialization
|
|
||||||
|
|
||||||
reset
|
|
||||||
do
|
|
||||||
if attached client_socket_source as l_sock then
|
|
||||||
cleanup_separate_socket (l_sock)
|
|
||||||
end
|
|
||||||
Precursor
|
|
||||||
client_socket_source := Void
|
|
||||||
end
|
|
||||||
|
|
||||||
cleanup_separate_socket (a_socket: attached like client_socket_source)
|
|
||||||
do
|
|
||||||
a_socket.cleanup
|
|
||||||
end
|
|
||||||
|
|
||||||
feature -- Access
|
|
||||||
|
|
||||||
client_socket: detachable HTTPD_STREAM_SOCKET
|
|
||||||
|
|
||||||
client_socket_source: detachable separate HTTPD_STREAM_SOCKET
|
|
||||||
-- Associated original client socket
|
|
||||||
-- kept to avoid being closed when disposed,
|
|
||||||
-- and thus avoid closing related `client_socket'.
|
|
||||||
|
|
||||||
feature -- Change
|
feature -- Change
|
||||||
|
|
||||||
set_client_socket (a_socket: separate HTTPD_STREAM_SOCKET)
|
accept_from_listening_socket (a_listening_socket: separate HTTPD_STREAM_SOCKET)
|
||||||
local
|
local
|
||||||
retried: BOOLEAN
|
retried: BOOLEAN
|
||||||
|
s: like client_socket
|
||||||
do
|
do
|
||||||
if retried then
|
if retried then
|
||||||
has_error := True
|
has_error := True
|
||||||
else
|
else
|
||||||
create client_socket.make_from_separate (a_socket)
|
create s.make_empty
|
||||||
client_socket_source := a_socket
|
client_socket := s
|
||||||
|
a_listening_socket.accept_to (s)
|
||||||
|
if not s.is_created then
|
||||||
|
has_error := True
|
||||||
|
client_socket := Void
|
||||||
|
end
|
||||||
end
|
end
|
||||||
rescue
|
rescue
|
||||||
retried := True
|
retried := True
|
||||||
@@ -99,7 +78,7 @@ feature {CONCURRENT_POOL, HTTPD_CONNECTION_HANDLER_I} -- Basic operation
|
|||||||
end
|
end
|
||||||
|
|
||||||
note
|
note
|
||||||
copyright: "2011-2014, 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)"
|
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
||||||
source: "[
|
source: "[
|
||||||
Eiffel Software
|
Eiffel Software
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ feature {NONE} -- Access
|
|||||||
|
|
||||||
feature {HTTPD_SERVER_I} -- Execution
|
feature {HTTPD_SERVER_I} -- Execution
|
||||||
|
|
||||||
process_incoming_connection (a_socket: HTTPD_STREAM_SOCKET)
|
accept_incoming_connection (a_listening_socket: HTTPD_STREAM_SOCKET)
|
||||||
deferred
|
deferred
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -72,7 +72,7 @@ feature {NONE} -- Output
|
|||||||
end
|
end
|
||||||
|
|
||||||
note
|
note
|
||||||
copyright: "2011-2014, 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)"
|
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
||||||
source: "[
|
source: "[
|
||||||
Eiffel Software
|
Eiffel Software
|
||||||
|
|||||||
@@ -23,21 +23,22 @@ feature {NONE} -- Initialization
|
|||||||
version := Void
|
version := Void
|
||||||
remote_info := Void
|
remote_info := Void
|
||||||
|
|
||||||
-- if attached client_socket as l_sock then
|
if attached client_socket as l_sock then
|
||||||
-- l_sock.cleanup
|
l_sock.cleanup
|
||||||
-- end
|
end
|
||||||
-- client_socket := Void
|
client_socket := Void
|
||||||
|
|
||||||
-- FIXME: optimize to just wipe_out if needed
|
-- FIXME: optimize to just wipe_out if needed
|
||||||
create method.make_empty
|
create method.make_empty
|
||||||
create uri.make_empty
|
create uri.make_empty
|
||||||
create request_header.make_empty
|
create request_header.make_empty
|
||||||
create request_header_map.make (10)
|
create request_header_map.make (10)
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
feature -- Access
|
feature -- Access
|
||||||
|
|
||||||
-- client_socket: detachable TCP_STREAM_SOCKET
|
client_socket: detachable HTTPD_STREAM_SOCKET
|
||||||
|
|
||||||
request_header: STRING
|
request_header: STRING
|
||||||
-- Header' source
|
-- Header' source
|
||||||
@@ -69,16 +70,6 @@ feature -- Status report
|
|||||||
|
|
||||||
feature -- Change
|
feature -- Change
|
||||||
|
|
||||||
-- set_client_socket (a_socket: separate TCP_STREAM_SOCKET)
|
|
||||||
-- require
|
|
||||||
-- socket_attached: a_socket /= Void
|
|
||||||
-- socket_valid: a_socket.is_open_read and then a_socket.is_open_write
|
|
||||||
-- a_http_socket: not a_socket.is_closed
|
|
||||||
-- deferred
|
|
||||||
-- ensure
|
|
||||||
-- attached client_socket as s implies s.descriptor = a_socket.descriptor
|
|
||||||
-- end
|
|
||||||
|
|
||||||
set_is_verbose (b: BOOLEAN)
|
set_is_verbose (b: BOOLEAN)
|
||||||
do
|
do
|
||||||
is_verbose := b
|
is_verbose := b
|
||||||
@@ -265,7 +256,7 @@ invariant
|
|||||||
request_header_attached: request_header /= Void
|
request_header_attached: request_header /= Void
|
||||||
|
|
||||||
note
|
note
|
||||||
copyright: "2011-2014, 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)"
|
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
||||||
source: "[
|
source: "[
|
||||||
Eiffel Software
|
Eiffel Software
|
||||||
|
|||||||
@@ -126,8 +126,7 @@ feature -- Listening
|
|||||||
-- Creates a socket and connects to the http server.
|
-- Creates a socket and connects to the http server.
|
||||||
-- `a_server': The main server object
|
-- `a_server': The main server object
|
||||||
local
|
local
|
||||||
l_listening_socket,
|
l_listening_socket: detachable HTTPD_STREAM_SOCKET
|
||||||
l_accepted_socket: detachable HTTPD_STREAM_SOCKET
|
|
||||||
l_http_port: INTEGER
|
l_http_port: INTEGER
|
||||||
l_connection_handler: HTTPD_CONNECTION_HANDLER
|
l_connection_handler: HTTPD_CONNECTION_HANDLER
|
||||||
do
|
do
|
||||||
@@ -164,23 +163,18 @@ feature -- Listening
|
|||||||
until
|
until
|
||||||
is_shutdown_requested
|
is_shutdown_requested
|
||||||
loop
|
loop
|
||||||
l_listening_socket.accept
|
|
||||||
if not is_shutdown_requested then
|
|
||||||
l_accepted_socket := l_listening_socket.accepted
|
|
||||||
if l_accepted_socket /= Void then
|
|
||||||
request_counter := request_counter + 1
|
request_counter := request_counter + 1
|
||||||
if is_verbose then
|
if is_verbose then
|
||||||
log ("#" + request_counter.out + "# Incoming connection...(socket:" + l_accepted_socket.descriptor.out + ")")
|
log ("#" + request_counter.out + "# Waiting connection...(listening socket:" + l_listening_socket.descriptor.out + ")")
|
||||||
end
|
end
|
||||||
debug ("dbglog")
|
debug ("dbglog")
|
||||||
dbglog (generator + ".before process_incoming_connection {" + l_accepted_socket.descriptor.out + "}" )
|
dbglog (generator + ".before process_waiting_incoming_connection")
|
||||||
end
|
end
|
||||||
l_connection_handler.process_incoming_connection (l_accepted_socket)
|
l_connection_handler.accept_incoming_connection (l_listening_socket)
|
||||||
debug ("dbglog")
|
debug ("dbglog")
|
||||||
dbglog (generator + ".after process_incoming_connection {" + l_accepted_socket.descriptor.out + "}")
|
dbglog (generator + ".after process_waiting_incoming_connection")
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
update_is_shutdown_requested (l_connection_handler)
|
update_is_shutdown_requested (l_connection_handler)
|
||||||
end
|
end
|
||||||
wait_for_connection_handler_completion (l_connection_handler)
|
wait_for_connection_handler_completion (l_connection_handler)
|
||||||
@@ -304,7 +298,7 @@ feature -- Output
|
|||||||
end
|
end
|
||||||
|
|
||||||
note
|
note
|
||||||
copyright: "2011-2014, 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)"
|
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
||||||
source: "[
|
source: "[
|
||||||
Eiffel Software
|
Eiffel Software
|
||||||
|
|||||||
@@ -12,7 +12,8 @@ class
|
|||||||
create
|
create
|
||||||
make_server_by_address_and_port,
|
make_server_by_address_and_port,
|
||||||
make_server_by_port,
|
make_server_by_port,
|
||||||
make_from_separate
|
make_from_separate,
|
||||||
|
make_empty
|
||||||
|
|
||||||
create {HTTPD_STREAM_SOCKET}
|
create {HTTPD_STREAM_SOCKET}
|
||||||
make
|
make
|
||||||
@@ -36,6 +37,11 @@ feature {NONE} -- Initialization
|
|||||||
create {TCP_STREAM_SOCKET} socket.make_from_separate (s.socket)
|
create {TCP_STREAM_SOCKET} socket.make_from_separate (s.socket)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
make_empty
|
||||||
|
do
|
||||||
|
create {TCP_STREAM_SOCKET} socket.make_empty
|
||||||
|
end
|
||||||
|
|
||||||
retrieve_socket (s: HTTPD_STREAM_SOCKET): INTEGER
|
retrieve_socket (s: HTTPD_STREAM_SOCKET): INTEGER
|
||||||
do
|
do
|
||||||
Result := s.socket.descriptor
|
Result := s.socket.descriptor
|
||||||
@@ -147,6 +153,13 @@ feature -- Status Report
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
is_created: BOOLEAN
|
||||||
|
do
|
||||||
|
if attached {NETWORK_SOCKET} socket as l_socket then
|
||||||
|
Result := l_socket.is_created
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
socket_ok: BOOLEAN
|
socket_ok: BOOLEAN
|
||||||
do
|
do
|
||||||
Result := socket.socket_ok
|
Result := socket.socket_ok
|
||||||
@@ -194,6 +207,18 @@ feature -- Status Report
|
|||||||
socket.accept
|
socket.accept
|
||||||
end
|
end
|
||||||
|
|
||||||
|
accept_to (other: separate HTTPD_STREAM_SOCKET)
|
||||||
|
-- Accept a new connection on listen socket.
|
||||||
|
-- Socket of accepted connection is available in `other'.
|
||||||
|
do
|
||||||
|
if
|
||||||
|
attached {NETWORK_STREAM_SOCKET} socket as l_socket and then
|
||||||
|
attached {separate NETWORK_STREAM_SOCKET} other.socket as l_other_socket
|
||||||
|
then
|
||||||
|
l_socket.accept_to (l_other_socket)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
set_blocking
|
set_blocking
|
||||||
do
|
do
|
||||||
socket.set_blocking
|
socket.set_blocking
|
||||||
@@ -225,7 +250,7 @@ feature -- Status Report
|
|||||||
|
|
||||||
accepted: detachable HTTPD_STREAM_SOCKET
|
accepted: detachable HTTPD_STREAM_SOCKET
|
||||||
do
|
do
|
||||||
if attached socket.accepted as l_accepted then
|
if attached {NETWORK_STREAM_SOCKET} socket.accepted as l_accepted then
|
||||||
create Result.make (l_accepted)
|
create Result.make (l_accepted)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -239,8 +264,15 @@ feature {HTTPD_STREAM_SOCKET} -- Implementation
|
|||||||
|
|
||||||
socket: STREAM_SOCKET
|
socket: STREAM_SOCKET
|
||||||
|
|
||||||
|
network_stream_socket: detachable NETWORK_STREAM_SOCKET
|
||||||
|
do
|
||||||
|
if attached {NETWORK_STREAM_SOCKET} socket as s then
|
||||||
|
Result := s
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
;note
|
;note
|
||||||
copyright: "2011-2014, 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)"
|
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
||||||
source: "[
|
source: "[
|
||||||
Eiffel Software
|
Eiffel Software
|
||||||
|
|||||||
@@ -15,11 +15,11 @@ inherit
|
|||||||
create
|
create
|
||||||
make_server_by_address_and_port,
|
make_server_by_address_and_port,
|
||||||
make_server_by_port,
|
make_server_by_port,
|
||||||
make_from_separate
|
make_from_separate,
|
||||||
|
make_empty
|
||||||
|
|
||||||
create {NETWORK_STREAM_SOCKET}
|
create {NETWORK_STREAM_SOCKET}
|
||||||
make_from_descriptor_and_address,
|
make_from_descriptor_and_address
|
||||||
make_empty
|
|
||||||
|
|
||||||
feature {NONE} -- Initialization
|
feature {NONE} -- Initialization
|
||||||
|
|
||||||
@@ -27,8 +27,10 @@ feature {NONE} -- Initialization
|
|||||||
-- Create a network stream socket.
|
-- Create a network stream socket.
|
||||||
do
|
do
|
||||||
Precursor
|
Precursor
|
||||||
|
debug
|
||||||
set_reuse_address
|
set_reuse_address
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
make_server_by_address_and_port (an_address: INET_ADDRESS; a_port: INTEGER)
|
make_server_by_address_and_port (an_address: INET_ADDRESS; a_port: INTEGER)
|
||||||
-- Create server socket on `an_address' and `a_port'.
|
-- Create server socket on `an_address' and `a_port'.
|
||||||
|
|||||||
Reference in New Issue
Block a user