wrest 2.1.9 → 4.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (76) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG +6 -0
  3. data/LICENCE +1 -1
  4. data/README.md +47 -40
  5. data/bin/wrest +2 -1
  6. data/bin/wrest_shell.rb +10 -8
  7. data/lib/wrest/async_request/event_machine_backend.rb +3 -1
  8. data/lib/wrest/async_request/thread_backend.rb +5 -2
  9. data/lib/wrest/async_request/thread_pool.rb +4 -2
  10. data/lib/wrest/async_request.rb +7 -6
  11. data/lib/wrest/cache_proxy.rb +39 -28
  12. data/lib/wrest/caching/memcached.rb +21 -18
  13. data/lib/wrest/caching/redis.rb +22 -22
  14. data/lib/wrest/caching.rb +16 -14
  15. data/lib/wrest/callback.rb +19 -16
  16. data/lib/wrest/components/container/alias_accessors.rb +51 -47
  17. data/lib/wrest/components/container/typecaster.rb +146 -95
  18. data/lib/wrest/components/container.rb +171 -152
  19. data/lib/wrest/components/mutators/base.rb +43 -34
  20. data/lib/wrest/components/mutators/camel_to_snake_case.rb +7 -3
  21. data/lib/wrest/components/mutators/{xml_mini_type_caster.rb → xml_type_caster.rb} +29 -16
  22. data/lib/wrest/components/mutators.rb +21 -19
  23. data/lib/wrest/components/translators/content_types.rb +20 -16
  24. data/lib/wrest/components/translators/json.rb +19 -16
  25. data/lib/wrest/components/translators/txt.rb +19 -15
  26. data/lib/wrest/components/translators/xml/conversions.rb +56 -0
  27. data/lib/wrest/components/translators/xml.rb +60 -18
  28. data/lib/wrest/components/translators.rb +7 -6
  29. data/lib/wrest/components.rb +11 -8
  30. data/lib/wrest/core_ext/hash/conversions.rb +10 -10
  31. data/lib/wrest/core_ext/hash.rb +4 -2
  32. data/lib/wrest/core_ext/string/conversions.rb +14 -13
  33. data/lib/wrest/core_ext/string.rb +5 -3
  34. data/lib/wrest/exceptions.rb +4 -2
  35. data/lib/wrest/hash_with_case_insensitive_access.rb +8 -8
  36. data/lib/wrest/hash_with_indifferent_access.rb +442 -0
  37. data/lib/wrest/http_codes.rb +20 -19
  38. data/lib/wrest/http_shared/headers.rb +2 -0
  39. data/lib/wrest/http_shared/standard_headers.rb +2 -2
  40. data/lib/wrest/http_shared/standard_tokens.rb +8 -6
  41. data/lib/wrest/http_shared.rb +5 -3
  42. data/lib/wrest/multipart.rb +20 -11
  43. data/lib/wrest/native/connection_factory.rb +15 -11
  44. data/lib/wrest/native/delete.rb +15 -11
  45. data/lib/wrest/native/get.rb +60 -55
  46. data/lib/wrest/native/options.rb +15 -11
  47. data/lib/wrest/native/patch.rb +27 -0
  48. data/lib/wrest/native/post.rb +15 -11
  49. data/lib/wrest/native/post_multipart.rb +22 -18
  50. data/lib/wrest/native/put.rb +16 -12
  51. data/lib/wrest/native/put_multipart.rb +22 -18
  52. data/lib/wrest/native/redirection.rb +13 -12
  53. data/lib/wrest/native/request.rb +144 -106
  54. data/lib/wrest/native/response.rb +87 -78
  55. data/lib/wrest/native/session.rb +49 -40
  56. data/lib/wrest/native.rb +14 -11
  57. data/lib/wrest/test/request_patches.rb +10 -3
  58. data/lib/wrest/test.rb +3 -1
  59. data/lib/wrest/uri/builders.rb +14 -12
  60. data/lib/wrest/uri.rb +92 -50
  61. data/lib/wrest/uri_template.rb +11 -7
  62. data/lib/wrest/utils.rb +129 -0
  63. data/lib/wrest/version.rb +3 -1
  64. data/lib/wrest.rb +31 -33
  65. data/lib/wrest_no_ext.rb +2 -0
  66. metadata +91 -56
  67. data/lib/wrest/components/mutators/xml_simple_type_caster.rb +0 -37
  68. data/lib/wrest/xml_mini/jdom/xpath_filter.rb +0 -17
  69. data/lib/wrest/xml_mini/jdom.rb +0 -6
  70. data/lib/wrest/xml_mini/libxml/xpath_filter.rb +0 -12
  71. data/lib/wrest/xml_mini/libxml.rb +0 -8
  72. data/lib/wrest/xml_mini/nokogiri/xpath_filter.rb +0 -15
  73. data/lib/wrest/xml_mini/nokogiri.rb +0 -7
  74. data/lib/wrest/xml_mini/rexml/xpath_filter.rb +0 -15
  75. data/lib/wrest/xml_mini/rexml.rb +0 -8
  76. data/lib/wrest/xml_mini.rb +0 -8
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # Copyright 2009 Sidu Ponnappa
2
4
 
