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.
Files changed (59) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +22 -0
  3. data/Manifest.txt +1 -1
  4. data/bundler/CHANGELOG.md +28 -0
  5. data/bundler/lib/bundler/build_metadata.rb +2 -2
  6. data/bundler/lib/bundler/cli/lock.rb +14 -3
  7. data/bundler/lib/bundler/cli/platform.rb +15 -1
  8. data/bundler/lib/bundler/cli.rb +17 -5
  9. data/bundler/lib/bundler/fetcher/downloader.rb +10 -4
  10. data/bundler/lib/bundler/installer.rb +4 -0
  11. data/bundler/lib/bundler/man/bundle-lock.1 +1 -1
  12. data/bundler/lib/bundler/man/bundle-lock.1.ronn +1 -1
  13. data/bundler/lib/bundler/man/bundle-outdated.1 +1 -1
  14. data/bundler/lib/bundler/man/bundle-outdated.1.ronn +1 -1
  15. data/bundler/lib/bundler/man/bundle-update.1 +2 -2
  16. data/bundler/lib/bundler/man/bundle-update.1.ronn +2 -2
  17. data/bundler/lib/bundler/templates/newgem/ext/newgem/Cargo.toml.tt +1 -1
  18. data/bundler/lib/bundler/vendor/connection_pool/lib/connection_pool/timed_stack.rb +14 -4
  19. data/bundler/lib/bundler/vendor/connection_pool/lib/connection_pool/version.rb +1 -1
  20. data/bundler/lib/bundler/vendor/connection_pool/lib/connection_pool.rb +3 -0
  21. data/bundler/lib/bundler/vendor/fileutils/lib/fileutils.rb +54 -29
  22. data/bundler/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent/pool.rb +1 -1
  23. data/bundler/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent/timed_stack_multi.rb +10 -1
  24. data/bundler/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent.rb +12 -6
  25. data/bundler/lib/bundler/vendor/thor/lib/thor/actions/inject_into_file.rb +35 -2
  26. data/bundler/lib/bundler/vendor/thor/lib/thor/base.rb +2 -1
  27. data/bundler/lib/bundler/vendor/thor/lib/thor/shell/basic.rb +14 -6
  28. data/bundler/lib/bundler/vendor/thor/lib/thor/shell/color.rb +2 -0
  29. data/bundler/lib/bundler/vendor/thor/lib/thor/version.rb +1 -1
  30. data/bundler/lib/bundler/vendor/thor/lib/thor.rb +34 -1
  31. data/bundler/lib/bundler/vendor/uri/lib/uri/common.rb +1 -1
  32. data/bundler/lib/bundler/vendor/uri/lib/uri/generic.rb +15 -3
  33. data/bundler/lib/bundler/vendor/uri/lib/uri/version.rb +1 -1
  34. data/bundler/lib/bundler/version.rb +1 -1
  35. data/bundler/lib/bundler.rb +1 -3
  36. data/lib/rubygems/commands/exec_command.rb +3 -0
  37. data/lib/rubygems/ext/builder.rb +7 -2
  38. data/lib/rubygems/gemcutter_utilities/webauthn_listener.rb +9 -0
  39. data/lib/rubygems/installer.rb +4 -0
  40. data/lib/rubygems/package.rb +36 -5
  41. data/lib/rubygems/uninstaller.rb +1 -0
  42. data/lib/rubygems/vendor/net-http/lib/net/http/exceptions.rb +2 -1
  43. data/lib/rubygems/vendor/net-http/lib/net/http/generic_request.rb +15 -7
  44. data/lib/rubygems/vendor/net-http/lib/net/http/header.rb +64 -19
  45. data/lib/rubygems/vendor/net-http/lib/net/http/request.rb +1 -0
  46. data/lib/rubygems/vendor/net-http/lib/net/http/requests.rb +74 -25
  47. data/lib/rubygems/vendor/net-http/lib/net/http/response.rb +42 -16
  48. data/lib/rubygems/vendor/net-http/lib/net/http/responses.rb +68 -0
  49. data/lib/rubygems/vendor/net-http/lib/net/http.rb +129 -37
  50. data/lib/rubygems/vendor/net-protocol/COPYING +56 -0
  51. data/lib/rubygems/vendor/net-protocol/lib/net/protocol.rb +95 -26
  52. data/lib/rubygems/vendor/optparse/lib/optparse.rb +23 -30
  53. data/lib/rubygems/vendor/timeout/lib/timeout.rb +190 -77
  54. data/lib/rubygems/vendor/uri/lib/uri/common.rb +1 -1
  55. data/lib/rubygems/vendor/uri/lib/uri/generic.rb +15 -3
  56. data/lib/rubygems/vendor/uri/lib/uri/version.rb +1 -1
  57. data/lib/rubygems.rb +1 -1
  58. metadata +2 -2
  59. data/lib/rubygems/vendor/net-protocol/LICENSE.txt +0 -22
