httpclient 2.7.0.1 → 2.7.1

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: e7236cf89169c32802c8800f4f679904f1f24e95
4
- data.tar.gz: 8096cd3b370e83a391239e6daa2657c3efa79e45
3
+ metadata.gz: 16f7baffe102a626c3028dcaad8bb4cf7824ebec
4
+ data.tar.gz: d0a2b4c9e430503c59923422df7b59b94d6a798f
5
5
  SHA512:
6
- metadata.gz: 60008ef0e10fa99bf0255cc7d78228af00eb25b457963d4108f942871925a41b0d71d90e697d66e2373b38d913349a198cd4cb818e8104536aa1670c7213d83e
7
- data.tar.gz: 859e12aadea51b63e5892ea0b162472a36bc75b683ec4b2fde065fda8f29a45e2d17aa1f7283773cd76e17f0f4b8f2a0a4ecf7c4d99900ae96a14bbd15dbaac9
6
+ metadata.gz: 9e1aaf56532a5932e483f23757e1e3648943dee5c198be8e1e59fbd38b9c77550b34e9e46bf2cbf6339afbaa30314efe8eef7907ca146fdb44518d022b8c86e7
7
+ data.tar.gz: bf1e76a63200ea981220c1f94e3e5c834fbe5cbba991e9463ef06efdfafc5441b0ac57461cea6d62cb377ee52c72de2bf8746d9e9b667a59b55a8a024335ae5b
@@ -393,10 +393,25 @@ class HTTPClient
393
393
  #
394
394
  # After you set :base_url, all resources you pass to get, post and other
395
395
  # methods are recognized to be prefixed with base_url. Say base_url is
396
- # 'https://api.example.com/v1, get('/users') is the same as
396
+ # 'https://api.example.com/v1/, get('users') is the same as
397
397
  # get('https://api.example.com/v1/users') internally. You can also pass
398
398
  # full URL from 'http://' even after setting base_url.
399
399
  #
400
+ # The expected base_url and path behavior is the following. Please take
401
+ # care of '/' in base_url and path.
402
+ #
403
+ # The last '/' is important for base_url:
404
+ # 1. http://foo/bar/baz/ + path -> http://foo/bar/baz/path
405
+ # 2. http://foo/bar/baz + path -> http://foo/bar/path
406
+ # Relative path handling:
407
+ # 3. http://foo/bar/baz/ + ../path -> http://foo/bar/path
408
+ # 4. http://foo/bar/baz + ../path -> http://foo/path
409
+ # 5. http://foo/bar/baz/ + ./path -> http://foo/bar/baz/path
410
+ # 6. http://foo/bar/baz + ./path -> http://foo/bar/path
411
+ # The leading '/' of path means absolute path:
412
+ # 7. http://foo/bar/baz/ + /path -> http://foo/path
413
+ # 8. http://foo/bar/baz + /path -> http://foo/path
414
+ #
400
415
  # :default_header is for providing default headers Hash that all HTTP
401
416
  # requests should have, such as custom 'Authorization' header in API.
402
417
  # You can override :default_header with :header Hash parameter in HTTP
@@ -703,9 +718,9 @@ class HTTPClient
703
718
  def default_redirect_uri_callback(uri, res)
704
719
  newuri = urify(res.header['location'][0])
705
720
  if !http?(newuri) && !https?(newuri)
706
- newuri = uri + newuri
707
- warn("could be a relative URI in location header which is not recommended")
721
+ warn("#{newuri}: a relative URI in location header which is not recommended")
708
722
  warn("'The field value consists of a single absolute URI' in HTTP spec")
723
+ newuri = uri + newuri
709
724
  end
710
725
  if https?(uri) && !https?(newuri)
711
726
  raise BadResponseError.new("redirecting to non-https resource")
@@ -1133,7 +1148,7 @@ private
1133
1148
  boundary = nil
1134
1149
  if body
1135
1150
  _, content_type = header.find { |key, value|
1136
- key.downcase == 'content-type'
1151
+ key.to_s.downcase == 'content-type'
1137
1152
  }
1138
1153
  if content_type
1139
1154
  if /\Amultipart/ =~ content_type
@@ -1142,7 +1157,7 @@ private
1142
1157
  else
1143
1158
  boundary = create_boundary
1144
1159
  content_type = "#{content_type}; boundary=#{boundary}"
1145
- header = override_header(header, 'Content-Type', content_type)
1160
+ header = override_header(header, 'content-type', content_type)
1146
1161
  end
1147
1162
  end
1148
1163
  else