3
5
  # Licensed under the Apache License, Version 2.0 (the "License");
@@ -7,51 +9,58 @@
7
9
  # is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
8
10
  # See the License for the specific language governing permissions and limitations under the License.
9
11
 
10
- module Wrest::Native
11
- # This class is a wrapper for a keep-alive HTTP connection. It simply passes the
12
- # same connection instance as an option to all Wrest::Native::Request instances created using it.
13
- #
14
- # If at any point the server closes an existing connection during a Session by returning a
15
- # Connection: Close header the current connection is destroyed and a fresh one created for the next
16
- # request.
17
- #
18
- # The Session constructor can accept either a String URI or a Wrest::Uri as a parameter. If you
19
- # need HTTP authentication, you should use a Wrest::Uri.
20
- class Session
21
- attr_reader :uri
22
- def initialize(uri)
23
- @uri = Wrest::Uri.new(uri)
24
- @default_headers = { Wrest::Native::StandardHeaders::Connection => Wrest::Native::StandardTokens::KeepAlive }
25
-
26
- yield(self) if block_given?
27
- end
12
+ module Wrest
13
+ module Native
14
+ # This class is a wrapper for a keep-alive HTTP connection. It simply passes the
15
+ # same connection instance as an option to all Wrest::Native::Request instances created using it.
16
+ #
17
+ # If at any point the server closes an existing connection during a Session by returning a
18
+ # Connection: Close header the current connection is destroyed and a fresh one created for the next
19
+ # request.
20
+ #
21
+ # The Session constructor can accept either a String URI or a Wrest::Uri as a parameter. If you
22
+ # need HTTP authentication, you should use a Wrest::Uri.
23
+ class Session
24
+ attr_reader :uri
28
25
 
29
- def connection
30
- @connection ||= @uri.create_connection
31
- end
26
+ def initialize(uri)
27
+ @uri = Wrest::Uri.new(uri)
28
+ @default_headers = { Wrest::Native::StandardHeaders::Connection => Wrest::Native::StandardTokens::KeepAlive }
32
29
 
33
- def get(path = '', parameters = {}, headers = {})
34
- maybe_destroy_connection @uri[path, {:connection => self.connection}].get(parameters, headers.merge(@default_headers))
35
- end
30
+ yield(self) if block_given?
31
+ end
36
32
 
37
- def post(path = '', body = '', headers = {}, params = {})
38
- maybe_destroy_connection @uri[path, {:connection => self.connection}].post(body, headers.merge(@default_headers), params)
39
- end
40
-
41
- def put(path = '', body = '', headers = {}, params = {})
42
- maybe_destroy_connection @uri[path, {:connection => self.connection}].put(body, headers.merge(@default_headers), params)
43
- end
33
+ def connection
34
+ @connection ||= @uri.create_connection
35
+ end
44
36
 
