fixed up the ol' http server
git-svn-id: file:///home/svn/incoming/trunk@2843 4d416f70-5f16-0410-b530-b9f4589650daunstable
parent
d99e5b4f89
commit
2b82d4c4c4
|
@ -40,6 +40,131 @@ module StreamServer
|
||||||
super
|
super
|
||||||
end
|
end
|
||||||
|
|
||||||
|
##
|
||||||
|
#
|
||||||
|
# Default server monitoring and client management implementation follows
|
||||||
|
# below.
|
||||||
|
#
|
||||||
|
##
|
||||||
|
|
||||||
|
def on_client_connect(client)
|
||||||
|
if (on_client_connect_proc)
|
||||||
|
on_client_connect_proc.call(client)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def on_client_data(client)
|
||||||
|
if (on_client_data_proc)
|
||||||
|
on_client_data_proc.call(client)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def on_client_close(client)
|
||||||
|
if (on_client_close_proc)
|
||||||
|
on_client_close_proc.call(client)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
#
|
||||||
|
# Start monitoring the listener socket for connections and keep track of
|
||||||
|
# all client connections.
|
||||||
|
#
|
||||||
|
def start
|
||||||
|
self.clients = []
|
||||||
|
self.clifds = []
|
||||||
|
self.fd2cli = {}
|
||||||
|
|
||||||
|
self.listener_thread = Thread.new {
|
||||||
|
monitor_listener
|
||||||
|
}
|
||||||
|
self.clients_thread = Thread.new {
|
||||||
|
monitor_clients
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
#
|
||||||
|
# Terminates the listener monitoring threads and closes all active clients.
|
||||||
|
#
|
||||||
|
def stop
|
||||||
|
self.listener_thread.kill
|
||||||
|
self.clients_thread.kill
|
||||||
|
|
||||||
|
self.clients.each { |cli|
|
||||||
|
close_client(cli)
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
#
|
||||||
|
# Closes a client connection.
|
||||||
|
#
|
||||||
|
def close_client(client)
|
||||||
|
if (client)
|
||||||
|
fd2cli.delete(client.sock)
|
||||||
|
clifds.delete(client.sock)
|
||||||
|
clients.delete(client)
|
||||||
|
|
||||||
|
client.close
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
#
|
||||||
|
# Callback procedures.
|
||||||
|
#
|
||||||
|
attr_accessor :on_client_connect_proc
|
||||||
|
attr_accessor :on_client_data_proc
|
||||||
|
attr_accessor :on_client_close_proc
|
||||||
|
|
||||||
|
protected
|
||||||
|
|
||||||
|
attr_accessor :clients, :clifds, :fd2cli
|
||||||
|
attr_accessor :listener_thread, :clients_thread
|
||||||
|
|
||||||
|
#
|
||||||
|
# Monitors the listener socket for new connections
|
||||||
|
#
|
||||||
|
def monitor_listener
|
||||||
|
begin
|
||||||
|
sd = Rex::ThreadSafe.select([ poll_fd ])
|
||||||
|
|
||||||
|
# Accept the new client connection
|
||||||
|
if (sd[0].length > 0)
|
||||||
|
cli = accept
|
||||||
|
|
||||||
|
next if (!cli)
|
||||||
|
|
||||||
|
# Insert it into some lists
|
||||||
|
self.clients << cli
|
||||||
|
self.clifds << cli.sock
|
||||||
|
self.fd2cli[cli.sock] = cli
|
||||||
|
|
||||||
|
on_client_connect(cli)
|
||||||
|
end
|
||||||
|
rescue
|
||||||
|
elog("Error in stream server listener monitor: #{$!}")
|
||||||
|
end while true
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
#
|
||||||
|
# Monitors clients for data.
|
||||||
|
#
|
||||||
|
def monitor_clients
|
||||||
|
begin
|
||||||
|
if (clients.length == 0)
|
||||||
|
Rex::ThreadSafe::sleep(0.2)
|
||||||
|
next
|
||||||
|
end
|
||||||
|
|
||||||
|
sd = Rex::ThreadSafe.select(clifds)
|
||||||
|
|
||||||
|
sd[0].each { |fd|
|
||||||
|
on_client_data(self.fd2cli[fd])
|
||||||
|
}
|
||||||
|
rescue
|
||||||
|
elog("Error in stream server client monitor: #{$!}")
|
||||||
|
end while true
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -78,9 +78,6 @@ class Server
|
||||||
self.listen_port = port
|
self.listen_port = port
|
||||||
self.listen_host = listen_host
|
self.listen_host = listen_host
|
||||||
self.listener = nil
|
self.listener = nil
|
||||||
self.clients = []
|
|
||||||
self.clifds = []
|
|
||||||
self.fd2cli = {}
|
|
||||||
self.resources = {}
|
self.resources = {}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -92,39 +89,30 @@ class Server
|
||||||
'LocalHost' => self.listen_host,
|
'LocalHost' => self.listen_host,
|
||||||
'LocalPort' => self.listen_port)
|
'LocalPort' => self.listen_port)
|
||||||
|
|
||||||
self.listener_thread = Thread.new {
|
# Register callbacks
|
||||||
monitor_listener
|
self.listener.on_client_connect_proc = Proc.new { |cli|
|
||||||
|
on_client_connect(cli)
|
||||||
}
|
}
|
||||||
self.clients_thread = Thread.new {
|
self.listener.on_client_data_proc = Proc.new { |cli|
|
||||||
monitor_clients
|
on_client_data(cli)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
self.listener.start
|
||||||
end
|
end
|
||||||
|
|
||||||
#
|
#
|
||||||
# Terminates the monitor thread and turns off the listener.
|
# Terminates the monitor thread and turns off the listener.
|
||||||
#
|
#
|
||||||
def stop
|
def stop
|
||||||
self.listener_thread.kill
|
self.listener.stop
|
||||||
self.clients_thread.kill
|
|
||||||
|
|
||||||
self.clients.each { |cli|
|
|
||||||
close_client(cli)
|
|
||||||
}
|
|
||||||
|
|
||||||
self.listener.close
|
self.listener.close
|
||||||
end
|
end
|
||||||
|
|
||||||
#
|
#
|
||||||
# Closes the supplied client connection and removes it from the internal
|
# Closes the supplied client, if valid.
|
||||||
# hashes and lists.
|
|
||||||
#
|
#
|
||||||
def close_client(cli)
|
def close_client(cli)
|
||||||
if (cli)
|
listener.close_client(cli)
|
||||||
self.fd2cli.delete(cli.sock)
|
|
||||||
self.clifds.delete(cli.sock)
|
|
||||||
self.clients.delete(cli)
|
|
||||||
cli.close
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
#
|
#
|
||||||
|
@ -153,7 +141,7 @@ class Server
|
||||||
end
|
end
|
||||||
|
|
||||||
#
|
#
|
||||||
# Adds Server headers and stuff
|
# Adds Server headers and stuff.
|
||||||
#
|
#
|
||||||
def add_response_headers(resp)
|
def add_response_headers(resp)
|
||||||
resp['Server'] = DefaultServer
|
resp['Server'] = DefaultServer
|
||||||
|
@ -163,63 +151,21 @@ class Server
|
||||||
|
|
||||||
protected
|
protected
|
||||||
|
|
||||||
attr_accessor :listener
|
attr_accessor :listener, :resources
|
||||||
attr_accessor :listener_thread, :clients_thread
|
|
||||||
attr_accessor :clients, :clifds, :fd2cli
|
|
||||||
attr_accessor :resources
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Monitors the listener for new connections
|
# Extends new clients with the ServerClient module and initializes them.
|
||||||
#
|
#
|
||||||
def monitor_listener
|
def on_client_connect(cli)
|
||||||
begin
|
|
||||||
sd = Rex::ThreadSafe.select([ listener.sock ])
|
|
||||||
|
|
||||||
# Accept the new client connection
|
|
||||||
if (sd[0].length > 0)
|
|
||||||
cli = listener.accept
|
|
||||||
|
|
||||||
next if (!cli)
|
|
||||||
|
|
||||||
cli.extend(ServerClient)
|
cli.extend(ServerClient)
|
||||||
|
|
||||||
# Initialize the server client extension
|
|
||||||
cli.init_cli(self)
|
cli.init_cli(self)
|
||||||
|
|
||||||
# Insert it into some lists
|
|
||||||
self.clients << cli
|
|
||||||
self.clifds << cli.sock
|
|
||||||
self.fd2cli[cli.sock] = cli
|
|
||||||
end
|
|
||||||
rescue
|
|
||||||
elog("Exception caught in HTTP server listener monitor: #{$!}")
|
|
||||||
end while true
|
|
||||||
end
|
end
|
||||||
|
|
||||||
#
|
#
|
||||||
# Monitors client connections for data
|
# Processes data coming in from a client.
|
||||||
#
|
#
|
||||||
def monitor_clients
|
def on_client_data(cli)
|
||||||
begin
|
|
||||||
if (clients.length == 0)
|
|
||||||
Rex::ThreadSafe::sleep(0.2)
|
|
||||||
next
|
|
||||||
end
|
|
||||||
|
|
||||||
sd = Rex::ThreadSafe.select(clifds)
|
|
||||||
|
|
||||||
sd[0].each { |fd|
|
|
||||||
process_client(self.fd2cli[fd])
|
|
||||||
}
|
|
||||||
rescue
|
|
||||||
elog("Exception caught in HTTP server clients monitor: #{$!}")
|
|
||||||
end while true
|
|
||||||
end
|
|
||||||
|
|
||||||
#
|
|
||||||
# Processes data coming in from a client
|
|
||||||
#
|
|
||||||
def process_client(cli)
|
|
||||||
begin
|
begin
|
||||||
case cli.request.parse(cli.get)
|
case cli.request.parse(cli.get)
|
||||||
when Packet::ParseCode::Completed
|
when Packet::ParseCode::Completed
|
||||||
|
|
|
@ -80,7 +80,7 @@ class Rex::Socket::Parameters
|
||||||
self.server = hash['Server'] || false
|
self.server = hash['Server'] || false
|
||||||
|
|
||||||
# The communication subsystem to use to create the socket
|
# The communication subsystem to use to create the socket
|
||||||
self.comm = hash['Comm'] || Rex::Socket::Comm::Local;
|
self.comm = hash['Comm'] || Rex::Socket::Comm::Local
|
||||||
|
|
||||||
# The number of connection retries to make (client only)
|
# The number of connection retries to make (client only)
|
||||||
self.retries = hash['Retries'] || 0
|
self.retries = hash['Retries'] || 0
|
||||||
|
|
Loading…
Reference in New Issue