Class: Waitress::HttpServer
- Inherits:
-
Array
- Object
- Array
- Waitress::HttpServer
- Defined in:
- lib/waitress/server.rb
Overview
The Waitress HTTPServer. This class is responsible for handling traffic from clients and delegating it to the correct Virtual Host to further handle. New threads and Processes are spawned for each connection to the server
Defined Under Namespace
Classes: HttpParams
Instance Attribute Summary collapse
-
#processes ⇒ Object
Returns the value of attribute processes.
Instance Method Summary collapse
- #build_request(headers, client_socket) ⇒ Object
- #connect_client(client) ⇒ Object
- #handle_client(client_socket) ⇒ Object
- #handle_request(request, client) ⇒ Object
-
#initialize(*ports) ⇒ HttpServer
constructor
Create a new Server instance with the given ports.
-
#internal_error(enabled) ⇒ Object
Set to true to enable clients to view the 500 error backtrace.
-
#join ⇒ Object
Join the server, blocking the current thread in order to keep the server alive.
-
#killall ⇒ Object
Killall running processes.
- #launch_port(port) ⇒ Object
-
#ports(*ports) ⇒ Object
Set or Get the ports for this server.
-
#read_io(io) ⇒ Object
Handle a client based on an IO stream, if you plan to serve on a non-socket connection.
-
#run(*ports) ⇒ Object
Start the server.
-
#set_processes(count) ⇒ Object
Set the amount of concurrent Waitress Processes to run on this Server, per Port.
Constructor Details
#initialize(*ports) ⇒ HttpServer
Create a new Server instance with the given ports. If no ports are given, port 80 will be used as a default
19 20 21 22 23 24 25 26 |
# File 'lib/waitress/server.rb', line 19 def initialize(*ports) ports << 80 if ports.length == 0 @ports = ports @processes = 5 @processes = ENV["WAITRESS_PROCESSES"].to_i if ENV.include? "WAITRESS_PROCESSES" @backtrace_500 = false @running_processes = [] end |
Instance Attribute Details
#processes ⇒ Object
Returns the value of attribute processes.
15 16 17 |
# File 'lib/waitress/server.rb', line 15 def processes @processes end |
Instance Method Details
#build_request(headers, client_socket) ⇒ Object
139 140 141 142 143 144 145 146 147 148 149 150 151 |
# File 'lib/waitress/server.rb', line 139 def build_request headers, client_socket request_headers = {} headers.each do |k,v| if k.start_with? "HTTP_HEAD_" request_headers[k.sub(/HTTP_HEAD_/, "")] = v end end request = Waitress::Request.new( headers["REQUEST_METHOD"], headers["REQUEST_PATH"], headers["REQUEST_URI"], headers["QUERY_STRING"], headers["HTTP_VERSION"], headers.http_body, request_headers ) handle_request request, client_socket end |
#connect_client(client) ⇒ Object
97 98 99 100 101 102 103 104 105 106 107 108 |
# File 'lib/waitress/server.rb', line 97 def connect_client client begin gofork do # Makes sure requires etc don't get triggered across requests handle_client client end.wait client.close rescue nil rescue => e puts "Server Error: #{e} (Fix This!)" puts e.backtrace client.close rescue nil end end |
#handle_client(client_socket) ⇒ Object
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 |
# File 'lib/waitress/server.rb', line 110 def handle_client client_socket begin data = client_socket.readpartial(8192) nparsed = 0 parser = Waitress::HttpParser.new params = HttpParams.new while nparsed < data.length nparsed = parser.execute(params, data, nparsed) if parser.finished? build_request params, client_socket else ch = client.readpartial(8192) break if !ch or ch.length == 0 data << ch end end rescue EOFError, Errno::ECONNRESET, Errno::EPIPE, Errno::EINVAL, Errno::EBADF client_socket.close rescue nil rescue => e # puts "Client Error: #{e}" # puts e.backtrace Handler500.trigger client_socket, self, e, @backtrace_500 end client_socket.close rescue nil end |
#handle_request(request, client) ⇒ Object
153 154 155 156 157 158 159 160 161 162 163 164 165 166 |
# File 'lib/waitress/server.rb', line 153 def handle_request request, client match, pri = self[0], nil self.each do |vhost| if (request.headers['Host'].to_s =~ vhost.domain) != nil match = vhost if pri.nil? || vhost.priority > pri end end if match.nil? # Subdomain not found (or default) else match.handle_request request, client end end |
#internal_error(enabled) ⇒ Object
Set to true to enable clients to view the 500 error backtrace
74 75 76 |
# File 'lib/waitress/server.rb', line 74 def internal_error enabled @backtrace_500 = enabled end |
#join ⇒ Object
Join the server, blocking the current thread in order to keep the server alive.
63 64 65 |
# File 'lib/waitress/server.rb', line 63 def join @running_processes.each { |x| x.wait } end |
#killall ⇒ Object
Killall running processes
58 59 60 |
# File 'lib/waitress/server.rb', line 58 def killall @running_processes.each { |x| x.kill rescue nil } end |
#launch_port(port) ⇒ Object
79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 |
# File 'lib/waitress/server.rb', line 79 def launch_port port serv = TCPServer.new port processes = [] @processes.times do processes << gofork { while true client = serv.accept connect_client(client) end } end processes.each do |pr| Process.detach(pr.pid) end processes end |
#ports(*ports) ⇒ Object
Set or Get the ports for this server. If arguments are provided, the ports for this server will be replaced with the ones listed. If no arguments are provided, this method simply returns the ports
36 37 38 39 |
# File 'lib/waitress/server.rb', line 36 def ports *ports @ports = *ports unless ports.length == 0 @ports end |
#read_io(io) ⇒ Object
Handle a client based on an IO stream, if you plan to serve on a non-socket connection
69 70 71 |
# File 'lib/waitress/server.rb', line 69 def read_io io handle_client io end |
#run(*ports) ⇒ Object
Start the server. If arguments are provided, it will run with the ports declared in the arguments, otherwise, it will use the ports it already has set (or 80 for the default)
44 45 46 47 48 49 50 51 52 53 54 55 |
# File 'lib/waitress/server.rb', line 44 def run *ports @ports = ports unless ports.length == 0 self.each do |vhost| vhost.on_server_start self end @running_processes = @ports.map do |port| launch_port(port) end @running_processes.flatten! self end |
#set_processes(count) ⇒ Object
Set the amount of concurrent Waitress Processes to run on this Server, per Port
29 30 31 |
# File 'lib/waitress/server.rb', line 29 def set_processes count @processes = count end |