net-http 0.2.0 → 0.2.1.pre1
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/.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
|