Class | WEBrick::GenericServer |
In: |
lib/webrick/server.rb
lib/webrick/ssl.rb |
Parent: | Object |
config | [R] | |
listeners | [R] | |
logger | [R] | |
status | [R] | |
tokens | [R] |
# File lib/webrick/server.rb, line 44 44: def initialize(config={}, default=Config::General) 45: @config = default.dup.update(config) 46: @status = :Stop 47: @config[:Logger] ||= Log::new 48: @logger = @config[:Logger] 49: 50: @tokens = SizedQueue.new(@config[:MaxClients]) 51: @config[:MaxClients].times{ @tokens.push(nil) } 52: 53: webrickv = WEBrick::VERSION 54: rubyv = "#{RUBY_VERSION} (#{RUBY_RELEASE_DATE}) [#{RUBY_PLATFORM}]" 55: @logger.info("WEBrick #{webrickv}") 56: @logger.info("ruby #{rubyv}") 57: 58: @listeners = [] 59: unless @config[:DoNotListen] 60: if @config[:Listen] 61: warn(":Listen option is deprecated; use GenericServer#listen") 62: end 63: listen(@config[:BindAddress], @config[:Port]) 64: if @config[:Port] == 0 65: @config[:Port] = @listeners[0].addr[1] 66: end 67: end 68: end
# File lib/webrick/server.rb, line 74 74: def listen(address, port) 75: @listeners += Utils::create_listeners(address, port, @logger) 76: end
# File lib/webrick/ssl.rb, line 86 86: def listen(address, port) 87: listeners = Utils::create_listeners(address, port, @logger) 88: if @config[:SSLEnable] 89: unless ssl_context 90: @ssl_context = setup_ssl_context(@config) 91: @logger.info("\n" + @config[:SSLCertificate].to_text) 92: end 93: listeners.collect!{|svr| 94: ssvr = ::OpenSSL::SSL::SSLServer.new(svr, ssl_context) 95: ssvr.start_immediately = @config[:SSLStartImmediately] 96: ssvr 97: } 98: end 99: @listeners += listeners 100: end
# File lib/webrick/server.rb, line 138 138: def run(sock) 139: @logger.fatal "run() must be provided by user." 140: end
# File lib/webrick/ssl.rb, line 102 102: def setup_ssl_context(config) 103: unless config[:SSLCertificate] 104: cn = config[:SSLCertName] 105: comment = config[:SSLCertComment] 106: cert, key = Utils::create_self_signed_cert(1024, cn, comment) 107: config[:SSLCertificate] = cert 108: config[:SSLPrivateKey] = key 109: end 110: ctx = OpenSSL::SSL::SSLContext.new 111: ctx.key = config[:SSLPrivateKey] 112: ctx.cert = config[:SSLCertificate] 113: ctx.client_ca = config[:SSLClientCA] 114: ctx.extra_chain_cert = config[:SSLExtraChainCert] 115: ctx.ca_file = config[:SSLCACertificateFile] 116: ctx.ca_path = config[:SSLCACertificatePath] 117: ctx.cert_store = config[:SSLCertificateStore] 118: ctx.verify_mode = config[:SSLVerifyClient] 119: ctx.verify_depth = config[:SSLVerifyDepth] 120: ctx.verify_callback = config[:SSLVerifyCallback] 121: ctx.timeout = config[:SSLTimeout] 122: ctx.options = config[:SSLOptions] 123: ctx 124: end
# File lib/webrick/server.rb, line 126 126: def shutdown 127: stop 128: @listeners.each{|s| 129: if @logger.debug? 130: addr = s.addr 131: @logger.debug("close TCPSocket(#{addr[2]}, #{addr[1]})") 132: end 133: s.close 134: } 135: @listeners.clear 136: end
# File lib/webrick/server.rb, line 78 78: def start(&block) 79: raise ServerError, "already started." if @status != :Stop 80: server_type = @config[:ServerType] || SimpleServer 81: 82: server_type.start{ 83: @logger.info \ 84: "#{self.class}#start: pid=#{$$} port=#{@config[:Port]}" 85: call_callback(:StartCallback) 86: 87: thgroup = ThreadGroup.new 88: @status = :Running 89: while @status == :Running 90: begin 91: if svrs = IO.select(@listeners, nil, nil, 2.0) 92: svrs[0].each{|svr| 93: @tokens.pop # blocks while no token is there. 94: if sock = accept_client(svr) 95: th = start_thread(sock, &block) 96: th[:WEBrickThread] = true 97: thgroup.add(th) 98: else 99: @tokens.push(nil) 100: end 101: } 102: end 103: rescue Errno::EBADF, IOError => ex 104: # if the listening socket was closed in GenericServer#shutdown, 105: # IO::select raise it. 106: rescue Exception => ex 107: msg = "#{ex.class}: #{ex.message}\n\t#{ex.backtrace[0]}" 108: @logger.error msg 109: end 110: end 111: 112: @logger.info "going to shutdown ..." 113: thgroup.list.each{|th| th.join if th[:WEBrickThread] } 114: call_callback(:StopCallback) 115: @logger.info "#{self.class}#start done." 116: @status = :Stop 117: } 118: end
# File lib/webrick/server.rb, line 120 120: def stop 121: if @status == :Running 122: @status = :Shutdown 123: end 124: end
# File lib/webrick/server.rb, line 144 144: def accept_client(svr) 145: sock = nil 146: begin 147: sock = svr.accept 148: sock.sync = true 149: Utils::set_non_blocking(sock) 150: Utils::set_close_on_exec(sock) 151: rescue Errno::ECONNRESET, Errno::ECONNABORTED, Errno::EPROTO => ex 152: # TCP connection was established but RST segment was sent 153: # from peer before calling TCPServer#accept. 154: rescue Exception => ex 155: msg = "#{ex.class}: #{ex.message}\n\t#{ex.backtrace[0]}" 156: @logger.error msg 157: end 158: return sock 159: end
# File lib/webrick/server.rb, line 194 194: def call_callback(callback_name, *args) 195: if cb = @config[callback_name] 196: cb.call(*args) 197: end 198: end
# File lib/webrick/server.rb, line 161 161: def start_thread(sock, &block) 162: Thread.start{ 163: begin 164: Thread.current[:WEBrickSocket] = sock 165: begin 166: addr = sock.peeraddr 167: @logger.debug "accept: #{addr[3]}:#{addr[1]}" 168: rescue SocketError 169: @logger.debug "accept: <address unknown>" 170: raise 171: end 172: call_callback(:AcceptCallback, sock) 173: block ? block.call(sock) : run(sock) 174: rescue Errno::ENOTCONN 175: @logger.debug "Errno::ENOTCONN raised" 176: rescue ServerError => ex 177: msg = "#{ex.class}: #{ex.message}\n\t#{ex.backtrace[0]}" 178: @logger.error msg 179: rescue Exception => ex 180: @logger.error ex 181: ensure 182: @tokens.push(nil) 183: Thread.current[:WEBrickSocket] = nil 184: if addr 185: @logger.debug "close: #{addr[3]}:#{addr[1]}" 186: else 187: @logger.debug "close: <address unknown>" 188: end 189: sock.close 190: end 191: } 192: end