# class WEBrick::HTTPServer

An HTTP Server

### Public Class Methods

new(config={}, default=Config::HTTP) click to toggle source

Creates a new HTTP server according to `config`

An HTTP server uses the following attributes:

:AccessLog

  An array of access logs. See `WEBrick::AccessLog`

:BindAddress

  Local address for the server to bind to

:DocumentRoot

  Root path to serve files from

:DocumentRootOptions

  Options for the default `HTTPServlet::FileHandler`

:HTTPVersion

  The HTTP version of this server

:Port

  Port to listen on

:RequestCallback

  Called with a request and response before each request is serviced.

:RequestTimeout

  Maximum time to wait between requests

:ServerAlias

  `Array` of alternate names for this server for virtual hosting

:ServerName

  Name for this server for virtual hosting

Calls superclass method `WEBrick::GenericServer::new`

    # File lib/webrick/httpserver.rb, line 46
    def initialize(config={}, default=Config::HTTP)
      super(config, default)
      @http_version = HTTPVersion::convert(@config[:HTTPVersion])

      @mount_tab = MountTable.new
      if @config[:DocumentRoot]
        mount("/", HTTPServlet::FileHandler, @config[:DocumentRoot],
              @config[:DocumentRootOptions])
      end

      unless @config[:AccessLog]
        @config[:AccessLog] = [
          [ $stderr, AccessLog::COMMON_LOG_FORMAT ],
          [ $stderr, AccessLog::REFERER_LOG_FORMAT ]
        ]
      end

      @virtual_hosts = Array.new
    end

### Public Instance Methods

access_log(config, req, res) click to toggle source

Logs `req` and `res` in the access logs. `config` is used for the server name.

    # File lib/webrick/httpserver.rb, line 220
    def access_log(config, req, res)
      param = AccessLog::setup_params(config, req, res)
      @config[:AccessLog].each{|logger, fmt|
        logger << AccessLog::format(fmt+"\n", param)
      }
    end

create_request(with_webrick_config) click to toggle source

Creates the `HTTPRequest` used when handling the HTTP request. Can be overridden by subclasses.

    # File lib/webrick/httpserver.rb, line 230
    def create_request(with_webrick_config)
      HTTPRequest.new(with_webrick_config)
    end

create_response(with_webrick_config) click to toggle source

Creates the `HTTPResponse` used when handling the HTTP request. Can be overridden by subclasses.

    # File lib/webrick/httpserver.rb, line 237
    def create_response(with_webrick_config)
      HTTPResponse.new(with_webrick_config)
    end

do_OPTIONS(req, res) click to toggle source

The default OPTIONS request handler says GET, HEAD, POST and OPTIONS requests are allowed.

    # File lib/webrick/httpserver.rb, line 147
    def do_OPTIONS(req, res)
      res["allow"] = "GET,HEAD,POST,OPTIONS"
    end

lookup_server(req) click to toggle source

Finds the appropriate virtual host to handle `req`

    # File lib/webrick/httpserver.rb, line 207
    def lookup_server(req)
      @virtual_hosts.find{|s|
        (s[:BindAddress].nil? || req.addr[3] == s[:BindAddress]) &&
        (s[:Port].nil?        || req.port == s[:Port])           &&
        ((s[:ServerName].nil?  || req.host == s[:ServerName]) ||
         (!s[:ServerAlias].nil? && s[:ServerAlias].find{|h| h === req.host}))
      }
    end

mount(dir, servlet, *options) click to toggle source

Mounts `servlet` on `dir` passing `options` to the servlet at creation time

    # File lib/webrick/httpserver.rb, line 155
    def mount(dir, servlet, *options)
      @logger.debug(sprintf("%s is mounted on %s.", servlet.inspect, dir))
      @mount_tab[dir] = [ servlet, options ]
    end

mount_proc(dir, proc=nil, &block) click to toggle source

Mounts `proc` or `block` on `dir` and calls it with a `WEBrick::HTTPRequest` and `WEBrick::HTTPResponse`

    # File lib/webrick/httpserver.rb, line 164
    def mount_proc(dir, proc=nil, &block)
      proc ||= block
      raise HTTPServerError, "must pass a proc or block" unless proc
      mount(dir, HTTPServlet::ProcHandler.new(proc))
    end