45
- def delete(path = '', parameters = {}, headers = {})
46
- maybe_destroy_connection @uri[path, {:connection => self.connection}].delete(parameters, headers.merge(@default_headers))
47
- end
48
-
49
- def maybe_destroy_connection(response)
50
- if response.connection_closed?
51
- Wrest.logger.warn "Connection #{@connection.hash} has been closed by the server"
52
- @connection = nil
37
+ def get(path = '', parameters = {}, headers = {})
38
+ maybe_destroy_connection @uri[path, { connection: connection }].get(parameters,
39
+ headers.merge(@default_headers))
40
+ end
41
+
42
+ def post(path = '', body = '', headers = {}, params = {})
43
+ maybe_destroy_connection @uri[path, { connection: connection }].post(body, headers.merge(@default_headers),
44
+ params)
45
+ end
46
+
47
+ def put(path = '', body = '', headers = {}, params = {})
48
+ maybe_destroy_connection @uri[path, { connection: connection }].put(body, headers.merge(@default_headers),
49
+ params)
50
+ end
51
+
52
+ def delete(path = '', parameters = {}, headers = {})
53
+ maybe_destroy_connection @uri[path, { connection: connection }].delete(parameters,
54
+ headers.merge(@default_headers))
55
+ end
56
+
57
+ def maybe_destroy_connection(response)
58
+ if response.connection_closed?
59
+ Wrest.logger.warn "Connection #{@connection.hash} has been closed by the server"
60
+ @connection = nil
61
+ end
62
+ response
53
63
  end
54
- response
55
64
  end
56
65
  end
57
66
  end
data/lib/wrest/native.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # Copyright 2009 Sidu Ponnappa
2
4
 
3
5
  # Licensed under the Apache License, Version 2.0 (the "License");
@@ -18,16 +20,17 @@ module Wrest
18
20
  end
19
21
  end
20
22
 
21
- require "wrest/native/connection_factory"
22
- require "wrest/native/response"
23
- require "wrest/native/redirection"
24
- require "wrest/native/request"
25
- require "wrest/native/get"
26
- require "wrest/native/put"
27
- require "wrest/native/post"
28
- require "wrest/native/delete"
29
- require "wrest/native/options"
30
- require "wrest/native/session"
23
+ require 'wrest/native/connection_factory'
24
+ require 'wrest/native/response'
25
+ require 'wrest/native/redirection'
26
+ require 'wrest/native/request'
27
+ require 'wrest/native/get'
28
+ require 'wrest/native/put'
29
+ require 'wrest/native/patch'
30
+ require 'wrest/native/post'
31
+ require 'wrest/native/delete'
32
+ require 'wrest/native/options'
33
+ require 'wrest/native/session'
31
34
 
32
35
  # default to using Native libs
33
- Wrest::Http = Wrest::Native
36
+ Wrest::Http = Wrest::Native
@@ -1,5 +1,12 @@
1
- class Wrest::Native::Request
2
- def invoke
3
- raise Wrest::Exceptions::RealRequestMadeInTestEnvironmet, 'A real HTTP request was made while running tests. Please avoid using live HTTP connections while testing and replace them with mocks.'
1
+ # frozen_string_literal: true
2
+
3
+ module Wrest
4
+ module Native
5
+ class Request
6
+ def invoke
7
+ raise Wrest::Exceptions::RealRequestMadeInTestEnvironmet,
8
+ 'A real HTTP request was made while running tests. Please avoid using live HTTP connections while testing and replace them with mocks.'
9
+ end
10
+ end
4
11
  end
5
12
  end
data/lib/wrest/test.rb CHANGED
@@ -1 +1,3 @@
1
- require "wrest/test/request_patches"
1
+ # frozen_string_literal: true
2
+
3
+ require 'wrest/test/request_patches'
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Wrest
2
4
  class Uri
3
5
  # Contains methods that depend on Uri#clone to build
@@ -5,42 +7,42 @@ module Wrest
5
7
  module Builders
6
8
  # Returns a Uri object that uses threads to perform asynchronous requests.
7
9
  def using_threads
8
- clone(:asynchronous_backend => Wrest::AsyncRequest::ThreadBackend.new)
10
+ clone(asynchronous_backend: Wrest::AsyncRequest::ThreadBackend.new)
9
11
  end
10
12
 
11
13
  # Returns a Uri object that uses eventmachine to perform asynchronous requests.
12
- # Remember to do Wrest::AsyncRequest.enable_em first so that
14
+ # Remember to do Wrest::AsyncRequest.enable_em first so that
13
15
  # EventMachine is available for use.
14
16
  def using_em
15
- clone(:asynchronous_backend => Wrest::AsyncRequest::EventMachineBackend.new)
17
+ clone(asynchronous_backend: Wrest::AsyncRequest::EventMachineBackend.new)
16
18
  end