@@ -36,7 +36,7 @@ module Gem::Net #:nodoc:
36
36
  # For information about \HTTP, see:
37
37
  #
38
38
  # - {Hypertext Transfer Protocol}[https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol].
39
- # - {Technical overview}[https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Technical_overview].
39
+ # - {Technology}[https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Technology].
40
40
  #
41
41
  # == About the Examples
42
42
  #
@@ -71,7 +71,7 @@ module Gem::Net #:nodoc:
71
71
  #
72
72
  # - If performance is important, consider using sessions, which lower request overhead.
73
73
  # This {session}[rdoc-ref:Gem::Net::HTTP@Sessions] has multiple requests for
74
- # {HTTP methods}[https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Request_methods]
74
+ # {HTTP methods}[https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Method]
75
75
  # and {WebDAV methods}[https://en.wikipedia.org/wiki/WebDAV#Implementation]:
76
76
  #
77
77
  # Gem::Net::HTTP.start(hostname) do |http|
@@ -81,6 +81,7 @@ module Gem::Net #:nodoc:
81
81
  # body = 'Some text'
82
82
  # http.post(path, body) # Can also have a block.
83
83
  # http.put(path, body)
84
+ # http.query(path, body) # Can also have a block.
84
85
  # http.delete(path)
85
86
  # http.options(path)
86
87
  # http.trace(path)
@@ -197,7 +198,7 @@ module Gem::Net #:nodoc:
197
198
  # In the block, you can use these instance methods,
198
199
  # each of which that sends a single request:
199
200
  #
200
- # - {HTTP methods}[https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Request_methods]:
201
+ # - {HTTP methods}[https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Method]:
201
202
  #
202
203
  # - #get, #request_get: GET.
203
204
  # - #head, #request_head: HEAD.
@@ -206,6 +207,7 @@ module Gem::Net #:nodoc:
206
207
  # - #options: OPTIONS.
207
208
  # - #trace: TRACE.
208
209
  # - #patch: PATCH.
210
+ # - #query, #request_query: QUERY.
209
211
  #
210
212
  # - {WebDAV methods}[https://en.wikipedia.org/wiki/WebDAV#Implementation]:
211
213
  #
@@ -446,7 +448,7 @@ module Gem::Net #:nodoc:
446
448
  # if the response has header <tt>'Content-Range'</tt>.
447
449
  #
448
450
  # Otherwise decompression (or not) depends on the value of header
449
- # {Content-Encoding}[https://en.wikipedia.org/wiki/List_of_HTTP_header_fields#content-encoding-response-header]:
451
+ # {Content-Encoding}[https://en.wikipedia.org/wiki/List_of_HTTP_header_fields#Content-Encoding_2]:
450
452
  #
451
453
  # - <tt>'deflate'</tt>, <tt>'gzip'</tt>, or <tt>'x-gzip'</tt>:
452
454
  # decompresses the body and deletes the header.
@@ -459,7 +461,7 @@ module Gem::Net #:nodoc:
459
461
  #
460
462
  # First, what's elsewhere. Class Gem::Net::HTTP:
461
463
  #
462
- # - Inherits from {class Object}[https://docs.ruby-lang.org/en/master/Object.html#class-Object-label-What-27s+Here].
464
+ # - Inherits from {class Object}[https://docs.ruby-lang.org/en/master/Object.html#class-object-whats-here].
463
465
  #
464
466
  # This is a categorized summary of methods and attributes.
465
467
  #
@@ -552,6 +554,8 @@ module Gem::Net #:nodoc:
552
554
  # Sends a PROPPATCH request and returns a response object.
553
555
  # - {#put}[rdoc-ref:Gem::Net::HTTP#put]:
554
556
  # Sends a PUT request and returns a response object.
557
+ # - {#query}[rdoc-ref:Gem::Net::HTTP#query]:
558
+ # Sends a QUERY request and returns a response object.
555
559
  # - {#request}[rdoc-ref:Gem::Net::HTTP#request]:
556
560
  # Sends a request and returns a response object.
557
561
  # - {#request_get}[rdoc-ref:Gem::Net::HTTP#request_get]:
@@ -723,7 +727,7 @@ module Gem::Net #:nodoc:
723
727
  class HTTP < Protocol
724
728
 
725
729
  # :stopdoc:
726
- VERSION = "0.7.0"
730
+ VERSION = "0.10.0"
727
731
  HTTPVersion = '1.1'
728
732
  begin
729
733
  require 'zlib'