@@ -1180,7 +1195,7 @@ private
1180
1195
  def override_header(header, key, value)
1181
1196
  result = []
1182
1197
  header.each do |k, v|
1183
- if k.downcase == key.downcase
1198
+ if k.to_s.downcase == key
1184
1199
  result << [key, value]
1185
1200
  else
1186
1201
  result << [k, v]
@@ -3,9 +3,12 @@ unless defined?(HTTPClient::CookieManager)
3
3
  begin # for catching LoadError and load webagent-cookie instead
4
4
 
5
5
  require 'http-cookie'
6
+ require 'httpclient/util'
6
7
 
7
8
  class HTTPClient
8
9
  class CookieManager
10
+ include HTTPClient::Util
11
+
9
12
  attr_reader :format, :jar
10
13
  attr_accessor :cookies_file
11
14
 
@@ -68,7 +71,7 @@ class HTTPClient
68
71
  end
69
72
 
70
73
  def find(uri)
71
- warn('CookieManager#find is deprecated and will be removed in near future. Use HTTP::Cookie.cookie_value(CookieManager#cookies) instead')
74
+ warning('CookieManager#find is deprecated and will be removed in near future. Use HTTP::Cookie.cookie_value(CookieManager#cookies) instead')
72
75
  if cookie = cookies(uri)
73
76
  HTTP::Cookie.cookie_value(cookie)
74
77
  end
@@ -174,8 +177,7 @@ class WebAgent
174
177
  CookieManager = ::HTTPClient::CookieManager
175
178
 
176
179
  class Cookie < HTTP::Cookie
177
- @@domain_warned = false
178
- @@warned = false
180
+ include HTTPClient::Util
179
181
 
180
182
  def url
181
183
  deprecated('url', 'origin')
@@ -195,7 +197,7 @@ class WebAgent
195
197
  alias original_domain domain
196
198
 
197
199
  def domain
198
- domain_warning
200
+ warning('Cookie#domain returns dot-less domain name now. Use Cookie#dot_domain if you need "." at the beginning.')
199
201
  self.original_domain
200
202
  end
201
203
 
@@ -206,18 +208,8 @@ class WebAgent
206
208
 
207
209
  private
208
210
 
209
- def domain_warning
210
- unless @@domain_warned
211
- warn('Cookie#domain returns dot-less domain name now. Use Cookie#dot_domain if you need "." at the beginning.')
212
- @@domain_warned = true
213
- end
214
- end
215
-
216
211
  def deprecated(old, new)
217
- unless @@warned
218
- warn("WebAgent::Cookie is deprecated and will be replaced with HTTP::Cookie in the near future. Please use Cookie##{new} instead of Cookie##{old} for the replacement.")
219
- @@warned = true
220
- end
212
+ warning("WebAgent::Cookie is deprecated and will be replaced with HTTP::Cookie in the near future. Please use Cookie##{new} instead of Cookie##{old} for the replacement.")
221
213
  end
222
214
  end
223
215
  end
@@ -12,6 +12,7 @@ require 'time'
12
12
  if defined?(Encoding::ASCII_8BIT)
13
13
  require 'open-uri' # for encoding
14
14
  end
15
+ require 'httpclient/util'
15
16
 
16
17
 
17
18
  # A namespace module for HTTP Message definitions used by HTTPClient.
@@ -95,6 +96,7 @@ module HTTP
95
96
  # p res.header['last-modified'].first
96
97
  #
97
98
  class Message
99
+ include HTTPClient::Util
98
100
 
99
101
  CRLF = "\r\n"
100
102
 
@@ -980,12 +982,12 @@ module HTTP
980
982
 
981
983
  VERSION_WARNING = 'Message#version (Float) is deprecated. Use Message#http_version (String) instead.'
982
984
  def version
983
- warn(VERSION_WARNING)
985
+ warning(VERSION_WARNING)
984
986
  @http_header.http_version.to_f
985
987
  end
986
988
 
987
989
  def version=(version)
988
- warn(VERSION_WARNING)
990
+ warning(VERSION_WARNING)
989
991
  @http_header.http_version = version
990
992
  end
991
993
 
@@ -315,7 +315,7 @@ unless defined?(SSLSocket)
315
315
  def add(file_or_dir)
316
316
  return if file_or_dir == :default
317
317
  if File.directory?(file_or_dir)
318
- warn('directory not yet supported')
318
+ warn("#{file_or_dir}: directory not yet supported")
319
319
  else
320
320
  pem = nil
321
321
  File.read(file_or_dir).each_line do |line|
