Skip to content
This repository
Browse code

Add support for setting custom headers per ActiveResource model [Rick]

git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@6624 5ecf4fe2-1ee6-0310-87b1-e25e094e27de
  • Loading branch information...
commit bd50d82f701c55d89b891ebd216ec84008b486c1 1 parent 1162c29
risk danger olson authored April 29, 2007
9  activeresource/CHANGELOG
... ...
@@ -1,5 +1,14 @@
1 1
 *SVN*
2 2
 
  3
+* Add support for setting custom headers per ActiveResource model [Rick]
  4
+
  5
+  class Project
  6
+    custom_headers['X-Token'] = 'foo'
  7
+  end
  8
+  
  9
+  # makes the GET request with the custom X-Token header
  10
+  Project.find(:all)
  11
+
3 12
 * Added find-by-path options to ActiveResource::Base.find [DHH]. Examples:
4 13
 
5 14
     employees = Person.find(:all, :from => "/companies/1/people.xml") # => GET /companies/1/people.xml
14  activeresource/lib/active_resource/base.rb
@@ -29,6 +29,10 @@ def connection(refresh = false)
29 29
         @connection
30 30
       end
31 31
 
  32
+      def custom_headers
  33
+        @custom_headers ||= {}
  34
+      end
  35
+
32 36
       # Do not include any modules in the default element name. This makes it easier to seclude ARes objects
33 37
       # in a separate namespace without having to set element_name repeatedly.
34 38
       attr_accessor_with_default(:element_name)    { to_s.split("::").last.underscore } #:nodoc:
@@ -150,7 +154,7 @@ def find_every(options)
150 154
           prefix_options, query_options = split_options(options)
151 155
           from ||= collection_path(prefix_options, query_options)
152 156
 
153  
-          instantiate_collection(connection.get(from) || [])
  157
+          instantiate_collection(connection.get(from, custom_headers) || [])
154 158
         end
155 159
         
156 160
         def instantiate_collection(collection, prefix_options = {})
@@ -167,7 +171,7 @@ def find_single(scope, options)
167 171
           prefix_options, query_options = split_options(options)
168 172
           from = scope.to_s.include?("/") ? scope : element_path(scope, prefix_options, query_options)
169 173
 
170  
-          returning new(connection.get(from)) do |resource|
  174
+          returning new(connection.get(from, custom_headers)) do |resource|
171 175
             resource.prefix_options = prefix_options
172 176
           end
173 177
         end
@@ -254,7 +258,7 @@ def save
254 258
 
255 259
     # Delete the resource.
256 260
     def destroy
257  
-      connection.delete(element_path)
  261
+      connection.delete(element_path, self.class.custom_headers)
258 262
     end
259 263
 
260 264
     # Evaluates to <tt>true</tt> if this resource is found.
@@ -300,14 +304,14 @@ def connection(refresh = false)
300 304
 
301 305
       # Update the resource on the remote service.
302 306
       def update
303  
-        returning connection.put(element_path(prefix_options), to_xml) do |response|
  307
+        returning connection.put(element_path(prefix_options), to_xml, self.class.custom_headers) do |response|
304 308
           load_attributes_from_response(response)
305 309
         end
306 310
       end
307 311
 
308 312
       # Create (i.e., save to the remote service) the new resource.
309 313
       def create
310  
-        returning connection.post(collection_path, to_xml) do |response|
  314
+        returning connection.post(collection_path, to_xml, self.class.custom_headers) do |response|
311 315
           self.id = id_from_response(response)
312 316
           load_attributes_from_response(response)
313 317
         end
20  activeresource/lib/active_resource/connection.rb
@@ -51,26 +51,26 @@ def site=(site)
51 51
 
52 52
     # Execute a GET request.
53 53
     # Used to get (find) resources.
54  
-    def get(path)
55  
-      xml_from_response(request(:get, path, build_request_headers))
  54
+    def get(path, headers = {})
  55
+      xml_from_response(request(:get, path, build_request_headers(headers)))
56 56
     end
57 57
 
58 58
     # Execute a DELETE request (see HTTP protocol documentation if unfamiliar).
59 59
     # Used to delete resources.
60  
-    def delete(path)
61  
-      request(:delete, path, build_request_headers)
  60
