Class: WEBrick::GenericServer

Inherits:
Object
  • Object
show all
Defined in:
lib/webrick/ssl.rb,
lib/webrick/server.rb

Direct Known Subclasses

HTTPServer

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(config = {}, default = Config::General) ⇒ GenericServer

Returns a new instance of GenericServer.



51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
# File 'lib/webrick/server.rb', line 51

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

Instance Attribute Details

#configObject (readonly)

Returns the value of attribute config.



49
50
51
# File 'lib/webrick/server.rb', line 49

def config
  @config
end

#listenersObject (readonly)

Returns the value of attribute listeners.



49
50
51
# File 'lib/webrick/server.rb', line 49

def listeners
  @listeners
end

#loggerObject (readonly)

Returns the value of attribute logger.



49
50
51
# File 'lib/webrick/server.rb', line 49

def logger
  @logger
end

#statusObject (readonly)

Returns the value of attribute status.



49
50
51
# File 'lib/webrick/server.rb', line 49

def status
  @status
end

#tokensObject (readonly)

Returns the value of attribute tokens.



49
50
51
# File 'lib/webrick/server.rb', line 49

def tokens
  @tokens
end

Instance Method Details

#[](key) ⇒ Object



77
78
79
# File 'lib/webrick/server.rb', line 77

def [](key)
  @config[key]
end

#listen(address, port) ⇒ Object



87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
# File 'lib/webrick/ssl.rb', line 87

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

#run(sock) ⇒ Object



157
158
159
# File 'lib/webrick/server.rb', line 157

def run(sock)
  @logger.fatal "run() must be provided by user."
end

#setup_ssl_context(config) ⇒ Object



103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
# File 'lib/webrick/ssl.rb', line 103

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

#shutdownObject



134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
# File 'lib/webrick/server.rb', line 134

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

#ssl_contextObject



82
83
84
# File 'lib/webrick/ssl.rb', line 82

def ssl_context
  @ssl_context ||= nil
end

#start(&block) ⇒ Object

Raises:



85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
# File 'lib/webrick/server.rb', line 85

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.
            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 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

#stopObject



128
129
130
131
132
# File 'lib/webrick/server.rb', line 128

def stop
  if @status == :Running
    @status = :Shutdown
  end
end