waitress-core 0.0.3 → 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (60) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +4 -4
  3. data/LICENSE +21 -21
  4. data/Rakefile +13 -4
  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 +83 -83
  16. data/lib/waitress/chef.rb +110 -110
  17. data/lib/waitress/configure.rb +116 -116
  18. data/lib/waitress/handlers/dirhandler.rb +39 -39
  19. data/lib/waitress/handlers/handler.rb +57 -57
  20. data/lib/waitress/handlers/handler404.rb +25 -25
  21. data/lib/waitress/handlers/libhandler.rb +58 -58
  22. data/lib/waitress/kernel.rb +182 -182
  23. data/lib/waitress/parse/query.rb +60 -60
  24. data/lib/waitress/request.rb +45 -45
  25. data/lib/waitress/resources/default_config.rb +52 -52
  26. data/lib/waitress/resources/http/404.html +18 -18
  27. data/lib/waitress/resources/http/css/hack.css +37 -37
  28. data/lib/waitress/resources/http/css/waitress.css +57 -57
  29. data/lib/waitress/resources/http/fonts/eot/latin/hack-bold-latin-webfont.eot +0 -0
  30. data/lib/waitress/resources/http/fonts/eot/latin/hack-bolditalic-latin-webfont.eot +0 -0
  31. data/lib/waitress/resources/http/fonts/eot/latin/hack-italic-latin-webfont.eot +0 -0
  32. data/lib/waitress/resources/http/fonts/eot/latin/hack-regular-latin-webfont.eot +0 -0
  33. data/lib/waitress/resources/http/fonts/svg/latin/hack-bold-latin-webfont.svg +240 -240
  34. data/lib/waitress/resources/http/fonts/svg/latin/hack-bolditalic-latin-webfont.svg +240 -240
  35. data/lib/waitress/resources/http/fonts/svg/latin/hack-italic-latin-webfont.svg +240 -240
  36. data/lib/waitress/resources/http/fonts/svg/latin/hack-regular-latin-webfont.svg +240 -240
  37. data/lib/waitress/resources/http/fonts/web-ttf/latin/hack-bold-latin-webfont.ttf +0 -0
  38. data/lib/waitress/resources/http/fonts/web-ttf/latin/hack-bolditalic-latin-webfont.ttf +0 -0
  39. data/lib/waitress/resources/http/fonts/web-ttf/latin/hack-italic-latin-webfont.ttf +0 -0
  40. data/lib/waitress/resources/http/fonts/web-ttf/latin/hack-regular-latin-webfont.ttf +0 -0
  41. data/lib/waitress/resources/http/fonts/woff/latin/hack-bold-latin-webfont.woff +0 -0
  42. data/lib/waitress/resources/http/fonts/woff/latin/hack-bolditalic-latin-webfont.woff +0 -0
  43. data/lib/waitress/resources/http/fonts/woff/latin/hack-italic-latin-webfont.woff +0 -0
  44. data/lib/waitress/resources/http/fonts/woff/latin/hack-regular-latin-webfont.woff +0 -0
  45. data/lib/waitress/resources/http/fonts/woff2/latin/hack-bold-latin-webfont.woff2 +0 -0
  46. data/lib/waitress/resources/http/fonts/woff2/latin/hack-bolditalic-latin-webfont.woff2 +0 -0
  47. data/lib/waitress/resources/http/fonts/woff2/latin/hack-italic-latin-webfont.woff2 +0 -0
  48. data/lib/waitress/resources/http/fonts/woff2/latin/hack-regular-latin-webfont.woff2 +0 -0
  49. data/lib/waitress/resources/http/img/404.png +0 -0
  50. data/lib/waitress/resources/http/index.html +15 -15
  51. data/lib/waitress/response.rb +104 -104
  52. data/lib/waitress/server.rb +126 -115
  53. data/lib/waitress/util.rb +707 -713
  54. data/lib/waitress/version.rb +3 -3
  55. data/lib/waitress/vhost.rb +217 -217
  56. data/lib/waitress.rb +98 -98
  57. data/lib/waitress_http11.bundle +0 -0
  58. data/waitress-core.gemspec +29 -27
  59. metadata +35 -7
  60. data/lib/waitress_http11.so +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,104 +1,104 @@
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
100
- end
101
- end
102
-
103
- end
104
- 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
100
+ end
101
+ end
102
+
103
+ end
104
+ end
@@ -1,115 +1,126 @@
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
- # Create a new Server instance with the given ports. If no ports are given,
16
- # port 80 will be used as a default
17
- def initialize(*ports)
18
- ports << 80 if ports.length == 0
19
- @ports = ports
20
- end
21
-
22
- # Set or Get the ports for this server. If arguments are provided, the ports
23
- # for this server will be replaced with the ones listed. If no arguments are provided,
24
- # this method simply returns the ports
25
- def ports *ports
26
- @ports = *ports unless ports.length == 0
27
- @ports
28
- end
29
-
30
- # Start the server. If arguments are provided, it will run with the ports
31
- # declared in the arguments, otherwise, it will use the ports it already has
32
- # set (or 80 for the default)
33
- def run *ports
34
- @ports = ports unless ports.length == 0
35
- @threads = @ports.map { |x| Thread.new { launch_port x } }
36
- self.each do |vhost|
37
- vhost.on_server_start self
38
- end
39
- self
40
- end
41
-
42
- # Join the server, blocking the current thread in order to keep the server alive.
43
- def join
44
- @threads.each { |x| x.join }
45
- end
46
-
47
- # Handle a client based on an IO stream, if you plan to serve on a non-socket
48
- # connection
49
- def read_io io
50
- handle_client io
51
- end
52
-
53
- :private
54
- def launch_port port
55
- @server = TCPServer.new port
56
- while true
57
- client = @server.accept
58
- go do
59
- begin
60
- handle_client client
61
- rescue => e
62
- puts "Server Error: #{e} (Fix This!)"
63
- puts e.backtrace
64
- end
65
- end
66
- end
67
- end
68
-
69
- def handle_client client_socket
70
- begin
71
- data = client_socket.readpartial(8196)
72
- rescue
73
- client_socket.close unless client_socket.closed?
74
- return
75
- end
76
-
77
- gofork do
78
- parser = Waitress::HttpParser.new
79
- params = HttpParams.new
80
- parser.execute(params, data, 0)
81
- build_request params, client_socket
82
- end.wait
83
- client_socket.close unless client_socket.closed?
84
- end
85
-
86
- def build_request headers, client_socket
87
- request_headers = {}
88
- headers.each do |k,v|
89
- if k.start_with? "HTTP_HEAD_"
90
- request_headers[k.sub(/HTTP_HEAD_/, "")] = v
91
- end
92
- end
93
- request = Waitress::Request.new(
94
- headers["REQUEST_METHOD"], headers["REQUEST_PATH"], headers["REQUEST_URI"],
95
- headers["QUERY_STRING"], headers["HTTP_VERSION"], headers.http_body, request_headers
96
- )
97
- handle_request request, client_socket
98
- end
99
-
100
- def handle_request request, client
101
- match, pri = self[0], nil
102
- self.each do |vhost|
103
- if (request.headers['Host'].to_s =~ vhost.domain) != nil
104
- match = vhost if pri.nil? || vhost.priority > pri
105
- end
106
- end
107
-
108
- if match.nil?
109
- # Subdomain not found (or default)
110
- else
111
- match.handle_request request, client
112
- end
113
- end
114
- end
115
- 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
+ # Create a new Server instance with the given ports. If no ports are given,
16
+ # port 80 will be used as a default
17
+ def initialize(*ports)
18
+ ports << 80 if ports.length == 0
19
+ @ports = ports
20
+ end
21
+
22
+ # Set or Get the ports for this server. If arguments are provided, the ports
23
+ # for this server will be replaced with the ones listed. If no arguments are provided,
24
+ # this method simply returns the ports
25
+ def ports *ports
26
+ @ports = *ports unless ports.length == 0
27
+ @ports
28
+ end
29
+
30
+ # Start the server. If arguments are provided, it will run with the ports
31
+ # declared in the arguments, otherwise, it will use the ports it already has
32
+ # set (or 80 for the default)
33
+ def run *ports
34
+ @ports = ports unless ports.length == 0
35
+ @threads = @ports.map { |x| Thread.new { launch_port x } }
36
+ self.each do |vhost|
37
+ vhost.on_server_start self
38
+ end
39
+ self
40
+ end
41
+
42
+ # Join the server, blocking the current thread in order to keep the server alive.
43
+ def join
44
+ @threads.each { |x| x.join }
45
+ end
46
+
47
+ # Handle a client based on an IO stream, if you plan to serve on a non-socket
48
+ # connection
49
+ def read_io io
50
+ handle_client io
51
+ end
52
+
53
+ :private
54
+ def launch_port port
55
+ @server = TCPServer.new port
56
+ while true
57
+ client = @server.accept
58
+ go do
59
+ begin
60
+ handle_client client
61
+ rescue => e
62
+ puts "Server Error: #{e} (Fix This!)"
63
+ puts e.backtrace
64
+ end
65
+ end
66
+ end
67
+ end
68
+
69
+ def handle_client client_socket
70
+ gofork do
71
+ begin
72
+ data = client_socket.readpartial(8192)
73
+ nparsed = 0
74
+
75
+ parser = Waitress::HttpParser.new
76
+ params = HttpParams.new
77
+
78
+ while nparsed < data.length
79
+ nparsed = parser.execute(params, data, nparsed)
80
+ if parser.finished?
81
+ build_request params, client_socket
82
+ else
83
+ ch = client.readpartial(8192)
84
+ break if !ch or ch.length == 0
85
+
86
+ data << ch
87
+ end
88
+ end
89
+ rescue => e
90
+ puts "Client Error: #{e}"
91
+ puts e.backtrace
92
+ end
93
+ end.wait
94
+ client_socket.close unless client_socket.closed?
95
+ end
96
+
97
+ def build_request headers, client_socket
98
+ request_headers = {}
99
+ headers.each do |k,v|
100
+ if k.start_with? "HTTP_HEAD_"
101
+ request_headers[k.sub(/HTTP_HEAD_/, "")] = v
102
+ end
103
+ end
104
+ request = Waitress::Request.new(
105
+ headers["REQUEST_METHOD"], headers["REQUEST_PATH"], headers["REQUEST_URI"],
106
+ headers["QUERY_STRING"], headers["HTTP_VERSION"], headers.http_body, request_headers
107
+ )
108
+ handle_request request, client_socket
109
+ end
110
+
111
+ def handle_request request, client
112
+ match, pri = self[0], nil
113
+ self.each do |vhost|
114
+ if (request.headers['Host'].to_s =~ vhost.domain) != nil
115
+ match = vhost if pri.nil? || vhost.priority > pri
116
+ end
117
+ end
118
+
119
+ if match.nil?
120
+ # Subdomain not found (or default)
121
+ else
122
+ match.handle_request request, client
123
+ end
124
+ end
125
+ end
126
+ end