+    def delete(path, headers = {})
  61
+      request(:delete, path, build_request_headers(headers))
62 62
     end
63 63
 
64 64
     # Execute a PUT request (see HTTP protocol documentation if unfamiliar).
65 65
     # Used to update resources.
66  
-    def put(path, body = '')
67  
-      request(:put, path, body, build_request_headers)
  66
+    def put(path, body = '', headers = {})
  67
+      request(:put, path, body, build_request_headers(headers))
68 68
     end
69 69
 
70 70
     # Execute a POST request.
71 71
     # Used to create new resources.
72  
-    def post(path, body = '')
73  
-      request(:post, path, body, build_request_headers)
  72
+    def post(path, body = '', headers = {})
  73
+      request(:post, path, body, build_request_headers(headers))
74 74
     end
75 75
 
76 76
     def xml_from_response(response)
@@ -125,8 +125,8 @@ def http
125 125
       end
126 126
       
127 127
       # Builds headers for request to remote service.
128  
-      def build_request_headers
129  
-        authorization_header.update(self.class.default_header)
  128
+      def build_request_headers(headers)
  129
+        authorization_header.update(self.class.default_header).update(headers)
130 130
       end
131 131
       
132 132
       # Sets authorization header; authentication information is pulled from credentials provided with site URI.
18  activeresource/lib/active_resource/custom_methods.rb
@@ -36,21 +36,21 @@ class << self
36 36
           alias :orig_delete :delete
37 37
           
38 38
           def get(method_name, options = {})
39  
-            connection.get(custom_method_collection_url(method_name, options))
  39
+            connection.get(custom_method_collection_url(method_name, options), custom_headers)
40 40
           end
41 41
       
42 42
           def post(method_name, options = {}, body = nil)
43  
-            connection.post(custom_method_collection_url(method_name, options), body)
  43
+            connection.post(custom_method_collection_url(method_name, options), body, custom_headers)
44 44
           end
45 45
       
46 46
           def put(method_name, options = {}, body = nil)
47  
-            connection.put(custom_method_collection_url(method_name, options), body)
  47
+            connection.put(custom_method_collection_url(method_name, options), body, custom_headers)
48 48
           end
49 49
       
50 50
           # Need to jump through some hoops to retain the original class 'delete' method
51 51
           def delete(custom_method_name, options = {})
52 52
             if (custom_method_name.is_a?(Symbol))
53  
-              connection.delete(custom_method_collection_url(custom_method_name, options))
  53
+              connection.delete(custom_method_collection_url(custom_method_name, options), custom_headers)
54 54
             else
55 55
               orig_delete(custom_method_name, options)
56 56
             end
@@ -71,23 +71,23 @@ def custom_method_collection_url(method_name, options = {})
71 71
     
72 72
     module InstanceMethods
73 73
       def get(method_name, options = {})
74  
-        connection.get(custom_method_element_url(method_name, options))
  74
+        connection.get(custom_method_element_url(method_name, options), self.class.custom_headers)
75 75
       end
76 76
       
77 77
       def post(method_name, options = {}, body = nil)
78 78
         if new?
79  
-          connection.post(custom_method_new_element_url(method_name, options), (body.nil? ? to_xml : body))
  79
+          connection.post(custom_method_new_element_url(method_name, options), (body.nil? ? to_xml : body), self.class.custom_headers)
80 80
         else
81  
-          connection.post(custom_method_element_url(method_name, options), body)
  81
+          connection.post(custom_method_element_url(method_name, options), body, self.class.custom_headers)
82 82
         end
83 83
       end
84 84
       
85 85
       def put(method_name, options = {}, body = nil)
86  
-        connection.put(custom_method_element_url(method_name, options), body)
  86
+        connection.put(custom_method_element_url(method_name, options), body, self.class.custom_headers)
87 87
       end
88 88
       
89 89
       def delete(method_name, options = {})
90  
-        connection.delete(custom_method_element_url(method_name, options))
  90
+        connection.delete(custom_method_element_url(method_name, options), self.class.custom_headers)
91 91
       end
92 92
 
93 93
 
8  activeresource/test/base_test.rb
@@ -13,6 +13,7 @@ def setup
13 13
     ActiveResource::HttpMock.respond_to do |mock|
