rest-man 1.0.0 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/{multi-matrix-test.yml → ci.yml} +10 -1
- data/.github/workflows/single-matrix-test.yml +1 -0
- data/.gitignore +2 -0
- data/.rubocop-disables.yml +4 -29
- data/AUTHORS +5 -1
- data/CHANGELOG.md +14 -0
- data/Gemfile +3 -0
- data/README.md +30 -37
- data/Rakefile +1 -59
- data/_doc/lib/restman/abstract_response/_follow_redirection.rdoc +7 -0
- data/_doc/lib/restman/abstract_response/beautify_headers.rdoc +24 -0
- data/_doc/lib/restman/abstract_response/cookie_jar.rdoc +4 -0
- data/_doc/lib/restman/abstract_response/cookies.rdoc +12 -0
- data/_doc/lib/restman/abstract_response/follow_get_redirection.rdoc +2 -0
- data/_doc/lib/restman/abstract_response/follow_redirection.rdoc +2 -0
- data/_doc/lib/restman/abstract_response/headers.rdoc +2 -0
- data/_doc/lib/restman/abstract_response/response_set_vars.rdoc +5 -0
- data/_doc/lib/restman/abstract_response/return.rdoc +9 -0
- data/_doc/lib/restman/add_before_execution_proc.rdoc +2 -0
- data/_doc/lib/restman/create_log.rdoc +2 -0
- data/_doc/lib/restman/exception.rdoc +6 -0
- data/_doc/lib/restman/exceptions/timeout.rdoc +4 -0
- data/_doc/lib/restman/exceptions.rdoc +4 -0
- data/_doc/lib/restman/log=.rdoc +3 -0
- data/_doc/lib/restman/params_array/new.rdoc +20 -0
- data/_doc/lib/restman/params_array/process_pair.rdoc +4 -0
- data/_doc/lib/restman/params_array.rdoc +11 -0
- data/_doc/lib/restman/platform/jruby?.rdoc +4 -0
- data/_doc/lib/restman/platform/mac_mri?.rdoc +5 -0
- data/_doc/lib/restman/proxy.rdoc +2 -0
- data/_doc/lib/restman/proxy_set?.rdoc +5 -0
- data/_doc/lib/restman/raw_response/new.rdoc +6 -0
- data/_doc/lib/restman/raw_response.rdoc +10 -0
- data/_doc/lib/restman/request/cookie_jar.rdoc +3 -0
- data/_doc/lib/restman/request/cookies.rdoc +11 -0
- data/_doc/lib/restman/request/default_headers.rdoc +5 -0
- data/_doc/lib/restman/request/default_ssl_cert_store.rdoc +8 -0
- data/_doc/lib/restman/request/init/cookie_jar.rdoc +55 -0
- data/_doc/lib/restman/request/init/http_method.rdoc +15 -0
- data/_doc/lib/restman/request/make_cookie_header.rdoc +8 -0
- data/_doc/lib/restman/request/make_headers.rdoc +25 -0
- data/_doc/lib/restman/request/maybe_convert_extension.rdoc +18 -0
- data/_doc/lib/restman/request/process_result.rdoc +4 -0
- data/_doc/lib/restman/request/proxy_uri.rdoc +7 -0
- data/_doc/lib/restman/request/stringify_headers.rdoc +9 -0
- data/_doc/lib/restman/request/use_ssl.rdoc +4 -0
- data/_doc/lib/restman/request.rdoc +46 -0
- data/_doc/lib/restman/reset_before_execution_procs.rdoc +1 -0
- data/_doc/lib/restman/resource/[].rdoc +25 -0
- data/_doc/lib/restman/resource.rdoc +33 -0
- data/_doc/lib/restman/response/body.rdoc +7 -0
- data/_doc/lib/restman/response/create.rdoc +10 -0
- data/_doc/lib/restman/response/fix_encoding.rdoc +2 -0
- data/_doc/lib/restman/statuses.rdoc +11 -0
- data/_doc/lib/restman/utils/cgi_parse_header.rdoc +6 -0
- data/_doc/lib/restman/utils/encode_query_string.rdoc +90 -0
- data/_doc/lib/restman/utils/escape.rdoc +11 -0
- data/_doc/lib/restman/utils/flatten_params.rdoc +16 -0
- data/_doc/lib/restman/utils/get_encoding_from_headers.rdoc +24 -0
- data/_doc/lib/restman.rdoc +43 -0
- data/bin/console +15 -0
- data/lib/restman/abstract_response.rb +13 -60
- data/lib/restman/exception.rb +43 -0
- data/lib/restman/exceptions/exception_with_response.rb +7 -0
- data/lib/restman/exceptions/exceptions_map.rb +26 -0
- data/lib/restman/exceptions/request_failed.rb +15 -0
- data/lib/restman/exceptions/server_broke_connection.rb +13 -0
- data/lib/restman/exceptions/timeout.rb +37 -0
- data/lib/restman/params_array/process_pair.rb +39 -0
- data/lib/restman/params_array.rb +3 -48
- data/lib/restman/payload/base.rb +57 -0
- data/lib/restman/payload/multipart/write_content_disposition.rb +88 -0
- data/lib/restman/payload/multipart.rb +56 -0
- data/lib/restman/payload/streamed.rb +22 -0
- data/lib/restman/payload/url_encoded.rb +14 -0
- data/lib/restman/payload.rb +14 -196
- data/lib/restman/platform.rb +2 -18
- data/lib/restman/raw_response.rb +2 -14
- data/lib/restman/request/default_ssl_cert_store.rb +13 -0
- data/lib/restman/request/fetch_body_to_tempfile.rb +58 -0
- data/lib/restman/request/init/cookie_jar.rb +65 -0
- data/lib/restman/request/init/ssl_opts.rb +70 -0
- data/lib/restman/request/init/url/add_query_from_headers.rb +51 -0
- data/lib/restman/request/init/url/normalize_url.rb +19 -0
- data/lib/restman/request/init/url.rb +40 -0
- data/lib/restman/request/init.rb +106 -0
- data/lib/restman/request/log_request.rb +46 -0
- data/lib/restman/request/make_cookie_header.rb +16 -0
- data/lib/restman/request/make_headers.rb +39 -0
- data/lib/restman/request/maybe_convert_extension.rb +28 -0
- data/lib/restman/request/net_http_object.rb +25 -0
- data/lib/restman/request/process_result.rb +36 -0
- data/lib/restman/request/proxy_uri.rb +31 -0
- data/lib/restman/request/stringify_headers.rb +36 -0
- data/lib/restman/request/transmit.rb +152 -0
- data/lib/restman/request.rb +60 -745
- data/lib/restman/resource.rb +2 -60
- data/lib/restman/response.rb +3 -21
- data/lib/restman/statuses.rb +75 -0
- data/lib/restman/statuses_compatibility.rb +18 -0
- data/lib/restman/utils.rb +10 -206
- data/lib/restman/version.rb +1 -1
- data/lib/restman.rb +24 -62
- data/matrixeval.yml +19 -1
- data/rest-man.gemspec +4 -10
- data/spec/integration/capath_digicert/ce5e74ef.0 +1 -1
- data/spec/integration/request_spec.rb +13 -1
- data/spec/spec_helper.rb +11 -0
- data/spec/unit/abstract_response_spec.rb +14 -0
- data/spec/unit/exception_spec.rb +64 -0
- data/spec/unit/exceptions/backwards_campatibility_spec.rb +29 -0
- data/spec/unit/exceptions/exceptions_map_spec.rb +89 -0
- data/spec/unit/exceptions/request_failed_spec.rb +51 -0
- data/spec/unit/exceptions/server_broke_connection_spec.rb +8 -0
- data/spec/unit/exceptions/timeout_spec.rb +59 -0
- data/spec/unit/params_array/process_pair_spec.rb +59 -0
- data/spec/unit/params_array_spec.rb +15 -10
- data/spec/unit/payload/multipart_spec.rb +116 -0
- data/spec/unit/payload/streamed_spec.rb +48 -0
- data/spec/unit/payload/url_encoded_spec.rb +65 -0
- data/spec/unit/payload_spec.rb +0 -208
- data/spec/unit/request/init/url/add_query_from_headers_spec.rb +40 -0
- data/spec/unit/request/init/url/normalize_url_spec.rb +25 -0
- data/spec/unit/request/init_spec.rb +83 -0
- data/spec/unit/request_spec.rb +143 -151
- data/spec/unit/utils_spec.rb +96 -104
- metadata +132 -16
- data/lib/restman/exceptions.rb +0 -238
- data/lib/restman/windows/root_certs.rb +0 -105
- data/lib/restman/windows.rb +0 -8
- data/spec/unit/exceptions_spec.rb +0 -108
- data/spec/unit/windows/root_certs_spec.rb +0 -22
data/lib/restman/resource.rb
CHANGED
@@ -1,38 +1,5 @@
|
|
1
1
|
module RestMan
|
2
|
-
#
|
3
|
-
# including authentication.
|
4
|
-
#
|
5
|
-
# Example:
|
6
|
-
#
|
7
|
-
# resource = RestMan::Resource.new('http://some/resource')
|
8
|
-
# jpg = resource.get(:accept => 'image/jpg')
|
9
|
-
#
|
10
|
-
# With HTTP basic authentication:
|
11
|
-
#
|
12
|
-
# resource = RestMan::Resource.new('http://protected/resource', :user => 'user', :password => 'password')
|
13
|
-
# resource.delete
|
14
|
-
#
|
15
|
-
# With a timeout (seconds):
|
16
|
-
#
|
17
|
-
# RestMan::Resource.new('http://slow', :read_timeout => 10)
|
18
|
-
#
|
19
|
-
# With an open timeout (seconds):
|
20
|
-
#
|
21
|
-
# RestMan::Resource.new('http://behindfirewall', :open_timeout => 10)
|
22
|
-
#
|
23
|
-
# You can also use resources to share common headers. For headers keys,
|
24
|
-
# symbols are converted to strings. Example:
|
25
|
-
#
|
26
|
-
# resource = RestMan::Resource.new('http://some/resource', :headers => { :client_version => 1 })
|
27
|
-
#
|
28
|
-
# This header will be transported as X-Client-Version (notice the X prefix,
|
29
|
-
# capitalization and hyphens)
|
30
|
-
#
|
31
|
-
# Use the [] syntax to allocate subresources:
|
32
|
-
#
|
33
|
-
# site = RestMan::Resource.new('http://example.com', :user => 'adam', :password => 'mypasswd')
|
34
|
-
# site['posts/1/comments'].post 'Good article.', :content_type => 'text/plain'
|
35
|
-
#
|
2
|
+
# :include: _doc/lib/restman/resource.rdoc
|
36
3
|
class Resource
|
37
4
|
attr_reader :url, :options, :block
|
38
5
|
|
@@ -131,32 +98,7 @@ module RestMan
|
|
131
98
|
options[:log] || RestMan.log
|
132
99
|
end
|
133
100
|
|
134
|
-
#
|
135
|
-
#
|
136
|
-
# Example:
|
137
|
-
#
|
138
|
-
# site = RestMan::Resource.new('http://example.com', 'adam', 'mypasswd')
|
139
|
-
# site['posts/1/comments'].post 'Good article.', :content_type => 'text/plain'
|
140
|
-
#
|
141
|
-
# This is especially useful if you wish to define your site in one place and
|
142
|
-
# call it in multiple locations:
|
143
|
-
#
|
144
|
-
# def orders
|
145
|
-
# RestMan::Resource.new('http://example.com/orders', 'admin', 'mypasswd')
|
146
|
-
# end
|
147
|
-
#
|
148
|
-
# orders.get # GET http://example.com/orders
|
149
|
-
# orders['1'].get # GET http://example.com/orders/1
|
150
|
-
# orders['1/items'].delete # DELETE http://example.com/orders/1/items
|
151
|
-
#
|
152
|
-
# Nest resources as far as you want:
|
153
|
-
#
|
154
|
-
# site = RestMan::Resource.new('http://example.com')
|
155
|
-
# posts = site['posts']
|
156
|
-
# first_post = posts['1']
|
157
|
-
# comments = first_post['comments']
|
158
|
-
# comments.post 'Hello', :content_type => 'text/plain'
|
159
|
-
#
|
101
|
+
# :include: _doc/lib/restman/resource/[].rdoc
|
160
102
|
def [](suburl, &new_block)
|
161
103
|
case
|
162
104
|
when block_given? then self.class.new(concat_urls(url, suburl), options, &new_block)
|
data/lib/restman/response.rb
CHANGED
@@ -6,13 +6,7 @@ module RestMan
|
|
6
6
|
|
7
7
|
include AbstractResponse
|
8
8
|
|
9
|
-
#
|
10
|
-
#
|
11
|
-
# Future versions of RestMan will deprecate treating response objects
|
12
|
-
# directly as strings, so it will be necessary to call `.body`.
|
13
|
-
#
|
14
|
-
# @return [String]
|
15
|
-
#
|
9
|
+
# :include: _doc/lib/restman/response/body.rdoc
|
16
10
|
def body
|
17
11
|
# Benchmarking suggests that "#{self}" is fastest, and that caching the
|
18
12
|
# body string in an instance variable doesn't make it enough faster to be
|
@@ -21,15 +15,11 @@ module RestMan
|
|
21
15
|
end
|
22
16
|
|
23
17
|
# Convert the HTTP response body to a pure String object.
|
24
|
-
#
|
25
|
-
# @return [String]
|
26
18
|
def to_s
|
27
19
|
body
|
28
20
|
end
|
29
21
|
|
30
22
|
# Convert the HTTP response body to a pure String object.
|
31
|
-
#
|
32
|
-
# @return [String]
|
33
23
|
def to_str
|
34
24
|
body
|
35
25
|
end
|
@@ -38,14 +28,7 @@ module RestMan
|
|
38
28
|
"<RestMan::Response #{code.inspect} #{body_truncated(10).inspect}>"
|
39
29
|
end
|
40
30
|
|
41
|
-
#
|
42
|
-
# (unfortunately) a subclass of String for historical reasons,
|
43
|
-
# Response.create is the preferred initializer.
|
44
|
-
#
|
45
|
-
# @param [String, nil] body The response body from the Net::HTTPResponse
|
46
|
-
# @param [Net::HTTPResponse] net_http_res
|
47
|
-
# @param [RestMan::Request] request
|
48
|
-
# @param [Time] start_time
|
31
|
+
# :include: _doc/lib/restman/response/create.rdoc
|
49
32
|
def self.create(body, net_http_res, request, start_time=nil)
|
50
33
|
result = self.new(body || '')
|
51
34
|
|
@@ -55,8 +38,7 @@ module RestMan
|
|
55
38
|
result
|
56
39
|
end
|
57
40
|
|
58
|
-
#
|
59
|
-
# if possible.
|
41
|
+
# :include: _doc/lib/restman/response/fix_encoding.rdoc
|
60
42
|
def self.fix_encoding(response)
|
61
43
|
charset = RestMan::Utils.get_encoding_from_headers(response.headers)
|
62
44
|
encoding = nil
|
@@ -0,0 +1,75 @@
|
|
1
|
+
module RestMan
|
2
|
+
|
3
|
+
# :include: _doc/lib/restman/statuses.rdoc
|
4
|
+
STATUSES = {
|
5
|
+
100 => 'Continue',
|
6
|
+
101 => 'Switching Protocols',
|
7
|
+
102 => 'Processing', #WebDAV
|
8
|
+
|
9
|
+
200 => 'OK',
|
10
|
+
201 => 'Created',
|
11
|
+
202 => 'Accepted',
|
12
|
+
203 => 'Non-Authoritative Information', # http/1.1
|
13
|
+
204 => 'No Content',
|
14
|
+
205 => 'Reset Content',
|
15
|
+
206 => 'Partial Content',
|
16
|
+
207 => 'Multi-Status', #WebDAV
|
17
|
+
208 => 'Already Reported', # RFC5842
|
18
|
+
226 => 'IM Used', # RFC3229
|
19
|
+
|
20
|
+
300 => 'Multiple Choices',
|
21
|
+
301 => 'Moved Permanently',
|
22
|
+
302 => 'Found',
|
23
|
+
303 => 'See Other', # http/1.1
|
24
|
+
304 => 'Not Modified',
|
25
|
+
305 => 'Use Proxy', # http/1.1
|
26
|
+
306 => 'Switch Proxy', # no longer used
|
27
|
+
307 => 'Temporary Redirect', # http/1.1
|
28
|
+
308 => 'Permanent Redirect', # RFC7538
|
29
|
+
|
30
|
+
400 => 'Bad Request',
|
31
|
+
401 => 'Unauthorized',
|
32
|
+
402 => 'Payment Required',
|
33
|
+
403 => 'Forbidden',
|
34
|
+
404 => 'Not Found',
|
35
|
+
405 => 'Method Not Allowed',
|
36
|
+
406 => 'Not Acceptable',
|
37
|
+
407 => 'Proxy Authentication Required',
|
38
|
+
408 => 'Request Timeout',
|
39
|
+
409 => 'Conflict',
|
40
|
+
410 => 'Gone',
|
41
|
+
411 => 'Length Required',
|
42
|
+
412 => 'Precondition Failed',
|
43
|
+
413 => 'Payload Too Large', # RFC7231 (renamed, see below)
|
44
|
+
414 => 'URI Too Long', # RFC7231 (renamed, see below)
|
45
|
+
415 => 'Unsupported Media Type',
|
46
|
+
416 => 'Range Not Satisfiable', # RFC7233 (renamed, see below)
|
47
|
+
417 => 'Expectation Failed',
|
48
|
+
418 => 'I\'m A Teapot', #RFC2324
|
49
|
+
421 => 'Too Many Connections From This IP',
|
50
|
+
422 => 'Unprocessable Entity', #WebDAV
|
51
|
+
423 => 'Locked', #WebDAV
|
52
|
+
424 => 'Failed Dependency', #WebDAV
|
53
|
+
425 => 'Unordered Collection', #WebDAV
|
54
|
+
426 => 'Upgrade Required',
|
55
|
+
428 => 'Precondition Required', #RFC6585
|
56
|
+
429 => 'Too Many Requests', #RFC6585
|
57
|
+
431 => 'Request Header Fields Too Large', #RFC6585
|
58
|
+
449 => 'Retry With', #Microsoft
|
59
|
+
450 => 'Blocked By Windows Parental Controls', #Microsoft
|
60
|
+
|
61
|
+
500 => 'Internal Server Error',
|
62
|
+
501 => 'Not Implemented',
|
63
|
+
502 => 'Bad Gateway',
|
64
|
+
503 => 'Service Unavailable',
|
65
|
+
504 => 'Gateway Timeout',
|
66
|
+
505 => 'HTTP Version Not Supported',
|
67
|
+
506 => 'Variant Also Negotiates',
|
68
|
+
507 => 'Insufficient Storage', #WebDAV
|
69
|
+
508 => 'Loop Detected', # RFC5842
|
70
|
+
509 => 'Bandwidth Limit Exceeded', #Apache
|
71
|
+
510 => 'Not Extended',
|
72
|
+
511 => 'Network Authentication Required', # RFC6585
|
73
|
+
}
|
74
|
+
|
75
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module RestMan
|
2
|
+
|
3
|
+
STATUSES_COMPATIBILITY = {
|
4
|
+
# The RFCs all specify "Not Found", but "Resource Not Found" was used in
|
5
|
+
# earlier RestMan releases.
|
6
|
+
404 => ['ResourceNotFound'],
|
7
|
+
|
8
|
+
# HTTP 413 was renamed to "Payload Too Large" in RFC7231.
|
9
|
+
413 => ['RequestEntityTooLarge'],
|
10
|
+
|
11
|
+
# HTTP 414 was renamed to "URI Too Long" in RFC7231.
|
12
|
+
414 => ['RequestURITooLong'],
|
13
|
+
|
14
|
+
# HTTP 416 was renamed to "Range Not Satisfiable" in RFC7233.
|
15
|
+
416 => ['RequestedRangeNotSatisfiable'],
|
16
|
+
}
|
17
|
+
|
18
|
+
end
|
data/lib/restman/utils.rb
CHANGED
@@ -4,55 +4,21 @@ module RestMan
|
|
4
4
|
# Various utility methods
|
5
5
|
module Utils
|
6
6
|
|
7
|
-
#
|
8
|
-
#
|
9
|
-
# We use the RFC 7231 specification and do not impose a default encoding on
|
10
|
-
# text. This differs from the older RFC 2616 behavior, which specifies
|
11
|
-
# using ISO-8859-1 for text/* content types without a charset.
|
12
|
-
#
|
13
|
-
# Strings will use the default encoding when this method returns nil. This
|
14
|
-
# default is likely to be UTF-8 for Ruby >= 2.0
|
15
|
-
#
|
16
|
-
# @param headers [Hash<Symbol,String>]
|
17
|
-
#
|
18
|
-
# @return [String, nil] Return the string encoding or nil if no header is
|
19
|
-
# found.
|
20
|
-
#
|
21
|
-
# @example
|
22
|
-
# >> get_encoding_from_headers({:content_type => 'text/plain; charset=UTF-8'})
|
23
|
-
# => "UTF-8"
|
24
|
-
#
|
7
|
+
# :include: _doc/lib/restman/utils/get_encoding_from_headers.rdoc
|
25
8
|
def self.get_encoding_from_headers(headers)
|
26
9
|
type_header = headers[:content_type]
|
27
10
|
return nil unless type_header
|
28
11
|
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
if params.include?('charset')
|
34
|
-
return params.fetch('charset').gsub(/(\A["']*)|(["']*\z)/, '')
|
35
|
-
end
|
36
|
-
|
12
|
+
begin
|
13
|
+
_content_type, params = cgi_parse_header(type_header)
|
14
|
+
rescue HTTP::Accept::ParseError
|
15
|
+
return nil
|
37
16
|
else
|
38
|
-
|
39
|
-
begin
|
40
|
-
_content_type, params = cgi_parse_header(type_header)
|
41
|
-
rescue HTTP::Accept::ParseError
|
42
|
-
return nil
|
43
|
-
else
|
44
|
-
params['charset']
|
45
|
-
end
|
17
|
+
params['charset']
|
46
18
|
end
|
47
19
|
end
|
48
20
|
|
49
|
-
#
|
50
|
-
#
|
51
|
-
# Return the main content-type and a hash of params.
|
52
|
-
#
|
53
|
-
# @param [String] line
|
54
|
-
# @return [Array(String, Hash)]
|
55
|
-
#
|
21
|
+
# :include: _doc/lib/restman/utils/cgi_parse_header.rdoc
|
56
22
|
def self.cgi_parse_header(line)
|
57
23
|
types = HTTP::Accept::MediaTypes.parse(line)
|
58
24
|
|
@@ -63,165 +29,12 @@ module RestMan
|
|
63
29
|
[types.first.mime_type, types.first.parameters]
|
64
30
|
end
|
65
31
|
|
66
|
-
#
|
67
|
-
#
|
68
|
-
# @private
|
69
|
-
#
|
70
|
-
# @deprecated This method is deprecated and only exists to support Ruby
|
71
|
-
# 2.0, which is not supported by HTTP::Accept.
|
72
|
-
#
|
73
|
-
# @todo remove this method when dropping support for Ruby 2.0
|
74
|
-
#
|
75
|
-
def self._cgi_parseparam(s)
|
76
|
-
return enum_for(__method__, s) unless block_given?
|
77
|
-
|
78
|
-
while s[0] == ';'
|
79
|
-
s = s[1..-1]
|
80
|
-
ends = s.index(';')
|
81
|
-
while ends && ends > 0 \
|
82
|
-
&& (s[0...ends].count('"') -
|
83
|
-
s[0...ends].scan('\"').count) % 2 != 0
|
84
|
-
ends = s.index(';', ends + 1)
|
85
|
-
end
|
86
|
-
if ends.nil?
|
87
|
-
ends = s.length
|
88
|
-
end
|
89
|
-
f = s[0...ends]
|
90
|
-
yield f.strip
|
91
|
-
s = s[ends..-1]
|
92
|
-
end
|
93
|
-
nil
|
94
|
-
end
|
95
|
-
|
96
|
-
# Parse a Content-Type like header.
|
97
|
-
#
|
98
|
-
# Return the main content-type and a hash of options.
|
99
|
-
#
|
100
|
-
# This method was ported directly from Python's cgi.parse_header(). It
|
101
|
-
# probably doesn't read or perform particularly well in ruby.
|
102
|
-
# https://github.com/python/cpython/blob/3.4/Lib/cgi.py#L301-L331
|
103
|
-
#
|
104
|
-
# @param [String] line
|
105
|
-
# @return [Array(String, Hash)]
|
106
|
-
#
|
107
|
-
# @deprecated This method is deprecated and only exists to support Ruby
|
108
|
-
# 2.0, which is not supported by HTTP::Accept.
|
109
|
-
#
|
110
|
-
# @todo remove this method when dropping support for Ruby 2.0
|
111
|
-
#
|
112
|
-
def self.deprecated_cgi_parse_header(line)
|
113
|
-
parts = _cgi_parseparam(';' + line)
|
114
|
-
key = parts.next
|
115
|
-
pdict = {}
|
116
|
-
|
117
|
-
begin
|
118
|
-
while (p = parts.next)
|
119
|
-
i = p.index('=')
|
120
|
-
if i
|
121
|
-
name = p[0...i].strip.downcase
|
122
|
-
value = p[i+1..-1].strip
|
123
|
-
if value.length >= 2 && value[0] == '"' && value[-1] == '"'
|
124
|
-
value = value[1...-1]
|
125
|
-
value = value.gsub('\\\\', '\\').gsub('\\"', '"')
|
126
|
-
end
|
127
|
-
pdict[name] = value
|
128
|
-
end
|
129
|
-
end
|
130
|
-
rescue StopIteration
|
131
|
-
end
|
132
|
-
|
133
|
-
[key, pdict]
|
134
|
-
end
|
135
|
-
|
136
|
-
# Serialize a ruby object into HTTP query string parameters.
|
137
|
-
#
|
138
|
-
# There is no standard for doing this, so we choose our own slightly
|
139
|
-
# idiosyncratic format. The output closely matches the format understood by
|
140
|
-
# Rails, Rack, and PHP.
|
141
|
-
#
|
142
|
-
# If you don't want handling of complex objects and only want to handle
|
143
|
-
# simple flat hashes, you may want to use `URI.encode_www_form` instead,
|
144
|
-
# which implements HTML5-compliant URL encoded form data.
|
145
|
-
#
|
146
|
-
# @param [Hash,ParamsArray] object The object to serialize
|
147
|
-
#
|
148
|
-
# @return [String] A string appropriate for use as an HTTP query string
|
149
|
-
#
|
150
|
-
# @see {flatten_params}
|
151
|
-
#
|
152
|
-
# @see URI.encode_www_form
|
153
|
-
#
|
154
|
-
# @see See also Object#to_query in ActiveSupport
|
155
|
-
# @see http://php.net/manual/en/function.http-build-query.php
|
156
|
-
# http_build_query in PHP
|
157
|
-
# @see See also Rack::Utils.build_nested_query in Rack
|
158
|
-
#
|
159
|
-
# Notable differences from the ActiveSupport implementation:
|
160
|
-
#
|
161
|
-
# - Empty hash and empty array are treated the same as nil instead of being
|
162
|
-
# omitted entirely from the output. Rather than disappearing, they will
|
163
|
-
# appear to be nil instead.
|
164
|
-
#
|
165
|
-
# It's most common to pass a Hash as the object to serialize, but you can
|
166
|
-
# also use a ParamsArray if you want to be able to pass the same key with
|
167
|
-
# multiple values and not use the rack/rails array convention.
|
168
|
-
#
|
169
|
-
# @since 2.0.0
|
170
|
-
#
|
171
|
-
# @example Simple hashes
|
172
|
-
# >> encode_query_string({foo: 123, bar: 456})
|
173
|
-
# => 'foo=123&bar=456'
|
174
|
-
#
|
175
|
-
# @example Simple arrays
|
176
|
-
# >> encode_query_string({foo: [1,2,3]})
|
177
|
-
# => 'foo[]=1&foo[]=2&foo[]=3'
|
178
|
-
#
|
179
|
-
# @example Nested hashes
|
180
|
-
# >> encode_query_string({outer: {foo: 123, bar: 456}})
|
181
|
-
# => 'outer[foo]=123&outer[bar]=456'
|
182
|
-
#
|
183
|
-
# @example Deeply nesting
|
184
|
-
# >> encode_query_string({coords: [{x: 1, y: 0}, {x: 2}, {x: 3}]})
|
185
|
-
# => 'coords[][x]=1&coords[][y]=0&coords[][x]=2&coords[][x]=3'
|
186
|
-
#
|
187
|
-
# @example Null and empty values
|
188
|
-
# >> encode_query_string({string: '', empty: nil, list: [], hash: {}})
|
189
|
-
# => 'string=&empty&list&hash'
|
190
|
-
#
|
191
|
-
# @example Nested nulls
|
192
|
-
# >> encode_query_string({foo: {string: '', empty: nil}})
|
193
|
-
# => 'foo[string]=&foo[empty]'
|
194
|
-
#
|
195
|
-
# @example Multiple fields with the same name using ParamsArray
|
196
|
-
# >> encode_query_string(RestMan::ParamsArray.new([[:foo, 1], [:foo, 2], [:foo, 3]]))
|
197
|
-
# => 'foo=1&foo=2&foo=3'
|
198
|
-
#
|
199
|
-
# @example Nested ParamsArray
|
200
|
-
# >> encode_query_string({foo: RestMan::ParamsArray.new([[:a, 1], [:a, 2]])})
|
201
|
-
# => 'foo[a]=1&foo[a]=2'
|
202
|
-
#
|
203
|
-
# >> encode_query_string(RestMan::ParamsArray.new([[:foo, {a: 1}], [:foo, {a: 2}]]))
|
204
|
-
# => 'foo[a]=1&foo[a]=2'
|
205
|
-
#
|
32
|
+
# :include: _doc/lib/restman/utils/encode_query_string.rdoc
|
206
33
|
def self.encode_query_string(object)
|
207
34
|
flatten_params(object, true).map {|k, v| v.nil? ? k : "#{k}=#{v}" }.join('&')
|
208
35
|
end
|
209
36
|
|
210
|
-
#
|
211
|
-
# value] pairs.
|
212
|
-
#
|
213
|
-
# @example
|
214
|
-
# >> flatten_params({key1: {key2: 123}})
|
215
|
-
# => [["key1[key2]", 123]]
|
216
|
-
#
|
217
|
-
# @example
|
218
|
-
# >> flatten_params({key1: {key2: 123, arr: [1,2,3]}})
|
219
|
-
# => [["key1[key2]", 123], ["key1[arr][]", 1], ["key1[arr][]", 2], ["key1[arr][]", 3]]
|
220
|
-
#
|
221
|
-
# @param object [Hash, ParamsArray] The container to flatten
|
222
|
-
# @param uri_escape [Boolean] Whether to URI escape keys and values
|
223
|
-
# @param parent_key [String] Should not be passed (used for recursion)
|
224
|
-
#
|
37
|
+
# :include: _doc/lib/restman/utils/flatten_params.rdoc
|
225
38
|
def self.flatten_params(object, uri_escape=false, parent_key=nil)
|
226
39
|
unless object.is_a?(Hash) || object.is_a?(ParamsArray) ||
|
227
40
|
(parent_key && object.is_a?(Array))
|
@@ -257,16 +70,7 @@ module RestMan
|
|
257
70
|
}
|
258
71
|
end
|
259
72
|
|
260
|
-
#
|
261
|
-
# style escape, which transforms ` ` into `+` and various special
|
262
|
-
# characters into percent encoded forms.
|
263
|
-
#
|
264
|
-
# This calls URI.encode_www_form_component for the implementation. The only
|
265
|
-
# difference between this and CGI.escape is that it does not escape `*`.
|
266
|
-
# http://stackoverflow.com/questions/25085992/
|
267
|
-
#
|
268
|
-
# @see URI.encode_www_form_component
|
269
|
-
#
|
73
|
+
# :include: _doc/lib/restman/utils/escape.rdoc
|
270
74
|
def self.escape(string)
|
271
75
|
URI.encode_www_form_component(string)
|
272
76
|
end
|
data/lib/restman/version.rb
CHANGED
data/lib/restman.rb
CHANGED
@@ -2,64 +2,35 @@ require 'net/http'
|
|
2
2
|
require 'openssl'
|
3
3
|
require 'stringio'
|
4
4
|
require 'uri'
|
5
|
+
require 'active_method'
|
5
6
|
|
6
7
|
require File.dirname(__FILE__) + '/restman/version'
|
8
|
+
require File.dirname(__FILE__) + '/restman/statuses'
|
9
|
+
require File.dirname(__FILE__) + '/restman/statuses_compatibility'
|
7
10
|
require File.dirname(__FILE__) + '/restman/platform'
|
8
|
-
require File.dirname(__FILE__) + '/restman/
|
11
|
+
require File.dirname(__FILE__) + '/restman/exception'
|
12
|
+
require File.dirname(__FILE__) + '/restman/exceptions/exception_with_response'
|
13
|
+
require File.dirname(__FILE__) + '/restman/exceptions/request_failed'
|
14
|
+
require File.dirname(__FILE__) + '/restman/exceptions/exceptions_map'
|
15
|
+
require File.dirname(__FILE__) + '/restman/exceptions/timeout'
|
16
|
+
require File.dirname(__FILE__) + '/restman/exceptions/server_broke_connection'
|
9
17
|
require File.dirname(__FILE__) + '/restman/utils'
|
18
|
+
require File.dirname(__FILE__) + '/restman/request/init'
|
19
|
+
require File.dirname(__FILE__) + '/restman/request/transmit'
|
10
20
|
require File.dirname(__FILE__) + '/restman/request'
|
11
21
|
require File.dirname(__FILE__) + '/restman/abstract_response'
|
12
22
|
require File.dirname(__FILE__) + '/restman/response'
|
13
23
|
require File.dirname(__FILE__) + '/restman/raw_response'
|
14
24
|
require File.dirname(__FILE__) + '/restman/resource'
|
15
25
|
require File.dirname(__FILE__) + '/restman/params_array'
|
26
|
+
require File.dirname(__FILE__) + '/restman/params_array/process_pair'
|
16
27
|
require File.dirname(__FILE__) + '/restman/payload'
|
17
|
-
require File.dirname(__FILE__) + '/restman/
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
#
|
23
|
-
# jpg = RestMan.get 'http://example.com/resource', :accept => 'image/jpg'
|
24
|
-
#
|
25
|
-
# # authentication and SSL
|
26
|
-
# RestMan.get 'https://user:password@example.com/private/resource'
|
27
|
-
#
|
28
|
-
# # POST or PUT with a hash sends parameters as a urlencoded form body
|
29
|
-
# RestMan.post 'http://example.com/resource', :param1 => 'one'
|
30
|
-
#
|
31
|
-
# # nest hash parameters
|
32
|
-
# RestMan.post 'http://example.com/resource', :nested => { :param1 => 'one' }
|
33
|
-
#
|
34
|
-
# # POST and PUT with raw payloads
|
35
|
-
# RestMan.post 'http://example.com/resource', 'the post body', :content_type => 'text/plain'
|
36
|
-
# RestMan.post 'http://example.com/resource.xml', xml_doc
|
37
|
-
# RestMan.put 'http://example.com/resource.pdf', File.read('my.pdf'), :content_type => 'application/pdf'
|
38
|
-
#
|
39
|
-
# # DELETE
|
40
|
-
# RestMan.delete 'http://example.com/resource'
|
41
|
-
#
|
42
|
-
# # retrieve the response http code and headers
|
43
|
-
# res = RestMan.get 'http://example.com/some.jpg'
|
44
|
-
# res.code # => 200
|
45
|
-
# res.headers[:content_type] # => 'image/jpg'
|
46
|
-
#
|
47
|
-
# # HEAD
|
48
|
-
# RestMan.head('http://example.com').headers
|
49
|
-
#
|
50
|
-
# To use with a proxy, just set RestMan.proxy to the proper http proxy:
|
51
|
-
#
|
52
|
-
# RestMan.proxy = "http://proxy.example.com/"
|
53
|
-
#
|
54
|
-
# Or inherit the proxy from the environment:
|
55
|
-
#
|
56
|
-
# RestMan.proxy = ENV['http_proxy']
|
57
|
-
#
|
58
|
-
# For live tests of RestMan, try using http://rest-test.heroku.com, which echoes back information about the rest call:
|
59
|
-
#
|
60
|
-
# >> RestMan.put 'http://rest-test.heroku.com/resource', :foo => 'baz'
|
61
|
-
# => "PUT http://rest-test.heroku.com/resource with a 7 byte payload, content type application/x-www-form-urlencoded {\"foo\"=>\"baz\"}"
|
62
|
-
#
|
28
|
+
require File.dirname(__FILE__) + '/restman/payload/base'
|
29
|
+
require File.dirname(__FILE__) + '/restman/payload/multipart'
|
30
|
+
require File.dirname(__FILE__) + '/restman/payload/streamed'
|
31
|
+
require File.dirname(__FILE__) + '/restman/payload/url_encoded'
|
32
|
+
|
33
|
+
# :include: _doc/lib/restman.rdoc
|
63
34
|
module RestMan
|
64
35
|
|
65
36
|
def self.get(url, headers={}, &block)
|
@@ -90,8 +61,7 @@ module RestMan
|
|
90
61
|
Request.execute(:method => :options, :url => url, :headers => headers, &block)
|
91
62
|
end
|
92
63
|
|
93
|
-
#
|
94
|
-
# per-request basis by passing `:proxy` to RestMan::Request.
|
64
|
+
# :include: _doc/lib/restman/proxy.rdoc
|
95
65
|
def self.proxy
|
96
66
|
@proxy ||= nil
|
97
67
|
end
|
@@ -101,24 +71,17 @@ module RestMan
|
|
101
71
|
@proxy_set = true
|
102
72
|
end
|
103
73
|
|
104
|
-
#
|
105
|
-
# differentiate between no value being set and a value explicitly set to nil.
|
106
|
-
#
|
107
|
-
# @return [Boolean]
|
108
|
-
#
|
74
|
+
# :include: _doc/lib/restman/proxy_set?.rdoc
|
109
75
|
def self.proxy_set?
|
110
76
|
@proxy_set ||= false
|
111
77
|
end
|
112
78
|
|
113
|
-
#
|
114
|
-
# Value should be a logger but can can be stdout, stderr, or a filename.
|
115
|
-
# You can also configure logging by the environment variable RESTCLIENT_LOG.
|
79
|
+
# :include: _doc/lib/restman/log=.rdoc
|
116
80
|
def self.log= log
|
117
81
|
@@log = create_log log
|
118
82
|
end
|
119
83
|
|
120
|
-
#
|
121
|
-
# param can be 'stdout', 'stderr', a string (then we will log to that file) or a logger (then we return it)
|
84
|
+
# :include: _doc/lib/restman/create_log.rdoc
|
122
85
|
def self.create_log param
|
123
86
|
if param
|
124
87
|
if param.is_a? String
|
@@ -164,14 +127,13 @@ module RestMan
|
|
164
127
|
|
165
128
|
@@before_execution_procs = []
|
166
129
|
|
167
|
-
#
|
168
|
-
# The proc parameters will be the http request and the request params.
|
130
|
+
# :include: _doc/lib/restman/add_before_execution_proc.rdoc
|
169
131
|
def self.add_before_execution_proc &proc
|
170
132
|
raise ArgumentError.new('block is required') unless proc
|
171
133
|
@@before_execution_procs << proc
|
172
134
|
end
|
173
135
|
|
174
|
-
#
|
136
|
+
# :include: _doc/lib/restman/reset_before_execution_procs.rdoc
|
175
137
|
def self.reset_before_execution_procs
|
176
138
|
@@before_execution_procs = []
|
177
139
|
end
|
data/matrixeval.yml
CHANGED
@@ -4,6 +4,8 @@ project_name: rest_man
|
|
4
4
|
parallel_workers: number_of_processors
|
5
5
|
commands:
|
6
6
|
- jruby
|
7
|
+
- rubycritic
|
8
|
+
- rdoc
|
7
9
|
# - ps
|
8
10
|
# - top
|
9
11
|
# - an_additional_command
|
@@ -12,16 +14,25 @@ commands:
|
|
12
14
|
matrix:
|
13
15
|
ruby:
|
14
16
|
variants:
|
17
|
+
- key: 2.6
|
18
|
+
container:
|
19
|
+
image: ruby:2.6.10
|
15
20
|
- key: 2.7
|
16
21
|
container:
|
17
22
|
image: ruby:2.7.6
|
18
23
|
- key: 3.0
|
19
|
-
default: true
|
20
24
|
container:
|
21
25
|
image: ruby:3.0.4
|
22
26
|
- key: 3.1
|
23
27
|
container:
|
24
28
|
image: ruby:3.1.0
|
29
|
+
- key: 3.2
|
30
|
+
default: true
|
31
|
+
container:
|
32
|
+
image: ruby:3.2.2
|
33
|
+
- key: 3.3
|
34
|
+
container:
|
35
|
+
image: ruby:3.3.0-preview1
|
25
36
|
- key: jruby-9.3
|
26
37
|
container:
|
27
38
|
image: hoppergee/jruby:9.3.7-dev
|
@@ -29,6 +40,13 @@ matrix:
|
|
29
40
|
PATH: "/opt/jruby/bin:/app/bin:/bundle/bin:$PATH"
|
30
41
|
JRUBY_OPTS: "--dev -X-C --debug"
|
31
42
|
JAVA_OPTS: "-client -XX:+TieredCompilation -XX:TieredStopAtLevel=1"
|
43
|
+
- key: jruby-9.4
|
44
|
+
container:
|
45
|
+
image: hoppergee/jruby:9.4.2-dev
|
46
|
+
env:
|
47
|
+
PATH: "/opt/jruby/bin:/app/bin:/bundle/bin:$PATH"
|
48
|
+
JRUBY_OPTS: "--dev -X-C --debug"
|
49
|
+
JAVA_OPTS: "-client -XX:+TieredCompilation -XX:TieredStopAtLevel=1"
|
32
50
|
# mounts:
|
33
51
|
# - /a/path/need/to/mount:/a/path/mount/to
|
34
52
|
|