Acts as an HTTP server, processing requests and dispatching them to registered procs. Some of this server was modeled after webrick.
The default server name that will be returned in the Server attribute of a response.
A hash that associated a file extension with a mime type for use as the content type of responses.
Returns the hardcore alias for the HTTP service
# File lib/rex/proto/http/server.rb, line 118 def self.hardcore_alias(*args) "#{(args[0] || '')}#{(args[1] || '')}" end
Initializes an HTTP server as listening on the provided port and hostname.
# File lib/rex/proto/http/server.rb, line 102 def initialize(port = 80, listen_host = '0.0.0.0', ssl = false, context = {}, comm = nil, ssl_cert = nil) self.listen_host = listen_host self.listen_port = port self.ssl = ssl self.context = context self.comm = comm self.ssl_cert = ssl_cert self.listener = nil self.resources = {} self.server_name = DefaultServer end
Adds a resource handler, such as one for /, which will be called whenever the resource is requested. The "opts" parameter can have any of the following:
Proc (proc) - The procedure to call when a request comes in for this resource. LongCall (bool) - Hints to the server that this resource may have long
request processing times.
# File lib/rex/proto/http/server.rb, line 200 def add_resource(name, opts) if (resources[name]) raise RuntimeError, "The supplied resource '#{name}' is already added.", caller end # If a procedure was passed, mount the resource with it. if (opts['Proc']) mount(name, Handler::Proc, false, opts['Proc'], opts['VirtualDirectory']) else raise ArgumentError, "You must specify a procedure." end end
Adds Server headers and stuff.
# File lib/rex/proto/http/server.rb, line 224 def add_response_headers(resp) resp['Server'] = self.server_name if not resp['Server'] end
HTTP server.
# File lib/rex/proto/http/server.rb, line 125 def alias super || "HTTP Server" end
Closes the supplied client, if valid.
# File lib/rex/proto/http/server.rb, line 173 def close_client(cli) listener.close_client(cli) end
Returns the mime type associated with the supplied file. Right now the set of mime types is fairly limited.
# File lib/rex/proto/http/server.rb, line 232 def mime_type(file) type = nil if (file =~ /\.(.+?)$/) type = ExtensionMimeTypes[$1.downcase] end type || "text/plain" end
Mounts a directory or resource as being serviced by the supplied handler.
# File lib/rex/proto/http/server.rb, line 180 def mount(root, handler, long_call = false, *args) resources[root] = [ handler, long_call, args ] end
Removes the supplied resource handler.
# File lib/rex/proto/http/server.rb, line 217 def remove_resource(name) self.resources.delete(name) end
Sends a 404 error to the client for a given request.
# File lib/rex/proto/http/server.rb, line 245 def send_e404(cli, request) resp = Response::E404.new resp['Content-Type'] = 'text/html' resp.body = "<html><head>" + "<title>404 Not Found</title>" + "</head><body>" + "<h1>Not found</h1>" + "The requested URL #{html_escape(request.resource)} was not found on this server.<p><hr>" + "</body></html>" # Send the response to the client like what cli.send_response(resp) end
Listens on the defined port and host and starts monitoring for clients.
# File lib/rex/proto/http/server.rb, line 132 def start self.listener = Rex::Socket::TcpServer.create( 'LocalHost' => self.listen_host, 'LocalPort' => self.listen_port, 'Context' => self.context, 'SSL' => self.ssl, 'SSLCert' => self.ssl_cert, 'Comm' => self.comm ) # Register callbacks self.listener.on_client_connect_proc = Proc.new { |cli| on_client_connect(cli) } self.listener.on_client_data_proc = Proc.new { |cli| on_client_data(cli) } self.listener.start end
Terminates the monitor thread and turns off the listener.
# File lib/rex/proto/http/server.rb, line 157 def stop self.listener.stop self.listener.close end
Dispatches the supplied request for a given connection.
# File lib/rex/proto/http/server.rb, line 313 def dispatch_request(cli, request) # Is the client requesting keep-alive? if ((request['Connection']) and (request['Connection'].downcase == 'Keep-Alive'.downcase)) cli.keepalive = true end # Search for the resource handler for the requested URL. This is pretty # inefficient right now, but we can spruce it up later. p = nil len = 0 root = nil resources.each_pair { |k, val| if (request.resource =~ /^#{k}/ and k.length > len) p = val len = k.length root = k end } if (p) # Create an instance of the handler for this resource handler = p[0].new(self, *p[2]) # If the handler class requires a relative resource... if (handler.relative_resource_required?) # Substituted the mount point root in the request to make things # relative to the mount point. request.relative_resource = request.resource.gsub(/^#{root}/, '') request.relative_resource = '/' + request.relative_resource if (request.relative_resource !~ /^\//) end # If we found the resource handler for this resource, call its # procedure. if (p[1] == true) Rex::ThreadFactory.spawn("HTTPServerRequestHandler", false) { handler.on_request(cli, request) } else handler.on_request(cli, request) end else elog("Failed to find handler for resource: #{request.resource}", LogSource) send_e404(cli, request) end # If keep-alive isn't enabled for this client, close the connection if (cli.keepalive == false) close_client(cli) end end
Extends new clients with the ServerClient module and initializes them.
# File lib/rex/proto/http/server.rb, line 270 def on_client_connect(cli) cli.extend(ServerClient) cli.init_cli(self) end
Processes data coming in from a client.
# File lib/rex/proto/http/server.rb, line 279 def on_client_data(cli) begin data = cli.read(65535) raise ::EOFError if not data raise ::EOFError if data.empty? case cli.request.parse(data) when Packet::ParseCode::Completed dispatch_request(cli, cli.request) cli.reset_cli when Packet::ParseCode::Partial # Return and wait for the on_client_data handler to be called again # The Request object tracks the state of the request for us return when Packet::ParseCode::Error close_client(cli) end rescue EOFError if (cli.request.completed?) dispatch_request(cli, cli.request) cli.reset_cli end close_client(cli) end end
Generated with the Darkfish Rdoc Generator 2.