# WEBrick::GenericServer (Class)

In: | webrick/ssl.rb webrick/server.rb
Parent: | Object

## Methods

[] listen listen new run setup_ssl_context shutdown ssl_context start stop

## Attributes

config | [R] |
listeners | [R] |
logger | [R] |
status | [R] |
tokens | [R] |

## Public Class methods

new(config={}, default=Config::General)

[Source]

    # File webrick/server.rb, line 44
        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])
          end
        end

## Public Instance methods

ssl_context()

[Source]

    # File webrick/ssl.rb, line 82
        def ssl_context
          @ssl_context ||= nil
        end

listen(address, port)

[Source]

    # File webrick/ssl.rb, line 86
        def listen(address, port)
          listeners = Utils::create_listeners(address, port, @logger)
          if @config[:SSLEnable]
            unless ssl_context
              @ssl_context = setup_ssl_context(@config)
              @logger.info("\n" + @config[:SSLCertificate].to_text)
            end
            listeners.collect!{|svr|
              ssvr = ::OpenSSL::SSL::SSLServer.new(svr, ssl_context)
              ssvr.start_immediately = @config[:SSLStartImmediately]
              ssvr
            }
          end
          @listeners += listeners
        end

setup_ssl_context(config)

[Source]

    # File webrick/ssl.rb, line 102
        def setup_ssl_context(config)
          unless config[:SSLCertificate]
            cn = config[:SSLCertName]
            comment = config[:SSLCertComment]
            cert, key = Utils::create_self_signed_cert(1024, cn, comment)
            config[:SSLCertificate] = cert
            config[:SSLPrivateKey] = key
          end
          ctx = OpenSSL::SSL::SSLContext.new
          ctx.key = config[:SSLPrivateKey]
          ctx.cert = config[:SSLCertificate]
          ctx.client_ca = config[:SSLClientCA]
          ctx.extra_chain_cert = config[:SSLExtraChainCert]
          ctx.ca_file = config[:SSLCACertificateFile]
          ctx.ca_path = config[:SSLCACertificatePath]
          ctx.cert_store = config[:SSLCertificateStore]
          ctx.verify_mode = config[:SSLVerifyClient]
          ctx.verify_depth = config[:SSLVerifyDepth]
          ctx.verify_callback = config[:SSLVerifyCallback]
          ctx.timeout = config[:SSLTimeout]
          ctx.options = config[:SSLOptions]
          ctx
        end

[](key)

[Source]

    # File webrick/server.rb, line 67
        def [](key)
          @config[key]
        end

listen(address, port)

[Source]

    # File webrick/server.rb, line 71
        def listen(address, port)
          @listeners += Utils::create_listeners(address, port, @logger)
        end

start(&block)

[Source]

    # File webrick/server.rb, line 75
        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
            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.

                    sock = svr.accept
                    sock.sync = true
                    Utils::set_close_on_exec(sock)
                    th = start_thread(sock, &block)
                    th[:WEBrickThread] = true
                    thgroup.add(th)
                  }
                end
              rescue Errno::ECONNRESET, Errno::ECONNABORTED, Errno::EPROTO => ex
                # TCP connection was established but RST segment was sent

                # from peer before calling TCPServer#accept.

              rescue Errno::EBADF, IOError => ex
                # if the listening socket was closed in GenericServer#shutdown,

                # IO::select raise it.

              rescue Exception => ex
                msg = "#{ex.class}: #{ex.message}\n\t#{ex.backtrace[0]}"
                @logger.error msg
              end
            end

            @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

stop()

[Source]

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

shutdown()

[Source]

    # File webrick/server.rb, line 125
        def shutdown
          stop
          @listeners.each{|s|
            if @logger.debug?
              addr = s.addr
              @logger.debug("close TCPSocket(#{addr[2]}, #{addr[1]})")
            end
            s.close
          }
          @listeners.clear
        end

run(sock)

[Source]

    # File webrick/server.rb, line 137
        def run(sock)
          @logger.fatal "run() must be provided by user."
        end

[Validate]