@@ -1178,6 +1182,7 @@ module Gem::Net #:nodoc:
1178
1182
  @debug_output = options[:debug_output]
1179
1183
  @response_body_encoding = options[:response_body_encoding]
1180
1184
  @ignore_eof = options[:ignore_eof]
1185
+ @tcpsocket_supports_open_timeout = nil
1181
1186
 
1182
1187
  @proxy_from_env = false
1183
1188
  @proxy_uri = nil
@@ -1302,7 +1307,7 @@ module Gem::Net #:nodoc:
1302
1307
 
1303
1308
  # Sets whether to determine the proxy from environment variable
1304
1309
  # '<tt>ENV['http_proxy']</tt>';
1305
- # see {Proxy Using ENV['http_proxy']}[rdoc-ref:Gem::Net::HTTP@Proxy+Using+-27ENV-5B-27http_proxy-27-5D-27].
1310
+ # see {Proxy Using ENV}[rdoc-ref:Gem::Net::HTTP@Proxy+Using+ENVHTTPProxy].
1306
1311
  attr_writer :proxy_from_env
1307
1312
 
1308
1313
  # Sets the proxy address;
@@ -1320,6 +1325,9 @@ module Gem::Net #:nodoc:
1320
1325
  # Sets the proxy password;
1321
1326
  # see {Proxy Server}[rdoc-ref:Gem::Net::HTTP@Proxy+Server].
1322
1327
  attr_writer :proxy_pass
1328
+
1329
+ # Sets whether the proxy uses SSL;
1330
+ # see {Proxy Server}[rdoc-ref:Gem::Net::HTTP@Proxy+Server].
1323
1331
  attr_writer :proxy_use_ssl
1324
1332
 
1325
1333
  # Returns the IP address for the connection.
@@ -1526,7 +1534,7 @@ module Gem::Net #:nodoc:
1526
1534
  :verify_depth,
1527
1535
  :verify_mode,
1528
1536
  :verify_hostname,
1529
- ] # :nodoc:
1537
+ ].freeze # :nodoc:
1530
1538
 
1531
1539
  SSL_IVNAMES = SSL_ATTRIBUTES.map { |a| "@#{a}".to_sym }.freeze # :nodoc:
1532
1540
 
@@ -1568,11 +1576,11 @@ module Gem::Net #:nodoc:
1568
1576
  attr_accessor :cert_store
1569
1577
 
1570
1578
  # Sets or returns the available SSL ciphers.
1571
- # See {OpenSSL::SSL::SSLContext#ciphers=}[OpenSSL::SSL::SSL::Context#ciphers=].
1579
+ # See {OpenSSL::SSL::SSLContext#ciphers=}[https://docs.ruby-lang.org/en/master/OpenSSL/SSL/SSLContext.html#method-i-ciphers-3D].
1572
1580
  attr_accessor :ciphers
1573
1581
 
1574
1582
  # Sets or returns the extra X509 certificates to be added to the certificate chain.
1575
- # See {OpenSSL::SSL::SSLContext#add_certificate}[OpenSSL::SSL::SSL::Context#add_certificate].
1583
+ # See {OpenSSL::SSL::SSLContext#add_certificate}[https://docs.ruby-lang.org/en/master/OpenSSL/SSL/SSLContext.html#method-i-add_certificate].
1576
1584
  attr_accessor :extra_chain_cert
1577
1585
 
1578
1586
  # Sets or returns the OpenSSL::PKey::RSA or OpenSSL::PKey::DSA object.
@@ -1582,15 +1590,15 @@ module Gem::Net #:nodoc:
1582
1590
  attr_accessor :ssl_timeout
1583
1591
 
1584
1592
  # Sets or returns the SSL version.
1585
- # See {OpenSSL::SSL::SSLContext#ssl_version=}[OpenSSL::SSL::SSL::Context#ssl_version=].
1593
+ # See {OpenSSL::SSL::SSLContext#ssl_version=}[https://docs.ruby-lang.org/en/master/OpenSSL/SSL/SSLContext.html#method-i-ssl_version-3D].
1586
1594
  attr_accessor :ssl_version
1587
1595
 
1588
1596
  # Sets or returns the minimum SSL version.
1589
- # See {OpenSSL::SSL::SSLContext#min_version=}[OpenSSL::SSL::SSL::Context#min_version=].
1597
+ # See {OpenSSL::SSL::SSLContext#min_version=}[https://docs.ruby-lang.org/en/master/OpenSSL/SSL/SSLContext.html#method-i-min_version-3D].
1590
1598
  attr_accessor :min_version
1591
1599
 
1592
1600
  # Sets or returns the maximum SSL version.
