rubygems-update 4.0.21 → 4.0.23
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +22 -0
- data/Manifest.txt +1 -1
- data/bundler/CHANGELOG.md +28 -0
- data/bundler/lib/bundler/build_metadata.rb +2 -2
- data/bundler/lib/bundler/cli/lock.rb +14 -3
- data/bundler/lib/bundler/cli/platform.rb +15 -1
- data/bundler/lib/bundler/cli.rb +17 -5
- data/bundler/lib/bundler/fetcher/downloader.rb +10 -4
- data/bundler/lib/bundler/installer.rb +4 -0
- data/bundler/lib/bundler/man/bundle-lock.1 +1 -1
- data/bundler/lib/bundler/man/bundle-lock.1.ronn +1 -1
- data/bundler/lib/bundler/man/bundle-outdated.1 +1 -1
- data/bundler/lib/bundler/man/bundle-outdated.1.ronn +1 -1
- data/bundler/lib/bundler/man/bundle-update.1 +2 -2
- data/bundler/lib/bundler/man/bundle-update.1.ronn +2 -2
- data/bundler/lib/bundler/templates/newgem/ext/newgem/Cargo.toml.tt +1 -1
- data/bundler/lib/bundler/vendor/connection_pool/lib/connection_pool/timed_stack.rb +14 -4
- data/bundler/lib/bundler/vendor/connection_pool/lib/connection_pool/version.rb +1 -1
- data/bundler/lib/bundler/vendor/connection_pool/lib/connection_pool.rb +3 -0
- data/bundler/lib/bundler/vendor/fileutils/lib/fileutils.rb +54 -29
- data/bundler/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent/pool.rb +1 -1
- data/bundler/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent/timed_stack_multi.rb +10 -1
- data/bundler/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent.rb +12 -6
- data/bundler/lib/bundler/vendor/thor/lib/thor/actions/inject_into_file.rb +35 -2
- data/bundler/lib/bundler/vendor/thor/lib/thor/base.rb +2 -1
- data/bundler/lib/bundler/vendor/thor/lib/thor/shell/basic.rb +14 -6
- data/bundler/lib/bundler/vendor/thor/lib/thor/shell/color.rb +2 -0
- data/bundler/lib/bundler/vendor/thor/lib/thor/version.rb +1 -1
- data/bundler/lib/bundler/vendor/thor/lib/thor.rb +34 -1
- data/bundler/lib/bundler/vendor/uri/lib/uri/common.rb +1 -1
- data/bundler/lib/bundler/vendor/uri/lib/uri/generic.rb +15 -3
- data/bundler/lib/bundler/vendor/uri/lib/uri/version.rb +1 -1
- data/bundler/lib/bundler/version.rb +1 -1
- data/bundler/lib/bundler.rb +1 -3
- data/lib/rubygems/commands/exec_command.rb +3 -0
- data/lib/rubygems/ext/builder.rb +7 -2
- data/lib/rubygems/gemcutter_utilities/webauthn_listener.rb +9 -0
- data/lib/rubygems/installer.rb +4 -0
- data/lib/rubygems/package.rb +36 -5
- data/lib/rubygems/uninstaller.rb +1 -0
- data/lib/rubygems/vendor/net-http/lib/net/http/exceptions.rb +2 -1
- data/lib/rubygems/vendor/net-http/lib/net/http/generic_request.rb +15 -7
- data/lib/rubygems/vendor/net-http/lib/net/http/header.rb +64 -19
- data/lib/rubygems/vendor/net-http/lib/net/http/request.rb +1 -0
- data/lib/rubygems/vendor/net-http/lib/net/http/requests.rb +74 -25
- data/lib/rubygems/vendor/net-http/lib/net/http/response.rb +42 -16
- data/lib/rubygems/vendor/net-http/lib/net/http/responses.rb +68 -0
- data/lib/rubygems/vendor/net-http/lib/net/http.rb +129 -37
- data/lib/rubygems/vendor/net-protocol/COPYING +56 -0
- data/lib/rubygems/vendor/net-protocol/lib/net/protocol.rb +95 -26
- data/lib/rubygems/vendor/optparse/lib/optparse.rb +23 -30
- data/lib/rubygems/vendor/timeout/lib/timeout.rb +190 -77
- data/lib/rubygems/vendor/uri/lib/uri/common.rb +1 -1
- data/lib/rubygems/vendor/uri/lib/uri/generic.rb +15 -3
- data/lib/rubygems/vendor/uri/lib/uri/version.rb +1 -1
- data/lib/rubygems.rb +1 -1
- metadata +2 -2
- data/lib/rubygems/vendor/net-protocol/LICENSE.txt +0 -22
|
@@ -179,7 +179,9 @@
|
|
|
179
179
|
# - #each_value: Passes each string field value to the block.
|
|
180
180
|
#
|
|
181
181
|
module Gem::Net::HTTPHeader
|
|
182
|
+
# The maximum length of HTTP header keys.
|
|
182
183
|
MAX_KEY_LENGTH = 1024
|
|
184
|
+
# The maximum length of HTTP header values.
|
|
183
185
|
MAX_FIELD_LENGTH = 65536
|
|
184
186
|
|
|
185
187
|
def initialize_http_header(initheader) #:nodoc:
|
|
@@ -191,11 +193,9 @@ module Gem::Net::HTTPHeader
|
|
|
191
193
|
warn "net/http: nil HTTP header: #{key}", uplevel: 3 if $VERBOSE
|
|
192
194
|
else
|
|
193
195
|
value = value.strip # raise error for invalid byte sequences
|
|
194
|
-
|
|
195
|
-
raise ArgumentError, "too long (#{key.bytesize} bytes) header: #{key[0, 30].inspect}..."
|
|
196
|
-
end
|
|
196
|
+
validate_field_name(key)
|
|
197
197
|
if value.to_s.bytesize > MAX_FIELD_LENGTH
|
|
198
|
-
raise ArgumentError, "header #{key} has too long field value: #{value.bytesize}"
|
|
198
|
+
raise ArgumentError, "header #{key} has too long field value: #{value.bytesize} bytes (limit #{MAX_FIELD_LENGTH})"
|
|
199
199
|
end
|
|
200
200
|
if value.count("\r\n") > 0
|
|
201
201
|
raise ArgumentError, "header #{key} has field value #{value.inspect}, this cannot include CR/LF"
|
|
@@ -261,20 +261,34 @@ module Gem::Net::HTTPHeader
|
|
|
261
261
|
def add_field(key, val)
|
|
262
262
|
stringified_downcased_key = key.downcase.to_s
|
|
263
263
|
if @header.key?(stringified_downcased_key)
|
|
264
|
-
append_field_value(@header[stringified_downcased_key], val)
|
|
264
|
+
append_field_value(@header[stringified_downcased_key], val, key)
|
|
265
265
|
else
|
|
266
266
|
set_field(key, val)
|
|
267
267
|
end
|
|
268
268
|
end
|
|
269
269
|
|
|
270
|
+
# :stopdoc:
|
|
271
|
+
private def validate_field_name(key)
|
|
272
|
+
if key.to_s.bytesize > MAX_KEY_LENGTH
|
|
273
|
+
raise ArgumentError, "too long (#{key.to_s.bytesize} bytes) header: #{key.to_s[0, 30].inspect}..."
|
|
274
|
+
end
|
|
275
|
+
if /[\x00-\x1f\x7f:]/n.match?(key.to_s.b)
|
|
276
|
+
raise ArgumentError, "header field name cannot include control characters or colon: #{key.to_s[0, 30].inspect}"
|
|
277
|
+
end
|
|
278
|
+
end
|
|
279
|
+
|
|
270
280
|
private def set_field(key, val)
|
|
281
|
+
validate_field_name(key)
|
|
271
282
|
case val
|
|
272
283
|
when Enumerable
|
|
273
284
|
ary = []
|
|
274
|
-
append_field_value(ary, val)
|
|
285
|
+
append_field_value(ary, val, key)
|
|
275
286
|
@header[key.downcase.to_s] = ary
|
|
276
287
|
else
|
|
277
288
|
val = val.to_s # for compatibility use to_s instead of to_str
|
|
289
|
+
if val.bytesize > MAX_FIELD_LENGTH
|
|
290
|
+
raise ArgumentError, "header #{key} has too long field value: #{val.bytesize} bytes (limit #{MAX_FIELD_LENGTH})"
|
|
291
|
+
end
|
|
278
292
|
if val.b.count("\r\n") > 0
|
|
279
293
|
raise ArgumentError, 'header field value cannot include CR/LF'
|
|
280
294
|
end
|
|
@@ -282,18 +296,22 @@ module Gem::Net::HTTPHeader
|
|
|
282
296
|
end
|
|
283
297
|
end
|
|
284
298
|
|
|
285
|
-
private def append_field_value(ary, val)
|
|
299
|
+
private def append_field_value(ary, val, key)
|
|
286
300
|
case val
|
|
287
301
|
when Enumerable
|
|
288
|
-
val.each{|x| append_field_value(ary, x)}
|
|
302
|
+
val.each{|x| append_field_value(ary, x, key)}
|
|
289
303
|
else
|
|
290
304
|
val = val.to_s
|
|
305
|
+
if val.bytesize > MAX_FIELD_LENGTH
|
|
306
|
+
raise ArgumentError, "header #{key} has too long field value: #{val.bytesize} bytes (limit #{MAX_FIELD_LENGTH})"
|
|
307
|
+
end
|
|
291
308
|
if /[\r\n]/n.match?(val.b)
|
|
292
309
|
raise ArgumentError, 'header field value cannot include CR/LF'
|
|
293
310
|
end
|
|
294
311
|
ary.push val
|
|
295
312
|
end
|
|
296
313
|
end
|
|
314
|
+
# :startdoc:
|
|
297
315
|
|
|
298
316
|
# Returns the array field value for the given +key+,
|
|
299
317
|
# or +nil+ if there is no such field;
|
|
@@ -490,7 +508,7 @@ module Gem::Net::HTTPHeader
|
|
|
490
508
|
|
|
491
509
|
alias canonical_each each_capitalized
|
|
492
510
|
|
|
493
|
-
def capitalize(name)
|
|
511
|
+
def capitalize(name) # :nodoc:
|
|
494
512
|
name.to_s.split('-'.freeze).map {|s| s.capitalize }.join('-'.freeze)
|
|
495
513
|
end
|
|
496
514
|
private :capitalize
|
|
@@ -613,11 +631,35 @@ module Gem::Net::HTTPHeader
|
|
|
613
631
|
# res = Gem::Net::HTTP.get_response(hostname, '/todos/1')
|
|
614
632
|
# res.content_length # => nil
|
|
615
633
|
#
|
|
634
|
+
# The value must consist of digits only.
|
|
635
|
+
# Multiple <tt>'Content-Length'</tt> values are accepted
|
|
636
|
+
# only when they are all identical;
|
|
637
|
+
# otherwise Gem::Net::HTTPHeaderSyntaxError is raised.
|
|
638
|
+
# See {RFC 9110 Section 8.6}[https://www.rfc-editor.org/rfc/rfc9110.html#section-8.6].
|
|
616
639
|
def content_length
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
640
|
+
values = @header['content-length']
|
|
641
|
+
return nil if values.nil?
|
|
642
|
+
|
|
643
|
+
lengths = []
|
|
644
|
+
values.each do |value|
|
|
645
|
+
value = value.strip
|
|
646
|
+
if value.empty?
|
|
647
|
+
raise Gem::Net::HTTPHeaderSyntaxError,
|
|
648
|
+
"empty Content-Length value"
|
|
649
|
+
end
|
|
650
|
+
lengths.concat(value.split(/\s*,\s*/, -1))
|
|
651
|
+
end
|
|
652
|
+
if lengths.uniq.size != 1
|
|
653
|
+
raise Gem::Net::HTTPHeaderSyntaxError,
|
|
654
|
+
"Content-Length has multiple different values: " +
|
|
655
|
+
values.join(", ")
|
|
656
|
+
end
|
|
657
|
+
length = lengths.first
|
|
658
|
+
unless /\A\d+\z/.match?(length)
|
|
659
|
+
raise Gem::Net::HTTPHeaderSyntaxError,
|
|
660
|
+
"wrong Content-Length format: #{length}"
|
|
661
|
+
end
|
|
662
|
+
length.to_i
|
|
621
663
|
end
|
|
622
664
|
|
|
623
665
|
# Sets the value of field <tt>'Content-Length'</tt> to the given numeric;
|
|
@@ -643,7 +685,7 @@ module Gem::Net::HTTPHeader
|
|
|
643
685
|
end
|
|
644
686
|
|
|
645
687
|
# Returns +true+ if field <tt>'Transfer-Encoding'</tt>
|
|
646
|
-
# exists and has
|
|
688
|
+
# exists and has <tt>'chunked'</tt> as its final transfer coding,
|
|
647
689
|
# +false+ otherwise;
|
|
648
690
|
# see {Transfer-Encoding response header}[https://en.wikipedia.org/wiki/List_of_HTTP_header_fields#transfer-encoding-response-header]:
|
|
649
691
|
#
|
|
@@ -651,10 +693,13 @@ module Gem::Net::HTTPHeader
|
|
|
651
693
|
# res['Transfer-Encoding'] # => "chunked"
|
|
652
694
|
# res.chunked? # => true
|
|
653
695
|
#
|
|
696
|
+
# <tt>'gzip, chunked'</tt> is chunked but <tt>'chunked, gzip'</tt> is not,
|
|
697
|
+
# because only the final transfer coding frames the message.
|
|
698
|
+
# See {RFC 9112 Section 6.3}[https://www.rfc-editor.org/rfc/rfc9112.html#section-6.3].
|
|
654
699
|
def chunked?
|
|
655
700
|
return false unless @header['transfer-encoding']
|
|
656
701
|
field = self['Transfer-Encoding']
|
|
657
|
-
(/(?:\A|[^\-\w])chunked(?![\-\w])/i =~ field) ? true : false
|
|
702
|
+
(/(?:\A|[^\-\w])chunked(?![\-\w])\s*(?:,\s*)*\z/i =~ field) ? true : false
|
|
658
703
|
end
|
|
659
704
|
|
|
660
705
|
# Returns a Range object representing the value of field
|
|
@@ -770,7 +815,7 @@ module Gem::Net::HTTPHeader
|
|
|
770
815
|
#
|
|
771
816
|
# Gem::Net::HTTPHeader#content_type= is an alias for Gem::Net::HTTPHeader#set_content_type.
|
|
772
817
|
def set_content_type(type, params = {})
|
|
773
|
-
|
|
818
|
+
set_field('Content-Type', type + params.map{|k,v|"; #{k}=#{v}"}.join(''))
|
|
774
819
|
end
|
|
775
820
|
|
|
776
821
|
alias content_type= set_content_type
|
|
@@ -957,12 +1002,12 @@ module Gem::Net::HTTPHeader
|
|
|
957
1002
|
@header['proxy-authorization'] = [basic_encode(account, password)]
|
|
958
1003
|
end
|
|
959
1004
|
|
|
960
|
-
def basic_encode(account, password)
|
|
1005
|
+
def basic_encode(account, password) # :nodoc:
|
|
961
1006
|
'Basic ' + ["#{account}:#{password}"].pack('m0')
|
|
962
1007
|
end
|
|
963
1008
|
private :basic_encode
|
|
964
1009
|
|
|
965
|
-
# Returns whether the HTTP session is to be closed.
|
|
1010
|
+
# Returns whether the HTTP session is to be closed.
|
|
966
1011
|
def connection_close?
|
|
967
1012
|
token = /(?:\A|,)\s*close\s*(?:\z|,)/i
|
|
968
1013
|
@header['connection']&.grep(token) {return true}
|
|
@@ -970,7 +1015,7 @@ module Gem::Net::HTTPHeader
|
|
|
970
1015
|
false
|
|
971
1016
|
end
|
|
972
1017
|
|
|
973
|
-
# Returns whether the HTTP session is to be kept alive.
|
|
1018
|
+
# Returns whether the HTTP session is to be kept alive.
|
|
974
1019
|
def connection_keep_alive?
|
|
975
1020
|
token = /(?:\A|,)\s*keep-alive\s*(?:\z|,)/i
|
|
976
1021
|
@header['connection']&.grep(token) {return true}
|
|
@@ -19,9 +19,9 @@
|
|
|
19
19
|
#
|
|
20
20
|
# - Request body: optional.
|
|
21
21
|
# - Response body: yes.
|
|
22
|
-
# - {Safe}[https://en.wikipedia.org/wiki/
|
|
23
|
-
# - {Idempotent}[https://en.wikipedia.org/wiki/
|
|
24
|
-
# - {Cacheable}[https://en.wikipedia.org/wiki/
|
|
22
|
+
# - {Safe}[https://en.wikipedia.org/wiki/HTTP#Safe_method]: yes.
|
|
23
|
+
# - {Idempotent}[https://en.wikipedia.org/wiki/HTTP#Idempotent_method]: yes.
|
|
24
|
+
# - {Cacheable}[https://en.wikipedia.org/wiki/HTTP#Cacheable_method]: yes.
|
|
25
25
|
#
|
|
26
26
|
# Related:
|
|
27
27
|
#
|
|
@@ -29,6 +29,7 @@
|
|
|
29
29
|
# - Gem::Net::HTTP#get: sends +GET+ request, returns response object.
|
|
30
30
|
#
|
|
31
31
|
class Gem::Net::HTTP::Get < Gem::Net::HTTPRequest
|
|
32
|
+
# :stopdoc:
|
|
32
33
|
METHOD = 'GET'
|
|
33
34
|
REQUEST_HAS_BODY = false
|
|
34
35
|
RESPONSE_HAS_BODY = true
|
|
@@ -51,15 +52,16 @@ end
|
|
|
51
52
|
#
|
|
52
53
|
# - Request body: optional.
|
|
53
54
|
# - Response body: no.
|
|
54
|
-
# - {Safe}[https://en.wikipedia.org/wiki/
|
|
55
|
-
# - {Idempotent}[https://en.wikipedia.org/wiki/
|
|
56
|
-
# - {Cacheable}[https://en.wikipedia.org/wiki/
|
|
55
|
+
# - {Safe}[https://en.wikipedia.org/wiki/HTTP#Safe_method]: yes.
|
|
56
|
+
# - {Idempotent}[https://en.wikipedia.org/wiki/HTTP#Idempotent_method]: yes.
|
|
57
|
+
# - {Cacheable}[https://en.wikipedia.org/wiki/HTTP#Cacheable_method]: yes.
|
|
57
58
|
#
|
|
58
59
|
# Related:
|
|
59
60
|
#
|
|
60
61
|
# - Gem::Net::HTTP#head: sends +HEAD+ request, returns response object.
|
|
61
62
|
#
|
|
62
63
|
class Gem::Net::HTTP::Head < Gem::Net::HTTPRequest
|
|
64
|
+
# :stopdoc:
|
|
63
65
|
METHOD = 'HEAD'
|
|
64
66
|
REQUEST_HAS_BODY = false
|
|
65
67
|
RESPONSE_HAS_BODY = false
|
|
@@ -85,9 +87,9 @@ end
|
|
|
85
87
|
#
|
|
86
88
|
# - Request body: yes.
|
|
87
89
|
# - Response body: yes.
|
|
88
|
-
# - {Safe}[https://en.wikipedia.org/wiki/
|
|
89
|
-
# - {Idempotent}[https://en.wikipedia.org/wiki/
|
|
90
|
-
# - {Cacheable}[https://en.wikipedia.org/wiki/
|
|
90
|
+
# - {Safe}[https://en.wikipedia.org/wiki/HTTP#Safe_method]: no.
|
|
91
|
+
# - {Idempotent}[https://en.wikipedia.org/wiki/HTTP#Idempotent_method]: no.
|
|
92
|
+
# - {Cacheable}[https://en.wikipedia.org/wiki/HTTP#Cacheable_method]: yes.
|
|
91
93
|
#
|
|
92
94
|
# Related:
|
|
93
95
|
#
|
|
@@ -95,6 +97,7 @@ end
|
|
|
95
97
|
# - Gem::Net::HTTP#post: sends +POST+ request, returns response object.
|
|
96
98
|
#
|
|
97
99
|
class Gem::Net::HTTP::Post < Gem::Net::HTTPRequest
|
|
100
|
+
# :stopdoc:
|
|
98
101
|
METHOD = 'POST'
|
|
99
102
|
REQUEST_HAS_BODY = true
|
|
100
103
|
RESPONSE_HAS_BODY = true
|
|
@@ -120,9 +123,9 @@ end
|
|
|
120
123
|
#
|
|
121
124
|
# - Request body: yes.
|
|
122
125
|
# - Response body: yes.
|
|
123
|
-
# - {Safe}[https://en.wikipedia.org/wiki/
|
|
124
|
-
# - {Idempotent}[https://en.wikipedia.org/wiki/
|
|
125
|
-
# - {Cacheable}[https://en.wikipedia.org/wiki/
|
|
126
|
+
# - {Safe}[https://en.wikipedia.org/wiki/HTTP#Safe_method]: no.
|
|
127
|
+
# - {Idempotent}[https://en.wikipedia.org/wiki/HTTP#Idempotent_method]: yes.
|
|
128
|
+
# - {Cacheable}[https://en.wikipedia.org/wiki/HTTP#Cacheable_method]: no.
|
|
126
129
|
#
|
|
127
130
|
# Related:
|
|
128
131
|
#
|
|
@@ -130,6 +133,7 @@ end
|
|
|
130
133
|
# - Gem::Net::HTTP#put: sends +PUT+ request, returns response object.
|
|
131
134
|
#
|
|
132
135
|
class Gem::Net::HTTP::Put < Gem::Net::HTTPRequest
|
|
136
|
+
# :stopdoc:
|
|
133
137
|
METHOD = 'PUT'
|
|
134
138
|
REQUEST_HAS_BODY = true
|
|
135
139
|
RESPONSE_HAS_BODY = true
|
|
@@ -153,15 +157,16 @@ end
|
|
|
153
157
|
#
|
|
154
158
|
# - Request body: optional.
|
|
155
159
|
# - Response body: yes.
|
|
156
|
-
# - {Safe}[https://en.wikipedia.org/wiki/
|
|
157
|
-
# - {Idempotent}[https://en.wikipedia.org/wiki/
|
|
158
|
-
# - {Cacheable}[https://en.wikipedia.org/wiki/
|
|
160
|
+
# - {Safe}[https://en.wikipedia.org/wiki/HTTP#Safe_method]: no.
|
|
161
|
+
# - {Idempotent}[https://en.wikipedia.org/wiki/HTTP#Idempotent_method]: yes.
|
|
162
|
+
# - {Cacheable}[https://en.wikipedia.org/wiki/HTTP#Cacheable_method]: no.
|
|
159
163
|
#
|
|
160
164
|
# Related:
|
|
161
165
|
#
|
|
162
166
|
# - Gem::Net::HTTP#delete: sends +DELETE+ request, returns response object.
|
|
163
167
|
#
|
|
164
168
|
class Gem::Net::HTTP::Delete < Gem::Net::HTTPRequest
|
|
169
|
+
# :stopdoc:
|
|
165
170
|
METHOD = 'DELETE'
|
|
166
171
|
REQUEST_HAS_BODY = false
|
|
167
172
|
RESPONSE_HAS_BODY = true
|
|
@@ -184,15 +189,16 @@ end
|
|
|
184
189
|
#
|
|
185
190
|
# - Request body: optional.
|
|
186
191
|
# - Response body: yes.
|
|
187
|
-
# - {Safe}[https://en.wikipedia.org/wiki/
|
|
188
|
-
# - {Idempotent}[https://en.wikipedia.org/wiki/
|
|
189
|
-
# - {Cacheable}[https://en.wikipedia.org/wiki/
|
|
192
|
+
# - {Safe}[https://en.wikipedia.org/wiki/HTTP#Safe_method]: yes.
|
|
193
|
+
# - {Idempotent}[https://en.wikipedia.org/wiki/HTTP#Idempotent_method]: yes.
|
|
194
|
+
# - {Cacheable}[https://en.wikipedia.org/wiki/HTTP#Cacheable_method]: no.
|
|
190
195
|
#
|
|
191
196
|
# Related:
|
|
192
197
|
#
|
|
193
198
|
# - Gem::Net::HTTP#options: sends +OPTIONS+ request, returns response object.
|
|
194
199
|
#
|
|
195
200
|
class Gem::Net::HTTP::Options < Gem::Net::HTTPRequest
|
|
201
|
+
# :stopdoc:
|
|
196
202
|
METHOD = 'OPTIONS'
|
|
197
203
|
REQUEST_HAS_BODY = false
|
|
198
204
|
RESPONSE_HAS_BODY = true
|
|
@@ -215,15 +221,16 @@ end
|
|
|
215
221
|
#
|
|
216
222
|
# - Request body: no.
|
|
217
223
|
# - Response body: yes.
|
|
218
|
-
# - {Safe}[https://en.wikipedia.org/wiki/
|
|
219
|
-
# - {Idempotent}[https://en.wikipedia.org/wiki/
|
|
220
|
-
# - {Cacheable}[https://en.wikipedia.org/wiki/
|
|
224
|
+
# - {Safe}[https://en.wikipedia.org/wiki/HTTP#Safe_method]: yes.
|
|
225
|
+
# - {Idempotent}[https://en.wikipedia.org/wiki/HTTP#Idempotent_method]: yes.
|
|
226
|
+
# - {Cacheable}[https://en.wikipedia.org/wiki/HTTP#Cacheable_method]: no.
|
|
221
227
|
#
|
|
222
228
|
# Related:
|
|
223
229
|
#
|
|
224
230
|
# - Gem::Net::HTTP#trace: sends +TRACE+ request, returns response object.
|
|
225
231
|
#
|
|
226
232
|
class Gem::Net::HTTP::Trace < Gem::Net::HTTPRequest
|
|
233
|
+
# :stopdoc:
|
|
227
234
|
METHOD = 'TRACE'
|
|
228
235
|
REQUEST_HAS_BODY = false
|
|
229
236
|
RESPONSE_HAS_BODY = true
|
|
@@ -249,20 +256,56 @@ end
|
|
|
249
256
|
#
|
|
250
257
|
# - Request body: yes.
|
|
251
258
|
# - Response body: yes.
|
|
252
|
-
# - {Safe}[https://en.wikipedia.org/wiki/
|
|
253
|
-
# - {Idempotent}[https://en.wikipedia.org/wiki/
|
|
254
|
-
# - {Cacheable}[https://en.wikipedia.org/wiki/
|
|
259
|
+
# - {Safe}[https://en.wikipedia.org/wiki/HTTP#Safe_method]: no.
|
|
260
|
+
# - {Idempotent}[https://en.wikipedia.org/wiki/HTTP#Idempotent_method]: no.
|
|
261
|
+
# - {Cacheable}[https://en.wikipedia.org/wiki/HTTP#Cacheable_method]: no.
|
|
255
262
|
#
|
|
256
263
|
# Related:
|
|
257
264
|
#
|
|
258
265
|
# - Gem::Net::HTTP#patch: sends +PATCH+ request, returns response object.
|
|
259
266
|
#
|
|
260
267
|
class Gem::Net::HTTP::Patch < Gem::Net::HTTPRequest
|
|
268
|
+
# :stopdoc:
|
|
261
269
|
METHOD = 'PATCH'
|
|
262
270
|
REQUEST_HAS_BODY = true
|
|
263
271
|
RESPONSE_HAS_BODY = true
|
|
264
272
|
end
|
|
265
273
|
|
|
274
|
+
# \Class for representing
|
|
275
|
+
# {HTTP method QUERY}[https://www.rfc-editor.org/rfc/rfc10008.html]:
|
|
276
|
+
#
|
|
277
|
+
# require 'rubygems/vendor/net-http/lib/net/http'
|
|
278
|
+
# uri = Gem::URI('http://example.com')
|
|
279
|
+
# hostname = uri.hostname # => "example.com"
|
|
280
|
+
# uri.path = '/posts'
|
|
281
|
+
# req = Gem::Net::HTTP::Query.new(uri) # => #<Gem::Net::HTTP::Query QUERY>
|
|
282
|
+
# req.body = '{"title": "foo","body": "bar","userId": 1}'
|
|
283
|
+
# req.content_type = 'application/json'
|
|
284
|
+
# res = Gem::Net::HTTP.start(hostname) do |http|
|
|
285
|
+
# http.request(req)
|
|
286
|
+
# end
|
|
287
|
+
#
|
|
288
|
+
# See {Request Headers}[rdoc-ref:Gem::Net::HTTPRequest@Request+Headers].
|
|
289
|
+
#
|
|
290
|
+
# Properties:
|
|
291
|
+
#
|
|
292
|
+
# - Request body: yes.
|
|
293
|
+
# - Response body: yes.
|
|
294
|
+
# - {Safe}[https://en.wikipedia.org/wiki/HTTP#Safe_method]: yes.
|
|
295
|
+
# - {Idempotent}[https://en.wikipedia.org/wiki/HTTP#Idempotent_method]: yes.
|
|
296
|
+
# - {Cacheable}[https://en.wikipedia.org/wiki/HTTP#Cacheable_method]: yes.
|
|
297
|
+
#
|
|
298
|
+
# Related:
|
|
299
|
+
#
|
|
300
|
+
# - Gem::Net::HTTP#query: sends +QUERY+ request, returns response object.
|
|
301
|
+
#
|
|
302
|
+
class Gem::Net::HTTP::Query < Gem::Net::HTTPRequest
|
|
303
|
+
# :stopdoc:
|
|
304
|
+
METHOD = 'QUERY'
|
|
305
|
+
REQUEST_HAS_BODY = true
|
|
306
|
+
RESPONSE_HAS_BODY = true
|
|
307
|
+
end
|
|
308
|
+
|
|
266
309
|
#
|
|
267
310
|
# WebDAV methods --- RFC2518
|
|
268
311
|
#
|
|
@@ -285,6 +328,7 @@ end
|
|
|
285
328
|
# - Gem::Net::HTTP#propfind: sends +PROPFIND+ request, returns response object.
|
|
286
329
|
#
|
|
287
330
|
class Gem::Net::HTTP::Propfind < Gem::Net::HTTPRequest
|
|
331
|
+
# :stopdoc:
|
|
288
332
|
METHOD = 'PROPFIND'
|
|
289
333
|
REQUEST_HAS_BODY = true
|
|
290
334
|
RESPONSE_HAS_BODY = true
|
|
@@ -308,6 +352,7 @@ end
|
|
|
308
352
|
# - Gem::Net::HTTP#proppatch: sends +PROPPATCH+ request, returns response object.
|
|
309
353
|
#
|
|
310
354
|
class Gem::Net::HTTP::Proppatch < Gem::Net::HTTPRequest
|
|
355
|
+
# :stopdoc:
|
|
311
356
|
METHOD = 'PROPPATCH'
|
|
312
357
|
REQUEST_HAS_BODY = true
|
|
313
358
|
RESPONSE_HAS_BODY = true
|
|
@@ -331,6 +376,7 @@ end
|
|
|
331
376
|
# - Gem::Net::HTTP#mkcol: sends +MKCOL+ request, returns response object.
|
|
332
377
|
#
|
|
333
378
|
class Gem::Net::HTTP::Mkcol < Gem::Net::HTTPRequest
|
|
379
|
+
# :stopdoc:
|
|
334
380
|
METHOD = 'MKCOL'
|
|
335
381
|
REQUEST_HAS_BODY = true
|
|
336
382
|
RESPONSE_HAS_BODY = true
|
|
@@ -354,6 +400,7 @@ end
|
|
|
354
400
|
# - Gem::Net::HTTP#copy: sends +COPY+ request, returns response object.
|
|
355
401
|
#
|
|
356
402
|
class Gem::Net::HTTP::Copy < Gem::Net::HTTPRequest
|
|
403
|
+
# :stopdoc:
|
|
357
404
|
METHOD = 'COPY'
|
|
358
405
|
REQUEST_HAS_BODY = false
|
|
359
406
|
RESPONSE_HAS_BODY = true
|
|
@@ -377,6 +424,7 @@ end
|
|
|
377
424
|
# - Gem::Net::HTTP#move: sends +MOVE+ request, returns response object.
|
|
378
425
|
#
|
|
379
426
|
class Gem::Net::HTTP::Move < Gem::Net::HTTPRequest
|
|
427
|
+
# :stopdoc:
|
|
380
428
|
METHOD = 'MOVE'
|
|
381
429
|
REQUEST_HAS_BODY = false
|
|
382
430
|
RESPONSE_HAS_BODY = true
|
|
@@ -400,6 +448,7 @@ end
|
|
|
400
448
|
# - Gem::Net::HTTP#lock: sends +LOCK+ request, returns response object.
|
|
401
449
|
#
|
|
402
450
|
class Gem::Net::HTTP::Lock < Gem::Net::HTTPRequest
|
|
451
|
+
# :stopdoc:
|
|
403
452
|
METHOD = 'LOCK'
|
|
404
453
|
REQUEST_HAS_BODY = true
|
|
405
454
|
RESPONSE_HAS_BODY = true
|
|
@@ -423,8 +472,8 @@ end
|
|
|
423
472
|
# - Gem::Net::HTTP#unlock: sends +UNLOCK+ request, returns response object.
|
|
424
473
|
#
|
|
425
474
|
class Gem::Net::HTTP::Unlock < Gem::Net::HTTPRequest
|
|
475
|
+
# :stopdoc:
|
|
426
476
|
METHOD = 'UNLOCK'
|
|
427
477
|
REQUEST_HAS_BODY = true
|
|
428
478
|
RESPONSE_HAS_BODY = true
|
|
429
479
|
end
|
|
430
|
-
|
|
@@ -133,6 +133,13 @@
|
|
|
133
133
|
# there is a protocol error.
|
|
134
134
|
#
|
|
135
135
|
class Gem::Net::HTTPResponse
|
|
136
|
+
# The maximum total size in bytes of the response header.
|
|
137
|
+
MAX_RESPONSE_HEADER_LENGTH = 1024 * 1024 # 1 MiB
|
|
138
|
+
|
|
139
|
+
# The maximum number of informational (1xx) responses accepted before the
|
|
140
|
+
# final response.
|
|
141
|
+
MAX_INFORMATIONAL_RESPONSES = 100
|
|
142
|
+
|
|
136
143
|
class << self
|
|
137
144
|
# true if the response has a body.
|
|
138
145
|
def body_permitted?
|
|
@@ -152,10 +159,17 @@ class Gem::Net::HTTPResponse
|
|
|
152
159
|
res
|
|
153
160
|
end
|
|
154
161
|
|
|
162
|
+
def read_line(sock, limit, ignore_eof = false) #:nodoc: internal use only
|
|
163
|
+
sock.readuntil("\n", ignore_eof, limit: limit)
|
|
164
|
+
rescue Gem::Net::ReadLimitExceeded
|
|
165
|
+
raise Gem::Net::HTTPBadResponse, 'response line too long'
|
|
166
|
+
end
|
|
167
|
+
|
|
155
168
|
private
|
|
169
|
+
# :stopdoc:
|
|
156
170
|
|
|
157
171
|
def read_status_line(sock)
|
|
158
|
-
str = sock.
|
|
172
|
+
str = read_line(sock, MAX_RESPONSE_HEADER_LENGTH).chop
|
|
159
173
|
m = /\AHTTP(?:\/(\d+\.\d+))?\s+(\d\d\d)(?:\s+(.*))?\z/in.match(str) or
|
|
160
174
|
raise Gem::Net::HTTPBadResponse, "wrong status line: #{str.dump}"
|
|
161
175
|
m.captures
|
|
@@ -169,12 +183,19 @@ class Gem::Net::HTTPResponse
|
|
|
169
183
|
|
|
170
184
|
def each_response_header(sock)
|
|
171
185
|
key = value = nil
|
|
186
|
+
remaining = MAX_RESPONSE_HEADER_LENGTH
|
|
172
187
|
while true
|
|
173
|
-
line = sock
|
|
188
|
+
line = read_line(sock, MAX_RESPONSE_HEADER_LENGTH, true)
|
|
189
|
+
remaining -= line.bytesize
|
|
190
|
+
raise Gem::Net::HTTPBadResponse, 'response header too large' if remaining < 0
|
|
191
|
+
line = line.chomp
|
|
174
192
|
break if line.empty?
|
|
175
193
|
if line[0] == ?\s or line[0] == ?\t and value
|
|
176
|
-
|
|
177
|
-
|
|
194
|
+
folded = line.strip
|
|
195
|
+
unless folded.empty?
|
|
196
|
+
value << ' ' unless value.empty?
|
|
197
|
+
value << folded
|
|
198
|
+
end
|
|
178
199
|
else
|
|
179
200
|
yield key, value if key
|
|
180
201
|
key, value = line.strip.split(/\s*:\s*/, 2)
|
|
@@ -259,7 +280,7 @@ class Gem::Net::HTTPResponse
|
|
|
259
280
|
# header.
|
|
260
281
|
attr_accessor :ignore_eof
|
|
261
282
|
|
|
262
|
-
def inspect
|
|
283
|
+
def inspect # :nodoc:
|
|
263
284
|
"#<#{self.class} #{@code} #{@message} readbody=#{@read}>"
|
|
264
285
|
end
|
|
265
286
|
|
|
@@ -598,15 +619,20 @@ class Gem::Net::HTTPResponse
|
|
|
598
619
|
|
|
599
620
|
@socket = inflate_body_io
|
|
600
621
|
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
622
|
+
# Transfer-Encoding overrides Content-Length, so a body that is not
|
|
623
|
+
# chunk-framed runs until the server closes the connection.
|
|
624
|
+
# See RFC 9112 Section 6.3.
|
|
625
|
+
unless @header['transfer-encoding']
|
|
626
|
+
clen = content_length()
|
|
627
|
+
if clen
|
|
628
|
+
@socket.read clen, dest, @ignore_eof
|
|
629
|
+
return
|
|
630
|
+
end
|
|
631
|
+
clen = range_length()
|
|
632
|
+
if clen
|
|
633
|
+
@socket.read clen, dest
|
|
634
|
+
return
|
|
635
|
+
end
|
|
610
636
|
end
|
|
611
637
|
@socket.read_all dest
|
|
612
638
|
end
|
|
@@ -622,7 +648,7 @@ class Gem::Net::HTTPResponse
|
|
|
622
648
|
def read_chunked(dest, chunk_data_io) # :nodoc:
|
|
623
649
|
total = 0
|
|
624
650
|
while true
|
|
625
|
-
line = @socket.
|
|
651
|
+
line = self.class.read_line(@socket, MAX_RESPONSE_HEADER_LENGTH).chop
|
|
626
652
|
hexlen = line.slice(/[0-9a-fA-F]+/) or
|
|
627
653
|
raise Gem::Net::HTTPBadResponse, "wrong chunk size line: #{line}"
|
|
628
654
|
len = hexlen.hex
|
|
@@ -634,7 +660,7 @@ class Gem::Net::HTTPResponse
|
|
|
634
660
|
@socket.read 2 # \r\n
|
|
635
661
|
end
|
|
636
662
|
end
|
|
637
|
-
until @socket.
|
|
663
|
+
until self.class.read_line(@socket, MAX_RESPONSE_HEADER_LENGTH).chop.empty?
|
|
638
664
|
# none
|
|
639
665
|
end
|
|
640
666
|
end
|