17
19
 
18
20
  # Returns a Uri object that uses hash for caching responses.
19
21
  def using_hash
20
- clone(:cache_store => {})
22
+ clone(cache_store: {})
21
23
  end
22
24
 
23
25
  # Returns a Uri object that uses memcached for caching responses.
24
- # Remember to do Wrest::AsyncRequest.enable_memcached first so that
26
+ # Remember to do Wrest::AsyncRequest.enable_memcached first so that
25
27
  # memcached is available for use.
26
28
  def using_memcached
27
- clone(:cache_store => Wrest::Caching::Memcached.new)
29
+ clone(cache_store: Wrest::Caching::Memcached.new)
28
30
  end
29
31
 
30
32
  def using_redis
31
- clone(:cache_store => Wrest::Caching::Redis.new)
33
+ clone(cache_store: Wrest::Caching::Redis.new)
32
34
  end
33
35
 
34
- # Disables using the globally configured cache for GET requests
36
+ # Disables using the globally configured cache for GET requests
35
37
  # made using the Uri returned by this method.
36
38
  def disable_cache
37
- clone(:disable_cache => true)
39
+ clone(disable_cache: true)
38
40
  end
39
-
41
+
40
42
  # Sets the specified string as the cookie for the Uri
41
43
  def using_cookie(cookie_string)
42
- clone(:default_headers => {Wrest::H::Cookie => cookie_string})
44
+ clone(default_headers: { Wrest::H::Cookie => cookie_string })
43
45
  end
44
46
  end
45
47
  end
46
- end
48
+ end
data/lib/wrest/uri.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # Copyright 2009 Sidu Ponnappa
2
4
 
3
5
  # Licensed under the Apache License, Version 2.0 (the "License");
@@ -7,7 +9,7 @@
7
9
  # is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
8
10
  # See the License for the specific language governing permissions and limitations under the License.
9
11
 
10
- module Wrest #:nodoc:
12
+ module Wrest # :nodoc:
11
13
  # Wrest::Uri provides a simple api for
12
14
  # REST calls. String#to_uri is a convenience
13
15
  # method to build a Wrest::Uri from a string url.
@@ -17,13 +19,13 @@ module Wrest #:nodoc:
17
19
  # Example:
18
20
  # "http://kaiwren:fupuppies@coathangers.com/portal/1".to_uri
19
21
  # "http://coathangers.com/portal/1".to_uri(:username => 'kaiwren', :password => 'fupuppies')
20
- #
22
+ #
21
23
  # The second form is preferred as it can handle passwords with special characters like ^ and @
22
24
  #
23
25
  # You can find examples that use real APIs (like delicious) under the wrest/examples directory.
24
26
  class Uri
25
27
  attr_reader :uri, :username, :password, :uri_string, :uri_path, :query, :default_headers
26
-
28
+
27
29
  # Valid tuples for the options are:
28
30
  # :asynchronous_backend => Can currently be set to either Wrest::AsyncRequest::EventMachineBackend.new
29
31
  # or Wrest::AsyncRequest::ThreadBackend.new. Easier to do using Uri#using_em and
@@ -36,29 +38,21 @@ module Wrest #:nodoc:
36
38
  # defaults if there are any clashes. Use this to set cookies or use OAuth2 Authorize
37
39
  # headers. When extending or cloning a Uri, passing in a new set of default_headers
38
40
  # will result in the old set being overridden.
41
+ # :username, :password => HTTP authentication. Passing nil for either username or password will skip it.
39
42
  # See Wrest::Native::Request for other available options and their default values.
40
43
  def initialize(uri_string, options = {})
41
44
  @options = options.clone
42
- @uri_string = uri_string.to_s
43
- @uri = URI.parse(@uri_string)
44
- uri_scheme = URI.split(@uri_string)
45
- @uri_path = uri_scheme[-4].split('?').first || ''
46
- @uri_path = (@uri_path.empty? ? '/' : @uri_path)
47
- @query = uri_scheme[-2] || ''
48
- @username = (@options[:username] ||= @uri.user)
49
- @password = (@options[:password] ||= @uri.password)
50
- @asynchronous_backend = @options[:asynchronous_backend] || Wrest::AsyncRequest.default_backend
51
- @options[:callback] = Callback.new(@options[:callback]) if @options[:callback]
52
- @default_headers = @options[:default_headers] || {}
53
- end
54
-
55
- # Builds a Wrest::UriTemplate by extending the current URI
45
+ setup_uri_state!(uri_string)
46
+ setup_request_config!
47
+ end
48
+
49
+ # Builds a Wrest::UriTemplate by extending the current URI
56
50
  # with the pattern passed to it.