1593
- # See {OpenSSL::SSL::SSLContext#max_version=}[OpenSSL::SSL::SSL::Context#max_version=].
1601
+ # See {OpenSSL::SSL::SSLContext#max_version=}[https://docs.ruby-lang.org/en/master/OpenSSL/SSL/SSLContext.html#method-i-max_version-3D].
1594
1602
  attr_accessor :max_version
1595
1603
 
1596
1604
  # Sets or returns the callback for the server certification verification.
@@ -1606,7 +1614,7 @@ module Gem::Net #:nodoc:
1606
1614
 
1607
1615
  # Sets or returns whether to verify that the server certificate is valid
1608
1616
  # for the hostname.
1609
- # See {OpenSSL::SSL::SSLContext#verify_hostname=}[OpenSSL::SSL::SSL::Context#verify_hostname=].
1617
+ # See {OpenSSL::SSL::SSLContext#verify_hostname=}[https://docs.ruby-lang.org/en/master/OpenSSL/SSL/SSLContext.html#attribute-i-verify_hostname].
1610
1618
  attr_accessor :verify_hostname
1611
1619
 
1612
1620
  # Returns the X509 certificate chain (an array of strings)
@@ -1654,6 +1662,21 @@ module Gem::Net #:nodoc:
1654
1662
  self
1655
1663
  end
1656
1664
 
1665
+ # Finishes the \HTTP session:
1666
+ #
1667
+ # http = Gem::Net::HTTP.new(hostname)
1668
+ # http.start
1669
+ # http.started? # => true
1670
+ # http.finish # => nil
1671
+ # http.started? # => false
1672
+ #
1673
+ # Raises IOError if not in a session.
1674
+ def finish
1675
+ raise IOError, 'HTTP session not yet started' unless started?
1676
+ do_finish
1677
+ end
1678
+
1679
+ # :stopdoc:
1657
1680
  def do_start
1658
1681
  connect
1659
1682
  @started = true
@@ -1676,14 +1699,15 @@ module Gem::Net #:nodoc:
1676
1699
  end
1677
1700
 
1678
1701
  debug "opening connection to #{conn_addr}:#{conn_port}..."
1679
- s = Gem::Timeout.timeout(@open_timeout, Gem::Net::OpenTimeout) {
1680
- begin
1681
- TCPSocket.open(conn_addr, conn_port, @local_host, @local_port)
1682
- rescue => e
1683
- raise e, "Failed to open TCP connection to " +
1684
- "#{conn_addr}:#{conn_port} (#{e.message})"
1702
+ begin
1703
+ s = timeouted_connect(conn_addr, conn_port)
1704
+ rescue => e
1705
+ if (defined?(IO::TimeoutError) && e.is_a?(IO::TimeoutError)) || e.is_a?(Errno::ETIMEDOUT) # for compatibility with previous versions
1706
+ e = Gem::Net::OpenTimeout.new(e)
1685
1707
  end
1686
- }
1708
+ raise e, "Failed to open TCP connection to " +
1709
+ "#{conn_addr}:#{conn_port} (#{e.message})"
1710
+ end
1687
1711
  s.setsockopt(Socket::IPPROTO_TCP, Socket::TCP_NODELAY, 1)
1688
1712
  debug "opened"
1689
1713
  if use_ssl?
@@ -1776,23 +1800,30 @@ module Gem::Net #:nodoc:
1776
1800
  end
1777
1801
  private :connect
1778
1802
 
1779
- def on_connect
1803
+ tcp_socket_parameters = TCPSocket.instance_method(:initialize).parameters
1804
+ TCP_SOCKET_NEW_HAS_OPEN_TIMEOUT = if tcp_socket_parameters != [[:rest]]
1805
+ tcp_socket_parameters.include?([:key, :open_timeout])
1806
+ else
1807
+ # Use Socket.tcp to find out since there is no parameters information for TCPSocket#initialize
1808
+ # See discussion in https://github.com/ruby/net-http/pull/224
1809
+ Socket.method(:tcp).parameters.include?([:key, :open_timeout])
1780
1810
  end
1781
- private :on_connect
1811
+ private_constant :TCP_SOCKET_NEW_HAS_OPEN_TIMEOUT
1782
1812
 
