waitress-core 0.2.4 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (63) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +4 -4
  3. data/LICENSE +21 -21
  4. data/Rakefile +17 -17
  5. data/bin/waitress +22 -22
  6. data/ext/Thanks.md +1 -1
  7. data/ext/waitress_http11/ext_help.h +15 -15
  8. data/ext/waitress_http11/extconf.rb +6 -6
  9. data/ext/waitress_http11/http11.c +532 -532
  10. data/ext/waitress_http11/http11_parser.c +1216 -1216
  11. data/ext/waitress_http11/http11_parser.h +49 -49
  12. data/ext/waitress_http11/http11_parser.java.rl +171 -171
  13. data/ext/waitress_http11/http11_parser.rl +165 -165
  14. data/ext/waitress_http11/http11_parser_common.rl +55 -55
  15. data/ext/waitress_http11/http11_wrb_parser.h +91 -91
  16. data/lib/waitress.rb +100 -99
  17. data/lib/waitress/chef.rb +113 -113
  18. data/lib/waitress/configure.rb +127 -121
  19. data/lib/waitress/evalbind.rb +9 -9
  20. data/lib/waitress/handlers/dirhandler.rb +39 -39
  21. data/lib/waitress/handlers/handler.rb +57 -57
  22. data/lib/waitress/handlers/handler404.rb +25 -25
  23. data/lib/waitress/handlers/libhandler.rb +135 -58
  24. data/lib/waitress/kernel.rb +189 -189
  25. data/lib/waitress/parse/query.rb +60 -60
  26. data/lib/waitress/request.rb +45 -45
  27. data/lib/waitress/resources/default_config.rb +52 -52
  28. data/lib/waitress/resources/default_less.yml +7 -0
  29. data/lib/waitress/resources/http/404.html +18 -18
  30. data/lib/waitress/resources/http/css/hack.css +37 -37
  31. data/lib/waitress/resources/http/css/waitress.css +57 -57
  32. data/lib/waitress/resources/http/fonts/eot/latin/hack-bold-latin-webfont.eot +0 -0
  33. data/lib/waitress/resources/http/fonts/eot/latin/hack-bolditalic-latin-webfont.eot +0 -0
  34. data/lib/waitress/resources/http/fonts/eot/latin/hack-italic-latin-webfont.eot +0 -0
  35. data/lib/waitress/resources/http/fonts/eot/latin/hack-regular-latin-webfont.eot +0 -0
  36. data/lib/waitress/resources/http/fonts/svg/latin/hack-bold-latin-webfont.svg +240 -240
  37. data/lib/waitress/resources/http/fonts/svg/latin/hack-bolditalic-latin-webfont.svg +240 -240
  38. data/lib/waitress/resources/http/fonts/svg/latin/hack-italic-latin-webfont.svg +240 -240
  39. data/lib/waitress/resources/http/fonts/svg/latin/hack-regular-latin-webfont.svg +240 -240
  40. data/lib/waitress/resources/http/fonts/web-ttf/latin/hack-bold-latin-webfont.ttf +0 -0
  41. data/lib/waitress/resources/http/fonts/web-ttf/latin/hack-bolditalic-latin-webfont.ttf +0 -0
  42. data/lib/waitress/resources/http/fonts/web-ttf/latin/hack-italic-latin-webfont.ttf +0 -0
  43. data/lib/waitress/resources/http/fonts/web-ttf/latin/hack-regular-latin-webfont.ttf +0 -0
  44. data/lib/waitress/resources/http/fonts/woff/latin/hack-bold-latin-webfont.woff +0 -0
  45. data/lib/waitress/resources/http/fonts/woff/latin/hack-bolditalic-latin-webfont.woff +0 -0
  46. data/lib/waitress/resources/http/fonts/woff/latin/hack-italic-latin-webfont.woff +0 -0
  47. data/lib/waitress/resources/http/fonts/woff/latin/hack-regular-latin-webfont.woff +0 -0
  48. data/lib/waitress/resources/http/fonts/woff2/latin/hack-bold-latin-webfont.woff2 +0 -0
  49. data/lib/waitress/resources/http/fonts/woff2/latin/hack-bolditalic-latin-webfont.woff2 +0 -0
  50. data/lib/waitress/resources/http/fonts/woff2/latin/hack-italic-latin-webfont.woff2 +0 -0
  51. data/lib/waitress/resources/http/fonts/woff2/latin/hack-regular-latin-webfont.woff2 +0 -0
  52. data/lib/waitress/resources/http/img/404.png +0 -0
  53. data/lib/waitress/resources/http/index.html +15 -15
  54. data/lib/waitress/response.rb +105 -105
  55. data/lib/waitress/server.rb +160 -160
  56. data/lib/waitress/util/less_watcher.rb +56 -0
  57. data/lib/waitress/{util.rb → util/util.rb} +707 -707
  58. data/lib/waitress/version.rb +3 -3
  59. data/lib/waitress/vhost.rb +229 -227
  60. data/lib/waitress_http11.so +0 -0
  61. data/waitress-core.gemspec +32 -29
  62. metadata +48 -4
  63. data/lib/waitress_http11.bundle +0 -0