57
51
  def to_template(pattern)
58
- template_pattern = URI.join(uri_string,pattern).to_s
52
+ template_pattern = URI.join(uri_string, pattern).to_s
59
53
  UriTemplate.new(template_pattern, @options)
60
54
  end
61
-
55
+
62
56
  # Build a new Wrest::Uri by appending _path_ to
63
57
  # the current uri. If the original Wrest::Uri
64
58
  # has a username and password, that will be
@@ -77,11 +71,11 @@ module Wrest #:nodoc:
77
71
  def [](path, options = nil)
78
72
  Uri.new(uri + File.join(uri_path, path), options || @options)
79
73
  end
80
-
74
+
81
75
  # Clones a Uri, building a new instance with exactly the same uri string.
82
76
  # You can however change the Uri options or add new ones.
83
77
  def clone(opts = {})
84
- merged_options = @options.merge(opts)
78
+ merged_options = @options.merge(opts)
85
79
  merged_options[:default_headers] = opts[:default_headers] ? @default_headers.merge(opts[:default_headers]) : {}
86
80
  Uri.new(@uri_string, merged_options)
87
81
  end
@@ -89,50 +83,61 @@ module Wrest #:nodoc:
89
83
  def eql?(other)
90
84
  self == other
91
85
  end
92
-
86
+
93
87
  def ==(other)
94
88
  return false if other.class != self.class
95
- return other.uri == self.uri && self.username == other.username && self.password == other.password
89
+
90
+ other.uri == uri && username == other.username && password == other.password
96
91
  end
97
-
92
+
98
93
  def hash
99
- @uri.hash + @username.hash + @password.hash + 20090423
94
+ [@uri, @username, @password].hash
100
95
  end
101
-
96
+
102
97
  # This produces exactly the same string as the Wrest::Uri was constructed with.
103
98
  # If the orignial URI contained a HTTP username and password, that too will
104
99
  # show up, so be careful if using this for logging.
105
100
  def to_s
106
101
  uri_string
107
102
  end
108
-
109
- #:nodoc:
103
+
104
+ # :nodoc:
110
105
  def build_get(parameters = {}, headers = {}, &block)
111
- Http::Get.new(self, parameters, default_headers.merge(headers), block ? @options.merge(:callback_block => block) : @options)
106
+ Http::Get.new(self, parameters, default_headers.merge(headers),
107
+ block ? @options.merge(callback_block: block) : @options)
112
108
  end
113
-
114
- #:nodoc:
109
+
110
+ # :nodoc:
115
111
  def build_put(body = '', headers = {}, parameters = {}, &block)
116
- Http::Put.new(self, body.to_s, default_headers.merge(headers), parameters, block ? @options.merge(:callback_block => block) : @options)
112
+ Http::Put.new(self, body.to_s, default_headers.merge(headers), parameters,
113
+ block ? @options.merge(callback_block: block) : @options)
114
+ end
115
+
116
+ # :nodoc:
117
+ def build_patch(body = '', headers = {}, parameters = {}, &block)
118
+ Http::Patch.new(self, body.to_s, default_headers.merge(headers), parameters,
119
+ block ? @options.merge(callback_block: block) : @options)
117
120
  end
118
-
119
- #:nodoc:
121
+
122
+ # :nodoc:
120
123
  def build_post(body = '', headers = {}, parameters = {}, &block)
121
- Http::Post.new(self, body.to_s, default_headers.merge(headers), parameters, block ? @options.merge(:callback_block => block) : @options)
124
+ Http::Post.new(self, body.to_s, default_headers.merge(headers), parameters,
125
+ block ? @options.merge(callback_block: block) : @options)
122
126
  end
123
127
 
124
- #:nodoc:
125
- def build_post_form(parameters ={}, headers = {}, &block)
128
+ # :nodoc:
129
+ def build_post_form(parameters = {}, headers = {}, &block)
126
130
  headers = default_headers.merge(headers).merge(Wrest::H::ContentType => Wrest::T::FormEncoded)