1783
- # Finishes the \HTTP session:
1784
- #
1785
- # http = Gem::Net::HTTP.new(hostname)
1786
- # http.start
1787
- # http.started? # => true
1788
- # http.finish # => nil
1789
- # http.started? # => false
1790
- #
1791
- # Raises IOError if not in a session.
1792
- def finish
1793
- raise IOError, 'HTTP session not yet started' unless started?
1794
- do_finish
1813
+ def timeouted_connect(conn_addr, conn_port)
1814
+ if TCP_SOCKET_NEW_HAS_OPEN_TIMEOUT
1815
+ TCPSocket.open(conn_addr, conn_port, @local_host, @local_port, open_timeout: @open_timeout)
1816
+ else
1817
+ Gem::Timeout.timeout(@open_timeout, Gem::Net::OpenTimeout) {
1818
+ TCPSocket.open(conn_addr, conn_port, @local_host, @local_port)
1819
+ }
1820
+ end
1821
+ end
1822
+ private :timeouted_connect
1823
+
1824
+ def on_connect
1795
1825
  end
1826
+ private :on_connect
1796
1827
 
1797
1828
  def do_finish
1798
1829
  @started = false
@@ -1843,6 +1874,8 @@ module Gem::Net #:nodoc:
1843
1874
  }
1844
1875
  end
1845
1876
 
1877
+ # :startdoc:
1878
+
1846
1879
  class << HTTP
1847
1880
  # Returns true if self is a class which was created by HTTP::Proxy.
1848
1881
  def proxy_class?
@@ -1937,6 +1970,7 @@ module Gem::Net #:nodoc:
1937
1970
  alias proxyport proxy_port #:nodoc: obsolete
1938
1971
 
1939
1972
  private
1973
+ # :stopdoc:
1940
1974
 
1941
1975
  def unescape(value)
1942
1976
  require 'cgi/escape'
@@ -1965,6 +1999,7 @@ module Gem::Net #:nodoc:
1965
1999
  path
1966
2000
  end
1967
2001
  end
2002
+ # :startdoc:
1968
2003
 
1969
2004
  #
1970
2005
  # HTTP operations
@@ -2092,6 +2127,25 @@ module Gem::Net #:nodoc:
2092
2127
  send_entity(path, data, initheader, dest, Patch, &block)
2093
2128
  end
2094
2129
 
2130
+ # Sends a QUERY request to the server;
2131
+ # returns an instance of a subclass of Gem::Net::HTTPResponse.
2132
+ #
2133
+ # The request is based on the Gem::Net::HTTP::Query object
2134
+ # created from string +path+, string +data+, and initial headers hash +initheader+.
2135
+ #
2136
+ # data = '{"userId": 1, "id": 1, "title": "delectus aut autem", "completed": false}'
2137
+ # http = Gem::Net::HTTP.new(hostname)
2138
+ # http.query('/todos/1', data) # => #<Gem::Net::HTTPOK 200 OK readbody=true>
2139
+ #
2140
+ # Related:
2141
+ #
2142
+ # - Gem::Net::HTTP::Query: request class for \HTTP method QUERY.
2143
+ # - Gem::Net::HTTP.query: sends QUERY request, returns response body.
2144
+ #
2145
+ def query(path, data, initheader = nil, dest = nil, &block) # :yield: +body_segment+
2146
+ send_entity(path, data, initheader, dest, Query, &block)
2147
+ end
2148
+
2095
2149
  # Sends a PUT request to the server;
2096
2150
  # returns an instance of a subclass of Gem::Net::HTTPResponse.
2097
2151
  #
@@ -2326,6 +2380,36 @@ module Gem::Net #:nodoc:
2326
2380
  request Put.new(path, initheader), data, &block
2327
2381
  end
2328
2382
 
2383
+ # Sends a QUERY request to the server;
2384
+ # returns an instance of a subclass of Gem::Net::HTTPResponse.
2385
+ #
2386
+ # The request is based on the Gem::Net::HTTP::Query object
2387
+ # created from string +path+, string +body+, and initial headers hash +initheader+.
2388
+ #
2389
+ # http = Gem::Net::HTTP.new(hostname)
2390
+ # http.query('/todos/1', 'xyzzy')
2391
+ # # => #<Gem::Net::HTTPOK 200 OK readbody=true>
2392
+ #
2393
+ # With no block given, returns the response object:
2394
+ #
2395
+ # http = Gem::Net::HTTP.new(hostname)
2396
+ # http.request_query('/todos') # => #<Gem::Net::HTTPOK 200 OK readbody=true>
2397
+ #
2398
+ # With a block given, calls the block with the response object
2399
+ # and returns the response object:
2400
+ #
2401
+ # http.request_query('/todos') do |res|
2402
+ # p res
2403
+ # end # => #<Gem::Net::HTTPOK 200 OK readbody=true>
2404
+ #
2405
+ # Output:
2406
+ #
2407
+ # #<Gem::Net::HTTPOK 200 OK readbody=false>
2408
+ #
2409
+ def request_query(path, data, initheader = nil, &block) # :yield: +response+
2410
+ request Query.new(path, initheader), data, &block
2411
+ end
2412
+
2329
2413
  alias get2 request_get #:nodoc: obsolete
