restfulie 0.9.3 → 1.0.0.beta1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (78) hide show
  1. data/Gemfile +2 -0
  2. data/Gemfile.lock +2 -2
  3. data/README.textile +4 -2
  4. data/Rakefile +12 -13
  5. data/lib/restfulie/client/base.rb +9 -2
  6. data/lib/restfulie/client/cache/basic.rb +6 -5
  7. data/lib/restfulie/client/cache/http_ext.rb +10 -8
  8. data/lib/restfulie/client/cache/restrictions.rb +1 -6
  9. data/lib/restfulie/client/dsl.rb +66 -0
  10. data/lib/restfulie/client/entry_point.rb +34 -9
  11. data/lib/restfulie/client/ext/atom_ext.rb +4 -2
  12. data/lib/restfulie/client/ext/json_ext.rb +5 -1
  13. data/lib/restfulie/client/feature/base.rb +75 -0
  14. data/lib/restfulie/client/feature/base_request.rb +35 -0
  15. data/lib/restfulie/client/feature/cache.rb +16 -0
  16. data/lib/restfulie/client/feature/enhance_response.rb +12 -0
  17. data/lib/restfulie/client/feature/follow_request.rb +41 -0
  18. data/lib/restfulie/client/feature/history.rb +26 -0
  19. data/lib/restfulie/client/feature/history_request.rb +19 -0
  20. data/lib/restfulie/client/feature/open_search/pattern_matcher.rb +25 -0
  21. data/lib/restfulie/client/feature/open_search.rb +21 -0
  22. data/lib/restfulie/client/feature/serialize_body.rb +32 -0
  23. data/lib/restfulie/client/feature/setup_header.rb +22 -0
  24. data/lib/restfulie/client/feature/throw_error.rb +41 -0
  25. data/lib/restfulie/client/feature/verb.rb +119 -0
  26. data/lib/restfulie/client/feature.rb +5 -0
  27. data/lib/restfulie/client/http/response_holder.rb +26 -6
  28. data/lib/restfulie/client/http.rb +1 -21
  29. data/lib/restfulie/client/master_delegator.rb +31 -0
  30. data/lib/restfulie/client/mikyung/core.rb +5 -4
  31. data/lib/restfulie/client/mikyung/steady_state_walker.rb +1 -1
  32. data/lib/restfulie/client/mikyung.rb +1 -8
  33. data/lib/restfulie/client.rb +3 -1
  34. data/lib/restfulie/common/converter/atom/base.rb +2 -0
  35. data/lib/restfulie/common/converter/form_url_encoded.rb +16 -0
  36. data/lib/restfulie/common/converter/json/base.rb +5 -2
  37. data/lib/restfulie/common/converter/open_search/descriptor.rb +32 -0
  38. data/lib/restfulie/common/converter/open_search.rb +16 -0
  39. data/lib/restfulie/common/converter/xml/base.rb +3 -1
  40. data/lib/restfulie/common/converter/xml/builder.rb +3 -2
  41. data/lib/restfulie/common/converter/xml/helpers.rb +4 -4
  42. data/lib/restfulie/common/converter/xml/link.rb +5 -0
  43. data/lib/restfulie/common/converter/xml/links.rb +1 -5
  44. data/lib/restfulie/common/converter.rb +25 -4
  45. data/lib/restfulie/common/core_ext/hash.rb +6 -0
  46. data/lib/restfulie/common/links.rb +9 -0
  47. data/lib/restfulie/common/representation/atom/base.rb +34 -33
  48. data/lib/restfulie/common/representation/atom/xml.rb +5 -10
  49. data/lib/restfulie/common/representation/generic.rb +0 -12
  50. data/lib/restfulie/common/representation/json/keys_as_methods.rb +2 -0
  51. data/lib/restfulie/common/representation.rb +2 -9
  52. data/lib/restfulie/common.rb +2 -1
  53. data/lib/restfulie/server/action_controller/trait/cacheable.rb +81 -0
  54. data/lib/restfulie/server/action_controller/trait/created.rb +17 -0
  55. data/lib/restfulie/server/action_controller/trait/save_prior_to_create.rb +13 -0
  56. data/lib/restfulie/server/action_controller/trait.rb +9 -0
  57. data/lib/restfulie/server/action_controller.rb +1 -5
  58. data/lib/restfulie/server/action_view/template_handlers/tokamak.rb +1 -1
  59. data/lib/restfulie/server.rb +6 -0
  60. data/lib/restfulie/version.rb +4 -4
  61. data/lib/restfulie.rb +21 -3
  62. metadata +37 -26
  63. data/lib/restfulie/client/ext/xml_ext.rb +0 -4
  64. data/lib/restfulie/client/http/link_request_builder.rb +0 -16
  65. data/lib/restfulie/client/http/request_adapter.rb +0 -213
  66. data/lib/restfulie/client/http/request_builder.rb +0 -114
  67. data/lib/restfulie/client/http/request_builder_executor.rb +0 -24
  68. data/lib/restfulie/client/http/request_executor.rb +0 -17
  69. data/lib/restfulie/client/http/request_follow.rb +0 -42
  70. data/lib/restfulie/client/http/request_follow_executor.rb +0 -10
  71. data/lib/restfulie/client/http/request_history.rb +0 -71
  72. data/lib/restfulie/client/http/request_history_executor.rb +0 -10
  73. data/lib/restfulie/client/http/request_marshaller.rb +0 -129
  74. data/lib/restfulie/client/http/request_marshaller_executor.rb +0 -10
  75. data/lib/restfulie/client/http/response.rb +0 -23
  76. data/lib/restfulie/client/http/response_handler.rb +0 -67
  77. data/lib/restfulie/server/action_controller/cacheable_responder.rb +0 -77
  78. data/lib/restfulie/server/action_controller/created_responder.rb +0 -19