14 14
       mock.get    "/people/1.xml",             {}, @matz
15 15
       mock.get    "/people/2.xml",             {}, @david
  16
+      mock.get    "/people/3.xml",             {'key' => 'value'}, nil, 404
16 17
       mock.put    "/people/1.xml",             {}, nil, 204
17 18
       mock.delete "/people/1.xml",             {}, nil, 200
18 19
       mock.delete "/people/2.xml",             {}, nil, 400
@@ -198,6 +199,13 @@ def test_find_first
198 199
     assert_equal "Matz", matz.name
199 200
   end
200 201
 
  202
+  def test_custom_header
  203
+    Person.custom_headers['key'] = 'value'
  204
+    assert_raises(ActiveResource::ResourceNotFound) { Person.find(3) }
  205
+  ensure
  206
+    Person.custom_headers.delete('key')
  207
+  end
  208
+
201 209
   def test_find_by_id_not_found
202 210
     assert_raises(ActiveResource::ResourceNotFound) { Person.find(99) }
203 211
     assert_raises(ActiveResource::ResourceNotFound) { StreetAddress.find(1) }
25  activeresource/test/connection_test.rb
@@ -13,16 +13,21 @@ def setup
13 13
     @people_empty = [ ].to_xml(:root => 'people-empty-elements')
14 14
     @matz = @matz.to_xml(:root => 'person')
15 15
     @david = @david.to_xml(:root => 'person')
  16
+    @header = {'key' => 'value'}
16 17
 
17 18
     @default_request_headers = { 'Content-Type' => 'application/xml' }
18 19
     ActiveResource::HttpMock.respond_to do |mock|
  20
+      mock.get    "/people/2.xml", @header, @david
19 21
       mock.get    "/people.xml", {}, @people
20 22
       mock.get    "/people_single_elements.xml", {}, @people_single
21 23
       mock.get    "/people_empty_elements.xml", {}, @people_empty
22 24
       mock.get    "/people/1.xml", {}, @matz
23 25
       mock.put    "/people/1.xml", {}, nil, 204
  26
+      mock.put    "/people/2.xml", {}, @header, 204
24 27
       mock.delete "/people/1.xml", {}, nil, 200
  28
+      mock.delete "/people/2.xml", @header, nil, 200
25 29
       mock.post   "/people.xml",   {}, nil, 201, 'Location' => '/people/5.xml'
  30
+      mock.post   "/members.xml",  {}, @header, 201, 'Location' => '/people/6.xml'
26 31
     end
27 32
   end
28 33
 
@@ -79,6 +84,11 @@ def test_get
79 84
     assert_equal "Matz", matz["name"]
80 85
   end
81 86
 
  87
+  def test_get_with_header
  88
+    david = @conn.get("/people/2.xml", @header)
  89
+    assert_equal "David", david["name"]
  90
+  end
  91
+
82 92
   def test_get_collection
83 93
     people = @conn.get("/people.xml")
84 94
     assert_equal "Matz", people[0]["name"]
@@ -100,16 +110,31 @@ def test_post
100 110
     assert_equal "/people/5.xml", response["Location"]
101 111
   end
102 112
 
  113
+  def test_post_with_header
  114
+    response = @conn.post("/members.xml", @header)
  115
+    assert_equal "/people/6.xml", response["Location"]
  116
+  end
  117
+
103 118
   def test_put
104 119
     response = @conn.put("/people/1.xml")
105 120
     assert_equal 204, response.code
106 121
   end
107 122
 
  123
+  def test_put_with_header
  124
+    response = @conn.put("/people/2.xml", @header)
  125
+    assert_equal 204, response.code
  126
+  end
  127
+
108 128
   def test_delete
109 129
     response = @conn.delete("/people/1.xml")
110 130
     assert_equal 200, response.code
111 131
   end
112 132
 
  133
+  def test_delete_with_header
  134
+    response = @conn.delete("/people/2.xml", @header)
  135
+    assert_equal 200, response.code
  136
+  end
  137
+
113 138
   protected
114 139
     def assert_response_raises(klass, code)
115 140
       assert_raise(klass, "Expected response code #{code} to raise #{klass}") do

0 notes on commit bd50d82

Please sign in to comment.
Something went wrong with that request. Please try again.