2330
2414
  alias head2 request_head #:nodoc: obsolete
2331
2415
  alias post2 request_post #:nodoc: obsolete
@@ -2419,7 +2503,9 @@ module Gem::Net #:nodoc:
2419
2503
  res
2420
2504
  end
2421
2505
 
2422
- IDEMPOTENT_METHODS_ = %w/GET HEAD PUT DELETE OPTIONS TRACE/ # :nodoc:
2506
+ # :stopdoc:
2507
+
2508
+ IDEMPOTENT_METHODS_ = %w/GET HEAD PUT DELETE OPTIONS TRACE QUERY/.freeze # :nodoc:
2423
2509
 
2424
2510
  def transport_request(req)
2425
2511
  count = 0
@@ -2433,11 +2519,17 @@ module Gem::Net #:nodoc:
2433
2519
  # still read the received response.
2434
2520
  end
2435
2521
 
2522
+ informational_count = 0
2436
2523
  begin
2437
2524
  res = HTTPResponse.read_new(@socket)
2438
2525
  res.decode_content = req.decode_content
2439
2526
  res.body_encoding = @response_body_encoding
2440
2527
  res.ignore_eof = @ignore_eof
2528
+ if res.kind_of?(HTTPInformation)
2529
+ informational_count += 1
2530
+ raise HTTPBadResponse, 'too many informational responses' if
2531
+ informational_count > HTTPResponse::MAX_INFORMATIONAL_RESPONSES
2532
+ end
2441
2533
  end while res.kind_of?(HTTPInformation)
2442
2534
 
2443
2535
  res.uri = req.uri
@@ -2576,7 +2668,7 @@ module Gem::Net #:nodoc:
2576
2668
  alias_method :D, :debug
2577
2669
  end
2578
2670
 
2579
- # for backward compatibility until Ruby 3.5
2671
+ # for backward compatibility until Ruby 4.0
2580
2672
  # https://bugs.ruby-lang.org/issues/20900
2581
2673
  # https://github.com/bblimke/webmock/pull/1081
2582
2674
  HTTPSession = HTTP
@@ -0,0 +1,56 @@
1
+ Ruby is copyrighted free software by Yukihiro Matsumoto <matz@netlab.jp>.
2
+ You can redistribute it and/or modify it under either the terms of the
3
+ 2-clause BSDL (see the file BSDL), or the conditions below:
4
+
5
+ 1. You may make and give away verbatim copies of the source form of the
6
+ software without restriction, provided that you duplicate all of the
7
+ original copyright notices and associated disclaimers.
8
+
9
+ 2. You may modify your copy of the software in any way, provided that
10
+ you do at least ONE of the following:
11
+
12
+ a. place your modifications in the Public Domain or otherwise
13
+ make them Freely Available, such as by posting said
14
+ modifications to Usenet or an equivalent medium, or by allowing
15
+ the author to include your modifications in the software.
16
+
17
+ b. use the modified software only within your corporation or
18
+ organization.
19
+
20
+ c. give non-standard binaries non-standard names, with
21
+ instructions on where to get the original software distribution.
22
+
23
+ d. make other distribution arrangements with the author.
24
+
25
+ 3. You may distribute the software in object code or binary form,
26
+ provided that you do at least ONE of the following:
27
+
28
+ a. distribute the binaries and library files of the software,
29
+ together with instructions (in the manual page or equivalent)
30
+ on where to get the original distribution.
31
+
32
+ b. accompany the distribution with the machine-readable source of
33
+ the software.
34
+
35
+ c. give non-standard binaries non-standard names, with
36
+ instructions on where to get the original software distribution.
37
+
38
+ d. make other distribution arrangements with the author.
39
+
40
+ 4. You may modify and include the part of the software into any other
41
+ software (possibly commercial). But some files in the distribution
42
+ are not written by the author, so that they are not under these terms.
43
+
44
+ For the list of those files and their copying conditions, see the
45
+ file LEGAL.
46
+
47
+ 5. The scripts and library files supplied as input to or produced as
48
+ output from the software do not automatically fall under the
49
+ copyright of the software, but belong to whomever generated them,
50
+ and may be sold commercially, and may be aggregated with this
51
+ software.
52
+
53
+ 6. THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR
54
+ IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
55
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
56
+ PURPOSE.
@@ -21,12 +21,12 @@
21
21
 
22
22
  require 'socket'
23
23
  require_relative '../../../timeout/lib/timeout'
24
- require 'io/wait'
24
+ require 'io/wait' if RUBY_VERSION < '3.2'
25
25
 
26
26
  module Gem::Net # :nodoc:
27
27
 
28
28
  class Protocol #:nodoc: internal use only