@@ -447,7 +447,7 @@ unless defined?(SSLSocket)
447
447
  if config.ssl_version == :auto
448
448
  ssl_version = DEFAULT_SSL_PROTOCOL
449
449
  else
450
- ssl_version = config.to_s.gsub(/_/, '.')
450
+ ssl_version = config.ssl_version.to_s.gsub(/_/, '.')
451
451
  end
452
452
  unless config.cert_store_crl_items.empty?
453
453
  raise NotImplementedError.new('Manual CRL configuration is not yet supported')
@@ -14,6 +14,7 @@
14
14
 
15
15
  require 'socket'
16
16
  require 'thread'
17
+ require 'timeout'
17
18
  require 'stringio'
18
19
  require 'zlib'
19
20
 
@@ -497,7 +498,7 @@ class HTTPClient
497
498
  # Use absolute URI (not absolute path) iif via proxy AND not HTTPS.
498
499
  req.header.request_absolute_uri = !@proxy.nil? && !https?(@dest)
499
500
  begin
500
- timeout(@send_timeout, SendTimeoutError) do
501
+ ::Timeout.timeout(@send_timeout, SendTimeoutError) do
501
502
  set_header(req)
502
503
  req.dump(@socket)
503
504
  # flush the IO stream as IO::sync mode is false
@@ -731,7 +732,7 @@ class HTTPClient
731
732
  site = @proxy || @dest
732
733
  retry_number = 0
733
734
  begin
734
- timeout(@connect_timeout, ConnectTimeoutError) do
735
+ ::Timeout.timeout(@connect_timeout, ConnectTimeoutError) do
735
736
  if str = @test_loopback_http_response.shift
736
737
  @socket = create_loopback_socket(site.host, site.port, str)
737
738
  elsif https?(@dest)
@@ -784,7 +785,7 @@ class HTTPClient
784
785
 
785
786
  StatusParseRegexp = %r(\AHTTP/(\d+\.\d+)\s+(\d\d\d)\s*([^\r\n]+)?\r?\n\z)
786
787
  def parse_header(socket)
787
- timeout(@receive_timeout, ReceiveTimeoutError) do
788
+ ::Timeout.timeout(@receive_timeout, ReceiveTimeoutError) do
788
789
  initial_line = nil
789
790
  begin
790
791
  begin
@@ -864,7 +865,7 @@ class HTTPClient
864
865
  buf = empty_bin_str
865
866
  maxbytes = @read_block_size
866
867
  maxbytes = @content_length if maxbytes > @content_length && @content_length > 0
867
- timeout(@receive_timeout, ReceiveTimeoutError) do
868
+ ::Timeout.timeout(@receive_timeout, ReceiveTimeoutError) do
868
869
  begin
869
870
  @socket.readpartial(maxbytes, buf)
870
871
  rescue EOFError
@@ -897,7 +898,7 @@ class HTTPClient
897
898
  @socket.gets(RS)
898
899
  return
899
900
  end
900
- timeout(@receive_timeout, ReceiveTimeoutError) do
901
+ ::Timeout.timeout(@receive_timeout, ReceiveTimeoutError) do
901
902
  @socket.read(@chunk_length, buf)
902
903
  @socket.read(2)
903
904
  end
@@ -914,7 +915,7 @@ class HTTPClient
914
915
  end
915
916
  while true
916
917
  buf = empty_bin_str
917
- timeout(@receive_timeout, ReceiveTimeoutError) do
918
+ ::Timeout.timeout(@receive_timeout, ReceiveTimeoutError) do
918
919
  begin
919
920
  @socket.readpartial(@read_block_size, buf)
920
921
  rescue EOFError
@@ -35,6 +35,7 @@ class HTTPClient
35
35
  # You may want to change trust anchor by yourself. Call clear_cert_store
36
36
  # then add_trust_ca for that purpose.
37
37
  class SSLConfig
38
+ include HTTPClient::Util
38
39
  include OpenSSL if SSLEnabled
39
40
 
40
41
  CIPHERS_DEFAULT = "ALL:!aNULL:!eNULL:!SSLv2" # OpenSSL >1.0.0 default
@@ -446,11 +447,14 @@ class HTTPClient
446
447
  (ver.start_with?('OpenSSL ') && ver >= 'OpenSSL 1.0.2d') || defined?(JRuby)
447
448
  filename = 'cacert.pem'
448
449
  else
449
- warn("RSA 1024 bit CA certificates are loaded due to old openssl compatibility")
450
+ warning("RSA 1024 bit CA certificates are loaded due to old openssl compatibility")
450
451
  filename = 'cacert1024.pem'