File without changes
@@ -1,15 +1,15 @@
1
- <html>
2
- <head>
3
- <title> Welcome to Waitress </title>
4
- <link rel="stylesheet" href="css/hack.css">
5
- <link rel="stylesheet" href="css/waitress.css">
6
- </head>
7
- <body>
8
- <div id="maincontainer">
9
- <div class="titlecontainer">
10
- <h1> Waitress </h1>
11
- <h2> Please take a seat and let me take your order </h2>
12
- </div>
13
- </div>
14
- </body>
15
- </html>
1
+ <html>
2
+ <head>
3
+ <title> Welcome to Waitress </title>
4
+ <link rel="stylesheet" href="css/hack.css">
5
+ <link rel="stylesheet" href="css/waitress.css">
6
+ </head>
7
+ <body>
8
+ <div id="maincontainer">
9
+ <div class="titlecontainer">
10
+ <h1> Waitress </h1>
11
+ <h2> Please take a seat and let me take your order </h2>
12
+ </div>
13
+ </div>
14
+ </body>
15
+ </html>
@@ -1,105 +1,105 @@
1
- module Waitress
2
- # The response class is used to cook responses to be served to the client.
3
- # This class contains things like response headers, status codes and the response
4
- # body itself
5
- class Response
6
-
7
- def initialize
8
- @headers = {}
9
- status 200
10
- default_headers
11
- @isdone = false
12
- end
13
-
14
- # Returns true if the response has already been sent to the client
15
- def done?
16
- @isdone
17
- end
18
-
19
- # Mark the response as done (already sent to the client)
20
- def done state=true
21
- @isdone = state
22
- end
23
-
24
- # Apply the default headers to this response
25
- def default_headers
26
- header "Server", "Waitress #{Waitress::VERSION} (#{RUBY_PLATFORM})"
27
- end
28
-
29
- # Apply the given Status code to the response, such as 200, 404, 500 or
30
- # any other code listed in the HTTP protocol specification
31
- def status status_code
32
- @status = status_code
33
- @status_msg = Waitress::Util.status @status
34
- header "Status", "#{@status} #{@status_msg}"
35
- end
36
-
37
- # Set the mimetype (Content-Type header) of this response to the one matching
38
- # the given file extension as matched by the +Waitress::Util+ class
39
- # +filext+:: The file extension to match, e.g. .html, .css, .js
40
- def mime filext
41
- m = Waitress::Util.mime filext
42
- header "Content-Type", m
43
- end
44
-
45
- # Set the mimetype (Content-Type header) of this response to the one given.
46
- # +type+:: The mime type to use, e.g. application/json, text/html,
47
- # application/scon
48
- def mime_raw type
49
- header "Content-Type", type
50
- end
51
-
52
- # Set a header for the response. This header will be encoded to the http
53
- # response
54
- # Params:
55
- # +header+:: The name of the header. e.g. "Content-Type"
56
- # +data+:: The data to be encoded into the header. e.g. "text/html"
57
- def header header, data
58
- @headers[header] = data
59
- end
60
-
61
- # Set the Body IO object for the response. This IO object will be read from
62
- # when the webpage is served, so usually this is a File reference or a StringIO
63
- # +io+:: The io object to use. Not required if you just want to get the IO object
64
- def body_io io=:get
65
- @io = io unless io == :get
66
- @io
67
- end
68
-
69
- # Append something to the Body IO. If the Body IO is a StringIO, this will usually be
70
- # a String. This is mostly used for the 'echo' function
71
- def append obj
72
- @io.write obj
73
- end
74
-
75
- # Set the body to be a String. This will replace the BodyIO with a StringIO
76
- # containing the string
77
- # +str+:: The new string to replace the BodyIO with
78
- def body str
79
- body_io StringIO.new(str)
80
- end
81
-
82
- # Serve the response to the given socket. This will write the Headers, Response
83
- # Code and Body.
84
- def serve sock
85
- unless done?
86
- sock.write "HTTP/1.1 #{@status} #{@status_msg}\r\n"
87
- @headers.each do |k, v|
88
- sock.write "#{k}: #{v}\r\n"
89
- end
90
- sock.write "\r\n"
91
- unless @io.nil?
92
- @io.pos = 0
93
- until @io.eof?
94
- s = @io.read(4096)
95
- sock.write s
96
- end
97
- end
98
- done
99
- sock.close rescue nil
100
- @io.close rescue nil
101
- end
102
- end
103
-
104
- end
105
- end
1
+ module Waitress
2
+ # The response class is used to cook responses to be served to the client.
3
+ # This class contains things like response headers, status codes and the response
4
+ # body itself
5
+ class Response
6
+
7
+ def initialize
8
+ @headers = {}
9
+ status 200
10
+ default_headers
11
+ @isdone = false
12
+ end
13
+
14
+ # Returns true if the response has already been sent to the client
15
+ def done?
16
+ @isdone
17
+ end
18
+
19
+ # Mark the response as done (already sent to the client)
20
+ def done state=true
21
+ @isdone = state
22
+ end
23
+
24
+ # Apply the default headers to this response
25
+ def default_headers
26
+ header "Server", "Waitress #{Waitress::VERSION} (#{RUBY_PLATFORM})"
27
+ end
28
+
29
+ # Apply the given Status code to the response, such as 200, 404, 500 or
30
+ # any other code listed in the HTTP protocol specification
31
+ def status status_code
32
+ @status = status_code
33
+ @status_msg = Waitress::Util.status @status
34
+ header "Status", "#{@status} #{@status_msg}"
35
+ end
36
+
37
+ # Set the mimetype (Content-Type header) of this response to the one matching
38
+ # the given file extension as matched by the +Waitress::Util+ class
39
+ # +filext+:: The file extension to match, e.g. .html, .css, .js
40
+ def mime filext
41
+ m = Waitress::Util.mime filext
42
+ header "Content-Type", m
43
+ end
44
+
45
+ # Set the mimetype (Content-Type header) of this response to the one given.
46
+ # +type+:: The mime type to use, e.g. application/json, text/html,
47
+ # application/scon
48
+ def mime_raw type
49
+ header "Content-Type", type
50
+ end
51
+
52
+ # Set a header for the response. This header will be encoded to the http
53
+ # response
54
+ # Params:
55
+ # +header+:: The name of the header. e.g. "Content-Type"
56
+ # +data+:: The data to be encoded into the header. e.g. "text/html"
57
+ def header header, data
58
+ @headers[header] = data
59
+ end
60
+
61
+ # Set the Body IO object for the response. This IO object will be read from
62
+ # when the webpage is served, so usually this is a File reference or a StringIO
63
+ # +io+:: The io object to use. Not required if you just want to get the IO object
64
+ def body_io io=:get
65
+ @io = io unless io == :get
66
+ @io
67
+ end
68
+
69
+ # Append something to the Body IO. If the Body IO is a StringIO, this will usually be
70
+ # a String. This is mostly used for the 'echo' function
71
+ def append obj
72
+ @io.write obj
73
+ end
74
+
75
+ # Set the body to be a String. This will replace the BodyIO with a StringIO
76
+ # containing the string
77
+ # +str+:: The new string to replace the BodyIO with
78
+ def body str
79
+ body_io StringIO.new(str)
80
+ end
81
+
82
+ # Serve the response to the given socket. This will write the Headers, Response
83
+ # Code and Body.
84
+ def serve sock
85
+ unless done?
86
+ sock.write "HTTP/1.1 #{@status} #{@status_msg}\r\n"
87
+ @headers.each do |k, v|
88
+ sock.write "#{k}: #{v}\r\n"
89
+ end
90
+ sock.write "\r\n"
91
+ unless @io.nil?
92
+ @io.pos = 0
93
+ until @io.eof?
94
+ s = @io.read(4096)
95
+ sock.write s
96
+ end
97
+ end
98
+ done
99
+ sock.close rescue nil
100
+ @io.close rescue nil
101
+ end
102
+ end
103
+
104
+ end
105
+ end
@@ -1,160 +1,160 @@
1
- require 'socket'
2
- require 'thread'
3
-
4
- module Waitress
5
-
6
- # The Waitress HTTPServer. This class is responsible for handling traffic from
7
- # clients and delegating it to the correct Virtual Host to further handle.
8
- # New threads and Processes are spawned for each connection to the server
9
- class HttpServer < Array
10
-
11
- class HttpParams < Hash
12
- attr_accessor :http_body
13
- end
14
-
15
- attr_accessor :processes
16
-
17
- # Create a new Server instance with the given ports. If no ports are given,
18
- # port 80 will be used as a default
19
- def initialize(*ports)
20
- ports << 80 if ports.length == 0
21
- @ports = ports
22
- @processes = 5
23
- @processes = ENV["WAITRESS_PROCESSES"].to_i if ENV.include? "WAITRESS_PROCESSES"
24
- @running_processes = []
25
- end
26
-
27
- # Set the amount of concurrent Waitress Processes to run on this Server, per Port
28
- def set_processes count
29
- @processes = count
30
- end
31
-
32
- # Set or Get the ports for this server. If arguments are provided, the ports
33
- # for this server will be replaced with the ones listed. If no arguments are provided,
34
- # this method simply returns the ports
35
- def ports *ports
36
- @ports = *ports unless ports.length == 0
37
- @ports
38
- end
39
-
40
- # Start the server. If arguments are provided, it will run with the ports
41
- # declared in the arguments, otherwise, it will use the ports it already has
42
- # set (or 80 for the default)
43
- def run *ports
44
- @ports = ports unless ports.length == 0
45
- self.each do |vhost|
46
- vhost.on_server_start self
47
- end
48
-
49
- @running_processes = @ports.map do |port|
50
- launch_port(port)
51
- end
52
- @running_processes.flatten!
53
- self
54
- end
55
-
56
- # Killall running processes
57
- def killall
58
- @running_processes.each { |x| x.kill rescue nil }
59
- end
60
-
61
- # Join the server, blocking the current thread in order to keep the server alive.
62
- def join
63
- @running_processes.each { |x| x.wait }
64
- end
65
-
66
- # Handle a client based on an IO stream, if you plan to serve on a non-socket
67
- # connection
68
- def read_io io
69
- handle_client io
70
- end
71
-
72
- :private
73
- def launch_port port
74
- serv = TCPServer.new port
75
- processes = []
76
- @processes.times do
77
- processes << gofork {
78
- while true
79
- begin
80
- client = serv.accept
81
- gofork do # Makes sure requires etc don't get triggered across requests
82
- handle_client client
83
- end.wait
84
- client.close rescue nil
85
- rescue => e
86
- puts "Server Error: #{e} (Fix This!)"
87
- puts e.backtrace
88
- client.close rescue nil
89
- end
90
- end
91
- }
92
- end
93
-
94
- processes.each do |pr|
95
- Process.detach(pr.pid)
96
- end
97
- processes
98
- end
99
-
100
- def handle_client client_socket
101
- # pro = gofork do
102
- begin
103
- data = client_socket.readpartial(8192)
104
- nparsed = 0
105
-
106
- parser = Waitress::HttpParser.new
107
- params = HttpParams.new
108
-
109
- while nparsed < data.length
110
- nparsed = parser.execute(params, data, nparsed)
111
- if parser.finished?
112
- build_request params, client_socket
113
- else
114
- ch = client.readpartial(8192)
115
- break if !ch or ch.length == 0
116
-
117
- data << ch
118
- end
119
- end
120
- rescue EOFError, Errno::ECONNRESET, Errno::EPIPE, Errno::EINVAL, Errno::EBADF
121
- client_socket.close rescue nil
122
- rescue => e
123
- puts "Client Error: #{e}"
124
- puts e.backtrace
125
- end
126
- # end
127
- client_socket.close rescue nil
128
- # pro.wait
129
- end
130
-
131
- def build_request headers, client_socket
132
- request_headers = {}
133
- headers.each do |k,v|
134
- if k.start_with? "HTTP_HEAD_"
135
- request_headers[k.sub(/HTTP_HEAD_/, "")] = v
136
- end
137
- end
138
- request = Waitress::Request.new(
139
- headers["REQUEST_METHOD"], headers["REQUEST_PATH"], headers["REQUEST_URI"],
140
- headers["QUERY_STRING"], headers["HTTP_VERSION"], headers.http_body, request_headers
141
- )
142
- handle_request request, client_socket
143
- end
144
-
145
- def handle_request request, client
146
- match, pri = self[0], nil
147
- self.each do |vhost|
148
- if (request.headers['Host'].to_s =~ vhost.domain) != nil
149
- match = vhost if pri.nil? || vhost.priority > pri
150
- end
151
- end
152
-
153
- if match.nil?
154
- # Subdomain not found (or default)
155
- else
156
- match.handle_request request, client
157
- end
158
- end
159
- end
160
- end
1
+ require 'socket'
2
+ require 'thread'
3
+
4
+ module Waitress
5
+
6
+ # The Waitress HTTPServer. This class is responsible for handling traffic from
7
+ # clients and delegating it to the correct Virtual Host to further handle.
8
+ # New threads and Processes are spawned for each connection to the server
9
+ class HttpServer < Array
10
+
11
+ class HttpParams < Hash
12
+ attr_accessor :http_body
13
+ end
14
+
15
+ attr_accessor :processes
16
+
17
+ # Create a new Server instance with the given ports. If no ports are given,
18
+ # port 80 will be used as a default
19
+ def initialize(*ports)
20
+ ports << 80 if ports.length == 0
21
+ @ports = ports
22
+ @processes = 5
23
+ @processes = ENV["WAITRESS_PROCESSES"].to_i if ENV.include? "WAITRESS_PROCESSES"
24
+ @running_processes = []
25
+ end
26
+
27
+ # Set the amount of concurrent Waitress Processes to run on this Server, per Port
28
+ def set_processes count
29
+ @processes = count
30
+ end
31
+
32
+ # Set or Get the ports for this server. If arguments are provided, the ports
33
+ # for this server will be replaced with the ones listed. If no arguments are provided,
34
+ # this method simply returns the ports
35
+ def ports *ports
36
+ @ports = *ports unless ports.length == 0
37
+ @ports
38
+ end
39
+
40
+ # Start the server. If arguments are provided, it will run with the ports
41
+ # declared in the arguments, otherwise, it will use the ports it already has
42
+ # set (or 80 for the default)
43
+ def run *ports
44
+ @ports = ports unless ports.length == 0
45
+ self.each do |vhost|
46
+ vhost.on_server_start self
47
+ end
48
+
49
+ @running_processes = @ports.map do |port|
50
+ launch_port(port)
51
+ end
52
+ @running_processes.flatten!
53
+ self
54
+ end
55
+
56
+ # Killall running processes
57
+ def killall
58
+ @running_processes.each { |x| x.kill rescue nil }
59
+ end
60
+
61
+ # Join the server, blocking the current thread in order to keep the server alive.
62
+ def join
63
+ @running_processes.each { |x| x.wait }
64
+ end
65
+
66
+ # Handle a client based on an IO stream, if you plan to serve on a non-socket
67
+ # connection
68
+ def read_io io
69
+ handle_client io
70
+ end
71
+
72
+ :private
73
+ def launch_port port
74
+ serv = TCPServer.new port
75
+ processes = []
76
+ @processes.times do
77
+ processes << gofork {
78
+ while true
79
+ begin
80
+ client = serv.accept
81
+ gofork do # Makes sure requires etc don't get triggered across requests
82
+ handle_client client
83
+ end.wait
84
+ client.close rescue nil
85
+ rescue => e
86
+ puts "Server Error: #{e} (Fix This!)"
87
+ puts e.backtrace
88
+ client.close rescue nil
89
+ end
90
+ end
91
+ }
92
+ end
93
+
94
+ processes.each do |pr|
95
+ Process.detach(pr.pid)
96
+ end
97
+ processes
98
+ end
99
+
100
+ def handle_client client_socket
101
+ # pro = gofork do
102
+ begin
103
+ data = client_socket.readpartial(8192)
104
+ nparsed = 0
105
+
106
+ parser = Waitress::HttpParser.new
107
+ params = HttpParams.new
108
+
109
+ while nparsed < data.length
110
+ nparsed = parser.execute(params, data, nparsed)
111
+ if parser.finished?
112
+ build_request params, client_socket
113
+ else
114
+ ch = client.readpartial(8192)
115
+ break if !ch or ch.length == 0
116
+
117
+ data << ch
118
+ end
119
+ end
120
+ rescue EOFError, Errno::ECONNRESET, Errno::EPIPE, Errno::EINVAL, Errno::EBADF
121
+ client_socket.close rescue nil
122
+ rescue => e
123
+ puts "Client Error: #{e}"
124
+ puts e.backtrace
125
+ end
126
+ # end
127
+ client_socket.close rescue nil
128
+ # pro.wait
129
+ end
130
+
131
+ def build_request headers, client_socket
132
+ request_headers = {}
133
+ headers.each do |k,v|
134
+ if k.start_with? "HTTP_HEAD_"
135
+ request_headers[k.sub(/HTTP_HEAD_/, "")] = v
136
+ end
137
+ end
138
+ request = Waitress::Request.new(
139
+ headers["REQUEST_METHOD"], headers["REQUEST_PATH"], headers["REQUEST_URI"],
140
+ headers["QUERY_STRING"], headers["HTTP_VERSION"], headers.http_body, request_headers
141
+ )
142
+ handle_request request, client_socket
143
+ end
144
+
145
+ def handle_request request, client
146
+ match, pri = self[0], nil
147
+ self.each do |vhost|
148
+ if (request.headers['Host'].to_s =~ vhost.domain) != nil
149
+ match = vhost if pri.nil? || vhost.priority > pri
150
+ end
151
+ end
152
+
153
+ if match.nil?
154
+ # Subdomain not found (or default)
155
+ else
156
+ match.handle_request request, client
157
+ end
158
+ end
159
+ end
160
+ end