29
- VERSION = "0.2.2"
29
+ VERSION = "0.4.0"
30
30
 
31
31
  private
32
32
  def Protocol.protocol_param(name, val)
@@ -54,9 +54,20 @@ module Gem::Net # :nodoc:
54
54
  s.connect
55
55
  end
56
56
  end
57
+
58
+ tcp_socket_parameters = TCPSocket.instance_method(:initialize).parameters
59
+ TCP_SOCKET_NEW_HAS_OPEN_TIMEOUT = if tcp_socket_parameters != [[:rest]]
60
+ tcp_socket_parameters.include?([:key, :open_timeout])
61
+ else
62
+ # Use Socket.tcp to find out since there is no parameters information for TCPSocket#initialize
63
+ # See discussion in https://github.com/ruby/net-http/pull/224
64
+ Socket.method(:tcp).parameters.include?([:key, :open_timeout])
65
+ end
66
+ private_constant :TCP_SOCKET_NEW_HAS_OPEN_TIMEOUT
57
67
  end
58
68
 
59
69
 
70
+ # :stopdoc:
60
71
  class ProtocolError < StandardError; end
61
72
  class ProtoSyntaxError < ProtocolError; end
62
73
  class ProtoFatalError < ProtocolError; end
@@ -66,6 +77,29 @@ module Gem::Net # :nodoc:
66
77
  class ProtoCommandError < ProtocolError; end
67
78
  class ProtoRetriableError < ProtocolError; end
68
79
  ProtocRetryError = ProtoRetriableError
80
+ # :startdoc:
81
+
82
+ ##
83
+ # ReadLimitExceeded, a subclass of ProtocolError, is raised if the
84
+ # terminator is not found within the byte limit given to
85
+ # Gem::Net::BufferedIO#readuntil.
86
+ #
87
+ # The limit is the largest result readuntil may return, counting the
88
+ # terminator itself, so a limit of 4 accepts "abc\n" and rejects
89
+ # "abcd\n". Unlike the limit of IO#gets it never truncates a result to
90
+ # fit. Either the whole thing comes back or this is raised, except
91
+ # under ignore_eof, which still returns what was buffered when the
92
+ # stream ended. The count is in bytes while the IO hands back binary
93
+ # strings, which every real one does.
94
+ #
95
+ # It bounds one call, not a connection. The unconsumed buffer can
96
+ # still run one BUFSIZE past the limit, and a peer sending endless
97
+ # short lines is not bounded at all.
98
+ #
99
+ # Nothing is consumed when this is raised, so the usual response is to
100
+ # close the connection rather than read on under a wider limit.
101
+
102
+ class ReadLimitExceeded < ProtocolError; end
69
103
 
70
104
  ##
71
105
  # OpenTimeout, a subclass of Gem::Timeout::Error, is raised if a connection cannot
@@ -78,6 +112,7 @@ module Gem::Net # :nodoc:
78
112
  # response cannot be read within the read_timeout.
79
113
 
80
114
  class ReadTimeout < Gem::Timeout::Error
115
+ # :stopdoc:
81
116
  def initialize(io = nil)
82
117
  @io = io
83
118
  end
@@ -97,6 +132,7 @@ module Gem::Net # :nodoc:
97
132
  # response cannot be written within the write_timeout. Not raised on Windows.
98
133
 
99
134
  class WriteTimeout < Gem::Timeout::Error
135
+ # :stopdoc:
100
136
  def initialize(io = nil)
101
137
  @io = io
102
138
  end
@@ -153,6 +189,7 @@ module Gem::Net # :nodoc:
153
189
  public
154
190
 
155
191
  def read(len, dest = ''.b, ignore_eof = false)
192
+ raise ArgumentError, "negative length #{len} given" if len < 0
156
193
  LOG "reading #{len} bytes..."
157
194
  read_bytes = 0
158
195
  begin
@@ -191,14 +228,31 @@ module Gem::Net # :nodoc:
191
228
  dest
192
229
  end
193
230
 
194
- def readuntil(terminator, ignore_eof = false)
231
+ def readuntil(terminator, ignore_eof = false, limit: nil)
232
+ unless limit.nil? || (Integer === limit && limit > 0)
233
+ # Integer === calls nothing on limit, and only an Integer is
234
+ # echoed back, so validation never runs the caller's code.
235
+ got = Integer === limit ? limit : "a non-Integer"
236
+ raise ArgumentError, "limit must be a positive Integer, got #{got}"
237
+ end
195
238
  offset = @rbuf_offset
196
239
  begin
197
240
  until idx = @rbuf.index(terminator, offset)
