net-http 0.2.0 → 0.2.1.pre1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/dependabot.yml +6 -0
- data/.github/workflows/test.yml +2 -2
- data/lib/net/http/backward.rb +26 -12
- data/lib/net/http/generic_request.rb +2 -2
- data/lib/net/http/response.rb +176 -1
- data/lib/net/http.rb +77 -23
- data/net-http.gemspec +0 -2
- metadata +7 -21
- data/Gemfile.lock +0 -33
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 31dbc20c10c0e3ca2a3fc77be6612257bb34ad8cbe8cfded64622fccdea6cb08
|
4
|
+
data.tar.gz: 2f043ee80140523a0d41f690dba72807f95cf8687cdac29de38bdc3bc9e6ccdb
|
5
5
|
SHA512:
|
6
|
-
metadata.gz: '
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: '00890bbc5eb9a6c3930cfc69554e5d76de6395a31fdcb2c865ad77c6fac0c55cbef5206b6adf0c5b97ea1bb1d8ccc79d2302e377f77d95132c87b5327aeef229'
|
7
|
+
data.tar.gz: a1856470ffbfe586204e9a3e97bfd01f86261bf51e9c2760f1b086be45ccafd7edcddb04854f4251b8a033246e7bc485b80a1374eb2a30c507a42d8d61526608
|
data/.github/workflows/test.yml
CHANGED
@@ -7,11 +7,11 @@ jobs:
|
|
7
7
|
name: build (${{ matrix.ruby }} / ${{ matrix.os }})
|
8
8
|
strategy:
|
9
9
|
matrix:
|
10
|
-
ruby: [ '3.0', 2.7, 2.6, head ]
|
10
|
+
ruby: [ 3.1, '3.0', 2.7, 2.6, head ]
|
11
11
|
os: [ ubuntu-latest, macos-latest ]
|
12
12
|
runs-on: ${{ matrix.os }}
|
13
13
|
steps:
|
14
|
-
- uses: actions/checkout@
|
14
|
+
- uses: actions/checkout@v3
|
15
15
|
- name: Set up Ruby
|
16
16
|
uses: ruby/setup-ruby@v1
|
17
17
|
with:
|
data/lib/net/http/backward.rb
CHANGED
@@ -5,22 +5,36 @@
|
|
5
5
|
|
6
6
|
class Net::HTTP
|
7
7
|
ProxyMod = ProxyDelta
|
8
|
-
|
9
|
-
|
10
|
-
module Net
|
11
|
-
HTTPSession = Net::HTTP
|
8
|
+
deprecate_constant :ProxyMod
|
12
9
|
end
|
13
10
|
|
14
11
|
module Net::NetPrivate
|
15
12
|
HTTPRequest = ::Net::HTTPRequest
|
13
|
+
deprecate_constant :HTTPRequest
|
16
14
|
end
|
17
15
|
|
18
|
-
|
19
|
-
|
20
|
-
Net::HTTPRedirectionCode = Net::HTTPRedirection
|
21
|
-
Net::HTTPRetriableCode = Net::HTTPRedirection
|
22
|
-
Net::HTTPClientErrorCode = Net::HTTPClientError
|
23
|
-
Net::HTTPFatalErrorCode = Net::HTTPClientError
|
24
|
-
Net::HTTPServerErrorCode = Net::HTTPServerError
|
25
|
-
Net::HTTPResponceReceiver = Net::HTTPResponse
|
16
|
+
module Net
|
17
|
+
HTTPSession = HTTP
|
26
18
|
|
19
|
+
HTTPInformationCode = HTTPInformation
|
20
|
+
HTTPSuccessCode = HTTPSuccess
|
21
|
+
HTTPRedirectionCode = HTTPRedirection
|
22
|
+
HTTPRetriableCode = HTTPRedirection
|
23
|
+
HTTPClientErrorCode = HTTPClientError
|
24
|
+
HTTPFatalErrorCode = HTTPClientError
|
25
|
+
HTTPServerErrorCode = HTTPServerError
|
26
|
+
HTTPResponseReceiver = HTTPResponse
|
27
|
+
|
28
|
+
HTTPResponceReceiver = HTTPResponse # Typo since 2001
|
29
|
+
|
30
|
+
deprecate_constant :HTTPSession,
|
31
|
+
:HTTPInformationCode,
|
32
|
+
:HTTPSuccessCode,
|
33
|
+
:HTTPRedirectionCode,
|
34
|
+
:HTTPRetriableCode,
|
35
|
+
:HTTPClientErrorCode,
|
36
|
+
:HTTPFatalErrorCode,
|
37
|
+
:HTTPServerErrorCode,
|
38
|
+
:HTTPResponseReceiver,
|
39
|
+
:HTTPResponceReceiver
|
40
|
+
end
|
@@ -31,12 +31,12 @@ class Net::HTTPGenericRequest
|
|
31
31
|
|
32
32
|
@decode_content = false
|
33
33
|
|
34
|
-
if
|
34
|
+
if Net::HTTP::HAVE_ZLIB then
|
35
35
|
if !initheader ||
|
36
36
|
!initheader.keys.any? { |k|
|
37
37
|
%w[accept-encoding range].include? k.downcase
|
38
38
|
} then
|
39
|
-
@decode_content = true
|
39
|
+
@decode_content = true if @response_has_body
|
40
40
|
initheader = initheader ? initheader.dup : {}
|
41
41
|
initheader["accept-encoding"] =
|
42
42
|
"gzip;q=1.0,deflate;q=0.6,identity;q=0.3"
|
data/lib/net/http/response.rb
CHANGED
@@ -84,6 +84,8 @@ class Net::HTTPResponse
|
|
84
84
|
@read = false
|
85
85
|
@uri = nil
|
86
86
|
@decode_content = false
|
87
|
+
@body_encoding = false
|
88
|
+
@ignore_eof = true
|
87
89
|
end
|
88
90
|
|
89
91
|
# The HTTP version supported by the server.
|
@@ -106,6 +108,22 @@ class Net::HTTPResponse
|
|
106
108
|
# Accept-Encoding header from the user.
|
107
109
|
attr_accessor :decode_content
|
108
110
|
|
111
|
+
# The encoding to use for the response body. If Encoding, use that encoding.
|
112
|
+
# If other true value, attempt to detect the appropriate encoding, and use
|
113
|
+
# that.
|
114
|
+
attr_reader :body_encoding
|
115
|
+
|
116
|
+
# Set the encoding to use for the response body. If given a String, find
|
117
|
+
# the related Encoding.
|
118
|
+
def body_encoding=(value)
|
119
|
+
value = Encoding.find(value) if value.is_a?(String)
|
120
|
+
@body_encoding = value
|
121
|
+
end
|
122
|
+
|
123
|
+
# Whether to ignore EOF when reading bodies with a specified Content-Length
|
124
|
+
# header.
|
125
|
+
attr_accessor :ignore_eof
|
126
|
+
|
109
127
|
def inspect
|
110
128
|
"#<#{self.class} #{@code} #{@message} readbody=#{@read}>"
|
111
129
|
end
|
@@ -214,6 +232,17 @@ class Net::HTTPResponse
|
|
214
232
|
end
|
215
233
|
@read = true
|
216
234
|
|
235
|
+
case enc = @body_encoding
|
236
|
+
when Encoding, false, nil
|
237
|
+
# Encoding: force given encoding
|
238
|
+
# false/nil: do not force encoding
|
239
|
+
else
|
240
|
+
# other value: detect encoding from body
|
241
|
+
enc = detect_encoding(@body)
|
242
|
+
end
|
243
|
+
|
244
|
+
@body.force_encoding(enc) if enc
|
245
|
+
|
217
246
|
@body
|
218
247
|
end
|
219
248
|
|
@@ -245,6 +274,141 @@ class Net::HTTPResponse
|
|
245
274
|
|
246
275
|
private
|
247
276
|
|
277
|
+
# :nodoc:
|
278
|
+
def detect_encoding(str, encoding=nil)
|
279
|
+
if encoding
|
280
|
+
elsif encoding = type_params['charset']
|
281
|
+
elsif encoding = check_bom(str)
|
282
|
+
else
|
283
|
+
encoding = case content_type&.downcase
|
284
|
+
when %r{text/x(?:ht)?ml|application/(?:[^+]+\+)?xml}
|
285
|
+
/\A<xml[ \t\r\n]+
|
286
|
+
version[ \t\r\n]*=[ \t\r\n]*(?:"[0-9.]+"|'[0-9.]*')[ \t\r\n]+
|
287
|
+
encoding[ \t\r\n]*=[ \t\r\n]*
|
288
|
+
(?:"([A-Za-z][\-A-Za-z0-9._]*)"|'([A-Za-z][\-A-Za-z0-9._]*)')/x =~ str
|
289
|
+
encoding = $1 || $2 || Encoding::UTF_8
|
290
|
+
when %r{text/html.*}
|
291
|
+
sniff_encoding(str)
|
292
|
+
end
|
293
|
+
end
|
294
|
+
return encoding
|
295
|
+
end
|
296
|
+
|
297
|
+
# :nodoc:
|
298
|
+
def sniff_encoding(str, encoding=nil)
|
299
|
+
# the encoding sniffing algorithm
|
300
|
+
# http://www.w3.org/TR/html5/parsing.html#determining-the-character-encoding
|
301
|
+
if enc = scanning_meta(str)
|
302
|
+
enc
|
303
|
+
# 6. last visited page or something
|
304
|
+
# 7. frequency
|
305
|
+
elsif str.ascii_only?
|
306
|
+
Encoding::US_ASCII
|
307
|
+
elsif str.dup.force_encoding(Encoding::UTF_8).valid_encoding?
|
308
|
+
Encoding::UTF_8
|
309
|
+
end
|
310
|
+
# 8. implementation-defined or user-specified
|
311
|
+
end
|
312
|
+
|
313
|
+
# :nodoc:
|
314
|
+
def check_bom(str)
|
315
|
+
case str.byteslice(0, 2)
|
316
|
+
when "\xFE\xFF"
|
317
|
+
return Encoding::UTF_16BE
|
318
|
+
when "\xFF\xFE"
|
319
|
+
return Encoding::UTF_16LE
|
320
|
+
end
|
321
|
+
if "\xEF\xBB\xBF" == str.byteslice(0, 3)
|
322
|
+
return Encoding::UTF_8
|
323
|
+
end
|
324
|
+
nil
|
325
|
+
end
|
326
|
+
|
327
|
+
# :nodoc:
|
328
|
+
def scanning_meta(str)
|
329
|
+
require 'strscan'
|
330
|
+
ss = StringScanner.new(str)
|
331
|
+
if ss.scan_until(/<meta[\t\n\f\r ]*/)
|
332
|
+
attrs = {} # attribute_list
|
333
|
+
got_pragma = false
|
334
|
+
need_pragma = nil
|
335
|
+
charset = nil
|
336
|
+
|
337
|
+
# step: Attributes
|
338
|
+
while attr = get_attribute(ss)
|
339
|
+
name, value = *attr
|
340
|
+
next if attrs[name]
|
341
|
+
attrs[name] = true
|
342
|
+
case name
|
343
|
+
when 'http-equiv'
|
344
|
+
got_pragma = true if value == 'content-type'
|
345
|
+
when 'content'
|
346
|
+
encoding = extracting_encodings_from_meta_elements(value)
|
347
|
+
unless charset
|
348
|
+
charset = encoding
|
349
|
+
end
|
350
|
+
need_pragma = true
|
351
|
+
when 'charset'
|
352
|
+
need_pragma = false
|
353
|
+
charset = value
|
354
|
+
end
|
355
|
+
end
|
356
|
+
|
357
|
+
# step: Processing
|
358
|
+
return if need_pragma.nil?
|
359
|
+
return if need_pragma && !got_pragma
|
360
|
+
|
361
|
+
charset = Encoding.find(charset) rescue nil
|
362
|
+
return unless charset
|
363
|
+
charset = Encoding::UTF_8 if charset == Encoding::UTF_16
|
364
|
+
return charset # tentative
|
365
|
+
end
|
366
|
+
nil
|
367
|
+
end
|
368
|
+
|
369
|
+
def get_attribute(ss)
|
370
|
+
ss.scan(/[\t\n\f\r \/]*/)
|
371
|
+
if ss.peek(1) == '>'
|
372
|
+
ss.getch
|
373
|
+
return nil
|
374
|
+
end
|
375
|
+
name = ss.scan(/[^=\t\n\f\r \/>]*/)
|
376
|
+
name.downcase!
|
377
|
+
raise if name.empty?
|
378
|
+
ss.skip(/[\t\n\f\r ]*/)
|
379
|
+
if ss.getch != '='
|
380
|
+
value = ''
|
381
|
+
return [name, value]
|
382
|
+
end
|
383
|
+
ss.skip(/[\t\n\f\r ]*/)
|
384
|
+
case ss.peek(1)
|
385
|
+
when '"'
|
386
|
+
ss.getch
|
387
|
+
value = ss.scan(/[^"]+/)
|
388
|
+
value.downcase!
|
389
|
+
ss.getch
|
390
|
+
when "'"
|
391
|
+
ss.getch
|
392
|
+
value = ss.scan(/[^']+/)
|
393
|
+
value.downcase!
|
394
|
+
ss.getch
|
395
|
+
when '>'
|
396
|
+
value = ''
|
397
|
+
else
|
398
|
+
value = ss.scan(/[^\t\n\f\r >]+/)
|
399
|
+
value.downcase!
|
400
|
+
end
|
401
|
+
[name, value]
|
402
|
+
end
|
403
|
+
|
404
|
+
def extracting_encodings_from_meta_elements(value)
|
405
|
+
# http://dev.w3.org/html5/spec/fetching-resources.html#algorithm-for-extracting-an-encoding-from-a-meta-element
|
406
|
+
if /charset[\t\n\f\r ]*=(?:"([^"]*)"|'([^']*)'|["']|\z|([^\t\n\f\r ;]+))/i =~ value
|
407
|
+
return $1 || $2 || $3
|
408
|
+
end
|
409
|
+
return nil
|
410
|
+
end
|
411
|
+
|
248
412
|
##
|
249
413
|
# Checks for a supported Content-Encoding header and yields an Inflate
|
250
414
|
# wrapper for this response's socket when zlib is present. If the
|
@@ -272,6 +436,9 @@ class Net::HTTPResponse
|
|
272
436
|
ensure
|
273
437
|
begin
|
274
438
|
inflate_body_io.finish
|
439
|
+
if self['content-length']
|
440
|
+
self['content-length'] = inflate_body_io.bytes_inflated.to_s
|
441
|
+
end
|
275
442
|
rescue => err
|
276
443
|
# Ignore #finish's error if there is an exception from yield
|
277
444
|
raise err if success
|
@@ -297,7 +464,7 @@ class Net::HTTPResponse
|
|
297
464
|
|
298
465
|
clen = content_length()
|
299
466
|
if clen
|
300
|
-
@socket.read clen, dest,
|
467
|
+
@socket.read clen, dest, @ignore_eof
|
301
468
|
return
|
302
469
|
end
|
303
470
|
clen = range_length()
|
@@ -373,6 +540,14 @@ class Net::HTTPResponse
|
|
373
540
|
@inflate.finish
|
374
541
|
end
|
375
542
|
|
543
|
+
##
|
544
|
+
# The number of bytes inflated, used to update the Content-Length of
|
545
|
+
# the response.
|
546
|
+
|
547
|
+
def bytes_inflated
|
548
|
+
@inflate.total_out
|
549
|
+
end
|
550
|
+
|
376
551
|
##
|
377
552
|
# Returns a Net::ReadAdapter that inflates each read chunk into +dest+.
|
378
553
|
#
|
data/lib/net/http.rb
CHANGED
@@ -22,6 +22,7 @@
|
|
22
22
|
|
23
23
|
require 'net/protocol'
|
24
24
|
require 'uri'
|
25
|
+
require 'resolv'
|
25
26
|
autoload :OpenSSL, 'openssl'
|
26
27
|
|
27
28
|
module Net #:nodoc:
|
@@ -327,6 +328,8 @@ module Net #:nodoc:
|
|
327
328
|
# HTTPInformation:: 1xx
|
328
329
|
# HTTPContinue:: 100
|
329
330
|
# HTTPSwitchProtocol:: 101
|
331
|
+
# HTTPProcessing:: 102
|
332
|
+
# HTTPEarlyHints:: 103
|
330
333
|
# HTTPSuccess:: 2xx
|
331
334
|
# HTTPOK:: 200
|
332
335
|
# HTTPCreated:: 201
|
@@ -336,6 +339,7 @@ module Net #:nodoc:
|
|
336
339
|
# HTTPResetContent:: 205
|
337
340
|
# HTTPPartialContent:: 206
|
338
341
|
# HTTPMultiStatus:: 207
|
342
|
+
# HTTPAlreadyReported:: 208
|
339
343
|
# HTTPIMUsed:: 226
|
340
344
|
# HTTPRedirection:: 3xx
|
341
345
|
# HTTPMultipleChoices:: 300
|
@@ -345,6 +349,7 @@ module Net #:nodoc:
|
|
345
349
|
# HTTPNotModified:: 304
|
346
350
|
# HTTPUseProxy:: 305
|
347
351
|
# HTTPTemporaryRedirect:: 307
|
352
|
+
# HTTPPermanentRedirect:: 308
|
348
353
|
# HTTPClientError:: 4xx
|
349
354
|
# HTTPBadRequest:: 400
|
350
355
|
# HTTPUnauthorized:: 401
|
@@ -364,6 +369,7 @@ module Net #:nodoc:
|
|
364
369
|
# HTTPUnsupportedMediaType:: 415
|
365
370
|
# HTTPRequestedRangeNotSatisfiable:: 416
|
366
371
|
# HTTPExpectationFailed:: 417
|
372
|
+
# HTTPMisdirectedRequest:: 421
|
367
373
|
# HTTPUnprocessableEntity:: 422
|
368
374
|
# HTTPLocked:: 423
|
369
375
|
# HTTPFailedDependency:: 424
|
@@ -379,7 +385,10 @@ module Net #:nodoc:
|
|
379
385
|
# HTTPServiceUnavailable:: 503
|
380
386
|
# HTTPGatewayTimeOut:: 504
|
381
387
|
# HTTPVersionNotSupported:: 505
|
388
|
+
# HTTPVariantAlsoNegotiates:: 506
|
382
389
|
# HTTPInsufficientStorage:: 507
|
390
|
+
# HTTPLoopDetected:: 508
|
391
|
+
# HTTPNotExtended:: 510
|
383
392
|
# HTTPNetworkAuthenticationRequired:: 511
|
384
393
|
#
|
385
394
|
# There is also the Net::HTTPBadResponse exception which is raised when
|
@@ -388,7 +397,7 @@ module Net #:nodoc:
|
|
388
397
|
class HTTP < Protocol
|
389
398
|
|
390
399
|
# :stopdoc:
|
391
|
-
VERSION = "0.2.
|
400
|
+
VERSION = "0.2.1.pre1"
|
392
401
|
Revision = %q$Revision$.split[1]
|
393
402
|
HTTPVersion = '1.1'
|
394
403
|
begin
|
@@ -689,6 +698,8 @@ module Net #:nodoc:
|
|
689
698
|
@continue_timeout = nil
|
690
699
|
@max_retries = 1
|
691
700
|
@debug_output = nil
|
701
|
+
@response_body_encoding = false
|
702
|
+
@ignore_eof = true
|
692
703
|
|
693
704
|
@proxy_from_env = false
|
694
705
|
@proxy_uri = nil
|
@@ -736,6 +747,18 @@ module Net #:nodoc:
|
|
736
747
|
# The local port used to establish the connection.
|
737
748
|
attr_accessor :local_port
|
738
749
|
|
750
|
+
# The encoding to use for the response body. If Encoding, uses the
|
751
|
+
# specified encoding. If other true value, tries to detect the response
|
752
|
+
# body encoding.
|
753
|
+
attr_reader :response_body_encoding
|
754
|
+
|
755
|
+
# Set the encoding to use for the response body. If given a String, find
|
756
|
+
# the related Encoding.
|
757
|
+
def response_body_encoding=(value)
|
758
|
+
value = Encoding.find(value) if value.is_a?(String)
|
759
|
+
@response_body_encoding = value
|
760
|
+
end
|
761
|
+
|
739
762
|
attr_writer :proxy_from_env
|
740
763
|
attr_writer :proxy_address
|
741
764
|
attr_writer :proxy_port
|
@@ -817,6 +840,10 @@ module Net #:nodoc:
|
|
817
840
|
# The default value is 2 seconds.
|
818
841
|
attr_accessor :keep_alive_timeout
|
819
842
|
|
843
|
+
# Whether to ignore EOF when reading response bodies with defined
|
844
|
+
# Content-Length headers. For backwards compatibility, the default is true.
|
845
|
+
attr_accessor :ignore_eof
|
846
|
+
|
820
847
|
# Returns true if the HTTP session has been started.
|
821
848
|
def started?
|
822
849
|
@started
|
@@ -985,7 +1012,7 @@ module Net #:nodoc:
|
|
985
1012
|
conn_port = port
|
986
1013
|
end
|
987
1014
|
|
988
|
-
|
1015
|
+
debug "opening connection to #{conn_addr}:#{conn_port}..."
|
989
1016
|
begin
|
990
1017
|
s = Socket.tcp conn_addr, conn_port, @local_host, @local_port, connect_timeout: @open_timeout
|
991
1018
|
rescue => e
|
@@ -994,7 +1021,7 @@ module Net #:nodoc:
|
|
994
1021
|
"#{conn_addr}:#{conn_port} (#{e.message})"
|
995
1022
|
end
|
996
1023
|
s.setsockopt(Socket::IPPROTO_TCP, Socket::TCP_NODELAY, 1)
|
997
|
-
|
1024
|
+
debug "opened"
|
998
1025
|
if use_ssl?
|
999
1026
|
if proxy?
|
1000
1027
|
plain_sock = BufferedIO.new(s, read_timeout: @read_timeout,
|
@@ -1024,33 +1051,55 @@ module Net #:nodoc:
|
|
1024
1051
|
end
|
1025
1052
|
end
|
1026
1053
|
@ssl_context.set_params(ssl_parameters)
|
1027
|
-
@ssl_context.session_cache_mode
|
1028
|
-
|
1029
|
-
|
1030
|
-
|
1031
|
-
|
1054
|
+
unless @ssl_context.session_cache_mode.nil? # a dummy method on JRuby
|
1055
|
+
@ssl_context.session_cache_mode =
|
1056
|
+
OpenSSL::SSL::SSLContext::SESSION_CACHE_CLIENT |
|
1057
|
+
OpenSSL::SSL::SSLContext::SESSION_CACHE_NO_INTERNAL_STORE
|
1058
|
+
end
|
1059
|
+
if @ssl_context.respond_to?(:session_new_cb) # not implemented under JRuby
|
1060
|
+
@ssl_context.session_new_cb = proc {|sock, sess| @ssl_session = sess }
|
1061
|
+
end
|
1062
|
+
|
1063
|
+
# Still do the post_connection_check below even if connecting
|
1064
|
+
# to IP address
|
1065
|
+
verify_hostname = @ssl_context.verify_hostname
|
1066
|
+
|
1067
|
+
# Server Name Indication (SNI) RFC 3546/6066
|
1068
|
+
case @address
|
1069
|
+
when Resolv::IPv4::Regex, Resolv::IPv6::Regex
|
1070
|
+
# don't set SNI, as IP addresses in SNI is not valid
|
1071
|
+
# per RFC 6066, section 3.
|
1072
|
+
|
1073
|
+
# Avoid openssl warning
|
1074
|
+
@ssl_context.verify_hostname = false
|
1075
|
+
else
|
1076
|
+
ssl_host_address = @address
|
1077
|
+
end
|
1078
|
+
|
1079
|
+
debug "starting SSL for #{conn_addr}:#{conn_port}..."
|
1032
1080
|
s = OpenSSL::SSL::SSLSocket.new(s, @ssl_context)
|
1033
1081
|
s.sync_close = true
|
1034
|
-
|
1035
|
-
|
1082
|
+
s.hostname = ssl_host_address if s.respond_to?(:hostname=) && ssl_host_address
|
1083
|
+
|
1036
1084
|
if @ssl_session and
|
1037
1085
|
Process.clock_gettime(Process::CLOCK_REALTIME) < @ssl_session.time.to_f + @ssl_session.timeout
|
1038
1086
|
s.session = @ssl_session
|
1039
1087
|
end
|
1040
1088
|
ssl_socket_connect(s, @open_timeout)
|
1041
|
-
if (@ssl_context.verify_mode != OpenSSL::SSL::VERIFY_NONE) &&
|
1089
|
+
if (@ssl_context.verify_mode != OpenSSL::SSL::VERIFY_NONE) && verify_hostname
|
1042
1090
|
s.post_connection_check(@address)
|
1043
1091
|
end
|
1044
|
-
|
1092
|
+
debug "SSL established, protocol: #{s.ssl_version}, cipher: #{s.cipher[0]}"
|
1045
1093
|
end
|
1046
1094
|
@socket = BufferedIO.new(s, read_timeout: @read_timeout,
|
1047
1095
|
write_timeout: @write_timeout,
|
1048
1096
|
continue_timeout: @continue_timeout,
|
1049
1097
|
debug_output: @debug_output)
|
1098
|
+
@last_communicated = nil
|
1050
1099
|
on_connect
|
1051
1100
|
rescue => exception
|
1052
1101
|
if s
|
1053
|
-
|
1102
|
+
debug "Conn close because of connect error #{exception}"
|
1054
1103
|
s.close
|
1055
1104
|
end
|
1056
1105
|
raise
|
@@ -1565,6 +1614,8 @@ module Net #:nodoc:
|
|
1565
1614
|
begin
|
1566
1615
|
res = HTTPResponse.read_new(@socket)
|
1567
1616
|
res.decode_content = req.decode_content
|
1617
|
+
res.body_encoding = @response_body_encoding
|
1618
|
+
res.ignore_eof = @ignore_eof
|
1568
1619
|
end while res.kind_of?(HTTPInformation)
|
1569
1620
|
|
1570
1621
|
res.uri = req.uri
|
@@ -1584,10 +1635,10 @@ module Net #:nodoc:
|
|
1584
1635
|
if count < max_retries && IDEMPOTENT_METHODS_.include?(req.method)
|
1585
1636
|
count += 1
|
1586
1637
|
@socket.close if @socket
|
1587
|
-
|
1638
|
+
debug "Conn close because of error #{exception}, and retry"
|
1588
1639
|
retry
|
1589
1640
|
end
|
1590
|
-
|
1641
|
+
debug "Conn close because of error #{exception}"
|
1591
1642
|
@socket.close if @socket
|
1592
1643
|
raise
|
1593
1644
|
end
|
@@ -1595,7 +1646,7 @@ module Net #:nodoc:
|
|
1595
1646
|
end_transport req, res
|
1596
1647
|
res
|
1597
1648
|
rescue => exception
|
1598
|
-
|
1649
|
+
debug "Conn close because of error #{exception}"
|
1599
1650
|
@socket.close if @socket
|
1600
1651
|
raise exception
|
1601
1652
|
end
|
@@ -1605,11 +1656,11 @@ module Net #:nodoc:
|
|
1605
1656
|
connect
|
1606
1657
|
elsif @last_communicated
|
1607
1658
|
if @last_communicated + @keep_alive_timeout < Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
1608
|
-
|
1659
|
+
debug 'Conn close because of keep_alive_timeout'
|
1609
1660
|
@socket.close
|
1610
1661
|
connect
|
1611
1662
|
elsif @socket.io.to_io.wait_readable(0) && @socket.eof?
|
1612
|
-
|
1663
|
+
debug "Conn close because of EOF"
|
1613
1664
|
@socket.close
|
1614
1665
|
connect
|
1615
1666
|
end
|
@@ -1627,15 +1678,15 @@ module Net #:nodoc:
|
|
1627
1678
|
@curr_http_version = res.http_version
|
1628
1679
|
@last_communicated = nil
|
1629
1680
|
if @socket.closed?
|
1630
|
-
|
1681
|
+
debug 'Conn socket closed'
|
1631
1682
|
elsif not res.body and @close_on_empty_response
|
1632
|
-
|
1683
|
+
debug 'Conn close'
|
1633
1684
|
@socket.close
|
1634
1685
|
elsif keep_alive?(req, res)
|
1635
|
-
|
1686
|
+
debug 'Conn keep-alive'
|
1636
1687
|
@last_communicated = Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
1637
1688
|
else
|
1638
|
-
|
1689
|
+
debug 'Conn close'
|
1639
1690
|
@socket.close
|
1640
1691
|
end
|
1641
1692
|
end
|
@@ -1690,11 +1741,14 @@ module Net #:nodoc:
|
|
1690
1741
|
default_port == port ? addr : "#{addr}:#{port}"
|
1691
1742
|
end
|
1692
1743
|
|
1693
|
-
|
1744
|
+
# Adds a message to debugging output
|
1745
|
+
def debug(msg)
|
1694
1746
|
return unless @debug_output
|
1695
1747
|
@debug_output << msg
|
1696
1748
|
@debug_output << "\n"
|
1697
1749
|
end
|
1750
|
+
|
1751
|
+
alias_method :D, :debug
|
1698
1752
|
end
|
1699
1753
|
|
1700
1754
|
end
|
data/net-http.gemspec
CHANGED
@@ -28,9 +28,7 @@ Gem::Specification.new do |spec|
|
|
28
28
|
`git ls-files -z 2>/dev/null`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
29
29
|
end
|
30
30
|
spec.bindir = "exe"
|
31
|
-
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
32
31
|
spec.require_paths = ["lib"]
|
33
32
|
|
34
|
-
spec.add_dependency "net-protocol"
|
35
33
|
spec.add_dependency "uri"
|
36
34
|
end
|
metadata
CHANGED
@@ -1,38 +1,24 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: net-http
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.1.pre1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- NARUSE, Yui
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2022-04-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
|
-
name: net-protocol
|
15
14
|
requirement: !ruby/object:Gem::Requirement
|
16
15
|
requirements:
|
17
16
|
- - ">="
|
18
17
|
- !ruby/object:Gem::Version
|
19
18
|
version: '0'
|
20
|
-
type: :runtime
|
21
|
-
prerelease: false
|
22
|
-
version_requirements: !ruby/object:Gem::Requirement
|
23
|
-
requirements:
|
24
|
-
- - ">="
|
25
|
-
- !ruby/object:Gem::Version
|
26
|
-
version: '0'
|
27
|
-
- !ruby/object:Gem::Dependency
|
28
19
|
name: uri
|
29
|
-
requirement: !ruby/object:Gem::Requirement
|
30
|
-
requirements:
|
31
|
-
- - ">="
|
32
|
-
- !ruby/object:Gem::Version
|
33
|
-
version: '0'
|
34
|
-
type: :runtime
|
35
20
|
prerelease: false
|
21
|
+
type: :runtime
|
36
22
|
version_requirements: !ruby/object:Gem::Requirement
|
37
23
|
requirements:
|
38
24
|
- - ">="
|
@@ -45,10 +31,10 @@ executables: []
|
|
45
31
|
extensions: []
|
46
32
|
extra_rdoc_files: []
|
47
33
|
files:
|
34
|
+
- ".github/dependabot.yml"
|
48
35
|
- ".github/workflows/test.yml"
|
49
36
|
- ".gitignore"
|
50
37
|
- Gemfile
|
51
|
-
- Gemfile.lock
|
52
38
|
- LICENSE.txt
|
53
39
|
- README.md
|
54
40
|
- Rakefile
|
@@ -85,11 +71,11 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
85
71
|
version: 2.6.0
|
86
72
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
87
73
|
requirements:
|
88
|
-
- - "
|
74
|
+
- - ">"
|
89
75
|
- !ruby/object:Gem::Version
|
90
|
-
version:
|
76
|
+
version: 1.3.1
|
91
77
|
requirements: []
|
92
|
-
rubygems_version: 3.3.
|
78
|
+
rubygems_version: 3.3.3
|
93
79
|
signing_key:
|
94
80
|
specification_version: 4
|
95
81
|
summary: HTTP client api for Ruby.
|
data/Gemfile.lock
DELETED
@@ -1,33 +0,0 @@
|
|
1
|
-
PATH
|
2
|
-
remote: .
|
3
|
-
specs:
|
4
|
-
net-http (0.1.1)
|
5
|
-
net-protocol
|
6
|
-
uri
|
7
|
-
|
8
|
-
GEM
|
9
|
-
remote: https://rubygems.org/
|
10
|
-
specs:
|
11
|
-
io-wait (0.1.0)
|
12
|
-
net-protocol (0.1.0)
|
13
|
-
io-wait
|
14
|
-
timeout
|
15
|
-
power_assert (1.1.5)
|
16
|
-
rake (13.0.1)
|
17
|
-
test-unit (3.3.5)
|
18
|
-
power_assert
|
19
|
-
timeout (0.1.1)
|
20
|
-
uri (0.10.1)
|
21
|
-
webrick (1.7.0)
|
22
|
-
|
23
|
-
PLATFORMS
|
24
|
-
ruby
|
25
|
-
|
26
|
-
DEPENDENCIES
|
27
|
-
net-http!
|
28
|
-
rake
|
29
|
-
test-unit
|
30
|
-
webrick
|
31
|
-
|
32
|
-
BUNDLED WITH
|
33
|
-
2.1.4
|