@@ -1,213 +0,0 @@
1
- module Restfulie
2
- module Client
3
- module HTTP #:nodoc:
4
- # Request Adapter provides a minimal interface to exchange information between server over HTTP protocol through simple adapters.
5
- #
6
- # All the concrete adapters follow the interface laid down in this module.
7
- # Default connection provider is net/http
8
- #
9
- #==Example
10
- #
11
- # @re = ::Restfulie::Client::HTTP::RequestExecutor.new('http://restfulie.com') #this class includes RequestAdapter module.
12
- # puts @re.as('application/atom+xml').get!('/posts').title #=> 'Hello World!'
13
- #
14
- module RequestAdapter
15
- attr_reader :host
16
- attr_accessor :cookies
17
- attr_writer :default_headers
18
-
19
- def host=(host)
20
- if host.is_a?(::URI)
21
- @host = host
22
- else
23
- @host = ::URI.parse(host)
24
- end
25
- end
26
-
27
- def default_headers
28
- @default_headers ||= {}
29
- end
30
-
31
- # GET HTTP verb without {Error}
32
- # * <tt>path: '/posts'</tt>
33
- # * <tt>headers: {'Accept' => '*/*', 'Content-Type' => 'application/atom+xml'}</tt>
34
- def get(path, *args)
35
- request(:get, path, *args)
36
- end
37
-
38
- # HEAD HTTP verb without {Error}
39
- # * <tt>path: '/posts'</tt>
40
- # * <tt>headers: {'Accept' => '*/*', 'Content-Type' => 'application/atom+xml'}</tt>
41
- def head(path, *args)
42
- request(:head, path, *args)
43
- end
44
-
45
- # POST HTTP verb without {Error}
46
- # * <tt>path: '/posts'</tt>
47
- # * <tt>payload: 'some text'</tt>
48
- # * <tt>headers: {'Accept' => '*/*', 'Content-Type' => 'application/atom+xml'}</tt>
49
- def post(path, payload, *args)
50
- request(:post, path, payload, *args)
51
- end
52
-
53
- # PATCH HTTP verb without {Error}
54
- # * <tt>path: '/posts'</tt>
55
- # * <tt>payload: 'some text'</tt>
56
- # * <tt>headers: {'Accept' => '*/*', 'Content-Type' => 'application/atom+xml'}</tt>
57
- def patch(path, payload, *args)
58
- request(:patch, path, payload, *args)
59
- end
60
-
61
- # PUT HTTP verb without {Error}
62
- # * <tt>path: '/posts'</tt>
63
- # * <tt>payload: 'some text'</tt>
64
- # * <tt>headers: {'Accept' => '*/*', 'Content-Type' => 'application/atom+xml'}</tt>
65
- def put(path, payload, *args)
66
- request(:put, path, payload, *args)
67
- end
68
-
69
- # DELETE HTTP verb without {Error}
70
- # * <tt>path: '/posts'</tt>
71
- # * <tt>headers: {'Accept' => '*/*', 'Content-Type' => 'application/atom+xml'}</tt>
72
- def delete(path, *args)
73
- request(:delete, path, *args)
74
- end
75
-
76
- # GET HTTP verb {Error}
77
- # * <tt>path: '/posts'</tt>
78
- # * <tt>headers: {'Accept' => '*/*', 'Content-Type' => 'application/atom+xml'}</tt>
79
- def get!(path, *args)
80
- request!(:get, path, *args)
81
- end
82
-
83
- # HEAD HTTP verb {Error}
84
- # * <tt>path: '/posts'</tt>
85
- # * <tt>headers: {'Accept' => '*/*', 'Content-Type' => 'application/atom+xml'}</tt>
86
- def head!(path, *args)
87
- request!(:head, path, *args)
88
- end
89
-
90
- # POST HTTP verb {Error}
91
- # * <tt>path: '/posts'</tt>
92
- # * <tt>payload: 'some text'</tt>
93
- # * <tt>headers: {'Accept' => '*/*', 'Content-Type' => 'application/atom+xml'}</tt>
94
- def post!(path, payload, *args)
95
- request!(:post, path, payload, *args)
96
- end
97
-
98
- # PATCH HTTP verb {Error}
99
- # * <tt>path: '/posts'</tt>
100
- # * <tt>payload: 'some text'</tt>
101
- # * <tt>headers: {'Accept' => '*/*', 'Content-Type' => 'application/atom+xml'}</tt>
102
- def patch!(path, payload, *args)
103
- request!(:patch, path, payload, *args)
104
- end
105
-
106
- # PUT HTTP verb {Error}
107
- # * <tt>path: '/posts'</tt>
108
- # * <tt>payload: 'some text'</tt>
109
- # * <tt>headers: {'Accept' => '*/*', 'Content-Type' => 'application/atom+xml'}</tt>
110
- def put!(path, payload, *args)
111
- request!(:put, path, payload, *args)
112
- end
113
-
114
- # DELETE HTTP verb {Error}
115
- # * <tt>path: '/posts'</tt>
116
- # * <tt>headers: {'Accept' => '*/*', 'Content-Type' => 'application/atom+xml'}</tt>
117
- def delete!(path, *args)
118
- request!(:delete, path, *args)
119
- end
120
-
121
- # Executes a request against your server and return a response instance without {Error}
122
- # * <tt>method: :get,:post,:delete,:head,:put</tt>
123
- # * <tt>path: '/posts'</tt>
124
- # * <tt>args: payload: 'some text' and/or headers: {'Accept' => '*/*', 'Content-Type' => 'application/atom+xml'}</tt>
125
- def request(method, path, *args)
126
- request!(method, path, *args)
127
- rescue Error::RESTError => se
128
- [[@host, path], nil, se.response]
129
- end
130
-
131
- # Executes a request against your server and return a response instance.
132
- # * <tt>method: :get,:post,:delete,:head,:put</tt>
133
- # * <tt>path: '/posts'</tt>
134
- # * <tt>args: payload: 'some text' and/or headers: {'Accept' => '*/*', 'Content-Type' => 'application/atom+xml'}</tt>
135
- def request!(method, path, *args)
136
- headers = default_headers.merge(args.extract_options!)
137
- unless @host.user.blank? && @host.password.blank?
138
- headers["Authorization"] = "Basic " + ["#{@host.user}:#{@host.password}"].pack("m").delete("\r\n")
139
- end
140
- headers['cookie'] = @cookies if @cookies
141
- args << headers
142
-
143
- ::Restfulie::Common::Logger.logger.info(request_to_s(method, path, *args)) if ::Restfulie::Common::Logger.logger
144
- begin
145
- http_request = get_connection_provider
146
- response = Restfulie::Client.cache_provider.get([@host, path], http_request, method)
147
- return [[@host, path], http_request, response] if response
148
- response = ResponseHandler.handle(method, path, http_request.send(method, path, *args))
149
- rescue Exception => e
150
- Restfulie::Common::Logger.logger.error(e)
151
- raise Error::ServerNotAvailableError.new(self, Response.new(method, path, 503, nil, {}), e )
152
- end
153
-
154
- case response.code
155
- when 100..299
156
- [[@host, path], http_request, response]
157
- when 300..399
158
- raise Error::Redirection.new(self, response)
159
- when 400
160
- raise Error::BadRequest.new(self, response)
161
- when 401
162
- raise Error::Unauthorized.new(self, response)
163
- when 403
164
- raise Error::Forbidden.new(self, response)
165
- when 404
166
- raise Error::NotFound.new(self, response)
167
- when 405
168
- raise Error::MethodNotAllowed.new(self, response)
169
- when 407
170
- raise Error::ProxyAuthenticationRequired.new(self, response)
171
- when 409
172
- raise Error::Conflict.new(self, response)
173
- when 410
174
- raise Error::Gone.new(self, response)
175
- when 412
176
- raise Error::PreconditionFailed.new(self, response)
177
- when 402, 406, 408, 411, 413..499
178
- raise Error::ClientError.new(self, response)
179
- when 501
180
- raise Error::NotImplemented.new(self, response)
181
- when 500, 502..599
182
- raise Error::ServerError.new(self, response)
183
- else
184
- raise Error::UnknownError.new(self, response)
185
- end
186
- end
187
-
188
- private
189
-
190
- def get_connection_provider
191
- @connection ||= ::Net::HTTP.new(@host.host, @host.port)
192
- end
193
-
194
- protected
195
-
196
- def request_to_s(method, path, *args)
197
- result = ["#{method.to_s.upcase} #{path}"]
198
-
199
- arguments = args.dup
200
- headers = arguments.extract_options!
201
-
202
- if [:post, :put].include?(method)
203
- body = arguments.shift
204
- end
205
-
206
- result << headers.collect { |key, value| "#{key}: #{value}" }.join("\n")
207
-
208
- (result + [body ? (body.inspect + "\n") : nil]).compact.join("\n") << "\n"
209
- end
210
- end
211
- end
212
- end
213
- end
@@ -1,114 +0,0 @@
1
- require 'uri'
2
-
3
- module Restfulie
4
- module Client
5
- module HTTP #:nodoc:
6
- # ==== RequestBuilder
7
- # Uses RequestAdapater to create a HTTP Request DSL
8
- #
9
- # ==== Example:
10
- #
11
- # @builder = ::Restfulie::Client::HTTP::RequestBuilderExecutor.new("http://restfulie.com") #this class includes RequestBuilder module.
12
- # @builder.at('/posts').as('application/xml').accepts('application/atom+xml').with('Accept-Language' => 'en').get.code #=> 200
13
- #
14
- module RequestBuilder
15
- include RequestAdapter
16
-
17
- #Set host
18
- def at(url)
19
- self.host = url
20
- self
21
- end
22
-
23
- #Set Content-Type and Accept headers
24
- def as(content_type)
25
- headers['Content-Type'] = content_type
26
- accepts(content_type)
27
- end
28
-
29
- #Set Accept headers
30
- def accepts(content_type)
31
- headers['Accept'] = content_type
32
- self
33
- end
34
-
35
- # Merge internal header
36
- #
37
- # * <tt>headers (e.g. {'Cache-control' => 'no-cache'})</tt>
38
- #
39
- def with(headers)
40
- self.headers.merge!(headers)
41
- self
42
- end
43
-
44
- def headers
45
- @headers ||= {}
46
- end
47
-
48
- # Path (e.g. http://restfulie.com/posts => /posts)
49
- def path
50
- host.path
51
- end
52
-
53
- def get(params = {})
54
- request(:get, add_querystring(path, params), headers)
55
- end
56
-
57
- def head
58
- request(:head, path, headers)
59
- end
60
-
61
- def post(payload)
62
- request(:post, path, payload, headers)
63
- end
64
-
65
- def patch(payload)
66
- request(:patch, path, payload, headers)
67
- end
68
-
69
- def put(payload)
70
- request(:put, path, payload, headers)
71
- end
72
-
73
- def delete
74
- request(:delete, path, headers)
75
- end
76
-
77
- def get!(params = {})
78
- request!(:get, add_querystring(path, params), headers)
79
- end
80
-
81
- def head!
82
- request!(:head, path, headers)
83
- end
84
-
85
- def post!(payload)
86
- request!(:post, path, payload, headers)
87
- end
88
-
89
- def patch!(payload)
90
- request!(:patch, path, payload, headers)
91
- end
92
-
93
- def put!(payload)
94
- request!(:put, path, payload, headers)
95
- end
96
-
97
- def delete!
98
- request!(:delete, path, headers)
99
- end
100
-
101
- protected
102
-
103
- def add_querystring(path, params)
104
- params = params.map { |param, value| "#{param}=#{value}"}.join("&")
105
- params.blank? ? path : URI.escape("#{path}?#{params}")
106
- end
107
-
108
- def headers=(h)
109
- @headers = h
110
- end
111
- end
112
- end
113
- end
114
- end
@@ -1,24 +0,0 @@
1
- module Restfulie
2
- module Client
3
- module HTTP #:nodoc:
4
- #=This class includes RequestBuilder module.
5
- class RequestBuilderExecutor < RequestExecutor
6
- include RequestBuilder
7
-
8
- def host=(host)
9
- super
10
- at(self.host.path)
11
- end
12
-
13
- def at(path)
14
- @path = path
15
- self
16
- end
17
-
18
- def path
19
- @path
20
- end
21
- end
22
- end
23
- end
24
- end
@@ -1,17 +0,0 @@
1
- module Restfulie
2
- module Client
3
- module HTTP #:nodoc:
4
- #=This class includes RequestAdapter module.
5
- class RequestExecutor
6
- include RequestAdapter
7
-
8
- # * <tt> host (e.g. 'http://restfulie.com') </tt>
9
- # * <tt> default_headers (e.g. {'Cache-control' => 'no-cache'} ) </tt>
10
- def initialize(host, default_headers = {})
11
- self.host=host
12
- self.default_headers=default_headers
13
- end
14
- end
15
- end
16
- end
17
- end
@@ -1,42 +0,0 @@
1
- module Restfulie
2
- module Client
3
- module HTTP #:nodoc:
4
- # ==== RequestFollow follow new location of a document usually with response codes 201,301,302,303 and 307. You can also configure other codes.
5
- #
6
- # ==== Example:
7
- # @executor = ::Restfulie::Client::HTTP::RequestFollowExecutor.new("http://restfulie.com") #this class includes RequestFollow module.
8
- # @executor.at('/custom/songs').accepts('application/atom+xml').follow(201).post!("custom").code
9
- module RequestFollow
10
- include RequestBuilder
11
-
12
- def follow(code = nil)
13
- @follow ||= true # turn on follow redirection
14
- follow_codes << code unless code.nil? or follow_codes.include?(code)
15
- self
16
- end
17
-
18
- def request!(method, path, *args)#:nodoc:
19
- begin
20
- response = super
21
- rescue Error::Redirection => e
22
- raise e unless @follow # normal behavior for bang methods is to raise the exception
23
- response = e.response
24
- if follow_codes.include?(response.code)
25
- location = response.headers['location'] || response.headers['Location']
26
- raise Error::AutoFollowWithoutLocationError.new(self, response) unless location
27
- self.host = location
28
- response = super(:get, location, headers)
29
- end
30
- response
31
- end
32
- end
33
-
34
- protected
35
-
36
- def follow_codes
37
- @follow_codes ||= [201,301,302,303,307]
38
- end
39
- end
40
- end
41
- end
42
- end
@@ -1,10 +0,0 @@
1
- module Restfulie
2
- module Client
3
- module HTTP #:nodoc:
4
- #=This class inherits RequestBuilderExecutor and include RequestFollow module.
5
- class RequestFollowExecutor < RequestBuilderExecutor
6
- include RequestFollow
7
- end
8
- end
9
- end
10
- end
@@ -1,71 +0,0 @@
1
- module Restfulie
2
- module Client
3
- module HTTP #:nodoc:
4
- # ==== RequestHistory
5
- # Uses RequestBuilder and remind previous requests
6
- #
7
- # ==== Example:
8
- #
9
- # @executor = ::Restfulie::Client::HTTP::RequestHistoryExecutor.new("http://restfulie.com") #this class includes RequestHistory module.
10
- # @executor.at('/posts').as('application/xml').accepts('application/atom+xml').with('Accept-Language' => 'en').get.code #=> 200 #first request
11
- # @executor.at('/blogs').as('application/xml').accepts('application/atom+xml').with('Accept-Language' => 'en').get.code #=> 200 #second request
12
- # @executor.request_history!(0) #doing first request
13
- #
14
- module RequestHistory
15
- include RequestBuilder
16
-
17
- def snapshots
18
- @snapshots ||= []
19
- end
20
-
21
- def max_to_remind
22
- 10
23
- end
24
-
25
- def request!(method=nil, path=nil, *args)#:nodoc:
26
- if method == nil || path == nil
27
- raise 'History not selected' unless @snapshot
28
- super( @snapshot[:method], @snapshot[:path], *@snapshot[:args] )
29
- else
30
- @snapshot = make_snapshot(method, path, *args)
31
- unless snapshots.include?(@snapshot)
32
- snapshots.shift if snapshots.size >= max_to_remind
33
- snapshots << @snapshot
34
- end
35
- super
36
- end
37
- end
38
-
39
- def request(method=nil, path=nil, *args)#:nodoc:
40
- request!(method, path, *args)
41
- rescue Error::RESTError => se
42
- [[@host, path], nil, se.response]
43
- end
44
-
45
- def history(number)
46
- @snapshot = snapshots[number]
47
- raise "Undefined snapshot for #{number}" unless @snapshot
48
- self.host = @snapshot[:host]
49
- self.cookies = @snapshot[:cookies]
50
- self.headers = @snapshot[:headers]
51
- self.default_headers = @snapshot[:default_headers]
52
- at(@snapshot[:path])
53
- end
54
-
55
- private
56
-
57
- def make_snapshot(method, path, *args)
58
- arguments = args.dup
59
- cutom_headers = arguments.extract_options!
60
- { :host => self.host.dup,
61
- :default_headers => self.default_headers.dup,
62
- :headers => self.headers.dup,
63
- :cookies => self.cookies,
64
- :method => method,
65
- :path => path,
66
- :args => arguments << self.headers.merge(cutom_headers) }
67
- end
68
- end
69
- end
70
- end
71
- end
@@ -1,10 +0,0 @@
1
- module Restfulie
2
- module Client
3
- module HTTP #:nodoc:
4
- #=This class inherits RequestFollowExecutor and include RequestHistory module.
5
- class RequestHistoryExecutor < RequestBuilderExecutor
6
- include RequestHistory
7
- end
8
- end
9
- end
10
- end
@@ -1,129 +0,0 @@
1
- module Restfulie
2
- module Client
3
- module HTTP
4
- module RequestMarshaller
5
- include RequestHistory
6
-
7
- @@representations = {
8
- 'application/atom+xml' => ::Restfulie::Common::Converter::Atom,
9
- 'application/xml' => ::Restfulie::Common::Converter::Xml,
10
- 'text/xml' => ::Restfulie::Common::Converter::Xml,
11
- 'application/json' => ::Restfulie::Common::Converter::Json
12
- }
13
-
14
- def self.register_representation(media_type,representation)
15
- @@representations[media_type] = representation
16
- end
17
-
18
- def self.content_type_for(media_type)
19
- return nil unless media_type
20
- content_type = media_type.split(';')[0] # [/(.*?);/, 1]
21
- @@representations[content_type]
22
- end
23
-
24
- def accepts(media_types)
25
- @default_representation = @@representations[media_types]
26
- super
27
- end
28
-
29
- def raw
30
- @raw = true
31
- self
32
- end
33
-
34
- def post(payload, options = { :recipe => nil })
35
- request(:post, path, payload, options.merge(headers))
36
- end
37
-
38
- def post!(payload, options = { :recipe => nil })
39
- request!(:post, path, payload, options.merge(headers))
40
- end
41
-
42
- # Executes super if its a raw request, returning the content itself.
43
- # otherwise tries to parse the content with a mediatype handler or returns the response itself.
44
- def request!(method, path, *args)
45
- if has_payload?(method, path, *args)
46
- recipe = get_recipe(*args)
47
-
48
- payload = get_payload(method, path, *args)
49
- rel = self.respond_to?(:rel) ? self.rel : ""
50
- type = headers['Content-Type']
51
- raise Restfulie::Common::Error::RestfulieError, "Missing content type related to the data to be submitted" unless type
52
- marshaller = RequestMarshaller.content_type_for(type)
53
- payload = marshaller.marshal(payload, { :rel => rel, :recipe => recipe }) unless payload.nil? || (payload.kind_of?(String) && payload.empty?)
54
- args = set_marshalled_payload(method, path, payload, *args)
55
- args = add_representation_headers(method, path, marshaller, *args)
56
- end
57
-
58
- if @acceptable_mediatypes
59
- unmarshaller = RequestMarshaller.content_type_for(@acceptable_mediatypes)
60
- args = add_representation_headers(method, path, unmarshaller, *args)
61
- end
62
-
63
- key, req, response = super(method, path, *args)
64
- Restfulie::Client.cache_provider.put(key, req, response)
65
-
66
- parse_response(response)
67
- end
68
-
69
- private
70
-
71
- # parses the http response.
72
- # first checks if its a 201, redirecting to the resource location.
73
- # otherwise check if its a raw request, returning the content itself.
74
- # finally, tries to parse the content with a mediatype handler or returns the response itself.
75
- def parse_response(response)
76
- if response.code == 201
77
- request = Restfulie.at(response.headers['location'])
78
- request.accepts(@acceptable_mediatypes) if @acceptable_mediatypes
79
- request.get!
80
- elsif @raw
81
- response
82
- elsif !response.body.empty?
83
- representation = RequestMarshaller.content_type_for(response.headers['content-type']) || Restfulie::Common::Representation::Generic.new
84
- representation.unmarshal(response.body).tap do |u|
85
- u.extend(ResponseHolder)
86
- u.response = response
87
- end
88
- else
89
- response.tap do |resp|
90
- resp.extend(ResponseHolder)
91
- resp.response = response
92
- end
93
- end
94
- end
95
-
96
- def get_recipe(*args)
97
- headers_and_recipe = args.extract_options!
98
- recipe = headers_and_recipe.delete(:recipe)
99
- args << headers_and_recipe
100
- recipe
101
- end
102
-
103
- def has_payload?(method, path, *args)
104
- [:put,:post,:patch].include?(method)
105
- end
106
-
107
- def get_payload(method, path, *args)
108
- args.extract_options! #remove header
109
- args.shift #payload
110
- end
111
-
112
- def set_marshalled_payload(method, path, payload, *args)
113
- headers = args.extract_options!
114
- args.tap do |a|
115
- a.shift #old payload
116
- a << payload << headers
117
- end
118
- end
119
-
120
- def add_representation_headers(method, path, representation, *args)
121
- headers = args.extract_options!
122
- headers = headers.merge(representation.headers[method] || {})
123
- args << headers
124
- args
125
- end
126
- end
127
- end
128
- end
129
- end
@@ -1,10 +0,0 @@
1
- module Restfulie
2
- module Client
3
- module HTTP
4
- #=This class includes RequestBuilder module.
5
- class RequestMarshallerExecutor < RequestHistoryExecutor
6
- include RequestMarshaller
7
- end
8
- end
9
- end
10
- end
@@ -1,23 +0,0 @@
1
- module Restfulie
2
- module Client
3
- module HTTP #:nodoc:
4
- #=Response
5
- # Default response class
6
- class Response
7
- attr_reader :method
8
- attr_reader :path
9
- attr_reader :code
10
- attr_reader :body
11
- attr_reader :headers
12
-
13
- def initialize(method, path, code, body, headers)
14
- @method = method
15
- @path = path
16
- @code = code
17
- @body = body
18
- @headers = headers
19
- end
20
- end
21
- end
22
- end
23
- end