webrick 1.3.1 → 1.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of webrick might be problematic. Click here for more details.
- checksums.yaml +7 -0
- data/Gemfile +3 -0
- data/LICENSE.txt +22 -0
- data/README.md +63 -0
- data/Rakefile +10 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- 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/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/httpauth.rb +6 -5
- data/lib/webrick/httpproxy.rb +93 -48
- data/lib/webrick/httprequest.rb +192 -27
- data/lib/webrick/httpresponse.rb +221 -70
- data/lib/webrick/https.rb +90 -2
- data/lib/webrick/httpserver.rb +45 -15
- 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/httpservlet.rb +6 -5
- data/lib/webrick/httpstatus.rb +24 -14
- data/lib/webrick/httputils.rb +133 -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
- data/lib/webrick.rb +7 -7
- data/webrick.gemspec +76 -0
- metadata +70 -69
- 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/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
|