httpclient 2.7.0.1 → 2.7.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/httpclient.rb +21 -6
- data/lib/httpclient/cookie.rb +7 -15
- data/lib/httpclient/http.rb +4 -2
- data/lib/httpclient/jruby_ssl_socket.rb +2 -2
- data/lib/httpclient/session.rb +7 -6
- data/lib/httpclient/ssl_config.rb +6 -2
- data/lib/httpclient/util.rb +10 -0
- data/lib/httpclient/version.rb +1 -1
- data/lib/httpclient/webagent-cookie.rb +1 -1
- data/test/test_auth.rb +1 -0
- data/test/test_httpclient.rb +10 -2
- data/test/test_ssl.rb +0 -2
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 16f7baffe102a626c3028dcaad8bb4cf7824ebec
|
4
|
+
data.tar.gz: d0a2b4c9e430503c59923422df7b59b94d6a798f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9e1aaf56532a5932e483f23757e1e3648943dee5c198be8e1e59fbd38b9c77550b34e9e46bf2cbf6339afbaa30314efe8eef7907ca146fdb44518d022b8c86e7
|
7
|
+
data.tar.gz: bf1e76a63200ea981220c1f94e3e5c834fbe5cbba991e9463ef06efdfafc5441b0ac57461cea6d62cb377ee52c72de2bf8746d9e9b667a59b55a8a024335ae5b
|
data/lib/httpclient.rb
CHANGED
@@ -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
|
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
|
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, '
|
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
|
1198
|
+
if k.to_s.downcase == key
|
1184
1199
|
result << [key, value]
|
1185
1200
|
else
|
1186
1201
|
result << [k, v]
|
data/lib/httpclient/cookie.rb
CHANGED
@@ -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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
data/lib/httpclient/http.rb
CHANGED
@@ -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
|
-
|
985
|
+
warning(VERSION_WARNING)
|
984
986
|
@http_header.http_version.to_f
|
985
987
|
end
|
986
988
|
|
987
989
|
def version=(version)
|
988
|
-
|
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(
|
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')
|
data/lib/httpclient/session.rb
CHANGED
@@ -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
|
-
|
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
|
-
|
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
|
-
|
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
|
data/lib/httpclient/util.rb
CHANGED
@@ -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'
|
data/lib/httpclient/version.rb
CHANGED
data/test/test_auth.rb
CHANGED
data/test/test_httpclient.rb
CHANGED
@@ -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)
|
data/test/test_ssl.rb
CHANGED
@@ -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.
|
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:
|
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.
|
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
|