198
- offset = @rbuf.bytesize
241
+ if limit && rbuf_size > limit
242
+ raise ReadLimitExceeded, "exceeded the #{limit} byte read limit"
243
+ end
244
+ # Rewind so a terminator split across reads is still found. The
245
+ # floor guards two things. String#index reads a negative offset
246
+ # as counting from the end, and an offset below @rbuf_offset
247
+ # matches inside bytes already returned.
248
+ offset = [@rbuf.bytesize - terminator.bytesize + 1, @rbuf_offset].max
199
249
  rbuf_fill
200
250
  end
201
- return rbuf_consume(idx + terminator.bytesize - @rbuf_offset)
251
+ len = idx + terminator.bytesize - @rbuf_offset
252
+ if limit && len > limit
253
+ raise ReadLimitExceeded, "exceeded the #{limit} byte read limit"
254
+ end
255
+ return rbuf_consume(len)
202
256
  rescue EOFError
203
257
  raise unless ignore_eof
204
258
  return rbuf_consume
@@ -303,9 +357,9 @@ module Gem::Net # :nodoc:
303
357
  @debug_output << '<- ' if @debug_output
304
358
  yield
305
359
  @debug_output << "\n" if @debug_output
306
- bytes = @written_bytes
360
+ @written_bytes
361
+ ensure
307
362
  @written_bytes = nil
308
- bytes
309
363
  end
310
364
 
311
365
  def write0(*strs)
@@ -331,6 +385,9 @@ module Gem::Net # :nodoc:
331
385
  # next string
332
386
  end
333
387
  # continue looping
388
+ when :wait_readable
389
+ (io = @io.to_io).wait_readable(@write_timeout) or raise Gem::Net::WriteTimeout.new(io)
390
+ # continue looping
334
391
  when :wait_writable
335
392
  (io = @io.to_io).wait_writable(@write_timeout) or raise Gem::Net::WriteTimeout.new(io)
336
393
  # continue looping
@@ -373,12 +430,15 @@ module Gem::Net # :nodoc:
373
430
  def each_message_chunk
374
431
  LOG 'reading message...'
375
432
  LOG_off()
376
- read_bytes = 0
377
- while (line = readuntil("\r\n")) != ".\r\n"
378
- read_bytes += line.size
379
- yield line.delete_prefix('.')
433
+ begin
434
+ read_bytes = 0
435
+ while (line = readuntil("\r\n")) != ".\r\n"
436
+ read_bytes += line.size
437
+ yield line.delete_prefix('.')
438
+ end
439
+ ensure
440
+ LOG_on()
380
441
  end
381
- LOG_on()
382
442
  LOG "read message (#{read_bytes} bytes)"
383
443
  end
384
444
 
@@ -404,12 +464,15 @@ module Gem::Net # :nodoc:
404
464
  def write_message(src)
405
465
  LOG "writing message from #{src.class}"
406
466
  LOG_off()
407
- len = writing {
408
- using_each_crlf_line {
409
- write_message_0 src
467
+ begin
468
+ len = writing {
469
+ using_each_crlf_line {
470
+ write_message_0 src
471
+ }
410
472
  }
411
- }
412
- LOG_on()
473
+ ensure
474
+ LOG_on()
475
+ end
413
476
  LOG "wrote #{len} bytes"
414
477
  len
415
478
  end
@@ -417,16 +480,19 @@ module Gem::Net # :nodoc:
417
480
  def write_message_by_block(&block)
418
481
  LOG 'writing message from block'
419
482
  LOG_off()
420
- len = writing {
421
- using_each_crlf_line {
422
- begin
423
- block.call(WriteAdapter.new(self.method(:write_message_0)))
424
- rescue LocalJumpError
425
- # allow `break' from writer block
426
- end
483
+ begin
484
+ len = writing {
485
+ using_each_crlf_line {
486
+ begin
487
+ block.call(WriteAdapter.new(self.method(:write_message_0)))
488
+ rescue LocalJumpError
489
+ # allow `break' from writer block
490
+ end
491
+ }
427
492
  }
428
- }
429
- LOG_on()
493
+ ensure
494
+ LOG_on()
495
+ end
430
496
  LOG "wrote #{len} bytes"
431
497
  len
432
498
  end
@@ -446,6 +512,8 @@ module Gem::Net # :nodoc:
446
512
  write0 "\r\n"
447
513
  end
448
514
  write0 ".\r\n"
515
+ nil
516
+ ensure
449
517
  @wbuf = nil
450
518
  end
451
519
 
@@ -484,6 +552,7 @@ module Gem::Net # :nodoc:
484
552
  # The writer adapter class
485
553
  #
486
554
  class WriteAdapter
555
+ # :stopdoc:
487
556
  def initialize(writer)
488
557
  @writer = writer
489
558
  end