Class: RaptorIO::Protocol::HTTP::Server
- Inherits:
-
Object
- Object
- RaptorIO::Protocol::HTTP::Server
- Defined in:
- lib/raptor-io/protocol/http/server.rb
Overview
HTTP Server class.
Constant Summary collapse
- LISTEN_BACKLOG =
IO#listen backlog, 5 seems to be the default setting in a lot of implementations.
5
- DEFAULT_OPTIONS =
Default server options.
{ address: '0.0.0.0', port: 4567, ssl_context: nil, request_mtu: 512, response_mtu: 512, timeout: 10, logger: ::Logger.new( STDOUT ), logger_level: Logger::INFO }.freeze
Instance Attribute Summary collapse
-
#address ⇒ String
readonly
Address of the server.
-
#port ⇒ Integer
readonly
Port number of the server.
-
#request_mtu ⇒ Integer
readonly
MTU for reading request bodies.
-
#response_mtu ⇒ Integer
readonly
MTU for sending responses.
-
#ssl_context ⇒ OpenSSL::SSL::SSLContext
SSL context to use.
- #switch_board ⇒ SwitchBoard readonly
-
#timeout ⇒ Integer
readonly
Configured connection timeout.
-
#timeouts ⇒ Integer
readonly
Amount of timed out connections.
Instance Method Summary collapse
-
#initialize(options = {}, &handler) ⇒ Server
constructor
A new instance of Server.
-
#run ⇒ Object
Starts the server.
-
#run_nonblock ⇒ Object
Runs the server in a Thread and returns once it’s ready.
-
#running? ⇒ Bool
‘true` if the server is running, `false` otherwise.
- #ssl? ⇒ Boolean
-
#stop ⇒ Object
Shuts down the server.
-
#url ⇒ String
URL of the server.
Constructor Details
#initialize(options = {}, &handler) ⇒ Server
Returns a new instance of Server.
77 78 79 80 81 82 83 84 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 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 |
# File 'lib/raptor-io/protocol/http/server.rb', line 77 def initialize( = {}, &handler ) @switch_board = .delete(:switch_board) unless @switch_board.is_a?(::RaptorIO::Socket::SwitchBoard) raise ArgumentError, 'Must provide a :switch_board' end DEFAULT_OPTIONS.merge( ).each do |k, v| begin send( "#{k}=", try_dup( v ) ) rescue NoMethodError instance_variable_set( "@#{k}".to_sym, try_dup( v ) ) end end @logger.level = @logger_level if @logger @sockets = { # Sockets ready to read from. reads: [], # Sockets ready to write to. writes: [], # IP address. client_address: {} } # In progress/buffered requests. @pending_requests = Hash.new do |h, socket| h[socket] = { # Buffered raw text request. buffer: '', # HTTP::Headers, parsed when in the :buffer. headers: nil, # Amount of the request body read, buffered to improve responsiveness # when handling large requests based on the :request_mtu option. body_bytes_read: 0, timeout: @timeout } end # In progress/buffered responses. @pending_responses = Hash.new do |h, socket| h[socket] = { # HTTP::Response object to transmit. object: nil, # Amount of HTTP::Response#to_s already sent, we buffer it for # performance reasons based on the :response_mtu option. bytes_sent: 0 } end @timeouts = 0 @stop = false @running = false @mutex = Mutex.new @system_responses = {} @handler = handler end |
Instance Attribute Details
#address ⇒ String (readonly)
Returns Address of the server.
29 30 31 |
# File 'lib/raptor-io/protocol/http/server.rb', line 29 def address @address end |
#port ⇒ Integer (readonly)
Returns Port number of the server.
32 33 34 |
# File 'lib/raptor-io/protocol/http/server.rb', line 32 def port @port end |
#request_mtu ⇒ Integer (readonly)
Returns MTU for reading request bodies.
38 39 40 |
# File 'lib/raptor-io/protocol/http/server.rb', line 38 def request_mtu @request_mtu end |
#response_mtu ⇒ Integer (readonly)
Returns MTU for sending responses.
41 42 43 |
# File 'lib/raptor-io/protocol/http/server.rb', line 41 def response_mtu @response_mtu end |
#ssl_context ⇒ OpenSSL::SSL::SSLContext
Returns SSL context to use.
35 36 37 |
# File 'lib/raptor-io/protocol/http/server.rb', line 35 def ssl_context @ssl_context end |
#switch_board ⇒ SwitchBoard (readonly)
Returns The routing table from which this RaptorIO::Protocol::HTTP::Server will listen.
52 53 54 |
# File 'lib/raptor-io/protocol/http/server.rb', line 52 def switch_board @switch_board end |
#timeout ⇒ Integer (readonly)
Returns Configured connection timeout.
44 45 46 |
# File 'lib/raptor-io/protocol/http/server.rb', line 44 def timeout @timeout end |
#timeouts ⇒ Integer (readonly)
Returns Amount of timed out connections.
47 48 49 |
# File 'lib/raptor-io/protocol/http/server.rb', line 47 def timeouts @timeouts end |
Instance Method Details
#run ⇒ Object
Starts the server.
148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 |
# File 'lib/raptor-io/protocol/http/server.rb', line 148 def run return if @server @server = listen synchronize { @running = true } while !stop? available_sockets = select_sockets next if !available_sockets # Go through the sockets which are available for reading. available_sockets[:reads].each do |socket| # Read and move to the next one if there are no new clients. if socket != @server read socket next end begin client = @server.accept_nonblock rescue => e log "#{e.class}: #{e}, #{client.inspect}", :error e.backtrace.each { |l| log l, :error } next end #$stderr.puts("http server accepted #{client.inspect}") @sockets[:client_address][client] = ::Socket.unpack_sockaddr_in( client.getpeername ).last @sockets[:reads] << client log 'Connected', :debug, client end # Handle sockets which are ready to be written to. available_sockets[:writes].each do |socket| write socket end # Close sockets with errors. available_sockets[:errors].each do |socket| log 'Connection error', :error, socket close socket end end synchronize { @running = false } end |
#run_nonblock ⇒ Object
Runs the server in a Thread and returns once it’s ready.
198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 |
# File 'lib/raptor-io/protocol/http/server.rb', line 198 def run_nonblock ex = nil Thread.new { begin run rescue => e log "#{e.class}: #{e}", :fatal e.backtrace.each { |l| log l, :fatal } synchronize { @running = true } ex = e end } sleep 0.1 while !running? if ex @running = false raise ex end end |
#running? ⇒ Bool
Returns ‘true` if the server is running, `false` otherwise.
220 221 222 |
# File 'lib/raptor-io/protocol/http/server.rb', line 220 def running? synchronize { @running } end |
#ssl? ⇒ Boolean
143 144 145 |
# File 'lib/raptor-io/protocol/http/server.rb', line 143 def ssl? !!@ssl_context end |
#stop ⇒ Object
Shuts down the server.
225 226 227 228 229 230 231 232 233 234 235 236 237 |
# File 'lib/raptor-io/protocol/http/server.rb', line 225 def stop return if !@server synchronize { @stop = true } sleep 0.05 while running? close @server @server = nil open_sockets.each { |socket| close socket } true end |
#url ⇒ String
Returns URL of the server.
240 241 242 |
# File 'lib/raptor-io/protocol/http/server.rb', line 240 def url "http#{'s' if ssl?}://#{address}:#{port}/" end |