127
- body = parameters.to_query
128
- Http::Post.new(self, body, headers, {}, block ? @options.merge(:callback_block => block) : @options)
131
+ body = Utils.hash_to_param(parameters)
132
+ Http::Post.new(self, body, headers, {}, block ? @options.merge(callback_block: block) : @options)
129
133
  end
130
134
 
131
- #:nodoc:
135
+ # :nodoc:
132
136
  def build_delete(parameters = {}, headers = {}, &block)
133
- Http::Delete.new(self, parameters, default_headers.merge(headers), block ? @options.merge(:callback_block => block) : @options)
137
+ Http::Delete.new(self, parameters, default_headers.merge(headers),
138
+ block ? @options.merge(callback_block: block) : @options)
134
139
  end
135
-
140
+
136
141
  # Make a GET request to this URI. This is a convenience API
137
142
  # that creates a Wrest::Native::Get, executes it and returns a Wrest::Native::Response.
138
143
  #
@@ -143,7 +148,7 @@ module Wrest #:nodoc:
143
148
 
144
149
  # Make a GET request to this URI. This is a convenience API
145
150
  # that creates a Wrest::Native::Get.
146
- #
151
+ #
147
152
  # Remember to escape all parameter strings if necessary, using URI.escape
148
153
  #
149
154
  # Note: get_async does not return a response and the response should be accessed through callbacks.
@@ -171,6 +176,24 @@ module Wrest #:nodoc:
171
176
  @asynchronous_backend.execute(build_put(body, headers, parameters, &block))
172
177
  end
173
178
 
179
+ # Make a PATCH request to this URI. This is a convenience API
180
+ # that creates a Wrest::Native::Patch, executes it and returns a Wrest::Native::Response.
181
+ #
182
+ # Remember to escape all parameter strings if necessary, using URI.escape
183
+ def patch(body = '', headers = {}, parameters = {}, &block)
184
+ build_patch(body, headers, parameters, &block).invoke
185
+ end
186
+
187
+ # Make a PATCH request to this URI. This is a convenience API
188
+ # that creates a Wrest::Native::Patch.
189
+ #
190
+ # Remember to escape all parameter strings if necessary, using URI.escape
191
+ #
192
+ # Note: patch_async does not return a response and the response should be accessed through callbacks.
193
+ def patch_async(body = '', headers = {}, parameters = {}, &block)
194
+ @asynchronous_backend.execute(build_patch(body, headers, parameters, &block))
195
+ end
196
+
174
197
  # Makes a POST request to this URI. This is a convenience API
175
198
  # that creates a Wrest::Native::Post, executes it and returns a Wrest::Native::Response.
176
199
  #
@@ -188,9 +211,9 @@ module Wrest #:nodoc:
188
211
  def post_async(body = '', headers = {}, parameters = {}, &block)
189
212
  @asynchronous_backend.execute(build_post(body, headers, parameters, &block))
190
213
  end
191
-
214
+
192
215
  # Makes a POST request to this URI. This is a convenience API
193
- # that mimics a form being posted; some allegly RESTful APIs like FCBK require
216
+ # that mimics a form being posted; some allegly RESTful APIs like FCBK require
194
217
  # this.
195
218
  #
196
219
  # Form encoding involves munging the parameters into a string and placing them
@@ -201,7 +224,7 @@ module Wrest #:nodoc:
201
224
  end
202
225
 
203
226
  # Makes a POST request to this URI. This is a convenience API
204
- # that mimics a form being posted; some allegly RESTful APIs like FCBK require
227
+ # that mimics a form being posted; some allegly RESTful APIs like FCBK require
205
228
  # this.
206
229
  #
207
230
  # Form encoding involves munging the parameters into a string and placing them
@@ -239,7 +262,7 @@ module Wrest #:nodoc:
239
262
  Http::Options.new(self, @options).invoke
240
263
  end
241
264
 
242
- def https?
265
+ def https?
243
266
  @uri.is_a?(URI::HTTPS)
244
267
  end
245
268
 
@@ -255,16 +278,35 @@ module Wrest #:nodoc:
255
278
  def protocol
256
279
  uri.scheme
257
280
  end
258
-
281
+
259
282
  def host
