rest-client 1.6.7 → 1.8.0
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 +7 -0
- data/.gitignore +7 -0
- data/.rspec +1 -0
- data/.travis.yml +14 -0
- data/AUTHORS +81 -0
- data/Gemfile +11 -0
- data/LICENSE +21 -0
- data/README.rdoc +63 -24
- data/Rakefile +85 -35
- data/bin/restclient +9 -8
- data/history.md +63 -1
- data/lib/restclient/abstract_response.rb +44 -15
- data/lib/restclient/exceptions.rb +20 -10
- data/lib/restclient/payload.rb +21 -18
- data/lib/restclient/platform.rb +30 -0
- data/lib/restclient/raw_response.rb +3 -2
- data/lib/restclient/request.rb +368 -63
- data/lib/restclient/resource.rb +3 -4
- data/lib/restclient/response.rb +2 -5
- data/lib/restclient/version.rb +7 -0
- data/lib/restclient/windows/root_certs.rb +105 -0
- data/lib/restclient/windows.rb +8 -0
- data/lib/restclient.rb +6 -15
- data/rest-client.gemspec +30 -0
- data/rest-client.windows.gemspec +19 -0
- data/spec/integration/capath_digicert/244b5494.0 +19 -0
- data/spec/integration/capath_digicert/81b9768f.0 +19 -0
- data/spec/integration/capath_digicert/README +8 -0
- data/spec/integration/capath_digicert/digicert.crt +19 -0
- data/spec/integration/capath_verisign/415660c1.0 +14 -0
- data/spec/integration/capath_verisign/7651b327.0 +14 -0
- data/spec/integration/capath_verisign/README +8 -0
- data/spec/integration/capath_verisign/verisign.crt +14 -0
- data/spec/integration/certs/digicert.crt +19 -0
- data/spec/{integration_spec.rb → integration/integration_spec.rb} +10 -13
- data/spec/integration/request_spec.rb +86 -7
- data/spec/spec_helper.rb +2 -0
- data/spec/{abstract_response_spec.rb → unit/abstract_response_spec.rb} +18 -15
- data/spec/{exceptions_spec.rb → unit/exceptions_spec.rb} +17 -20
- data/spec/unit/master_shake.jpg +0 -0
- data/spec/{payload_spec.rb → unit/payload_spec.rb} +42 -31
- data/spec/unit/raw_response_spec.rb +18 -0
- data/spec/{request2_spec.rb → unit/request2_spec.rb} +6 -14
- data/spec/unit/request_spec.rb +917 -0
- data/spec/{resource_spec.rb → unit/resource_spec.rb} +27 -31
- data/spec/{response_spec.rb → unit/response_spec.rb} +63 -57
- data/spec/{restclient_spec.rb → unit/restclient_spec.rb} +8 -2
- data/spec/unit/windows/root_certs_spec.rb +22 -0
- metadata +210 -112
- data/VERSION +0 -1
- data/lib/restclient/net_http_ext.rb +0 -55
- data/spec/base.rb +0 -16
- data/spec/integration/certs/equifax.crt +0 -19
- data/spec/master_shake.jpg +0 -0
- data/spec/raw_response_spec.rb +0 -17
- data/spec/request_spec.rb +0 -529
@@ -1,10 +1,11 @@
|
|
1
1
|
require 'cgi'
|
2
|
+
require 'http-cookie'
|
2
3
|
|
3
4
|
module RestClient
|
4
5
|
|
5
6
|
module AbstractResponse
|
6
7
|
|
7
|
-
attr_reader :net_http_res, :args
|
8
|
+
attr_reader :net_http_res, :args, :request
|
8
9
|
|
9
10
|
# HTTP status code
|
10
11
|
def code
|
@@ -22,11 +23,36 @@ module RestClient
|
|
22
23
|
@raw_headers ||= @net_http_res.to_hash
|
23
24
|
end
|
24
25
|
|
26
|
+
def response_set_vars(net_http_res, args, request)
|
27
|
+
@net_http_res = net_http_res
|
28
|
+
@args = args
|
29
|
+
@request = request
|
30
|
+
end
|
31
|
+
|
25
32
|
# Hash of cookies extracted from response headers
|
26
33
|
def cookies
|
27
|
-
|
28
|
-
|
34
|
+
hash = {}
|
35
|
+
|
36
|
+
cookie_jar.cookies.each do |cookie|
|
37
|
+
hash[cookie.name] = cookie.value
|
29
38
|
end
|
39
|
+
|
40
|
+
hash
|
41
|
+
end
|
42
|
+
|
43
|
+
# Cookie jar extracted from response headers.
|
44
|
+
#
|
45
|
+
# @return [HTTP::CookieJar]
|
46
|
+
#
|
47
|
+
def cookie_jar
|
48
|
+
return @cookie_jar if @cookie_jar
|
49
|
+
|
50
|
+
jar = HTTP::CookieJar.new
|
51
|
+
headers.fetch(:set_cookie, []).each do |cookie|
|
52
|
+
jar.parse(cookie, @request.url)
|
53
|
+
end
|
54
|
+
|
55
|
+
@cookie_jar = jar
|
30
56
|
end
|
31
57
|
|
32
58
|
# Return the default behavior corresponding to the response code:
|
@@ -61,28 +87,31 @@ module RestClient
|
|
61
87
|
|
62
88
|
# Follow a redirection
|
63
89
|
def follow_redirection request = nil, result = nil, & block
|
90
|
+
new_args = @args.dup
|
91
|
+
|
64
92
|
url = headers[:location]
|
65
93
|
if url !~ /^http/
|
66
|
-
url = URI.parse(
|
94
|
+
url = URI.parse(request.url).merge(url).to_s
|
67
95
|
end
|
68
|
-
|
96
|
+
new_args[:url] = url
|
69
97
|
if request
|
70
98
|
if request.max_redirects == 0
|
71
99
|
raise MaxRedirectsReached
|
72
100
|
end
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
101
|
+
new_args[:password] = request.password
|
102
|
+
new_args[:user] = request.user
|
103
|
+
new_args[:headers] = request.headers
|
104
|
+
new_args[:max_redirects] = request.max_redirects - 1
|
105
|
+
|
106
|
+
# TODO: figure out what to do with original :cookie, :cookies values
|
107
|
+
new_args[:headers]['Cookie'] = HTTP::Cookie.cookie_value(
|
108
|
+
cookie_jar.cookies(new_args.fetch(:url)))
|
81
109
|
end
|
82
|
-
|
110
|
+
|
111
|
+
Request.execute(new_args, &block)
|
83
112
|
end
|
84
113
|
|
85
|
-
def
|
114
|
+
def self.beautify_headers(headers)
|
86
115
|
headers.inject({}) do |out, (key, value)|
|
87
116
|
out[key.gsub(/-/, '_').downcase.to_sym] = %w{ set-cookie }.include?(key.downcase) ? value : value.first
|
88
117
|
out
|
@@ -21,7 +21,7 @@ module RestClient
|
|
21
21
|
305 => 'Use Proxy', # http/1.1
|
22
22
|
306 => 'Switch Proxy', # no longer used
|
23
23
|
307 => 'Temporary Redirect', # http/1.1
|
24
|
-
|
24
|
+
|
25
25
|
400 => 'Bad Request',
|
26
26
|
401 => 'Unauthorized',
|
27
27
|
402 => 'Payment Required',
|
@@ -40,13 +40,16 @@ module RestClient
|
|
40
40
|
415 => 'Unsupported Media Type',
|
41
41
|
416 => 'Requested Range Not Satisfiable',
|
42
42
|
417 => 'Expectation Failed',
|
43
|
-
418 => 'I\'m A Teapot',
|
43
|
+
418 => 'I\'m A Teapot', #RFC2324
|
44
44
|
421 => 'Too Many Connections From This IP',
|
45
45
|
422 => 'Unprocessable Entity', #WebDAV
|
46
46
|
423 => 'Locked', #WebDAV
|
47
47
|
424 => 'Failed Dependency', #WebDAV
|
48
48
|
425 => 'Unordered Collection', #WebDAV
|
49
|
-
426 => 'Upgrade Required',
|
49
|
+
426 => 'Upgrade Required',
|
50
|
+
428 => 'Precondition Required', #RFC6585
|
51
|
+
429 => 'Too Many Requests', #RFC6585
|
52
|
+
431 => 'Request Header Fields Too Large', #RFC6585
|
50
53
|
449 => 'Retry With', #Microsoft
|
51
54
|
450 => 'Blocked By Windows Parental Controls', #Microsoft
|
52
55
|
|
@@ -59,7 +62,9 @@ module RestClient
|
|
59
62
|
506 => 'Variant Also Negotiates',
|
60
63
|
507 => 'Insufficient Storage', #WebDAV
|
61
64
|
509 => 'Bandwidth Limit Exceeded', #Apache
|
62
|
-
510 => 'Not Extended'
|
65
|
+
510 => 'Not Extended',
|
66
|
+
511 => 'Network Authentication Required', # RFC6585
|
67
|
+
}
|
63
68
|
|
64
69
|
# Compatibility : make the Response act like a Net::HTTPResponse when needed
|
65
70
|
module ResponseForException
|
@@ -81,10 +86,11 @@ module RestClient
|
|
81
86
|
# probably an HTML error page) is e.response.
|
82
87
|
class Exception < RuntimeError
|
83
88
|
attr_accessor :response
|
84
|
-
attr_writer
|
89
|
+
attr_writer :message
|
85
90
|
|
86
91
|
def initialize response = nil, initial_response_code = nil
|
87
92
|
@response = response
|
93
|
+
@message = nil
|
88
94
|
@initial_response_code = initial_response_code
|
89
95
|
|
90
96
|
# compatibility: this make the exception behave like a Net::HTTPResponse
|
@@ -111,7 +117,7 @@ module RestClient
|
|
111
117
|
def to_s
|
112
118
|
inspect
|
113
119
|
end
|
114
|
-
|
120
|
+
|
115
121
|
def message
|
116
122
|
@message || self.class.name
|
117
123
|
end
|
@@ -154,7 +160,9 @@ module RestClient
|
|
154
160
|
# A redirect was encountered; caught by execute to retry with the new url.
|
155
161
|
class Redirect < Exception
|
156
162
|
|
157
|
-
message
|
163
|
+
def message
|
164
|
+
'Redirect'
|
165
|
+
end
|
158
166
|
|
159
167
|
attr_accessor :url
|
160
168
|
|
@@ -163,8 +171,10 @@ module RestClient
|
|
163
171
|
end
|
164
172
|
end
|
165
173
|
|
166
|
-
class MaxRedirectsReached < Exception
|
167
|
-
message
|
174
|
+
class MaxRedirectsReached < Exception
|
175
|
+
def message
|
176
|
+
'Maximum number of redirect reached'
|
177
|
+
end
|
168
178
|
end
|
169
179
|
|
170
180
|
# The server broke the connection prior to the request completing. Usually
|
@@ -185,8 +195,8 @@ module RestClient
|
|
185
195
|
end
|
186
196
|
end
|
187
197
|
|
188
|
-
# backwards compatibility
|
189
198
|
class RestClient::Request
|
199
|
+
# backwards compatibility
|
190
200
|
Redirect = RestClient::Redirect
|
191
201
|
Unauthorized = RestClient::Unauthorized
|
192
202
|
RequestFailed = RestClient::RequestFailed
|
data/lib/restclient/payload.rb
CHANGED
@@ -9,14 +9,14 @@ module RestClient
|
|
9
9
|
def generate(params)
|
10
10
|
if params.is_a?(String)
|
11
11
|
Base.new(params)
|
12
|
-
elsif params.
|
13
|
-
Streamed.new(params)
|
14
|
-
elsif params
|
12
|
+
elsif params.is_a?(Hash)
|
15
13
|
if params.delete(:multipart) == true || has_file?(params)
|
16
14
|
Multipart.new(params)
|
17
15
|
else
|
18
16
|
UrlEncoded.new(params)
|
19
17
|
end
|
18
|
+
elsif params.respond_to?(:read)
|
19
|
+
Streamed.new(params)
|
20
20
|
else
|
21
21
|
nil
|
22
22
|
end
|
@@ -25,12 +25,12 @@ module RestClient
|
|
25
25
|
def has_file?(params)
|
26
26
|
params.any? do |_, v|
|
27
27
|
case v
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
28
|
+
when Hash
|
29
|
+
has_file?(v)
|
30
|
+
when Array
|
31
|
+
has_file_array?(v)
|
32
|
+
else
|
33
|
+
v.respond_to?(:path) && v.respond_to?(:read)
|
34
34
|
end
|
35
35
|
end
|
36
36
|
end
|
@@ -38,13 +38,13 @@ module RestClient
|
|
38
38
|
def has_file_array?(params)
|
39
39
|
params.any? do |v|
|
40
40
|
case v
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
41
|
+
when Hash
|
42
|
+
has_file?(v)
|
43
|
+
when Array
|
44
|
+
has_file_array?(v)
|
45
|
+
else
|
46
|
+
v.respond_to?(:path) && v.respond_to?(:read)
|
47
|
+
end
|
48
48
|
end
|
49
49
|
end
|
50
50
|
|
@@ -147,12 +147,15 @@ module RestClient
|
|
147
147
|
|
148
148
|
# for UrlEncoded escape the keys
|
149
149
|
def handle_key key
|
150
|
-
|
150
|
+
Parser.escape(key.to_s, Escape)
|
151
151
|
end
|
152
152
|
|
153
153
|
def headers
|
154
154
|
super.merge({'Content-Type' => 'application/x-www-form-urlencoded'})
|
155
155
|
end
|
156
|
+
|
157
|
+
Parser = URI.const_defined?(:Parser) ? URI::Parser.new : URI
|
158
|
+
Escape = Regexp.new("[^#{URI::PATTERN::UNRESERVED}]")
|
156
159
|
end
|
157
160
|
|
158
161
|
class Multipart < Base
|
@@ -201,7 +204,7 @@ module RestClient
|
|
201
204
|
s.write(" filename=\"#{v.respond_to?(:original_filename) ? v.original_filename : File.basename(v.path)}\"#{EOL}")
|
202
205
|
s.write("Content-Type: #{v.respond_to?(:content_type) ? v.content_type : mime_for(v.path)}#{EOL}")
|
203
206
|
s.write(EOL)
|
204
|
-
while data = v.read(8124)
|
207
|
+
while (data = v.read(8124))
|
205
208
|
s.write(data)
|
206
209
|
end
|
207
210
|
ensure
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module RestClient
|
2
|
+
module Platform
|
3
|
+
# Return true if we are running on a darwin-based Ruby platform. This will
|
4
|
+
# be false for jruby even on OS X.
|
5
|
+
#
|
6
|
+
# @return [Boolean]
|
7
|
+
def self.mac_mri?
|
8
|
+
RUBY_PLATFORM.include?('darwin')
|
9
|
+
end
|
10
|
+
|
11
|
+
# Return true if we are running on Windows.
|
12
|
+
#
|
13
|
+
# @return [Boolean]
|
14
|
+
#
|
15
|
+
def self.windows?
|
16
|
+
# Ruby only sets File::ALT_SEPARATOR on Windows, and the Ruby standard
|
17
|
+
# library uses that to test what platform it's on.
|
18
|
+
!!File::ALT_SEPARATOR
|
19
|
+
end
|
20
|
+
|
21
|
+
# Return true if we are running on jruby.
|
22
|
+
#
|
23
|
+
# @return [Boolean]
|
24
|
+
#
|
25
|
+
def self.jruby?
|
26
|
+
# defined on mri >= 1.9
|
27
|
+
RUBY_ENGINE == 'jruby'
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -13,12 +13,13 @@ module RestClient
|
|
13
13
|
|
14
14
|
include AbstractResponse
|
15
15
|
|
16
|
-
attr_reader :file
|
16
|
+
attr_reader :file, :request
|
17
17
|
|
18
|
-
def initialize
|
18
|
+
def initialize(tempfile, net_http_res, args, request)
|
19
19
|
@net_http_res = net_http_res
|
20
20
|
@args = args
|
21
21
|
@file = tempfile
|
22
|
+
@request = request
|
22
23
|
end
|
23
24
|
|
24
25
|
def to_s
|