451
452
  end
452
453
  file = File.join(File.dirname(__FILE__), filename)
453
- add_trust_ca_to_store(cert_store, file)
454
+ unless defined?(JRuby)
455
+ # JRuby uses @cert_store_items
456
+ add_trust_ca_to_store(cert_store, file)
457
+ end
454
458
  @cert_store_items << file
455
459
  end
456
460
  end
@@ -198,6 +198,16 @@ class HTTPClient
198
198
  end
199
199
  module_function :try_require
200
200
 
201
+ # show one warning message only once by caching message
202
+ #
203
+ # it cached all messages in memory so be careful not to show many kinds of warning message.
204
+ @@__warned = {}
205
+ def warning(message)
206
+ return if @@__warned.key?(message)
207
+ warn(message)
208
+ @@__warned[message] = true
209
+ end
210
+
201
211
  # Checks if the given URI is https.
202
212
  def https?(uri)
203
213
  uri.scheme && uri.scheme.downcase == 'https'
@@ -1,3 +1,3 @@
1
1
  class HTTPClient
2
- VERSION = '2.7.0.1'
2
+ VERSION = '2.7.1'
3
3
  end
@@ -456,4 +456,4 @@ end
456
456
 
457
457
  class HTTPClient
458
458
  CookieManager = WebAgent::CookieManager
459
- end
459
+ end unless defined?(HTTPClient::CookieManager)
@@ -465,6 +465,7 @@ class TestAuth < Test::Unit::TestCase
465
465
  # TODO: WEBrick server returns ECONNRESET/EPIPE before sending Unauthorized response to client?
466
466
  raise if retry_times > 5
467
467
  retry_times += 1
468
+ sleep 1
468
469
  retry
469
470
  end
470
471
  end
@@ -115,6 +115,14 @@ class TestHTTPClient < Test::Unit::TestCase
115
115
  assert_equal("Accept: text/html", lines[4])
116
116
  end
117
117
 
118
+ def test_header_symbol
119
+ str = ""
120
+ @client.debug_dev = str
121
+ @client.post(serverurl + 'servlet', :header => {:'Content-Type' => 'application/json'}, :body => 'hello')
122
+ lines = str.split(/(?:\r?\n)+/).grep(/^Content-Type/)
123
+ assert_equal(2, lines.size) # 1 for both request and response
124
+ end
125
+
118
126
  def test_host_given
119
127
  str = ""
120
128
  @client.debug_dev = str
@@ -138,7 +146,7 @@ class TestHTTPClient < Test::Unit::TestCase
138
146
 
139
147
  def test_redirect_returns_not_modified
140
148
  assert_nothing_raised do
141
- timeout(2) do
149
+ ::Timeout.timeout(2) do
142
150
  @client.get(serverurl + 'status', {:status => 306}, {:follow_redirect => true})
143
151
  end
144
152
  end
@@ -531,7 +539,7 @@ EOS
531
539
 
532
540
  def test_no_content
533
541
  assert_nothing_raised do
534
- timeout(2) do
542
+ ::Timeout.timeout(2) do
535
543
  @client.get(serverurl + 'status', :status => 101)
536
544
  @client.get(serverurl + 'status', :status => 204)
537
545
  @client.get(serverurl + 'status', :status => 304)
@@ -11,7 +11,6 @@ class TestSSL < Test::Unit::TestCase
11
11
  super
12
12
  @serverpid = @client = nil
13
13
  @verify_callback_called = false
14
- @verbose, $VERBOSE = $VERBOSE, nil
15
14
  setup_server
16
15
  setup_client
17
16
  @url = "https://localhost:#{serverport}/hello"
@@ -19,7 +18,6 @@ class TestSSL < Test::Unit::TestCase
19
18
 
20
19
  def teardown
21
20
  super
22
- $VERBOSE = @verbose
23
21
  end
24
22
 
25
23
  def path(filename)
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: httpclient
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.7.0.1
4
+ version: 2.7.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Hiroshi Nakamura
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-11-07 00:00:00.000000000 Z
11
+ date: 2016-01-01 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description:
14
14
  email: nahi@ruby-lang.org
@@ -103,7 +103,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
103
103
  version: '0'
104
104
  requirements: []
105
105
  rubyforge_project:
106
- rubygems_version: 2.4.5.1
106
+ rubygems_version: 2.5.1
107
107
  signing_key:
108
108
  specification_version: 4
109
109
  summary: gives something like the functionality of libwww-perl (LWP) in Ruby