260
283
  uri.host
261
284
  end
262
-
285
+
263
286
  def port
264
287
  uri.port
265
288
  end
266
-
289
+
267
290
  include Http::ConnectionFactory
268
291
  include Uri::Builders
292
+
293
+ private
294
+
295
+ def setup_request_config!
296
+ @username = (@options[:username] ||= @uri.user)
297
+ @password = (@options[:password] ||= @uri.password)
298
+ @asynchronous_backend = @options[:asynchronous_backend] || Wrest::AsyncRequest.default_backend
299
+ @options[:callback] = Callback.new(@options[:callback]) if @options[:callback]
300
+ @default_headers = @options[:default_headers] || {}
301
+ end
302
+
303
+ def setup_uri_state!(uri_string)
304
+ @uri_string = uri_string.to_s
305
+ @uri = URI.parse(@uri_string)
306
+ uri_scheme = URI.split(@uri_string)
307
+ @uri_path = uri_scheme[-4].split('?').first || ''
308
+ @uri_path = (@uri_path.empty? ? '/' : @uri_path)
309
+ @query = uri_scheme[-2] || ''
310
+ end
269
311
  end
270
312
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # Copyright 2009 Sidu Ponnappa
2
4
 
3
5
  # Licensed under the Apache License, Version 2.0 (the "License");
@@ -10,12 +12,13 @@
10
12
  module Wrest
11
13
  class UriTemplate
12
14
  attr_reader :uri_pattern
15
+
13
16
  def initialize(uri_pattern, options = {})
14
17
  @uri_pattern = uri_pattern.clone
15
18
  @options = options.clone
16
19
  end
17
-
18
- # Builds a new Wrest::Uri from this uri template
20
+
21
+ # Builds a new Wrest::Uri from this uri template
19
22
  # by replacing the keys in the options that match with
20
23
  # the corressponding values.
21
24
  #
@@ -40,11 +43,11 @@ module Wrest
40
43
  # )
41
44
  # => #<Wrest::Uri:0x18e0bec @uri=#<URI::HTTP:0x18e09a8 URL:http://kaiwren:fupuppies@coathangers.com/portal/1>>
42
45
  def to_uri(options = {})
43
- merged_options = @options.merge(options)
44
- Wrest::Uri.new(merged_options.inject(uri_pattern.clone) do |uri_string, tuple|
46
+ merged_options = @options.merge(options)
47
+ Wrest::Uri.new(merged_options.inject(uri_pattern.clone) do |uri_string, tuple|
45
48
  key, value = tuple
46
- uri_string.gsub(":#{key.to_s}", value.to_s)
47
- end , @options)
49
+ uri_string.gsub(":#{key}", value.to_s)
50
+ end, @options)
48
51
  end
49
52
 
50
53
  def [](path)
@@ -53,7 +56,8 @@ module Wrest
53
56
 
54
57
  def ==(other)
55
58
  return false if other.class != self.class
56
- return other.uri_pattern == self.uri_pattern
59
+
60
+ other.uri_pattern == uri_pattern
57
61
  end
58
62
  end
59
63
  end
