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
@@ -0,0 +1,55 @@
|
|
1
|
+
:call-seq:
|
2
|
+
cookie_jar(uri, headers, args) -> HTTP::CookieJar
|
3
|
+
|
4
|
+
Process cookies passed as hash or as HTTP::CookieJar. For backwards
|
5
|
+
compatibility, these may be passed as a :cookies option masquerading
|
6
|
+
inside the headers hash. To avoid confusion, if :cookies is passed in
|
7
|
+
both headers and Request#initialize, raise an error.
|
8
|
+
|
9
|
+
[cookies may be a:]
|
10
|
+
|
11
|
+
- Hash{String/Symbol => String}
|
12
|
+
- Array<HTTP::Cookie>
|
13
|
+
- HTTP::CookieJar
|
14
|
+
|
15
|
+
Passing as a hash:
|
16
|
+
Keys may be symbols or strings. Values must be strings.
|
17
|
+
Infer the domain name from the request URI and allow subdomains (as
|
18
|
+
though '.example.com' had been set in a Set-Cookie header). Assume a
|
19
|
+
path of '/'.
|
20
|
+
|
21
|
+
RestMan::Request.new(url: 'http://example.com', method: :get,
|
22
|
+
:cookies => {:foo => 'Value', 'bar' => '123'}
|
23
|
+
)
|
24
|
+
|
25
|
+
results in cookies as though set from the server by:
|
26
|
+
Set-Cookie: foo=Value; Domain=.example.com; Path=/
|
27
|
+
Set-Cookie: bar=123; Domain=.example.com; Path=/
|
28
|
+
|
29
|
+
which yields a client cookie header of:
|
30
|
+
Cookie: foo=Value; bar=123
|
31
|
+
|
32
|
+
Passing as HTTP::CookieJar, which will be passed through directly:
|
33
|
+
|
34
|
+
jar = HTTP::CookieJar.new
|
35
|
+
jar.add(HTTP::Cookie.new('foo', 'Value', domain: 'example.com',
|
36
|
+
path: '/', for_domain: false))
|
37
|
+
|
38
|
+
RestMan::Request.new(..., :cookies => jar)
|
39
|
+
|
40
|
+
[Parameters:]
|
41
|
+
|
42
|
+
- *uri* (URI::HTTP) -- The URI for the request. This will be used to
|
43
|
+
infer the domain name for cookies passed as strings in a hash. To avoid
|
44
|
+
this implicit behavior, pass a full cookie jar or use HTTP::Cookie hash
|
45
|
+
values.
|
46
|
+
- *headers* (Hash) -- The headers hash from which to pull the :cookies
|
47
|
+
option. MUTATION NOTE: This key will be deleted from the hash if
|
48
|
+
present.
|
49
|
+
- *args* (Hash) -- The options passed to Request#initialize. This hash
|
50
|
+
will be used as another potential source for the :cookies key.
|
51
|
+
These args will not be mutated.
|
52
|
+
|
53
|
+
[Returns:]
|
54
|
+
|
55
|
+
- (HTTP::CookieJar) -- A cookie jar containing the parsed cookies.
|
@@ -0,0 +1,15 @@
|
|
1
|
+
:call-seq:
|
2
|
+
http_method(args) -> string
|
3
|
+
|
4
|
+
Parse `args[:method]` and return a normalized string version.
|
5
|
+
|
6
|
+
Raise ArgumentError if the `args[:method]` is falsy, but otherwise do no
|
7
|
+
validation.
|
8
|
+
|
9
|
+
[Parameters:]
|
10
|
+
|
11
|
+
- *args* (Hash)
|
12
|
+
|
13
|
+
[See Also:]
|
14
|
+
|
15
|
+
- net_http_request_class
|
@@ -0,0 +1,25 @@
|
|
1
|
+
:call-seq:
|
2
|
+
make_headers(user_headers) -> Hash<String, String>
|
3
|
+
|
4
|
+
Generate headers for use by a request. Header keys will be stringified
|
5
|
+
using `#stringify_headers` to normalize them as capitalized strings.
|
6
|
+
|
7
|
+
The final headers consist of:
|
8
|
+
- default headers from #default_headers
|
9
|
+
- user_headers provided here
|
10
|
+
- headers from the payload object (e.g. Content-Type, Content-Lenth)
|
11
|
+
- cookie headers from #make_cookie_header
|
12
|
+
|
13
|
+
BUG: stringify_headers does not alter the capitalization of headers that
|
14
|
+
are passed as strings, it only normalizes those passed as symbols. This
|
15
|
+
behavior will probably remain for a while for compatibility, but it means
|
16
|
+
that the warnings that attempt to detect accidental header overrides may
|
17
|
+
not always work.
|
18
|
+
https://github.com/rest-man/rest-man/issues/599
|
19
|
+
|
20
|
+
[Parameters:]
|
21
|
+
|
22
|
+
- user_headers (Hash) -- User-provided headers to include
|
23
|
+
|
24
|
+
[Returns]
|
25
|
+
- (Hash<String, String>) -- A hash of HTTP headers => values
|
@@ -0,0 +1,18 @@
|
|
1
|
+
:call-seq:
|
2
|
+
maybe_convert_extension(ext) -> string
|
3
|
+
|
4
|
+
Given a MIME type or file extension, return either a MIME type or, if
|
5
|
+
none is found, the input unchanged.
|
6
|
+
|
7
|
+
>> maybe_convert_extension('json')
|
8
|
+
=> 'application/json'
|
9
|
+
|
10
|
+
>> maybe_convert_extension('unknown')
|
11
|
+
=> 'unknown'
|
12
|
+
|
13
|
+
>> maybe_convert_extension('application/xml')
|
14
|
+
=> 'application/xml'
|
15
|
+
|
16
|
+
[Parameters:]
|
17
|
+
|
18
|
+
- ext (String)
|
@@ -0,0 +1,9 @@
|
|
1
|
+
:call-seq:
|
2
|
+
stringify_headers(headers) -> Object
|
3
|
+
|
4
|
+
Return a hash of headers whose keys are capitalized strings
|
5
|
+
|
6
|
+
BUG: stringify_headers does not fix the capitalization of headers that
|
7
|
+
are already Strings. Leaving this behavior as is for now for
|
8
|
+
backwards compatibility.
|
9
|
+
https://github.com/rest-man/rest-man/issues/599
|
@@ -0,0 +1,46 @@
|
|
1
|
+
This class is used internally by RestMan to send the request, but you can also
|
2
|
+
call it directly if you'd like to use a method not supported by the
|
3
|
+
main API. For example:
|
4
|
+
|
5
|
+
RestMan::Request.execute(:method => :head, :url => 'http://example.com')
|
6
|
+
|
7
|
+
Mandatory parameters:
|
8
|
+
* :method
|
9
|
+
* :url
|
10
|
+
Optional parameters (have a look at ssl and/or uri for some explanations):
|
11
|
+
* :headers a hash containing the request headers
|
12
|
+
* :cookies may be a Hash{String/Symbol => String} of cookie values, an
|
13
|
+
Array<HTTP::Cookie>, or an HTTP::CookieJar containing cookies. These
|
14
|
+
will be added to a cookie jar before the request is sent.
|
15
|
+
* :user and :password for basic auth, will be replaced by a user/password available in the :url
|
16
|
+
* :block_response call the provided block with the HTTPResponse as parameter
|
17
|
+
* :raw_response return a low-level RawResponse instead of a Response
|
18
|
+
* :log Set the log for this request only, overriding RestMan.log, if
|
19
|
+
any.
|
20
|
+
* :stream_log_percent (Only relevant with :raw_response => true) Customize
|
21
|
+
the interval at which download progress is logged. Defaults to every
|
22
|
+
10% complete.
|
23
|
+
* :max_retries maximum number of times to retry an idempotent request (default to 1)
|
24
|
+
* :max_redirects maximum number of redirections (default to 10)
|
25
|
+
* :proxy An HTTP proxy URI to use for this request. Any value here
|
26
|
+
(including nil) will override RestMan.proxy.
|
27
|
+
* :verify_ssl enable ssl verification, possible values are constants from
|
28
|
+
OpenSSL::SSL::VERIFY_*, defaults to OpenSSL::SSL::VERIFY_PEER
|
29
|
+
* :read_timeout, :open_timeout and :write_timeout are how long to wait for a response and
|
30
|
+
to open a connection, in seconds. Pass nil to disable the timeout.
|
31
|
+
* :timeout can be used to set: read_timeout, open_timeout and write_timeout
|
32
|
+
* :keep_alive_timeout sets seconds to reuse the connection of the previous request. (default to 2 seconds)
|
33
|
+
* :ssl_client_cert, :ssl_client_key, :ssl_ca_file, :ssl_ca_path,
|
34
|
+
:ssl_cert_store, :ssl_verify_callback, :ssl_verify_callback_warnings
|
35
|
+
* :ssl_version specifies the SSL version for the underlying Net::HTTP connection
|
36
|
+
* :ssl_min_version specifies the minimum SSL version for the underlying Net::HTTP connection
|
37
|
+
* :ssl_max_version specifies the maximum SSL version for the underlying Net::HTTP connection
|
38
|
+
* :ssl_timeout sets the SSL timeout seconds
|
39
|
+
* :ssl_ciphers sets SSL ciphers for the connection. See
|
40
|
+
OpenSSL::SSL::SSLContext#ciphers=
|
41
|
+
* :before_execution_proc a Proc to call before executing the request. This
|
42
|
+
proc, like procs from RestMan.before_execution_procs, will be
|
43
|
+
called with the HTTP request and request params.
|
44
|
+
* :close_on_empty_response default to false
|
45
|
+
* :local_host sets the local address for the outgoing connection
|
46
|
+
* :local_port sets the local port for the outgoing connection
|
@@ -0,0 +1 @@
|
|
1
|
+
Reset the procs to be called before each request is executed.
|
@@ -0,0 +1,25 @@
|
|
1
|
+
Construct a subresource, preserving authentication.
|
2
|
+
|
3
|
+
Example:
|
4
|
+
|
5
|
+
site = RestMan::Resource.new('http://example.com', 'adam', 'mypasswd')
|
6
|
+
site['posts/1/comments'].post 'Good article.', :content_type => 'text/plain'
|
7
|
+
|
8
|
+
This is especially useful if you wish to define your site in one place and
|
9
|
+
call it in multiple locations:
|
10
|
+
|
11
|
+
def orders
|
12
|
+
RestMan::Resource.new('http://example.com/orders', 'admin', 'mypasswd')
|
13
|
+
end
|
14
|
+
|
15
|
+
orders.get # GET http://example.com/orders
|
16
|
+
orders['1'].get # GET http://example.com/orders/1
|
17
|
+
orders['1/items'].delete # DELETE http://example.com/orders/1/items
|
18
|
+
|
19
|
+
Nest resources as far as you want:
|
20
|
+
|
21
|
+
site = RestMan::Resource.new('http://example.com')
|
22
|
+
posts = site['posts']
|
23
|
+
first_post = posts['1']
|
24
|
+
comments = first_post['comments']
|
25
|
+
comments.post 'Hello', :content_type => 'text/plain'
|
@@ -0,0 +1,33 @@
|
|
1
|
+
A class that can be instantiated for access to a RESTful resource,
|
2
|
+
including authentication.
|
3
|
+
|
4
|
+
Example:
|
5
|
+
|
6
|
+
resource = RestMan::Resource.new('http://some/resource')
|
7
|
+
jpg = resource.get(:accept => 'image/jpg')
|
8
|
+
|
9
|
+
With HTTP basic authentication:
|
10
|
+
|
11
|
+
resource = RestMan::Resource.new('http://protected/resource', :user => 'user', :password => 'password')
|
12
|
+
resource.delete
|
13
|
+
|
14
|
+
With a timeout (seconds):
|
15
|
+
|
16
|
+
RestMan::Resource.new('http://slow', :read_timeout => 10)
|
17
|
+
|
18
|
+
With an open timeout (seconds):
|
19
|
+
|
20
|
+
RestMan::Resource.new('http://behindfirewall', :open_timeout => 10)
|
21
|
+
|
22
|
+
You can also use resources to share common headers. For headers keys,
|
23
|
+
symbols are converted to strings. Example:
|
24
|
+
|
25
|
+
resource = RestMan::Resource.new('http://some/resource', :headers => { :client_version => 1 })
|
26
|
+
|
27
|
+
This header will be transported as X-Client-Version (notice the X prefix,
|
28
|
+
capitalization and hyphens)
|
29
|
+
|
30
|
+
Use the [] syntax to allocate subresources:
|
31
|
+
|
32
|
+
site = RestMan::Resource.new('http://example.com', :user => 'adam', :password => 'mypasswd')
|
33
|
+
site['posts/1/comments'].post 'Good article.', :content_type => 'text/plain'
|
@@ -0,0 +1,10 @@
|
|
1
|
+
Initialize a Response object. Because RestMan::Response is
|
2
|
+
(unfortunately) a subclass of String for historical reasons,
|
3
|
+
Response.create is the preferred initializer.
|
4
|
+
|
5
|
+
[Parameters:]
|
6
|
+
|
7
|
+
- *body* (String, nil) -- The response body from the Net::HTTPResponse
|
8
|
+
- *net_http_res* (Net::HTTPResponse)
|
9
|
+
- *request* (RestMan::Request)
|
10
|
+
- *start_time* (Time)
|
@@ -0,0 +1,11 @@
|
|
1
|
+
Hash of HTTP status code => message.
|
2
|
+
|
3
|
+
- *1xx*: Informational -- Request received, continuing process
|
4
|
+
- *2xx*: Success -- The action was successfully received, understood, and accepted
|
5
|
+
- *3xx*: Redirection -- Further action must be taken in order to complete the request
|
6
|
+
- *4xx*: Client Error -- The request contains bad syntax or cannot be fulfilled
|
7
|
+
- *5xx*: Server Error -- The server failed to fulfill an apparently valid request
|
8
|
+
|
9
|
+
[See Also:]
|
10
|
+
|
11
|
+
http://www.iana.org/assignments/http-status-codes/http-status-codes.xhtml
|
@@ -0,0 +1,90 @@
|
|
1
|
+
:call-seq:
|
2
|
+
encode_query_string(object) -> string
|
3
|
+
|
4
|
+
Serialize a ruby object into HTTP query string parameters.
|
5
|
+
|
6
|
+
There is no standard for doing this, so we choose our own slightly
|
7
|
+
idiosyncratic format. The output closely matches the format understood by
|
8
|
+
Rails, Rack, and PHP.
|
9
|
+
|
10
|
+
If you don't want handling of complex objects and only want to handle
|
11
|
+
simple flat hashes, you may want to use `URI.encode_www_form` instead,
|
12
|
+
which implements HTML5-compliant URL encoded form data.
|
13
|
+
|
14
|
+
[Examples:]
|
15
|
+
|
16
|
+
Simple hashes
|
17
|
+
|
18
|
+
>> encode_query_string({foo: 123, bar: 456})
|
19
|
+
=> 'foo=123&bar=456'
|
20
|
+
|
21
|
+
Simple arrays
|
22
|
+
|
23
|
+
>> encode_query_string({foo: [1,2,3]})
|
24
|
+
=> 'foo[]=1&foo[]=2&foo[]=3'
|
25
|
+
|
26
|
+
Nested hashes
|
27
|
+
|
28
|
+
>> encode_query_string({outer: {foo: 123, bar: 456}})
|
29
|
+
=> 'outer[foo]=123&outer[bar]=456'
|
30
|
+
|
31
|
+
Deeply nesting
|
32
|
+
|
33
|
+
>> encode_query_string({coords: [{x: 1, y: 0}, {x: 2}, {x: 3}]})
|
34
|
+
=> 'coords[][x]=1&coords[][y]=0&coords[][x]=2&coords[][x]=3'
|
35
|
+
|
36
|
+
Null and empty values
|
37
|
+
|
38
|
+
>> encode_query_string({string: '', empty: nil, list: [], hash: {}})
|
39
|
+
=> 'string=&empty&list&hash'
|
40
|
+
|
41
|
+
Nested nulls
|
42
|
+
|
43
|
+
>> encode_query_string({foo: {string: '', empty: nil}})
|
44
|
+
=> 'foo[string]=&foo[empty]'
|
45
|
+
|
46
|
+
Multiple fields with the same name using ParamsArray
|
47
|
+
|
48
|
+
>> encode_query_string(RestMan::ParamsArray.new([[:foo, 1], [:foo, 2], [:foo, 3]]))
|
49
|
+
=> 'foo=1&foo=2&foo=3'
|
50
|
+
|
51
|
+
Nested ParamsArray
|
52
|
+
|
53
|
+
>> encode_query_string({foo: RestMan::ParamsArray.new([[:a, 1], [:a, 2]])})
|
54
|
+
=> 'foo[a]=1&foo[a]=2'
|
55
|
+
|
56
|
+
>> encode_query_string(RestMan::ParamsArray.new([[:foo, {a: 1}], [:foo, {a: 2}]]))
|
57
|
+
=> 'foo[a]=1&foo[a]=2'
|
58
|
+
|
59
|
+
|
60
|
+
|
61
|
+
[Parameters:]
|
62
|
+
|
63
|
+
- object (Hash,ParamsArray) -- The object to serialize
|
64
|
+
|
65
|
+
[Returns:]
|
66
|
+
|
67
|
+
- (String) -- A string appropriate for use as an HTTP query string
|
68
|
+
|
69
|
+
[See Also:]
|
70
|
+
|
71
|
+
- flatten_params
|
72
|
+
- URI.encode_www_form
|
73
|
+
- Object#to_query in ActiveSupport
|
74
|
+
- http://php.net/manual/en/function.http-build-query.php
|
75
|
+
http_build_query in PHP
|
76
|
+
- Rack::Utils.build_nested_query in Rack
|
77
|
+
|
78
|
+
Notable differences from the ActiveSupport implementation:
|
79
|
+
|
80
|
+
- Empty hash and empty array are treated the same as nil instead of being
|
81
|
+
omitted entirely from the output. Rather than disappearing, they will
|
82
|
+
appear to be nil instead.
|
83
|
+
|
84
|
+
It's most common to pass a Hash as the object to serialize, but you can
|
85
|
+
also use a ParamsArray if you want to be able to pass the same key with
|
86
|
+
multiple values and not use the rack/rails array convention.
|
87
|
+
|
88
|
+
[since:]
|
89
|
+
|
90
|
+
- 2.0.0
|
@@ -0,0 +1,11 @@
|
|
1
|
+
Encode string for safe transport by URI or form encoding. This uses a CGI
|
2
|
+
style escape, which transforms ` ` into `+` and various special
|
3
|
+
characters into percent encoded forms.
|
4
|
+
|
5
|
+
This calls URI.encode_www_form_component for the implementation. The only
|
6
|
+
difference between this and CGI.escape is that it does not escape `*`.
|
7
|
+
http://stackoverflow.com/questions/25085992/
|
8
|
+
|
9
|
+
[See Also:]
|
10
|
+
|
11
|
+
- URI.encode_www_form_component
|
@@ -0,0 +1,16 @@
|
|
1
|
+
Transform deeply nested param containers into a flat array of [key,
|
2
|
+
value] pairs.
|
3
|
+
|
4
|
+
*Examples:*
|
5
|
+
|
6
|
+
>> flatten_params({key1: {key2: 123}})
|
7
|
+
=> [["key1[key2]", 123]]
|
8
|
+
|
9
|
+
>> flatten_params({key1: {key2: 123, arr: [1,2,3]}})
|
10
|
+
=> [["key1[key2]", 123], ["key1[arr][]", 1], ["key1[arr][]", 2], ["key1[arr][]", 3]]
|
11
|
+
|
12
|
+
[Parameters:]
|
13
|
+
|
14
|
+
- object (Hash, ParamsArray) -- The container to flatten
|
15
|
+
- uri_escape (Boolean) -- Whether to URI escape keys and values
|
16
|
+
- parent_key (String) -- Should not be passed (used for recursion)
|
@@ -0,0 +1,24 @@
|
|
1
|
+
:call-seq:
|
2
|
+
get_encoding_from_headers(headers) -> String or nil
|
3
|
+
|
4
|
+
Return encoding from an HTTP header hash.
|
5
|
+
|
6
|
+
We use the RFC 7231 specification and do not impose a default encoding on
|
7
|
+
text. This differs from the older RFC 2616 behavior, which specifies
|
8
|
+
using ISO-8859-1 for text/* content types without a charset.
|
9
|
+
|
10
|
+
Strings will use the default encoding when this method returns nil. This
|
11
|
+
default is likely to be UTF-8 for Ruby >= 2.0
|
12
|
+
|
13
|
+
[Parameters:]
|
14
|
+
|
15
|
+
- headers (Hash<Symbol, String>)
|
16
|
+
|
17
|
+
[Returns:]
|
18
|
+
|
19
|
+
- (String, nil) -- Return the string encoding or nil if no header is found.
|
20
|
+
|
21
|
+
Examples:
|
22
|
+
|
23
|
+
get_encoding_from_headers({:content_type => 'text/plain; charset=UTF-8'})
|
24
|
+
=> "UTF-8"
|
@@ -0,0 +1,43 @@
|
|
1
|
+
This module's static methods are the entry point for using the REST client.
|
2
|
+
|
3
|
+
# GET
|
4
|
+
xml = RestMan.get 'http://example.com/resource'
|
5
|
+
jpg = RestMan.get 'http://example.com/resource', :accept => 'image/jpg'
|
6
|
+
|
7
|
+
# authentication and SSL
|
8
|
+
RestMan.get 'https://user:password@example.com/private/resource'
|
9
|
+
|
10
|
+
# POST or PUT with a hash sends parameters as a urlencoded form body
|
11
|
+
RestMan.post 'http://example.com/resource', :param1 => 'one'
|
12
|
+
|
13
|
+
# nest hash parameters
|
14
|
+
RestMan.post 'http://example.com/resource', :nested => { :param1 => 'one' }
|
15
|
+
|
16
|
+
# POST and PUT with raw payloads
|
17
|
+
RestMan.post 'http://example.com/resource', 'the post body', :content_type => 'text/plain'
|
18
|
+
RestMan.post 'http://example.com/resource.xml', xml_doc
|
19
|
+
RestMan.put 'http://example.com/resource.pdf', File.read('my.pdf'), :content_type => 'application/pdf'
|
20
|
+
|
21
|
+
# DELETE
|
22
|
+
RestMan.delete 'http://example.com/resource'
|
23
|
+
|
24
|
+
# retrieve the response http code and headers
|
25
|
+
res = RestMan.get 'http://example.com/some.jpg'
|
26
|
+
res.code # => 200
|
27
|
+
res.headers[:content_type] # => 'image/jpg'
|
28
|
+
|
29
|
+
# HEAD
|
30
|
+
RestMan.head('http://example.com').headers
|
31
|
+
|
32
|
+
To use with a proxy, just set RestMan.proxy to the proper http proxy:
|
33
|
+
|
34
|
+
RestMan.proxy = "http://proxy.example.com/"
|
35
|
+
|
36
|
+
Or inherit the proxy from the environment:
|
37
|
+
|
38
|
+
RestMan.proxy = ENV['http_proxy']
|
39
|
+
|
40
|
+
For live tests of RestMan, try using http://rest-test.heroku.com, which echoes back information about the rest call:
|
41
|
+
|
42
|
+
>> RestMan.put 'http://rest-test.heroku.com/resource', :foo => 'baz'
|
43
|
+
=> "PUT http://rest-test.heroku.com/resource with a 7 byte payload, content type application/x-www-form-urlencoded {\"foo\"=>\"baz\"}"
|
data/bin/console
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require "bundler/setup"
|
5
|
+
require "restman"
|
6
|
+
|
7
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
8
|
+
# with your gem easier. You can also use a different console, if you like.
|
9
|
+
|
10
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
11
|
+
# require "pry"
|
12
|
+
# Pry.start
|
13
|
+
|
14
|
+
require "irb"
|
15
|
+
IRB.start(__FILE__)
|
@@ -31,12 +31,15 @@ module RestMan
|
|
31
31
|
@code ||= @net_http_res.code.to_i
|
32
32
|
end
|
33
33
|
|
34
|
+
def success?
|
35
|
+
(200..299).include?(code)
|
36
|
+
end
|
37
|
+
|
34
38
|
def history
|
35
39
|
@history ||= request.redirection_history || []
|
36
40
|
end
|
37
41
|
|
38
|
-
#
|
39
|
-
# e.g. "Content-type" will become :content_type.
|
42
|
+
# :include: _doc/lib/restman/abstract_response/headers.rdoc
|
40
43
|
def headers
|
41
44
|
@headers ||= AbstractResponse.beautify_headers(@net_http_res.to_hash)
|
42
45
|
end
|
@@ -46,9 +49,7 @@ module RestMan
|
|
46
49
|
@raw_headers ||= @net_http_res.to_hash
|
47
50
|
end
|
48
51
|
|
49
|
-
#
|
50
|
-
# @param [RestMan::Request] request
|
51
|
-
# @param [Time] start_time
|
52
|
+
# :include: _doc/lib/restman/abstract_response/response_set_vars.rdoc
|
52
53
|
def response_set_vars(net_http_res, request, start_time)
|
53
54
|
@net_http_res = net_http_res
|
54
55
|
@request = request
|
@@ -65,16 +66,7 @@ module RestMan
|
|
65
66
|
history
|
66
67
|
end
|
67
68
|
|
68
|
-
#
|
69
|
-
#
|
70
|
-
# NB: This will return only cookies whose domain matches this request, and
|
71
|
-
# may not even return all of those cookies if there are duplicate names.
|
72
|
-
# Use the full cookie_jar for more nuanced access.
|
73
|
-
#
|
74
|
-
# @see #cookie_jar
|
75
|
-
#
|
76
|
-
# @return [Hash]
|
77
|
-
#
|
69
|
+
# :include: _doc/lib/restman/abstract_response/cookies.rdoc
|
78
70
|
def cookies
|
79
71
|
hash = {}
|
80
72
|
|
@@ -85,10 +77,7 @@ module RestMan
|
|
85
77
|
hash
|
86
78
|
end
|
87
79
|
|
88
|
-
#
|
89
|
-
#
|
90
|
-
# @return [HTTP::CookieJar]
|
91
|
-
#
|
80
|
+
# :include: _doc/lib/restman/abstract_response/cookie_jar.rdoc
|
92
81
|
def cookie_jar
|
93
82
|
return @cookie_jar if defined?(@cookie_jar) && @cookie_jar
|
94
83
|
|
@@ -100,16 +89,7 @@ module RestMan
|
|
100
89
|
@cookie_jar = jar
|
101
90
|
end
|
102
91
|
|
103
|
-
#
|
104
|
-
#
|
105
|
-
# For 20x status codes: return the response itself
|
106
|
-
#
|
107
|
-
# For 30x status codes:
|
108
|
-
# 301, 302, 307: redirect GET / HEAD if there is a Location header
|
109
|
-
# 303: redirect, changing method to GET, if there is a Location header
|
110
|
-
#
|
111
|
-
# For all other responses, raise a response exception
|
112
|
-
#
|
92
|
+
# :include: _doc/lib/restman/abstract_response/return.rdoc
|
113
93
|
def return!(&block)
|
114
94
|
case code
|
115
95
|
when 200..207
|
@@ -139,14 +119,12 @@ module RestMan
|
|
139
119
|
"#{code} #{STATUSES[code]} | #{(headers[:content_type] || '').gsub(/;.*$/, '')} #{size} bytes\n"
|
140
120
|
end
|
141
121
|
|
142
|
-
#
|
143
|
-
# redirection target.
|
122
|
+
# :include: _doc/lib/restman/abstract_response/follow_redirection.rdoc
|
144
123
|
def follow_redirection(&block)
|
145
124
|
_follow_redirection(request.args.dup, &block)
|
146
125
|
end
|
147
126
|
|
148
|
-
#
|
149
|
-
# the payload from the original request.
|
127
|
+
# :include: _doc/lib/restman/abstract_response/follow_get_redirection.rdoc
|
150
128
|
def follow_get_redirection(&block)
|
151
129
|
new_args = request.args.dup
|
152
130
|
new_args[:method] = :get
|
@@ -155,27 +133,7 @@ module RestMan
|
|
155
133
|
_follow_redirection(new_args, &block)
|
156
134
|
end
|
157
135
|
|
158
|
-
#
|
159
|
-
#
|
160
|
-
# Header names will be converted to lowercase symbols with underscores
|
161
|
-
# instead of hyphens.
|
162
|
-
#
|
163
|
-
# Headers specified multiple times will be joined by comma and space,
|
164
|
-
# except for Set-Cookie, which will always be an array.
|
165
|
-
#
|
166
|
-
# Per RFC 2616, if a server sends multiple headers with the same key, they
|
167
|
-
# MUST be able to be joined into a single header by a comma. However,
|
168
|
-
# Set-Cookie (RFC 6265) cannot because commas are valid within cookie
|
169
|
-
# definitions. The newer RFC 7230 notes (3.2.2) that Set-Cookie should be
|
170
|
-
# handled as a special case.
|
171
|
-
#
|
172
|
-
# http://tools.ietf.org/html/rfc2616#section-4.2
|
173
|
-
# http://tools.ietf.org/html/rfc7230#section-3.2.2
|
174
|
-
# http://tools.ietf.org/html/rfc6265
|
175
|
-
#
|
176
|
-
# @param headers [Hash]
|
177
|
-
# @return [Hash]
|
178
|
-
#
|
136
|
+
# :include: _doc/lib/restman/abstract_response/beautify_headers.rdoc
|
179
137
|
def self.beautify_headers(headers)
|
180
138
|
headers.inject({}) do |out, (key, value)|
|
181
139
|
key_sym = key.tr('-', '_').downcase.to_sym
|
@@ -193,12 +151,7 @@ module RestMan
|
|
193
151
|
|
194
152
|
private
|
195
153
|
|
196
|
-
#
|
197
|
-
#
|
198
|
-
# @param new_args [Hash] Start with this hash of arguments for the
|
199
|
-
# redirection request. The hash will be mutated, so be sure to dup any
|
200
|
-
# existing hash that should not be modified.
|
201
|
-
#
|
154
|
+
# :include: _doc/lib/restman/abstract_response/_follow_redirection.rdoc
|
202
155
|
def _follow_redirection(new_args, &block)
|
203
156
|
|
204
157
|
# parse location header and merge into existing URL
|