restfulie 0.9.3 → 1.0.0.beta1

Sign up to get free protection for your applications and to get access to all the features.
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