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.
- checksums.yaml +4 -4
- data/Gemfile +4 -4
- data/LICENSE +21 -21
- data/Rakefile +13 -4
- data/bin/waitress +22 -22
- data/ext/Thanks.md +1 -1
- data/ext/waitress_http11/ext_help.h +15 -15
- data/ext/waitress_http11/extconf.rb +6 -6
- data/ext/waitress_http11/http11.c +532 -532
- data/ext/waitress_http11/http11_parser.c +1216 -1216
- data/ext/waitress_http11/http11_parser.h +49 -49
- data/ext/waitress_http11/http11_parser.java.rl +171 -171
- data/ext/waitress_http11/http11_parser.rl +165 -165
- data/ext/waitress_http11/http11_parser_common.rl +55 -55
- data/ext/waitress_http11/http11_wrb_parser.h +83 -83
- data/lib/waitress/chef.rb +110 -110
- data/lib/waitress/configure.rb +116 -116
- data/lib/waitress/handlers/dirhandler.rb +39 -39
- data/lib/waitress/handlers/handler.rb +57 -57
- data/lib/waitress/handlers/handler404.rb +25 -25
- data/lib/waitress/handlers/libhandler.rb +58 -58
- data/lib/waitress/kernel.rb +182 -182
- data/lib/waitress/parse/query.rb +60 -60
- data/lib/waitress/request.rb +45 -45
- data/lib/waitress/resources/default_config.rb +52 -52
- data/lib/waitress/resources/http/404.html +18 -18
- data/lib/waitress/resources/http/css/hack.css +37 -37
- data/lib/waitress/resources/http/css/waitress.css +57 -57
- data/lib/waitress/resources/http/fonts/eot/latin/hack-bold-latin-webfont.eot +0 -0
- data/lib/waitress/resources/http/fonts/eot/latin/hack-bolditalic-latin-webfont.eot +0 -0
- data/lib/waitress/resources/http/fonts/eot/latin/hack-italic-latin-webfont.eot +0 -0
- data/lib/waitress/resources/http/fonts/eot/latin/hack-regular-latin-webfont.eot +0 -0
- data/lib/waitress/resources/http/fonts/svg/latin/hack-bold-latin-webfont.svg +240 -240
- data/lib/waitress/resources/http/fonts/svg/latin/hack-bolditalic-latin-webfont.svg +240 -240
- data/lib/waitress/resources/http/fonts/svg/latin/hack-italic-latin-webfont.svg +240 -240
- data/lib/waitress/resources/http/fonts/svg/latin/hack-regular-latin-webfont.svg +240 -240
- data/lib/waitress/resources/http/fonts/web-ttf/latin/hack-bold-latin-webfont.ttf +0 -0
- data/lib/waitress/resources/http/fonts/web-ttf/latin/hack-bolditalic-latin-webfont.ttf +0 -0
- data/lib/waitress/resources/http/fonts/web-ttf/latin/hack-italic-latin-webfont.ttf +0 -0
- data/lib/waitress/resources/http/fonts/web-ttf/latin/hack-regular-latin-webfont.ttf +0 -0
- data/lib/waitress/resources/http/fonts/woff/latin/hack-bold-latin-webfont.woff +0 -0
- data/lib/waitress/resources/http/fonts/woff/latin/hack-bolditalic-latin-webfont.woff +0 -0
- data/lib/waitress/resources/http/fonts/woff/latin/hack-italic-latin-webfont.woff +0 -0
- data/lib/waitress/resources/http/fonts/woff/latin/hack-regular-latin-webfont.woff +0 -0
- data/lib/waitress/resources/http/fonts/woff2/latin/hack-bold-latin-webfont.woff2 +0 -0
- data/lib/waitress/resources/http/fonts/woff2/latin/hack-bolditalic-latin-webfont.woff2 +0 -0
- data/lib/waitress/resources/http/fonts/woff2/latin/hack-italic-latin-webfont.woff2 +0 -0
- data/lib/waitress/resources/http/fonts/woff2/latin/hack-regular-latin-webfont.woff2 +0 -0
- data/lib/waitress/resources/http/img/404.png +0 -0
- data/lib/waitress/resources/http/index.html +15 -15
- data/lib/waitress/response.rb +104 -104
- data/lib/waitress/server.rb +126 -115
- data/lib/waitress/util.rb +707 -713
- data/lib/waitress/version.rb +3 -3
- data/lib/waitress/vhost.rb +217 -217
- data/lib/waitress.rb +98 -98
- data/lib/waitress_http11.bundle +0 -0
- data/waitress-core.gemspec +29 -27
- metadata +35 -7
- data/lib/waitress_http11.so +0 -0
@@ -1,25 +1,25 @@
|
|
1
|
-
module Waitress
|
2
|
-
|
3
|
-
# The 404 Handler is a simple "Catch-All" handler which will be triggered if
|
4
|
-
# a valid handler is not found for the page, and will show an error page
|
5
|
-
# telling the user the page cannot be found
|
6
|
-
class Handler404 < ErrorHandler
|
7
|
-
|
8
|
-
def serve request, response, client, vhost
|
9
|
-
response.status 404
|
10
|
-
e404page = vhost.get_404
|
11
|
-
if !e404page.nil? && (Waitress::Chef.find_file(e404page)[:result]==:ok)
|
12
|
-
Waitress::Chef.serve_file request, response, client, vhost, e404page
|
13
|
-
else
|
14
|
-
if vhost.resources?
|
15
|
-
h = File.join Waitress::Chef.resources_http, "404.html"
|
16
|
-
Waitress::Chef.serve_file request, response, client, vhost, h
|
17
|
-
else
|
18
|
-
response.mime ".html"
|
19
|
-
response.body "<h1> 404 - Not Found </h1> <p> The page you have requested is not here </p>"
|
20
|
-
end
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
24
|
-
end
|
25
|
-
end
|
1
|
+
module Waitress
|
2
|
+
|
3
|
+
# The 404 Handler is a simple "Catch-All" handler which will be triggered if
|
4
|
+
# a valid handler is not found for the page, and will show an error page
|
5
|
+
# telling the user the page cannot be found
|
6
|
+
class Handler404 < ErrorHandler
|
7
|
+
|
8
|
+
def serve request, response, client, vhost
|
9
|
+
response.status 404
|
10
|
+
e404page = vhost.get_404
|
11
|
+
if !e404page.nil? && (Waitress::Chef.find_file(e404page)[:result]==:ok)
|
12
|
+
Waitress::Chef.serve_file request, response, client, vhost, e404page
|
13
|
+
else
|
14
|
+
if vhost.resources?
|
15
|
+
h = File.join Waitress::Chef.resources_http, "404.html"
|
16
|
+
Waitress::Chef.serve_file request, response, client, vhost, h
|
17
|
+
else
|
18
|
+
response.mime ".html"
|
19
|
+
response.body "<h1> 404 - Not Found </h1> <p> The page you have requested is not here </p>"
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
end
|
@@ -1,58 +1,58 @@
|
|
1
|
-
module Waitress
|
2
|
-
|
3
|
-
# The LibraryHandler is used to handle requests to the VHost regarding the
|
4
|
-
# libraries to be loaded by other Handlers and .wrb files. This will take any
|
5
|
-
# requests to /libraries (or whatever the user has set it to) to load libraries
|
6
|
-
class LibraryHandler < Handler
|
7
|
-
|
8
|
-
attr_accessor :priority
|
9
|
-
|
10
|
-
def initialize libraries, libdir, liburi, vhost
|
11
|
-
@priority = 150
|
12
|
-
@vhost = vhost
|
13
|
-
@libraries, @libdir, @liburi = libraries, File.expand_path(libdir), liburi
|
14
|
-
FileUtils.mkdir_p(@libdir) unless File.exist?(@libdir)
|
15
|
-
|
16
|
-
@libraries.each do |name, lib|
|
17
|
-
l = {}
|
18
|
-
d = dirType(lib[:bindtype])
|
19
|
-
matches = Dir["#{d}/**/*.#{lib[:bindtype].to_s}"].select { |x| (x =~ lib[:pattern]) != nil }
|
20
|
-
if matches.length > 0
|
21
|
-
l[:file] = matches[0]
|
22
|
-
l[:type] = lib[:bindtype]
|
23
|
-
else
|
24
|
-
l = nil
|
25
|
-
end
|
26
|
-
@libraries[name] = l
|
27
|
-
end
|
28
|
-
|
29
|
-
[:css, :js].each do |k|
|
30
|
-
d = dirType k
|
31
|
-
FileUtils.mkdir_p(d) unless File.exist?(d)
|
32
|
-
|
33
|
-
Dir["#{d}/**/*.#{k.to_s}"].each do |fl|
|
34
|
-
@libraries[File.basename(fl).to_sym] = { :file => fl, :type => k }
|
35
|
-
end
|
36
|
-
end
|
37
|
-
end
|
38
|
-
|
39
|
-
def dirType k
|
40
|
-
File.join(@libdir, k.to_s)
|
41
|
-
end
|
42
|
-
|
43
|
-
def respond? request, vhost
|
44
|
-
path = request.path
|
45
|
-
return false unless path.start_with?("/#{@liburi}/")
|
46
|
-
name = path.sub("/#{@liburi}/", "").to_sym
|
47
|
-
@libraries.include?(name)
|
48
|
-
end
|
49
|
-
|
50
|
-
def serve request, response, client, vhost
|
51
|
-
path = request.path
|
52
|
-
name = path.sub("/#{@liburi}/", "").to_sym
|
53
|
-
lib = @libraries[name]
|
54
|
-
Waitress::Chef.serve_file request, response, client, vhost, lib[:file]
|
55
|
-
end
|
56
|
-
|
57
|
-
end
|
58
|
-
end
|
1
|
+
module Waitress
|
2
|
+
|
3
|
+
# The LibraryHandler is used to handle requests to the VHost regarding the
|
4
|
+
# libraries to be loaded by other Handlers and .wrb files. This will take any
|
5
|
+
# requests to /libraries (or whatever the user has set it to) to load libraries
|
6
|
+
class LibraryHandler < Handler
|
7
|
+
|
8
|
+
attr_accessor :priority
|
9
|
+
|
10
|
+
def initialize libraries, libdir, liburi, vhost
|
11
|
+
@priority = 150
|
12
|
+
@vhost = vhost
|
13
|
+
@libraries, @libdir, @liburi = libraries, File.expand_path(libdir), liburi
|
14
|
+
FileUtils.mkdir_p(@libdir) unless File.exist?(@libdir)
|
15
|
+
|
16
|
+
@libraries.each do |name, lib|
|
17
|
+
l = {}
|
18
|
+
d = dirType(lib[:bindtype])
|
19
|
+
matches = Dir["#{d}/**/*.#{lib[:bindtype].to_s}"].select { |x| (x =~ lib[:pattern]) != nil }
|
20
|
+
if matches.length > 0
|
21
|
+
l[:file] = matches[0]
|
22
|
+
l[:type] = lib[:bindtype]
|
23
|
+
else
|
24
|
+
l = nil
|
25
|
+
end
|
26
|
+
@libraries[name] = l
|
27
|
+
end
|
28
|
+
|
29
|
+
[:css, :js].each do |k|
|
30
|
+
d = dirType k
|
31
|
+
FileUtils.mkdir_p(d) unless File.exist?(d)
|
32
|
+
|
33
|
+
Dir["#{d}/**/*.#{k.to_s}"].each do |fl|
|
34
|
+
@libraries[File.basename(fl).to_sym] = { :file => fl, :type => k }
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def dirType k
|
40
|
+
File.join(@libdir, k.to_s)
|
41
|
+
end
|
42
|
+
|
43
|
+
def respond? request, vhost
|
44
|
+
path = request.path
|
45
|
+
return false unless path.start_with?("/#{@liburi}/")
|
46
|
+
name = path.sub("/#{@liburi}/", "").to_sym
|
47
|
+
@libraries.include?(name)
|
48
|
+
end
|
49
|
+
|
50
|
+
def serve request, response, client, vhost
|
51
|
+
path = request.path
|
52
|
+
name = path.sub("/#{@liburi}/", "").to_sym
|
53
|
+
lib = @libraries[name]
|
54
|
+
Waitress::Chef.serve_file request, response, client, vhost, lib[:file]
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
58
|
+
end
|
data/lib/waitress/kernel.rb
CHANGED
@@ -1,182 +1,182 @@
|
|
1
|
-
# The Kernel Module provides global methods that will provide the 'builtins' for .wrb files
|
2
|
-
# and handlers. This is used to prevent verbose access of a namespace like Waitress::Global,
|
3
|
-
# and instead provide them here. Because requests are handled in new Processes, these values
|
4
|
-
# will change in each request and will not interfere.
|
5
|
-
module ::Kernel
|
6
|
-
|
7
|
-
# The +Waitress::Response+ object being used
|
8
|
-
def response_object
|
9
|
-
$RESPONSE
|
10
|
-
end
|
11
|
-
|
12
|
-
# The +Waitress::Request+ object being used
|
13
|
-
def request_object
|
14
|
-
$REQUEST
|
15
|
-
end
|
16
|
-
|
17
|
-
# Prepare the Kernel, by linking global variables
|
18
|
-
def kernel_prepare
|
19
|
-
$METHOD = get_method
|
20
|
-
$HEADERS = get_headers
|
21
|
-
$PATH = get_path
|
22
|
-
$URI = get_uri
|
23
|
-
$BODY = get_body
|
24
|
-
end
|
25
|
-
|
26
|
-
# Automatically load a library header into this file in the form of HTML.
|
27
|
-
# This will load a library in the VHost's libs/ folder, or any lib defined in the
|
28
|
-
# VHost's config.rb file with the name given. JS libraries will be linked with the
|
29
|
-
# <script> tag, whilst css files will be linked with the <link rel="stylesheet">
|
30
|
-
# tag. This is the recommended way of handling library loading.
|
31
|
-
# Params:
|
32
|
-
# +name+:: The name of the lib (the filename), or the name of the library as bound
|
33
|
-
# in the config.rb file.
|
34
|
-
def lib name
|
35
|
-
name = name.to_sym
|
36
|
-
type = $VHOST.libraries[name][:type]
|
37
|
-
libhome = $VHOST.liburi
|
38
|
-
if type == :js
|
39
|
-
echo "<script type='text/javascript' src='/#{libhome}/#{name}'></script>"
|
40
|
-
elsif type == :css
|
41
|
-
echo "<link rel='stylesheet' href='/#{libhome}/#{name}'></link>"
|
42
|
-
end
|
43
|
-
end
|
44
|
-
|
45
|
-
# Automatically load a Library Combo into this file. This will consecutively load
|
46
|
-
# all the libraries bound to the combination with the given name as defined in the
|
47
|
-
# VHost's config.rb file. This will call lib() for each of these libraries.
|
48
|
-
# Params:
|
49
|
-
# +name+:: The name of the combo to load
|
50
|
-
def combo name
|
51
|
-
name = name.to_sym
|
52
|
-
combo_arr = $VHOST.combos[name]
|
53
|
-
combo_arr.each { |n| lib(n) }
|
54
|
-
end
|
55
|
-
|
56
|
-
# Include another .wrb, .rb or any other file in the load path of the VHost into this
|
57
|
-
# file. If this file is .wrb or .rb, it will be evaluated. If it is another type of file
|
58
|
-
# (e.g. html), it will be directly echoed to the output buffer
|
59
|
-
# Params:
|
60
|
-
# +filename+:: The name of the file, relative to the loadpath
|
61
|
-
def includes filename
|
62
|
-
Waitress::Chef.include_file filename
|
63
|
-
end
|
64
|
-
|
65
|
-
# Include another .wrb, .rb or any other file in this file. If this file is
|
66
|
-
# .wrb or .rb, it will be evaluated. If it is another type of file
|
67
|
-
# (e.g. html), it will be directly echoed to the output buffer
|
68
|
-
# Params:
|
69
|
-
# +filename+:: The absolute filename of the file to load, anywhere in the filesystem
|
70
|
-
def includes_file filename
|
71
|
-
Waitress::Chef.include_absfile filename
|
72
|
-
end
|
73
|
-
|
74
|
-
# Returns a Hash of the GET query of the request. This may be an empty array
|
75
|
-
# if querystring was present
|
76
|
-
def get
|
77
|
-
request_object.get_query
|
78
|
-
end
|
79
|
-
|
80
|
-
# Returns a Hash of the POST query of the request. This may be an empty array
|
81
|
-
# if the body is not a valid querystring, or an exception raised if there was
|
82
|
-
# an error in parsing.
|
83
|
-
def post
|
84
|
-
request_object.post_query
|
85
|
-
end
|
86
|
-
|
87
|
-
# Get a header from the HTTP Request. This will fetch the header by the given
|
88
|
-
# name from the request object. Keep in mind that in requests, Headers are fully
|
89
|
-
# capitalized and any hyphens replaced with underscores (e.g. Content-Type becomes
|
90
|
-
# CONTENT_TYPE)
|
91
|
-
def get_header name
|
92
|
-
request_object.headers[name]
|
93
|
-
end
|
94
|
-
|
95
|
-
# Return the full list of headers available in the request object.
|
96
|
-
def get_headers
|
97
|
-
request_object.headers
|
98
|
-
end
|
99
|
-
|
100
|
-
# Returns the HTTP method that was used to retrieve this page (GET, POST, UPDATE,
|
101
|
-
# DELETE, PUT, etc)
|
102
|
-
def get_method
|
103
|
-
request_object.method
|
104
|
-
end
|
105
|
-
|
106
|
-
# Get the path of this request. This is after a URL rewrite, and does not contain
|
107
|
-
# a querystring. Be careful with these, as they start with a "/" and if not joined
|
108
|
-
# correctly can cause issues in the root of your filesystem (use File.join) if you
|
109
|
-
# plan to use this
|
110
|
-
def get_path
|
111
|
-
request_object.path
|
112
|
-
end
|
113
|
-
|
114
|
-
# Get the URI of this request. Unlike the path, the URI is not modified after a rewrite,
|
115
|
-
# and does contain a querystring. Use this if you want the *original* path and query
|
116
|
-
# of the request before it was rewritten
|
117
|
-
def get_uri
|
118
|
-
request_object.uri
|
119
|
-
end
|
120
|
-
|
121
|
-
# Get the request body. In most cases, this will be blank, but for POST requests it may
|
122
|
-
# contain a querystring, and for PUT and UPDATE methods it may contain other data
|
123
|
-
def get_body
|
124
|
-
request_object.body
|
125
|
-
end
|
126
|
-
|
127
|
-
# Get the querystring object as a string before it is parsed
|
128
|
-
def get_querystring
|
129
|
-
request_object.querystring
|
130
|
-
end
|
131
|
-
|
132
|
-
# Set a response header. This will be joined when writing the response with the delimiter ": "
|
133
|
-
# as in regular HTTP Protocol fashion.
|
134
|
-
# Params:
|
135
|
-
# +name+:: The name of the header, e.g. "Content-Type"
|
136
|
-
# +value+:: The value of the header, e.g. "text/html"
|
137
|
-
def set_header name, value
|
138
|
-
response_object.header name, value
|
139
|
-
end
|
140
|
-
|
141
|
-
# Set the content-type of the response. This is a shortcut to the Content-Type
|
142
|
-
# header and takes the full content-type (not fileextension) as an argument
|
143
|
-
# Params:
|
144
|
-
# +raw_type+:: The mime type of the content, e.g. "text/html"
|
145
|
-
def
|
146
|
-
response_object.mime_raw raw_type
|
147
|
-
end
|
148
|
-
|
149
|
-
# Set the content-type of the response. This is a shortcut to the Content-Type
|
150
|
-
# header, and will also lookup the fileextension in the +Waitress::Util+ mime-type
|
151
|
-
# lookup.
|
152
|
-
# Params:
|
153
|
-
# +extension+:: The file extension to map to a mimetype, e.g. ".html"
|
154
|
-
def file_ext extension
|
155
|
-
response_object.mime extension
|
156
|
-
end
|
157
|
-
|
158
|
-
# Write a string to the output buffer. This will write directly to the body of the
|
159
|
-
# response, similar to what 'print()' does for STDOUT. Use this to write data to the
|
160
|
-
# output stream
|
161
|
-
def echo obj
|
162
|
-
str = obj.to_s
|
163
|
-
write str
|
164
|
-
end
|
165
|
-
|
166
|
-
# Write a string to the output buffer, followed by a newline. Similar to echo(),
|
167
|
-
# this will write to the output buffer, but also adds a "\n". This does to the
|
168
|
-
# client output as 'puts()' does to STDOUT. Use this to write data to the output
|
169
|
-
# stream
|
170
|
-
def println obj
|
171
|
-
echo(obj.to_s + "\n")
|
172
|
-
end
|
173
|
-
|
174
|
-
# Write a set of bytes directly to the output stream. Use this if you don't want
|
175
|
-
# to cast to a string as echo() and println() do.
|
176
|
-
def write bytes
|
177
|
-
r = response_object
|
178
|
-
r.body "" if r.body_io.nil?
|
179
|
-
r.body_io.write bytes
|
180
|
-
end
|
181
|
-
|
182
|
-
end
|
1
|
+
# The Kernel Module provides global methods that will provide the 'builtins' for .wrb files
|
2
|
+
# and handlers. This is used to prevent verbose access of a namespace like Waitress::Global,
|
3
|
+
# and instead provide them here. Because requests are handled in new Processes, these values
|
4
|
+
# will change in each request and will not interfere.
|
5
|
+
module ::Kernel
|
6
|
+
|
7
|
+
# The +Waitress::Response+ object being used
|
8
|
+
def response_object
|
9
|
+
$RESPONSE
|
10
|
+
end
|
11
|
+
|
12
|
+
# The +Waitress::Request+ object being used
|
13
|
+
def request_object
|
14
|
+
$REQUEST
|
15
|
+
end
|
16
|
+
|
17
|
+
# Prepare the Kernel, by linking global variables
|
18
|
+
def kernel_prepare
|
19
|
+
$METHOD = get_method
|
20
|
+
$HEADERS = get_headers
|
21
|
+
$PATH = get_path
|
22
|
+
$URI = get_uri
|
23
|
+
$BODY = get_body
|
24
|
+
end
|
25
|
+
|
26
|
+
# Automatically load a library header into this file in the form of HTML.
|
27
|
+
# This will load a library in the VHost's libs/ folder, or any lib defined in the
|
28
|
+
# VHost's config.rb file with the name given. JS libraries will be linked with the
|
29
|
+
# <script> tag, whilst css files will be linked with the <link rel="stylesheet">
|
30
|
+
# tag. This is the recommended way of handling library loading.
|
31
|
+
# Params:
|
32
|
+
# +name+:: The name of the lib (the filename), or the name of the library as bound
|
33
|
+
# in the config.rb file.
|
34
|
+
def lib name
|
35
|
+
name = name.to_sym
|
36
|
+
type = $VHOST.libraries[name][:type]
|
37
|
+
libhome = $VHOST.liburi
|
38
|
+
if type == :js
|
39
|
+
echo "<script type='text/javascript' src='/#{libhome}/#{name}'></script>"
|
40
|
+
elsif type == :css
|
41
|
+
echo "<link rel='stylesheet' href='/#{libhome}/#{name}'></link>"
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
# Automatically load a Library Combo into this file. This will consecutively load
|
46
|
+
# all the libraries bound to the combination with the given name as defined in the
|
47
|
+
# VHost's config.rb file. This will call lib() for each of these libraries.
|
48
|
+
# Params:
|
49
|
+
# +name+:: The name of the combo to load
|
50
|
+
def combo name
|
51
|
+
name = name.to_sym
|
52
|
+
combo_arr = $VHOST.combos[name]
|
53
|
+
combo_arr.each { |n| lib(n) }
|
54
|
+
end
|
55
|
+
|
56
|
+
# Include another .wrb, .rb or any other file in the load path of the VHost into this
|
57
|
+
# file. If this file is .wrb or .rb, it will be evaluated. If it is another type of file
|
58
|
+
# (e.g. html), it will be directly echoed to the output buffer
|
59
|
+
# Params:
|
60
|
+
# +filename+:: The name of the file, relative to the loadpath
|
61
|
+
def includes filename
|
62
|
+
Waitress::Chef.include_file filename
|
63
|
+
end
|
64
|
+
|
65
|
+
# Include another .wrb, .rb or any other file in this file. If this file is
|
66
|
+
# .wrb or .rb, it will be evaluated. If it is another type of file
|
67
|
+
# (e.g. html), it will be directly echoed to the output buffer
|
68
|
+
# Params:
|
69
|
+
# +filename+:: The absolute filename of the file to load, anywhere in the filesystem
|
70
|
+
def includes_file filename
|
71
|
+
Waitress::Chef.include_absfile filename
|
72
|
+
end
|
73
|
+
|
74
|
+
# Returns a Hash of the GET query of the request. This may be an empty array
|
75
|
+
# if querystring was present
|
76
|
+
def get
|
77
|
+
request_object.get_query
|
78
|
+
end
|
79
|
+
|
80
|
+
# Returns a Hash of the POST query of the request. This may be an empty array
|
81
|
+
# if the body is not a valid querystring, or an exception raised if there was
|
82
|
+
# an error in parsing.
|
83
|
+
def post
|
84
|
+
request_object.post_query
|
85
|
+
end
|
86
|
+
|
87
|
+
# Get a header from the HTTP Request. This will fetch the header by the given
|
88
|
+
# name from the request object. Keep in mind that in requests, Headers are fully
|
89
|
+
# capitalized and any hyphens replaced with underscores (e.g. Content-Type becomes
|
90
|
+
# CONTENT_TYPE)
|
91
|
+
def get_header name
|
92
|
+
request_object.headers[name]
|
93
|
+
end
|
94
|
+
|
95
|
+
# Return the full list of headers available in the request object.
|
96
|
+
def get_headers
|
97
|
+
request_object.headers
|
98
|
+
end
|
99
|
+
|
100
|
+
# Returns the HTTP method that was used to retrieve this page (GET, POST, UPDATE,
|
101
|
+
# DELETE, PUT, etc)
|
102
|
+
def get_method
|
103
|
+
request_object.method
|
104
|
+
end
|
105
|
+
|
106
|
+
# Get the path of this request. This is after a URL rewrite, and does not contain
|
107
|
+
# a querystring. Be careful with these, as they start with a "/" and if not joined
|
108
|
+
# correctly can cause issues in the root of your filesystem (use File.join) if you
|
109
|
+
# plan to use this
|
110
|
+
def get_path
|
111
|
+
request_object.path
|
112
|
+
end
|
113
|
+
|
114
|
+
# Get the URI of this request. Unlike the path, the URI is not modified after a rewrite,
|
115
|
+
# and does contain a querystring. Use this if you want the *original* path and query
|
116
|
+
# of the request before it was rewritten
|
117
|
+
def get_uri
|
118
|
+
request_object.uri
|
119
|
+
end
|
120
|
+
|
121
|
+
# Get the request body. In most cases, this will be blank, but for POST requests it may
|
122
|
+
# contain a querystring, and for PUT and UPDATE methods it may contain other data
|
123
|
+
def get_body
|
124
|
+
request_object.body
|
125
|
+
end
|
126
|
+
|
127
|
+
# Get the querystring object as a string before it is parsed
|
128
|
+
def get_querystring
|
129
|
+
request_object.querystring
|
130
|
+
end
|
131
|
+
|
132
|
+
# Set a response header. This will be joined when writing the response with the delimiter ": "
|
133
|
+
# as in regular HTTP Protocol fashion.
|
134
|
+
# Params:
|
135
|
+
# +name+:: The name of the header, e.g. "Content-Type"
|
136
|
+
# +value+:: The value of the header, e.g. "text/html"
|
137
|
+
def set_header name, value
|
138
|
+
response_object.header name, value
|
139
|
+
end
|
140
|
+
|
141
|
+
# Set the content-type of the response. This is a shortcut to the Content-Type
|
142
|
+
# header and takes the full content-type (not fileextension) as an argument
|
143
|
+
# Params:
|
144
|
+
# +raw_type+:: The mime type of the content, e.g. "text/html"
|
145
|
+
def set_content_type raw_type
|
146
|
+
response_object.mime_raw raw_type
|
147
|
+
end
|
148
|
+
|
149
|
+
# Set the content-type of the response. This is a shortcut to the Content-Type
|
150
|
+
# header, and will also lookup the fileextension in the +Waitress::Util+ mime-type
|
151
|
+
# lookup.
|
152
|
+
# Params:
|
153
|
+
# +extension+:: The file extension to map to a mimetype, e.g. ".html"
|
154
|
+
def file_ext extension
|
155
|
+
response_object.mime extension
|
156
|
+
end
|
157
|
+
|
158
|
+
# Write a string to the output buffer. This will write directly to the body of the
|
159
|
+
# response, similar to what 'print()' does for STDOUT. Use this to write data to the
|
160
|
+
# output stream
|
161
|
+
def echo obj
|
162
|
+
str = obj.to_s
|
163
|
+
write str
|
164
|
+
end
|
165
|
+
|
166
|
+
# Write a string to the output buffer, followed by a newline. Similar to echo(),
|
167
|
+
# this will write to the output buffer, but also adds a "\n". This does to the
|
168
|
+
# client output as 'puts()' does to STDOUT. Use this to write data to the output
|
169
|
+
# stream
|
170
|
+
def println obj
|
171
|
+
echo(obj.to_s + "\n")
|
172
|
+
end
|
173
|
+
|
174
|
+
# Write a set of bytes directly to the output stream. Use this if you don't want
|
175
|
+
# to cast to a string as echo() and println() do.
|
176
|
+
def write bytes
|
177
|
+
r = response_object
|
178
|
+
r.body "" if r.body_io.nil?
|
179
|
+
r.body_io.write bytes
|
180
|
+
end
|
181
|
+
|
182
|
+
end
|
data/lib/waitress/parse/query.rb
CHANGED
@@ -1,60 +1,60 @@
|
|
1
|
-
module Waitress
|
2
|
-
# A lot of this class uses methods from Rack::QueryParser in order to Parse
|
3
|
-
# a given QueryString into a Hash of key/value pairs
|
4
|
-
class QueryParser
|
5
|
-
require 'uri'
|
6
|
-
|
7
|
-
DEFAULT_SEP = /[&;] */n
|
8
|
-
|
9
|
-
# Unescape a HTTP URL to regular text. e.g. %20 becomes a space (" ")
|
10
|
-
def self.unescape str, enc=Encoding::UTF_8
|
11
|
-
URI.decode_www_form_component(str, enc)
|
12
|
-
end
|
13
|
-
|
14
|
-
# Parse the given QueryString into a hash of key/value pairs
|
15
|
-
def self.parse qs
|
16
|
-
return {} if qs.nil? || qs.empty?
|
17
|
-
results = {}
|
18
|
-
(qs || '').split(DEFAULT_SEP).each do |p|
|
19
|
-
k, v = p.split('='.freeze, 2).map! { |s| unescape(s) }
|
20
|
-
|
21
|
-
normalize results, k, v
|
22
|
-
end
|
23
|
-
results
|
24
|
-
end
|
25
|
-
|
26
|
-
def self.normalize hash, name, v
|
27
|
-
name =~ %r(\A[\[\]]*([^\[\]]+)\]*)
|
28
|
-
k = $1 || ''
|
29
|
-
after = $' || ''
|
30
|
-
|
31
|
-
return if k.empty?
|
32
|
-
|
33
|
-
if after == ""
|
34
|
-
hash[k] = v
|
35
|
-
elsif after == "["
|
36
|
-
hash[name] = v
|
37
|
-
elsif after == "[]"
|
38
|
-
hash[k] ||= []
|
39
|
-
raise TypeError, "expected Array (got #{hash[k].class.name}) for param `#{k}'" unless hash[k].is_a?(Array)
|
40
|
-
hash[k] << v
|
41
|
-
elsif after =~ %r(^\[\]\[([^\[\]]+)\]$) || after =~ %r(^\[\](.+)$)
|
42
|
-
child_key = $1
|
43
|
-
hash[k] ||= []
|
44
|
-
raise TypeError, "expected Array (got #{hash[k].class.name}) for param `#{k}'" unless hash[k].is_a?(Array)
|
45
|
-
if hash[k].last.is_a?(Hash) && !hash[k].last.key?(child_key)
|
46
|
-
normalize(hash[k].last, child_key, v)
|
47
|
-
else
|
48
|
-
hash[k] << normalize({}, child_key, v)
|
49
|
-
end
|
50
|
-
else
|
51
|
-
hash[k] ||= {}
|
52
|
-
raise TypeError, "expected Hash (got #{hash[k].class.name}) for param `#{k}'" unless hash[k].is_a?(Hash)
|
53
|
-
hash[k] =
|
54
|
-
end
|
55
|
-
|
56
|
-
hash
|
57
|
-
end
|
58
|
-
|
59
|
-
end
|
60
|
-
end
|
1
|
+
module Waitress
|
2
|
+
# A lot of this class uses methods from Rack::QueryParser in order to Parse
|
3
|
+
# a given QueryString into a Hash of key/value pairs
|
4
|
+
class QueryParser
|
5
|
+
require 'uri'
|
6
|
+
|
7
|
+
DEFAULT_SEP = /[&;] */n
|
8
|
+
|
9
|
+
# Unescape a HTTP URL to regular text. e.g. %20 becomes a space (" ")
|
10
|
+
def self.unescape str, enc=Encoding::UTF_8
|
11
|
+
URI.decode_www_form_component(str, enc)
|
12
|
+
end
|
13
|
+
|
14
|
+
# Parse the given QueryString into a hash of key/value pairs
|
15
|
+
def self.parse qs
|
16
|
+
return {} if qs.nil? || qs.empty?
|
17
|
+
results = {}
|
18
|
+
(qs || '').split(DEFAULT_SEP).each do |p|
|
19
|
+
k, v = p.split('='.freeze, 2).map! { |s| unescape(s) }
|
20
|
+
|
21
|
+
normalize results, k, v
|
22
|
+
end
|
23
|
+
results
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.normalize hash, name, v
|
27
|
+
name =~ %r(\A[\[\]]*([^\[\]]+)\]*)
|
28
|
+
k = $1 || ''
|
29
|
+
after = $' || ''
|
30
|
+
|
31
|
+
return if k.empty?
|
32
|
+
|
33
|
+
if after == ""
|
34
|
+
hash[k] = v
|
35
|
+
elsif after == "["
|
36
|
+
hash[name] = v
|
37
|
+
elsif after == "[]"
|
38
|
+
hash[k] ||= []
|
39
|
+
raise TypeError, "expected Array (got #{hash[k].class.name}) for param `#{k}'" unless hash[k].is_a?(Array)
|
40
|
+
hash[k] << v
|
41
|
+
elsif after =~ %r(^\[\]\[([^\[\]]+)\]$) || after =~ %r(^\[\](.+)$)
|
42
|
+
child_key = $1
|
43
|
+
hash[k] ||= []
|
44
|
+
raise TypeError, "expected Array (got #{hash[k].class.name}) for param `#{k}'" unless hash[k].is_a?(Array)
|
45
|
+
if hash[k].last.is_a?(Hash) && !hash[k].last.key?(child_key)
|
46
|
+
normalize(hash[k].last, child_key, v)
|
47
|
+
else
|
48
|
+
hash[k] << normalize({}, child_key, v)
|
49
|
+
end
|
50
|
+
else
|
51
|
+
hash[k] ||= {}
|
52
|
+
raise TypeError, "expected Hash (got #{hash[k].class.name}) for param `#{k}'" unless hash[k].is_a?(Hash)
|
53
|
+
hash[k] = normalize(hash[k], after, v)
|
54
|
+
end
|
55
|
+
|
56
|
+
hash
|
57
|
+
end
|
58
|
+
|
59
|
+
end
|
60
|
+
end
|