webrick 1.3.1 → 1.4.3
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of webrick might be problematic. Click here for more details.
- checksums.yaml +7 -0
- data/lib/webrick.rb +6 -6
- data/lib/webrick/accesslog.rb +9 -1
- data/lib/webrick/cgi.rb +58 -5
- data/lib/webrick/compat.rb +2 -1
- data/lib/webrick/config.rb +47 -10
- data/lib/webrick/cookie.rb +69 -7
- data/lib/webrick/htmlutils.rb +4 -2
- data/lib/webrick/httpauth.rb +6 -5
- data/lib/webrick/httpauth/authenticator.rb +13 -8
- data/lib/webrick/httpauth/basicauth.rb +16 -8
- data/lib/webrick/httpauth/digestauth.rb +35 -32
- data/lib/webrick/httpauth/htdigest.rb +12 -8
- data/lib/webrick/httpauth/htgroup.rb +10 -6
- data/lib/webrick/httpauth/htpasswd.rb +46 -9
- data/lib/webrick/httpauth/userdb.rb +1 -0
- data/lib/webrick/httpproxy.rb +93 -48
- data/lib/webrick/httprequest.rb +192 -27
- data/lib/webrick/httpresponse.rb +182 -62
- data/lib/webrick/https.rb +90 -2
- data/lib/webrick/httpserver.rb +45 -15
- data/lib/webrick/httpservlet.rb +6 -5
- data/lib/webrick/httpservlet/abstract.rb +5 -6
- data/lib/webrick/httpservlet/cgi_runner.rb +3 -2
- data/lib/webrick/httpservlet/cgihandler.rb +22 -10
- data/lib/webrick/httpservlet/erbhandler.rb +4 -3
- data/lib/webrick/httpservlet/filehandler.rb +136 -65
- data/lib/webrick/httpservlet/prochandler.rb +15 -1
- data/lib/webrick/httpstatus.rb +24 -14
- data/lib/webrick/httputils.rb +132 -13
- data/lib/webrick/httpversion.rb +28 -1
- data/lib/webrick/log.rb +25 -5
- data/lib/webrick/server.rb +234 -74
- data/lib/webrick/ssl.rb +100 -12
- data/lib/webrick/utils.rb +98 -69
- data/lib/webrick/version.rb +6 -1
- metadata +66 -72
- data/README.txt +0 -21
- data/sample/webrick/demo-app.rb +0 -66
- data/sample/webrick/demo-multipart.cgi +0 -12
- data/sample/webrick/demo-servlet.rb +0 -6
- data/sample/webrick/demo-urlencoded.cgi +0 -12
- data/sample/webrick/hello.cgi +0 -11
- data/sample/webrick/hello.rb +0 -8
- data/sample/webrick/httpd.rb +0 -23
- data/sample/webrick/httpproxy.rb +0 -25
- data/sample/webrick/httpsd.rb +0 -33
- data/test/openssl/utils.rb +0 -313
- data/test/ruby/envutil.rb +0 -208
- data/test/webrick/test_cgi.rb +0 -134
- data/test/webrick/test_cookie.rb +0 -131
- data/test/webrick/test_filehandler.rb +0 -285
- data/test/webrick/test_httpauth.rb +0 -167
- data/test/webrick/test_httpproxy.rb +0 -282
- data/test/webrick/test_httprequest.rb +0 -411
- data/test/webrick/test_httpresponse.rb +0 -49
- data/test/webrick/test_httpserver.rb +0 -305
- data/test/webrick/test_httputils.rb +0 -96
- data/test/webrick/test_httpversion.rb +0 -40
- data/test/webrick/test_server.rb +0 -67
- data/test/webrick/test_utils.rb +0 -64
- data/test/webrick/utils.rb +0 -58
- data/test/webrick/webrick.cgi +0 -36
- data/test/webrick/webrick_long_filename.cgi +0 -36
data/lib/webrick/httpproxy.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: false
|
1
2
|
#
|
2
3
|
# httpproxy.rb -- HTTPProxy Class
|
3
4
|
#
|
@@ -9,22 +10,21 @@
|
|
9
10
|
# $IPR: httpproxy.rb,v 1.18 2003/03/08 18:58:10 gotoyuzo Exp $
|
10
11
|
# $kNotwork: straw.rb,v 1.3 2002/02/12 15:13:07 gotoken Exp $
|
11
12
|
|
12
|
-
|
13
|
+
require_relative "httpserver"
|
13
14
|
require "net/http"
|
14
15
|
|
15
|
-
Net::HTTP::version_1_2 if RUBY_VERSION < "1.7"
|
16
|
-
|
17
16
|
module WEBrick
|
18
|
-
|
19
|
-
|
17
|
+
|
18
|
+
NullReader = Object.new # :nodoc:
|
19
|
+
class << NullReader # :nodoc:
|
20
20
|
def read(*args)
|
21
21
|
nil
|
22
22
|
end
|
23
23
|
alias gets read
|
24
24
|
end
|
25
25
|
|
26
|
-
FakeProxyURI = Object.new
|
27
|
-
class << FakeProxyURI
|
26
|
+
FakeProxyURI = Object.new # :nodoc:
|
27
|
+
class << FakeProxyURI # :nodoc:
|
28
28
|
def method_missing(meth, *args)
|
29
29
|
if %w(scheme host port path query userinfo).member?(meth.to_s)
|
30
30
|
return nil
|
@@ -33,8 +33,38 @@ module WEBrick
|
|
33
33
|
end
|
34
34
|
end
|
35
35
|
|
36
|
+
# :startdoc:
|
37
|
+
|
36
38
|
##
|
37
39
|
# An HTTP Proxy server which proxies GET, HEAD and POST requests.
|
40
|
+
#
|
41
|
+
# To create a simple proxy server:
|
42
|
+
#
|
43
|
+
# require 'webrick'
|
44
|
+
# require 'webrick/httpproxy'
|
45
|
+
#
|
46
|
+
# proxy = WEBrick::HTTPProxyServer.new Port: 8000
|
47
|
+
#
|
48
|
+
# trap 'INT' do proxy.shutdown end
|
49
|
+
# trap 'TERM' do proxy.shutdown end
|
50
|
+
#
|
51
|
+
# proxy.start
|
52
|
+
#
|
53
|
+
# See ::new for proxy-specific configuration items.
|
54
|
+
#
|
55
|
+
# == Modifying proxied responses
|
56
|
+
#
|
57
|
+
# To modify content the proxy server returns use the +:ProxyContentHandler+
|
58
|
+
# option:
|
59
|
+
#
|
60
|
+
# handler = proc do |req, res|
|
61
|
+
# if res['content-type'] == 'text/plain' then
|
62
|
+
# res.body << "\nThis content was proxied!\n"
|
63
|
+
# end
|
64
|
+
# end
|
65
|
+
#
|
66
|
+
# proxy =
|
67
|
+
# WEBrick::HTTPProxyServer.new Port: 8000, ProxyContentHandler: handler
|
38
68
|
|
39
69
|
class HTTPProxyServer < HTTPServer
|
40
70
|
|
@@ -46,7 +76,7 @@ module WEBrick
|
|
46
76
|
# request
|
47
77
|
# :ProxyVia:: Appended to the via header
|
48
78
|
# :ProxyURI:: The proxy server's URI
|
49
|
-
# :ProxyContentHandler:: Called with a request and
|
79
|
+
# :ProxyContentHandler:: Called with a request and response and allows
|
50
80
|
# modification of the response
|
51
81
|
# :ProxyTimeout:: Sets the proxy timeouts to 30 seconds for open and 60
|
52
82
|
# seconds for read operations
|
@@ -57,6 +87,7 @@ module WEBrick
|
|
57
87
|
@via = "#{c[:HTTPVersion]} #{c[:ServerName]}:#{c[:Port]}"
|
58
88
|
end
|
59
89
|
|
90
|
+
# :stopdoc:
|
60
91
|
def service(req, res)
|
61
92
|
if req.request_method == "CONNECT"
|
62
93
|
do_CONNECT(req, res)
|
@@ -112,7 +143,7 @@ module WEBrick
|
|
112
143
|
if proxy = proxy_uri(req, res)
|
113
144
|
proxy_request_line = "CONNECT #{host}:#{port} HTTP/1.0"
|
114
145
|
if proxy.userinfo
|
115
|
-
credentials = "Basic " + [proxy.userinfo].pack("
|
146
|
+
credentials = "Basic " + [proxy.userinfo].pack("m0")
|
116
147
|
end
|
117
148
|
host, port = proxy.host, proxy.port
|
118
149
|
end
|
@@ -126,12 +157,12 @@ module WEBrick
|
|
126
157
|
os << proxy_request_line << CRLF
|
127
158
|
@logger.debug("CONNECT: > #{proxy_request_line}")
|
128
159
|
if credentials
|
129
|
-
@logger.debug("CONNECT: sending
|
160
|
+
@logger.debug("CONNECT: sending credentials")
|
130
161
|
os << "Proxy-Authorization: " << credentials << CRLF
|
131
162
|
end
|
132
163
|
os << CRLF
|
133
164
|
proxy_status_line = os.gets(LF)
|
134
|
-
@logger.debug("CONNECT: read
|
165
|
+
@logger.debug("CONNECT: read Status-Line from the upstream server")
|
135
166
|
@logger.debug("CONNECT: < #{proxy_status_line}")
|
136
167
|
if %r{^HTTP/\d+\.\d+\s+200\s*} =~ proxy_status_line
|
137
168
|
while line = os.gets(LF)
|
@@ -154,7 +185,7 @@ module WEBrick
|
|
154
185
|
res.send_response(ua)
|
155
186
|
access_log(@config, req, res)
|
156
187
|
|
157
|
-
# Should clear request-line not to send the
|
188
|
+
# Should clear request-line not to send the response twice.
|
158
189
|
# see: HTTPServer#run
|
159
190
|
req.parse(NullReader) rescue nil
|
160
191
|
end
|
@@ -162,16 +193,16 @@ module WEBrick
|
|
162
193
|
begin
|
163
194
|
while fds = IO::select([ua, os])
|
164
195
|
if fds[0].member?(ua)
|
165
|
-
buf = ua.
|
196
|
+
buf = ua.readpartial(1024);
|
166
197
|
@logger.debug("CONNECT: #{buf.bytesize} byte from User-Agent")
|
167
|
-
os.
|
198
|
+
os.write(buf)
|
168
199
|
elsif fds[0].member?(os)
|
169
|
-
buf = os.
|
200
|
+
buf = os.readpartial(1024);
|
170
201
|
@logger.debug("CONNECT: #{buf.bytesize} byte from #{host}:#{port}")
|
171
|
-
ua.
|
202
|
+
ua.write(buf)
|
172
203
|
end
|
173
204
|
end
|
174
|
-
rescue
|
205
|
+
rescue
|
175
206
|
os.close
|
176
207
|
@logger.debug("CONNECT #{host}:#{port}: closed")
|
177
208
|
end
|
@@ -180,21 +211,15 @@ module WEBrick
|
|
180
211
|
end
|
181
212
|
|
182
213
|
def do_GET(req, res)
|
183
|
-
perform_proxy_request(req, res
|
184
|
-
http.get(path, header)
|
185
|
-
end
|
214
|
+
perform_proxy_request(req, res, Net::HTTP::Get)
|
186
215
|
end
|
187
216
|
|
188
217
|
def do_HEAD(req, res)
|
189
|
-
perform_proxy_request(req, res
|
190
|
-
http.head(path, header)
|
191
|
-
end
|
218
|
+
perform_proxy_request(req, res, Net::HTTP::Head)
|
192
219
|
end
|
193
220
|
|
194
221
|
def do_POST(req, res)
|
195
|
-
perform_proxy_request(req, res
|
196
|
-
http.post(path, req.body || "", header)
|
197
|
-
end
|
222
|
+
perform_proxy_request(req, res, Net::HTTP::Post, req.body_reader)
|
198
223
|
end
|
199
224
|
|
200
225
|
def do_OPTIONS(req, res)
|
@@ -263,43 +288,63 @@ module WEBrick
|
|
263
288
|
if upstream = proxy_uri(req, res)
|
264
289
|
if upstream.userinfo
|
265
290
|
header['proxy-authorization'] =
|
266
|
-
"Basic " + [upstream.userinfo].pack("
|
291
|
+
"Basic " + [upstream.userinfo].pack("m0")
|
267
292
|
end
|
268
293
|
return upstream
|
269
294
|
end
|
270
295
|
return FakeProxyURI
|
271
296
|
end
|
272
297
|
|
273
|
-
def perform_proxy_request(req, res)
|
298
|
+
def perform_proxy_request(req, res, req_class, body_stream = nil)
|
274
299
|
uri = req.request_uri
|
275
300
|
path = uri.path.dup
|
276
301
|
path << "?" << uri.query if uri.query
|
277
302
|
header = setup_proxy_header(req, res)
|
278
303
|
upstream = setup_upstream_proxy_authentication(req, res, header)
|
279
|
-
response = nil
|
280
304
|
|
305
|
+
body_tmp = []
|
281
306
|
http = Net::HTTP.new(uri.host, uri.port, upstream.host, upstream.port)
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
307
|
+
req_fib = Fiber.new do
|
308
|
+
http.start do
|
309
|
+
if @config[:ProxyTimeout]
|
310
|
+
################################## these issues are
|
311
|
+
http.open_timeout = 30 # secs # necessary (maybe because
|
312
|
+
http.read_timeout = 60 # secs # Ruby's bug, but why?)
|
313
|
+
##################################
|
314
|
+
end
|
315
|
+
if body_stream && req['transfer-encoding'] =~ /\bchunked\b/i
|
316
|
+
header['Transfer-Encoding'] = 'chunked'
|
317
|
+
end
|
318
|
+
http_req = req_class.new(path, header)
|
319
|
+
http_req.body_stream = body_stream if body_stream
|
320
|
+
http.request(http_req) do |response|
|
321
|
+
# Persistent connection requirements are mysterious for me.
|
322
|
+
# So I will close the connection in every response.
|
323
|
+
res['proxy-connection'] = "close"
|
324
|
+
res['connection'] = "close"
|
325
|
+
|
326
|
+
# stream Net::HTTP::HTTPResponse to WEBrick::HTTPResponse
|
327
|
+
res.status = response.code.to_i
|
328
|
+
res.chunked = response.chunked?
|
329
|
+
choose_header(response, res)
|
330
|
+
set_cookie(response, res)
|
331
|
+
set_via(res)
|
332
|
+
response.read_body do |buf|
|
333
|
+
body_tmp << buf
|
334
|
+
Fiber.yield # wait for res.body Proc#call
|
335
|
+
end
|
336
|
+
end # http.request
|
337
|
+
end
|
338
|
+
end
|
339
|
+
req_fib.resume # read HTTP response headers and first chunk of the body
|
340
|
+
res.body = ->(socket) do
|
341
|
+
while buf = body_tmp.shift
|
342
|
+
socket.write(buf)
|
343
|
+
buf.clear
|
344
|
+
req_fib.resume # continue response.read_body
|
288
345
|
end
|
289
|
-
response = yield(http, path, header)
|
290
346
|
end
|
291
|
-
|
292
|
-
# Persistent connection requirements are mysterious for me.
|
293
|
-
# So I will close the connection in every response.
|
294
|
-
res['proxy-connection'] = "close"
|
295
|
-
res['connection'] = "close"
|
296
|
-
|
297
|
-
# Convert Net::HTTP::HTTPResponse to WEBrick::HTTPResponse
|
298
|
-
res.status = response.code.to_i
|
299
|
-
choose_header(response, res)
|
300
|
-
set_cookie(response, res)
|
301
|
-
set_via(res)
|
302
|
-
res.body = response.body
|
303
347
|
end
|
348
|
+
# :stopdoc:
|
304
349
|
end
|
305
350
|
end
|
data/lib/webrick/httprequest.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: false
|
1
2
|
#
|
2
3
|
# httprequest.rb -- HTTPRequest Class
|
3
4
|
#
|
@@ -9,39 +10,145 @@
|
|
9
10
|
# $IPR: httprequest.rb,v 1.64 2003/07/13 17:18:22 gotoyuzo Exp $
|
10
11
|
|
11
12
|
require 'uri'
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
require_relative 'httpversion'
|
14
|
+
require_relative 'httpstatus'
|
15
|
+
require_relative 'httputils'
|
16
|
+
require_relative 'cookie'
|
16
17
|
|
17
18
|
module WEBrick
|
18
19
|
|
19
20
|
##
|
20
|
-
# An HTTP request.
|
21
|
+
# An HTTP request. This is consumed by service and do_* methods in
|
22
|
+
# WEBrick servlets
|
23
|
+
|
21
24
|
class HTTPRequest
|
22
25
|
|
23
|
-
BODY_CONTAINABLE_METHODS = [ "POST", "PUT" ]
|
26
|
+
BODY_CONTAINABLE_METHODS = [ "POST", "PUT" ] # :nodoc:
|
24
27
|
|
25
28
|
# :section: Request line
|
29
|
+
|
30
|
+
##
|
31
|
+
# The complete request line such as:
|
32
|
+
#
|
33
|
+
# GET / HTTP/1.1
|
34
|
+
|
26
35
|
attr_reader :request_line
|
27
|
-
|
36
|
+
|
37
|
+
##
|
38
|
+
# The request method, GET, POST, PUT, etc.
|
39
|
+
|
40
|
+
attr_reader :request_method
|
41
|
+
|
42
|
+
##
|
43
|
+
# The unparsed URI of the request
|
44
|
+
|
45
|
+
attr_reader :unparsed_uri
|
46
|
+
|
47
|
+
##
|
48
|
+
# The HTTP version of the request
|
49
|
+
|
50
|
+
attr_reader :http_version
|
28
51
|
|
29
52
|
# :section: Request-URI
|
30
|
-
|
31
|
-
|
53
|
+
|
54
|
+
##
|
55
|
+
# The parsed URI of the request
|
56
|
+
|
57
|
+
attr_reader :request_uri
|
58
|
+
|
59
|
+
##
|
60
|
+
# The request path
|
61
|
+
|
62
|
+
attr_reader :path
|
63
|
+
|
64
|
+
##
|
65
|
+
# The script name (CGI variable)
|
66
|
+
|
67
|
+
attr_accessor :script_name
|
68
|
+
|
69
|
+
##
|
70
|
+
# The path info (CGI variable)
|
71
|
+
|
72
|
+
attr_accessor :path_info
|
73
|
+
|
74
|
+
##
|
75
|
+
# The query from the URI of the request
|
76
|
+
|
77
|
+
attr_accessor :query_string
|
32
78
|
|
33
79
|
# :section: Header and entity body
|
34
|
-
|
35
|
-
|
36
|
-
|
80
|
+
|
81
|
+
##
|
82
|
+
# The raw header of the request
|
83
|
+
|
84
|
+
attr_reader :raw_header
|
85
|
+
|
86
|
+
##
|
87
|
+
# The parsed header of the request
|
88
|
+
|
89
|
+
attr_reader :header
|
90
|
+
|
91
|
+
##
|
92
|
+
# The parsed request cookies
|
93
|
+
|
94
|
+
attr_reader :cookies
|
95
|
+
|
96
|
+
##
|
97
|
+
# The Accept header value
|
98
|
+
|
99
|
+
attr_reader :accept
|
100
|
+
|
101
|
+
##
|
102
|
+
# The Accept-Charset header value
|
103
|
+
|
104
|
+
attr_reader :accept_charset
|
105
|
+
|
106
|
+
##
|
107
|
+
# The Accept-Encoding header value
|
108
|
+
|
109
|
+
attr_reader :accept_encoding
|
110
|
+
|
111
|
+
##
|
112
|
+
# The Accept-Language header value
|
113
|
+
|
114
|
+
attr_reader :accept_language
|
37
115
|
|
38
116
|
# :section:
|
117
|
+
|
118
|
+
##
|
119
|
+
# The remote user (CGI variable)
|
120
|
+
|
39
121
|
attr_accessor :user
|
40
|
-
|
122
|
+
|
123
|
+
##
|
124
|
+
# The socket address of the server
|
125
|
+
|
126
|
+
attr_reader :addr
|
127
|
+
|
128
|
+
##
|
129
|
+
# The socket address of the client
|
130
|
+
|
131
|
+
attr_reader :peeraddr
|
132
|
+
|
133
|
+
##
|
134
|
+
# Hash of request attributes
|
135
|
+
|
41
136
|
attr_reader :attributes
|
137
|
+
|
138
|
+
##
|
139
|
+
# Is this a keep-alive connection?
|
140
|
+
|
42
141
|
attr_reader :keep_alive
|
142
|
+
|
143
|
+
##
|
144
|
+
# The local time this request was received
|
145
|
+
|
43
146
|
attr_reader :request_time
|
44
147
|
|
148
|
+
##
|
149
|
+
# Creates a new HTTP request. WEBrick::Config::HTTP is the default
|
150
|
+
# configuration.
|
151
|
+
|
45
152
|
def initialize(config)
|
46
153
|
@config = config
|
47
154
|
@buffer_size = @config[:InputBufferSize]
|
@@ -78,6 +185,10 @@ module WEBrick
|
|
78
185
|
@forwarded_server = @forwarded_for = nil
|
79
186
|
end
|
80
187
|
|
188
|
+
##
|
189
|
+
# Parses a request from +socket+. This is called internally by
|
190
|
+
# WEBrick::HTTPServer.
|
191
|
+
|
81
192
|
def parse(socket=nil)
|
82
193
|
@socket = socket
|
83
194
|
begin
|
@@ -126,21 +237,52 @@ module WEBrick
|
|
126
237
|
end
|
127
238
|
end
|
128
239
|
|
240
|
+
##
|
129
241
|
# Generate HTTP/1.1 100 continue response if the client expects it,
|
130
242
|
# otherwise does nothing.
|
131
|
-
|
243
|
+
|
244
|
+
def continue # :nodoc:
|
132
245
|
if self['expect'] == '100-continue' && @config[:HTTPVersion] >= "1.1"
|
133
246
|
@socket << "HTTP/#{@config[:HTTPVersion]} 100 continue#{CRLF}#{CRLF}"
|
134
247
|
@header.delete('expect')
|
135
248
|
end
|
136
249
|
end
|
137
250
|
|
138
|
-
|
251
|
+
##
|
252
|
+
# Returns the request body.
|
253
|
+
|
254
|
+
def body(&block) # :yields: body_chunk
|
139
255
|
block ||= Proc.new{|chunk| @body << chunk }
|
140
256
|
read_body(@socket, block)
|
141
257
|
@body.empty? ? nil : @body
|
142
258
|
end
|
143
259
|
|
260
|
+
##
|
261
|
+
# Prepares the HTTPRequest object for use as the
|
262
|
+
# source for IO.copy_stream
|
263
|
+
|
264
|
+
def body_reader
|
265
|
+
@body_tmp = []
|
266
|
+
@body_rd = Fiber.new do
|
267
|
+
body do |buf|
|
268
|
+
@body_tmp << buf
|
269
|
+
Fiber.yield
|
270
|
+
end
|
271
|
+
end
|
272
|
+
@body_rd.resume # grab the first chunk and yield
|
273
|
+
self
|
274
|
+
end
|
275
|
+
|
276
|
+
# for IO.copy_stream. Note: we may return a larger string than +size+
|
277
|
+
# here; but IO.copy_stream does not care.
|
278
|
+
def readpartial(size, buf = ''.b) # :nodoc
|
279
|
+
res = @body_tmp.shift or raise EOFError, 'end of file reached'
|
280
|
+
buf.replace(res)
|
281
|
+
res.clear
|
282
|
+
@body_rd.resume # get more chunks
|
283
|
+
buf
|
284
|
+
end
|
285
|
+
|
144
286
|
##
|
145
287
|
# Request query as a Hash
|
146
288
|
|
@@ -237,11 +379,14 @@ module WEBrick
|
|
237
379
|
ret
|
238
380
|
end
|
239
381
|
|
240
|
-
|
382
|
+
##
|
383
|
+
# Consumes any remaining body and updates keep-alive status
|
384
|
+
|
385
|
+
def fixup() # :nodoc:
|
241
386
|
begin
|
242
387
|
body{|chunk| } # read remaining body
|
243
388
|
rescue HTTPStatus::Error => ex
|
244
|
-
@logger.error("HTTPRequest#fixup: #{ex.class}
|
389
|
+
@logger.error("HTTPRequest#fixup: #{ex.class} occurred.")
|
245
390
|
@keep_alive = false
|
246
391
|
rescue => ex
|
247
392
|
@logger.error(ex)
|
@@ -251,7 +396,8 @@ module WEBrick
|
|
251
396
|
|
252
397
|
# This method provides the metavariables defined by the revision 3
|
253
398
|
# of "The WWW Common Gateway Interface Version 1.1"
|
254
|
-
#
|
399
|
+
# To browse the current document of CGI Version 1.1, see below:
|
400
|
+
# http://tools.ietf.org/html/rfc3875
|
255
401
|
|
256
402
|
def meta_vars
|
257
403
|
meta = Hash.new
|
@@ -290,15 +436,23 @@ module WEBrick
|
|
290
436
|
|
291
437
|
private
|
292
438
|
|
439
|
+
# :stopdoc:
|
440
|
+
|
293
441
|
MAX_URI_LENGTH = 2083 # :nodoc:
|
294
442
|
|
443
|
+
# same as Mongrel, Thin and Puma
|
444
|
+
MAX_HEADER_LENGTH = (112 * 1024) # :nodoc:
|
445
|
+
|
295
446
|
def read_request_line(socket)
|
296
447
|
@request_line = read_line(socket, MAX_URI_LENGTH) if socket
|
297
|
-
|
448
|
+
raise HTTPStatus::EOFError unless @request_line
|
449
|
+
|
450
|
+
@request_bytes = @request_line.bytesize
|
451
|
+
if @request_bytes >= MAX_URI_LENGTH and @request_line[-1, 1] != LF
|
298
452
|
raise HTTPStatus::RequestURITooLarge
|
299
453
|
end
|
454
|
+
|
300
455
|
@request_time = Time.now
|
301
|
-
raise HTTPStatus::EOFError unless @request_line
|
302
456
|
if /^(\S+)\s+(\S++)(?:\s+HTTP\/(\d+\.\d+))?\r?\n/mo =~ @request_line
|
303
457
|
@request_method = $1
|
304
458
|
@unparsed_uri = $2
|
@@ -313,6 +467,9 @@ module WEBrick
|
|
313
467
|
if socket
|
314
468
|
while line = read_line(socket)
|
315
469
|
break if /\A(#{CRLF}|#{LF})\z/om =~ line
|
470
|
+
if (@request_bytes += line.bytesize) > MAX_HEADER_LENGTH
|
471
|
+
raise HTTPStatus::RequestEntityTooLarge, 'headers too large'
|
472
|
+
end
|
316
473
|
@raw_header << line
|
317
474
|
end
|
318
475
|
end
|
@@ -380,12 +537,16 @@ module WEBrick
|
|
380
537
|
def read_chunked(socket, block)
|
381
538
|
chunk_size, = read_chunk_size(socket)
|
382
539
|
while chunk_size > 0
|
383
|
-
|
384
|
-
|
385
|
-
|
386
|
-
|
540
|
+
begin
|
541
|
+
sz = [ chunk_size, @buffer_size ].min
|
542
|
+
data = read_data(socket, sz) # read chunk-data
|
543
|
+
if data.nil? || data.bytesize != sz
|
544
|
+
raise HTTPStatus::BadRequest, "bad chunk data size."
|
545
|
+
end
|
546
|
+
block.call(data)
|
547
|
+
end while (chunk_size -= sz) > 0
|
548
|
+
|
387
549
|
read_line(socket) # skip CRLF
|
388
|
-
block.call(data)
|
389
550
|
chunk_size, = read_chunk_size(socket)
|
390
551
|
end
|
391
552
|
read_header(socket) # trailer + CRLF
|
@@ -400,7 +561,7 @@ module WEBrick
|
|
400
561
|
}
|
401
562
|
rescue Errno::ECONNRESET
|
402
563
|
return nil
|
403
|
-
rescue
|
564
|
+
rescue Timeout::Error
|
404
565
|
raise HTTPStatus::RequestTimeout
|
405
566
|
end
|
406
567
|
end
|
@@ -445,7 +606,9 @@ module WEBrick
|
|
445
606
|
if @forwarded_server = self["x-forwarded-server"]
|
446
607
|
@forwarded_server = @forwarded_server.split(",", 2).first
|
447
608
|
end
|
448
|
-
@forwarded_proto = self["x-forwarded-proto"]
|
609
|
+
if @forwarded_proto = self["x-forwarded-proto"]
|
610
|
+
@forwarded_proto = @forwarded_proto.split(",", 2).first
|
611
|
+
end
|
449
612
|
if host_port = self["x-forwarded-host"]
|
450
613
|
host_port = host_port.split(",", 2).first
|
451
614
|
@forwarded_host, tmp = host_port.split(":", 2)
|
@@ -457,5 +620,7 @@ module WEBrick
|
|
457
620
|
@forwarded_for = addrs.first
|
458
621
|
end
|
459
622
|
end
|
623
|
+
|
624
|
+
# :startdoc:
|
460
625
|
end
|
461
626
|
end
|