In Files

  • webrick/server.rb
  • webrick/ssl.rb

WEBrick::GenericServer

Base TCP server class. You must subclass GenericServer and provide a run method.

Attributes

config[R]

The server configuration

listeners[R]

Sockets listening for connections.

logger[R]

The server logger. This is independent from the HTTP access log.

status[R]

The server status. One of :Stop, :Running or :Shutdown

tokens[R]

Tokens control the number of outstanding clients. The :MaxClients configuration sets this.

Public Class Methods

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

Creates a new generic server from config. The default configuration comes from default.

 
               # File webrick/server.rb, line 94
def initialize(config={}, default=Config::General)
  @config = default.dup.update(config)
  @status = :Stop
  @config[:Logger] ||= Log::new
  @logger = @config[:Logger]

  @tokens = SizedQueue.new(@config[:MaxClients])
  @config[:MaxClients].times{ @tokens.push(nil) }

  webrickv = WEBrick::VERSION
  rubyv = "#{RUBY_VERSION} (#{RUBY_RELEASE_DATE}) [#{RUBY_PLATFORM}]"
  @logger.info("WEBrick #{webrickv}")
  @logger.info("ruby #{rubyv}")

  @listeners = []
  unless @config[:DoNotListen]
    if @config[:Listen]
      warn(":Listen option is deprecated; use GenericServer#listen")
    end
    listen(@config[:BindAddress], @config[:Port])
    if @config[:Port] == 0
      @config[:Port] = @listeners[0].addr[1]
    end
  end
end
            

Public Instance Methods

[](key) click to toggle source

Retrieves key from the configuration

 
               # File webrick/server.rb, line 123
def [](key)
  @config[key]
end
            
listen(address, port) click to toggle source

Adds listeners from address and port to the server. See WEBrick::Utils.create_listeners for details.

 
               # File webrick/server.rb, line 131
def listen(address, port)
  @listeners += Utils::create_listeners(address, port, @logger)
end
            
run(sock) click to toggle source

You must subclass GenericServer and implement #run which accepts a TCP client socket

 
               # File webrick/server.rb, line 246
def run(sock)
  @logger.fatal "run() must be provided by user."
end
            
shutdown() click to toggle source

Shuts down the server and all listening sockets. New listeners must be provided to restart the server.

 
               # File webrick/server.rb, line 219
def shutdown
  stop
  @listeners.each{|s|
    if @logger.debug?
      addr = s.addr
      @logger.debug("close TCPSocket(#{addr[2]}, #{addr[1]})")
    end
    begin
      s.shutdown
    rescue Errno::ENOTCONN
      # when `Errno::ENOTCONN: Socket is not connected' on some platforms,
      # call #close instead of #shutdown.
      # (ignore @config[:ShutdownSocketWithoutClose])
      s.close
    else
      unless @config[:ShutdownSocketWithoutClose]
        s.close
      end
    end
  }
  @listeners.clear
end
            
start(&block) click to toggle source

Starts the server and runs the block for each connection. This method does not return until the server is stopped from a signal handler or another thread using stop or shutdown.

If the block raises a subclass of StandardError the exception is logged and ignored. If an IOError or Errno::EBADF exception is raised the exception is ignored. If an Exception subclass is raised the exception is logged and re-raised which stops the server.

To completely shut down a server call shutdown from ensure:

server = WEBrick::GenericServer.new
# or WEBrick::HTTPServer.new

begin
  server.start
ensure
  server.shutdown
end
 
               # File webrick/server.rb, line 156
def start(&block)
  raise ServerError, "already started." if @status != :Stop
  server_type = @config[:ServerType] || SimpleServer

  server_type.start{
    @logger.info            "#{self.class}#start: pid=#{$$} port=#{@config[:Port]}"
    call_callback(:StartCallback)

    thgroup = ThreadGroup.new
    @status = :Running
    begin
      while @status == :Running
        begin
          if svrs = IO.select(@listeners, nil, nil, 2.0)
            svrs[0].each{|svr|
              @tokens.pop          # blocks while no token is there.
              if sock = accept_client(svr)
                sock.do_not_reverse_lookup = config[:DoNotReverseLookup]
                th = start_thread(sock, &block)
                th[:WEBrickThread] = true
                thgroup.add(th)
              else
                @tokens.push(nil)
              end
            }
          end
        rescue Errno::EBADF, IOError => ex
          # if the listening socket was closed in GenericServer#shutdown,
          # IO::select raise it.
        rescue StandardError => ex
          msg = "#{ex.class}: #{ex.message}\n\t#{ex.backtrace[0]}"
          @logger.error msg
        rescue Exception => ex
          @logger.fatal ex
          raise
        end
      end

    ensure
      @status = :Shutdown
      @logger.info "going to shutdown ..."
      thgroup.list.each{|th| th.join if th[:WEBrickThread] }
      call_callback(:StopCallback)
      @logger.info "#{self.class}#start done."
      @status = :Stop
    end
  }
end
            
stop() click to toggle source

Stops the server from accepting new connections.

 
               # File webrick/server.rb, line 209
def stop
  if @status == :Running
    @status = :Shutdown
  end
end
            

Commenting is here to help enhance the documentation. For example, code samples, or clarification of the documentation.

If you have questions about Ruby or the documentation, please post to one of the Ruby mailing lists. You will get better, faster, help that way.

If you wish to post a correction of the docs, please do so, but also file bug report so that it can be corrected for the next release. Thank you.

If you want to help improve the Ruby documentation, please visit Documenting-ruby.org.

blog comments powered by Disqus