Class: Rex::Proto::Http::Server

Inherits:
Object
  • Object
show all
Includes:
Rex::Proto
Defined in:
lib/rex/proto/http/server.rb

Overview

Acts as an HTTP server, processing requests and dispatching them to registered procs. Some of this server was modeled after webrick.

Constant Summary collapse

ExtensionMimeTypes =

A hash that associated a file extension with a mime type for use as the content type of responses.

{
  "rhtml" => "text/html",
  "html"  => "text/html",
  "htm"   => "text/htm",
  "jpg"   => "image/jpeg",
  "jpeg"  => "image/jpeg",
  "jpeg"  => "image/jpeg",
  "gif"   => "image/gif",
  "png"   => "image/png",
  "bmp"   => "image/bmp",
  "txt"   => "text/plain",
  "css"   => "text/css",
  "ico"   => "image/x-icon",
}
DefaultServer =

The default server name that will be returned in the Server attribute of a response.

"Rex"

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(port = 80, listen_host = '0.0.0.0', ssl = false, context = {}, comm = nil, ssl_cert = nil, ssl_compression = false) ⇒ Server

Initializes an HTTP server as listening on the provided port and hostname.



103
104
105
106
107
108
109
110
111
112
113
114
# File 'lib/rex/proto/http/server.rb', line 103

def initialize(port = 80, listen_host = '0.0.0.0', ssl = false, context = {}, comm = nil, ssl_cert = nil, ssl_compression = false)
  self.listen_host     = listen_host
  self.listen_port     = port
  self.ssl             = ssl
  self.context         = context
  self.comm            = comm
  self.ssl_cert        = ssl_cert
  self.ssl_compression = ssl_compression
  self.listener        = nil
  self.resources       = {}
  self.server_name     = DefaultServer
end

Instance Attribute Details

#commObject

Returns the value of attribute comm.



272
273
274
# File 'lib/rex/proto/http/server.rb', line 272

def comm
  @comm
end

#contextObject

Returns the value of attribute context.



272
273
274
# File 'lib/rex/proto/http/server.rb', line 272

def context
  @context
end

#listen_hostObject

Returns the value of attribute listen_host.



272
273
274
# File 'lib/rex/proto/http/server.rb', line 272

def listen_host
  @listen_host
end

#listen_portObject

Returns the value of attribute listen_port.



272
273
274
# File 'lib/rex/proto/http/server.rb', line 272

def listen_port
  @listen_port
end

#listenerObject

Returns the value of attribute listener.



274
275
276
# File 'lib/rex/proto/http/server.rb', line 274

def listener
  @listener
end

#resourcesObject

Returns the value of attribute resources.



274
275
276
# File 'lib/rex/proto/http/server.rb', line 274

def resources
  @resources
end

#server_nameObject

Returns the value of attribute server_name.



272
273
274
# File 'lib/rex/proto/http/server.rb', line 272

def server_name
  @server_name
end

#sslObject

Returns the value of attribute ssl.



273
274
275
# File 'lib/rex/proto/http/server.rb', line 273

def ssl
  @ssl
end

#ssl_certObject

Returns the value of attribute ssl_cert.



273
274
275
# File 'lib/rex/proto/http/server.rb', line 273

def ssl_cert
  @ssl_cert
end

#ssl_compressionObject

Returns the value of attribute ssl_compression.



273
274
275
# File 'lib/rex/proto/http/server.rb', line 273

def ssl_compression
  @ssl_compression
end

Class Method Details

.hardcore_alias(*args) ⇒ Object

Returns the hardcore alias for the HTTP service



127
128
129
# File 'lib/rex/proto/http/server.rb', line 127

def self.hardcore_alias(*args)
  "#{(args[0] || '')}#{(args[1] || '')}"
end

Instance Method Details

#add_resource(name, opts) ⇒ Object

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.


210
211
212
213
214
215
216
217
218
219
220
221
222
# File 'lib/rex/proto/http/server.rb', line 210

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

#add_response_headers(resp) ⇒ Object

Adds Server headers and stuff.



234
235
236
# File 'lib/rex/proto/http/server.rb', line 234

def add_response_headers(resp)
  resp['Server'] = self.server_name if not resp['Server']
end

#aliasObject

HTTP server.



134
135
136
# File 'lib/rex/proto/http/server.rb', line 134

def alias
  super || "HTTP Server"
end

#close_client(cli) ⇒ Object

Closes the supplied client, if valid.



183
184
185
# File 'lib/rex/proto/http/server.rb', line 183

def close_client(cli)
  listener.close_client(cli)
end

#inspectString

More readable inspect that only shows the url and resources

Returns:

  • (String)


118
119
120
121
122
# File 'lib/rex/proto/http/server.rb', line 118

def inspect
  resources_str = resources.keys.map{|r| r.inspect }.join ", "

  "#<#{self.class} http#{ssl ? "s" : ""}://#{listen_host}:#{listen_port} [ #{resources_str} ]>"
end

#mime_type(file) ⇒ Object

Returns the mime type associated with the supplied file. Right now the set of mime types is fairly limited.



242
243
244
245
246
247
248
249
250
# File 'lib/rex/proto/http/server.rb', line 242

def mime_type(file)
  type = nil

  if (file =~ /\.(.+?)$/)
    type = ExtensionMimeTypes[$1.downcase]
  end

  type || "text/plain"
end

#mount(root, handler, long_call = false, *args) ⇒ Object

Mounts a directory or resource as being serviced by the supplied handler.



190
191
192
# File 'lib/rex/proto/http/server.rb', line 190

def mount(root, handler, long_call = false, *args)
  resources[root] = [ handler, long_call, args ]
end

#remove_resource(name) ⇒ Object

Removes the supplied resource handler.



227
228
229
# File 'lib/rex/proto/http/server.rb', line 227

def remove_resource(name)
  self.resources.delete(name)
end

#send_e404(cli, request) ⇒ Object

Sends a 404 error to the client for a given request.



255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
# File 'lib/rex/proto/http/server.rb', line 255

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

#startObject

Listens on the defined port and host and starts monitoring for clients.



141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
# File 'lib/rex/proto/http/server.rb', line 141

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,
    'SSLCompression' => self.ssl_compression,
    '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

#stopObject

Terminates the monitor thread and turns off the listener.



167
168
169
170
# File 'lib/rex/proto/http/server.rb', line 167

def stop
  self.listener.stop
  self.listener.close
end

#unmount(root) ⇒ Object

Remove the mount point.



197
198
199
# File 'lib/rex/proto/http/server.rb', line 197

def unmount(root)
  resources.delete(root)
end

#waitObject

Waits for the HTTP service to terminate



176
177
178
# File 'lib/rex/proto/http/server.rb', line 176

def wait
  self.listener.wait if self.listener
end