run(sock) click to toggle source

Processes requests on `sock`

    # File lib/webrick/httpserver.rb, line 69
    def run(sock)
      while true
        req = create_request(@config)
        res = create_response(@config)
        server = self
        begin
          timeout = @config[:RequestTimeout]
          while timeout > 0
            break if sock.to_io.wait_readable(0.5)
            break if @status != :Running
            timeout -= 0.5
          end
          raise HTTPStatus::EOFError if timeout <= 0 || @status != :Running
          raise HTTPStatus::EOFError if sock.eof?
          req.parse(sock)
          res.request_method = req.request_method
          res.request_uri = req.request_uri
          res.request_http_version = req.http_version
          res.keep_alive = req.keep_alive?
          server = lookup_server(req) || self
          if callback = server[:RequestCallback]
            callback.call(req, res)
          elsif callback = server[:RequestHandler]
            msg = ":RequestHandler is deprecated, please use :RequestCallback"
            @logger.warn(msg)
            callback.call(req, res)
          end
          server.service(req, res)
        rescue HTTPStatus::EOFError, HTTPStatus::RequestTimeout => ex
          res.set_error(ex)
        rescue HTTPStatus::Error => ex
          @logger.error(ex.message)
          res.set_error(ex)
        rescue HTTPStatus::Status => ex
          res.status = ex.code
        rescue StandardError => ex
          @logger.error(ex)
          res.set_error(ex, true)
        ensure
          if req.request_line
            if req.keep_alive? && res.keep_alive?
              req.fixup()
            end
            res.send_response(sock)
            server.access_log(@config, req, res)
          end
        end
        break if @http_version < "1.1"
        break unless req.keep_alive?
        break unless res.keep_alive?
      end
    end

search_servlet(path) click to toggle source

Finds a servlet for `path`

    # File lib/webrick/httpserver.rb, line 182
    def search_servlet(path)
      script_name, path_info = @mount_tab.scan(path)
      servlet, options = @mount_tab[script_name]
      if servlet
        [ servlet, options, script_name, path_info ]
      end
    end

service(req, res) click to toggle source

Services `req` and fills in `res`

    # File lib/webrick/httpserver.rb, line 125
    def service(req, res)
      if req.unparsed_uri == "*"
        if req.request_method == "OPTIONS"
          do_OPTIONS(req, res)
          raise HTTPStatus::OK
        end
        raise HTTPStatus::NotFound, "`#{req.unparsed_uri}' not found."
      end

      servlet, options, script_name, path_info = search_servlet(req.path)
      raise HTTPStatus::NotFound, "`#{req.path}' not found." unless servlet
      req.script_name = script_name
      req.path_info = path_info
      si = servlet.get_instance(self, *options)
      @logger.debug(format("%s is invoked.", si.class.name))
      si.service(req, res)
    end

ssl_servername_callback(sslsocket, hostname = nil) click to toggle source

ServerNameIndication callback

    # File lib/webrick/https.rb, line 129
    def ssl_servername_callback(sslsocket, hostname = nil)
      req = SNIRequest.new(sslsocket, hostname)
      server = lookup_server(req)
      server ? server.ssl_context : nil
    end

umount(dir)
Alias for: unmount
unmount(dir) click to toggle source

Unmounts `dir`

    # File lib/webrick/httpserver.rb, line 173
    def unmount(dir)
      @logger.debug(sprintf("unmount %s.", dir))
      @mount_tab.delete(dir)
    end

Also aliased as: umount
virtual_host(server) click to toggle source

Adds `server` as a virtual host.

    # File lib/webrick/httpserver.rb, line 193
    def virtual_host(server)
      @virtual_hosts << server
      @virtual_hosts = @virtual_hosts.sort_by{|s|
        num = 0
        num -= 4 if s[:BindAddress]
        num -= 2 if s[:Port]
        num -= 1 if s[:ServerName]
        num
      }
    end