@@ -0,0 +1,129 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Wrest
4
+ module Utils
5
+ module_function
6
+
7
+ # https://github.com/rails/rails/commit/2a371368c91789a4d689d6a84eb20b238c37678a
8
+ # A string is blank if it's empty or contains whitespaces only:
9
+ #
10
+ # "".blank? # => true
11
+ # " ".blank? # => true
12
+ # " ".blank? # => true
13
+ # " something here ".blank? # => false
14
+ #
15
+ def string_blank?(string)
16
+ string !~ /[^[:space:]]/
17
+ end
18
+
19
+ # https://github.com/rails/rails/commit/69b550fc88f0e155ab997476e576142a2dbec324
20
+ # Tries to find a constant with the name specified in the argument string.
21
+ #
22
+ # constantize('Module') # => Module
23
+ # constantize('Foo::Bar') # => Foo::Bar
24
+ #
25
+ # The name is assumed to be the one of a top-level constant, no matter
26
+ # whether it starts with "::" or not. No lexical context is taken into
27
+ # account:
28
+ #
29
+ # C = 'outside'
30
+ # module M
31
+ # C = 'inside'
32
+ # C # => 'inside'
33
+ # constantize('C') # => 'outside', same as ::C
34
+ # end
35
+ #
36
+ # NameError is raised when the name is not in CamelCase or the constant is
37
+ # unknown.
38
+ def string_constantize(camel_cased_word)
39
+ Object.const_get(camel_cased_word)
40
+ end
41
+
42
+ # https://github.com/rails/rails/commit/69b550fc88f0e155ab997476e576142a2dbec324
43
+ # Removes the module part from the expression in the string.
44
+ #
45
+ # demodulize('ActiveSupport::Inflector::Inflections') # => "Inflections"
46
+ # demodulize('Inflections') # => "Inflections"
47
+ # demodulize('::Inflections') # => "Inflections"
48
+ # demodulize('') # => ""
49
+ #
50
+ def string_demodulize(path)
51
+ path = path.to_s
52
+ if (i = path.rindex('::'))
53
+ path[(i + 2)..]
54
+ else
55
+ path
56
+ end
57
+ end
58
+
59
+ # https://github.com/rails/rails/commit/69b550fc88f0e155ab997476e576142a2dbec324
60
+ # Makes an underscored, lowercase form from the expression in the string.
61
+ #
62
+ # Changes '::' to '/' to convert namespaces to paths.
63
+ #
64
+ # underscore('ActiveModel') # => "active_model"
65
+ # underscore('ActiveModel::Errors') # => "active_model/errors"
66
+ #
67
+ # As a rule of thumb you can think of +underscore+ as the inverse of
68
+ # #camelize, though there are cases where that does not hold:
69
+ #
70
+ # camelize(underscore('SSLError')) # => "SslError"
71
+ def string_underscore(camel_cased_word)
72
+ return camel_cased_word.to_s unless /[A-Z-]|::/.match?(camel_cased_word)
73
+
74
+ word = camel_cased_word.to_s.gsub('::', '/')
75
+ word.gsub!(/([A-Z]+)(?=[A-Z][a-z])|([a-z\d])(?=[A-Z])/) { (Regexp.last_match(1) || Regexp.last_match(2)) << '_' }
76
+ word.tr!('-', '_')
77
+ word.downcase!
78
+ word
79
+ end
80
+
81
+ # https://github.com/rails/rails/commit/a0d7247d1509762283c61182ad82c2eed8d54757
82
+ # Returns a string representation of the receiver suitable for use as a URL
83
+ # query string:
84
+ #
85
+ # {:name => 'David', :nationality => 'Danish'}.to_param
86
+ # # => "name=David&nationality=Danish"
87
+ #
88
+ # The string pairs "key=value" that conform the query string
89
+ # are sorted lexicographically in ascending order.
90
+ #
91
+ def hash_to_param(hash)
92
+ hash.collect do |key, value|
93
+ object_to_query(key, value)
94
+ end.sort * '&'
95
+ end
96
+
97
+ # https://github.com/rails/rails/commit/52b71c01fd3c8a87152f55129a8cb3234190734a
98
+ #
99
+ # Converts an object into a string suitable for use as a URL query string, using the given <tt>key</tt> as the
100
+ # param name.
101
+ def object_to_query(key, object)
102
+ "#{CGI.escape(key.to_s)}=#{CGI.escape(object.to_s)}"
103
+ end
104
+
105
+ # https://github.com/rails/rails/commit/18707ab17fa492eb25ad2e8f9818a320dc20b823
106
+ # An object is blank if it's false, empty, or a whitespace string.
107
+ # For example, +nil+, '', ' ', [], {}, and +false+ are all blank.
108
+ #
109
+ # This simplifies
110
+ #
111
+ # !address || address.empty?
112
+ #
113
+ # to
114
+ #
115
+ # address.blank?
116
+ #
117
+ # @return [true, false]
118
+ def object_blank?(object)
119
+ object.respond_to?(:empty?) ? !!object.empty? : !object
120
+ end
121
+
122
+ # https://github.com/rails/rails/commit/6372d23616b13c62c7a12efa89f958b334dd66ae
123
+ # Converts self to an integer number of seconds since the Unix epoch.
124
+ def datetime_to_i(datetime)
125
+ seconds_per_day = 86_400
126
+ ((datetime - ::DateTime.civil(1970)) * seconds_per_day).to_i
127
+ end
128
+ end
129
+ end