swivel 0.0.146 → 0.0.149

Sign up to get free protection for your applications and to get access to all the features.
Files changed (183) hide show
  1. data/README +4 -1
  2. data/Rakefile +1 -1
  3. data/lib/swivel.rb +1 -1
  4. data/lib/swivel2/benchmarking.rb +1 -0
  5. data/lib/swivel2/config.rb +45 -0
  6. data/lib/swivel2/connection.rb +89 -0
  7. data/lib/swivel2/formats.rb +11 -0
  8. data/lib/swivel2/logging.rb +1 -0
  9. data/lib/swivel2/performance.rb +21 -0
  10. data/lib/swivel2/response.rb +5 -0
  11. data/lib/swivel2/swivelrc.default +5 -0
  12. data/vendor/activeresource-2.0.2-/CHANGELOG +223 -0
  13. data/vendor/activeresource-2.0.2-/README +165 -0
  14. data/vendor/activeresource-2.0.2-/Rakefile +133 -0
  15. data/vendor/activeresource-2.0.2-/lib/active_resource.rb +47 -0
  16. data/vendor/activeresource-2.0.2-/lib/active_resource/base.rb +872 -0
  17. data/vendor/activeresource-2.0.2-/lib/active_resource/connection.rb +172 -0
  18. data/vendor/activeresource-2.0.2-/lib/active_resource/custom_methods.rb +105 -0
  19. data/vendor/activeresource-2.0.2-/lib/active_resource/formats.rb +14 -0
  20. data/vendor/activeresource-2.0.2-/lib/active_resource/formats/json_format.rb +23 -0
  21. data/vendor/activeresource-2.0.2-/lib/active_resource/formats/xml_format.rb +34 -0
  22. data/vendor/activeresource-2.0.2-/lib/active_resource/http_mock.rb +147 -0
  23. data/vendor/activeresource-2.0.2-/lib/active_resource/validations.rb +288 -0
  24. data/vendor/activeresource-2.0.2-/lib/active_resource/version.rb +9 -0
  25. data/vendor/activeresource-2.0.2-/lib/activeresource.rb +1 -0
  26. data/vendor/activeresource-2.0.2-/test/abstract_unit.rb +10 -0
  27. data/vendor/activeresource-2.0.2-/test/authorization_test.rb +82 -0
  28. data/vendor/activeresource-2.0.2-/test/base/custom_methods_test.rb +96 -0
  29. data/vendor/activeresource-2.0.2-/test/base/equality_test.rb +43 -0
  30. data/vendor/activeresource-2.0.2-/test/base/load_test.rb +111 -0
  31. data/vendor/activeresource-2.0.2-/test/base_errors_test.rb +48 -0
  32. data/vendor/activeresource-2.0.2-/test/base_test.rb +454 -0
  33. data/vendor/activeresource-2.0.2-/test/connection_test.rb +170 -0
  34. data/vendor/activeresource-2.0.2-/test/fixtures/beast.rb +14 -0
  35. data/vendor/activeresource-2.0.2-/test/fixtures/person.rb +3 -0
  36. data/vendor/activeresource-2.0.2-/test/fixtures/street_address.rb +4 -0
  37. data/vendor/activeresource-2.0.2-/test/format_test.rb +42 -0
  38. data/vendor/activeresource-2.0.2-/test/setter_trap.rb +27 -0
  39. data/vendor/activesupport-2.0.2-/CHANGELOG +986 -0
  40. data/vendor/activesupport-2.0.2-/README +43 -0
  41. data/vendor/activesupport-2.0.2-/lib/active_support.rb +49 -0
  42. data/vendor/activesupport-2.0.2-/lib/active_support/basic_object.rb +5 -0
  43. data/vendor/activesupport-2.0.2-/lib/active_support/buffered_logger.rb +107 -0
  44. data/vendor/activesupport-2.0.2-/lib/active_support/clean_logger.rb +127 -0
  45. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext.rb +4 -0
  46. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/array.rb +13 -0
  47. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/array/access.rb +28 -0
  48. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/array/conversions.rb +94 -0
  49. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/array/extract_options.rb +19 -0
  50. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/array/grouping.rb +68 -0
  51. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/array/random_access.rb +12 -0
  52. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/bigdecimal.rb +2 -0
  53. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/bigdecimal/conversions.rb +6 -0
  54. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/blank.rb +50 -0
  55. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/cgi.rb +5 -0
  56. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/cgi/escape_skipping_slashes.rb +14 -0
  57. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/class.rb +4 -0
  58. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/class/attribute_accessors.rb +48 -0
  59. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/class/delegating_attributes.rb +40 -0
  60. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/class/inheritable_attributes.rb +140 -0
  61. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/class/removal.rb +24 -0
  62. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/date.rb +10 -0
  63. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/date/behavior.rb +13 -0
  64. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/date/calculations.rb +188 -0
  65. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/date/conversions.rb +98 -0
  66. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/date_time.rb +10 -0
  67. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/date_time/calculations.rb +77 -0
  68. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/date_time/conversions.rb +74 -0
  69. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/duplicable.rb +37 -0
  70. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/enumerable.rb +63 -0
  71. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/exception.rb +33 -0
  72. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/file.rb +21 -0
  73. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/float.rb +5 -0
  74. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/float/rounding.rb +24 -0
  75. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/hash.rb +13 -0
  76. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/hash/conversions.rb +242 -0
  77. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/hash/diff.rb +19 -0
  78. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/hash/except.rb +24 -0
  79. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/hash/indifferent_access.rb +102 -0
  80. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/hash/keys.rb +54 -0
  81. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/hash/reverse_merge.rb +25 -0
  82. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/hash/slice.rb +28 -0
  83. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/integer.rb +7 -0
  84. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/integer/even_odd.rb +24 -0
  85. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/integer/inflections.rb +21 -0
  86. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/kernel.rb +5 -0
  87. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/kernel/agnostics.rb +11 -0
  88. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/kernel/daemonizing.rb +15 -0
  89. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/kernel/debugger.rb +13 -0
  90. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/kernel/reporting.rb +51 -0
  91. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/kernel/requires.rb +24 -0
  92. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/load_error.rb +38 -0
  93. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/logger.rb +16 -0
  94. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/module.rb +8 -0
  95. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/module/aliasing.rb +70 -0
  96. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/module/attr_accessor_with_default.rb +31 -0
  97. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/module/attr_internal.rb +31 -0
  98. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/module/attribute_accessors.rb +48 -0
  99. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/module/delegation.rb +62 -0
  100. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/module/inclusion.rb +11 -0
  101. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/module/introspection.rb +35 -0
  102. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/module/loading.rb +13 -0
  103. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/name_error.rb +17 -0
  104. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/numeric.rb +7 -0
  105. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/numeric/bytes.rb +44 -0
  106. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/numeric/time.rb +91 -0
  107. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/object.rb +4 -0
  108. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/object/conversions.rb +14 -0
  109. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/object/extending.rb +58 -0
  110. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/object/instance_variables.rb +22 -0
  111. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/object/misc.rb +59 -0
  112. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/pathname.rb +7 -0
  113. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/pathname/clean_within.rb +14 -0
  114. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/proc.rb +12 -0
  115. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/range.rb +11 -0
  116. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/range/blockless_step.rb +22 -0
  117. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/range/conversions.rb +23 -0
  118. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/range/include_range.rb +22 -0
  119. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/range/overlaps.rb +12 -0
  120. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/string.rb +23 -0
  121. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/string/access.rb +58 -0
  122. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/string/conversions.rb +28 -0
  123. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/string/inflections.rb +153 -0
  124. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/string/iterators.rb +17 -0
  125. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/string/starts_ends_with.rb +27 -0
  126. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/string/unicode.rb +42 -0
  127. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/string/xchar.rb +11 -0
  128. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/symbol.rb +14 -0
  129. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/test.rb +1 -0
  130. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/test/unit/assertions.rb +62 -0
  131. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/time.rb +19 -0
  132. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/time/behavior.rb +13 -0
  133. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/time/calculations.rb +224 -0
  134. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/time/conversions.rb +94 -0
  135. data/vendor/activesupport-2.0.2-/lib/active_support/dependencies.rb +540 -0
  136. data/vendor/activesupport-2.0.2-/lib/active_support/deprecation.rb +204 -0
  137. data/vendor/activesupport-2.0.2-/lib/active_support/duration.rb +96 -0
  138. data/vendor/activesupport-2.0.2-/lib/active_support/inflections.rb +53 -0
  139. data/vendor/activesupport-2.0.2-/lib/active_support/inflector.rb +282 -0
  140. data/vendor/activesupport-2.0.2-/lib/active_support/json.rb +31 -0
  141. data/vendor/activesupport-2.0.2-/lib/active_support/json/decoding.rb +60 -0
  142. data/vendor/activesupport-2.0.2-/lib/active_support/json/encoders/date.rb +5 -0
  143. data/vendor/activesupport-2.0.2-/lib/active_support/json/encoders/date_time.rb +5 -0
  144. data/vendor/activesupport-2.0.2-/lib/active_support/json/encoders/enumerable.rb +12 -0
  145. data/vendor/activesupport-2.0.2-/lib/active_support/json/encoders/false_class.rb +5 -0
  146. data/vendor/activesupport-2.0.2-/lib/active_support/json/encoders/hash.rb +50 -0
  147. data/vendor/activesupport-2.0.2-/lib/active_support/json/encoders/nil_class.rb +5 -0
  148. data/vendor/activesupport-2.0.2-/lib/active_support/json/encoders/numeric.rb +5 -0
  149. data/vendor/activesupport-2.0.2-/lib/active_support/json/encoders/object.rb +6 -0
  150. data/vendor/activesupport-2.0.2-/lib/active_support/json/encoders/regexp.rb +5 -0
  151. data/vendor/activesupport-2.0.2-/lib/active_support/json/encoders/string.rb +30 -0
  152. data/vendor/activesupport-2.0.2-/lib/active_support/json/encoders/symbol.rb +5 -0
  153. data/vendor/activesupport-2.0.2-/lib/active_support/json/encoders/time.rb +5 -0
  154. data/vendor/activesupport-2.0.2-/lib/active_support/json/encoders/true_class.rb +5 -0
  155. data/vendor/activesupport-2.0.2-/lib/active_support/json/encoding.rb +38 -0
  156. data/vendor/activesupport-2.0.2-/lib/active_support/json/variable.rb +10 -0
  157. data/vendor/activesupport-2.0.2-/lib/active_support/multibyte.rb +9 -0
  158. data/vendor/activesupport-2.0.2-/lib/active_support/multibyte/chars.rb +141 -0
  159. data/vendor/activesupport-2.0.2-/lib/active_support/multibyte/generators/generate_tables.rb +149 -0
  160. data/vendor/activesupport-2.0.2-/lib/active_support/multibyte/handlers/passthru_handler.rb +9 -0
  161. data/vendor/activesupport-2.0.2-/lib/active_support/multibyte/handlers/utf8_handler.rb +564 -0
  162. data/vendor/activesupport-2.0.2-/lib/active_support/multibyte/handlers/utf8_handler_proc.rb +43 -0
  163. data/vendor/activesupport-2.0.2-/lib/active_support/option_merger.rb +25 -0
  164. data/vendor/activesupport-2.0.2-/lib/active_support/ordered_options.rb +49 -0
  165. data/vendor/activesupport-2.0.2-/lib/active_support/test_case.rb +5 -0
  166. data/vendor/activesupport-2.0.2-/lib/active_support/testing.rb +1 -0
  167. data/vendor/activesupport-2.0.2-/lib/active_support/testing/default.rb +12 -0
  168. data/vendor/activesupport-2.0.2-/lib/active_support/values/time_zone.rb +181 -0
  169. data/vendor/activesupport-2.0.2-/lib/active_support/values/unicode_tables.dat +0 -0
  170. data/vendor/activesupport-2.0.2-/lib/active_support/vendor.rb +14 -0
  171. data/vendor/activesupport-2.0.2-/lib/active_support/vendor/builder-2.1.2/blankslate.rb +113 -0
  172. data/vendor/activesupport-2.0.2-/lib/active_support/vendor/builder-2.1.2/builder.rb +13 -0
  173. data/vendor/activesupport-2.0.2-/lib/active_support/vendor/builder-2.1.2/builder/blankslate.rb +20 -0
  174. data/vendor/activesupport-2.0.2-/lib/active_support/vendor/builder-2.1.2/builder/css.rb +250 -0
  175. data/vendor/activesupport-2.0.2-/lib/active_support/vendor/builder-2.1.2/builder/xchar.rb +115 -0
  176. data/vendor/activesupport-2.0.2-/lib/active_support/vendor/builder-2.1.2/builder/xmlbase.rb +139 -0
  177. data/vendor/activesupport-2.0.2-/lib/active_support/vendor/builder-2.1.2/builder/xmlevents.rb +63 -0
  178. data/vendor/activesupport-2.0.2-/lib/active_support/vendor/builder-2.1.2/builder/xmlmarkup.rb +328 -0
  179. data/vendor/activesupport-2.0.2-/lib/active_support/vendor/xml-simple-1.0.11/xmlsimple.rb +1021 -0
  180. data/vendor/activesupport-2.0.2-/lib/active_support/version.rb +9 -0
  181. data/vendor/activesupport-2.0.2-/lib/active_support/whiny_nil.rb +38 -0
  182. data/vendor/activesupport-2.0.2-/lib/activesupport.rb +1 -0
  183. metadata +222 -2
@@ -0,0 +1,172 @@
1
+ require 'net/https'
2
+ require 'date'
3
+ require 'time'
4
+ require 'uri'
5
+ require 'benchmark'
6
+
7
+ module ActiveResource
8
+ class ConnectionError < StandardError # :nodoc:
9
+ attr_reader :response
10
+
11
+ def initialize(response, message = nil)
12
+ @response = response
13
+ @message = message
14
+ end
15
+
16
+ def to_s
17
+ "Failed with #{response.code} #{response.message if response.respond_to?(:message)}"
18
+ end
19
+ end
20
+
21
+ # 3xx Redirection
22
+ class Redirection < ConnectionError # :nodoc:
23
+ def to_s; response['Location'] ? "#{super} => #{response['Location']}" : super; end
24
+ end
25
+
26
+ # 4xx Client Error
27
+ class ClientError < ConnectionError; end # :nodoc:
28
+
29
+ # 400 Bad Request
30
+ class BadRequest < ClientError; end # :nodoc
31
+
32
+ # 401 Unauthorized
33
+ class UnauthorizedAccess < ClientError; end # :nodoc
34
+
35
+ # 403 Forbidden
36
+ class ForbiddenAccess < ClientError; end # :nodoc
37
+
38
+ # 404 Not Found
39
+ class ResourceNotFound < ClientError; end # :nodoc:
40
+
41
+ # 409 Conflict
42
+ class ResourceConflict < ClientError; end # :nodoc:
43
+
44
+ # 5xx Server Error
45
+ class ServerError < ConnectionError; end # :nodoc:
46
+
47
+ # 405 Method Not Allowed
48
+ class MethodNotAllowed < ClientError # :nodoc:
49
+ def allowed_methods
50
+ @response['Allow'].split(',').map { |verb| verb.strip.downcase.to_sym }
51
+ end
52
+ end
53
+
54
+ # Class to handle connections to remote web services.
55
+ # This class is used by ActiveResource::Base to interface with REST
56
+ # services.
57
+ class Connection
58
+ attr_reader :site
59
+ attr_accessor :format
60
+
61
+ class << self
62
+ def requests
63
+ @@requests ||= []
64
+ end
65
+ end
66
+
67
+ # The +site+ parameter is required and will set the +site+
68
+ # attribute to the URI for the remote resource service.
69
+ def initialize(site, format = ActiveResource::Formats[:xml])
70
+ raise ArgumentError, 'Missing site URI' unless site
71
+ self.site = site
72
+ self.format = format
73
+ end
74
+
75
+ # Set URI for remote service.
76
+ def site=(site)
77
+ @site = site.is_a?(URI) ? site : URI.parse(site)
78
+ end
79
+
80
+ # Execute a GET request.
81
+ # Used to get (find) resources.
82
+ def get(path, headers = {})
83
+ format.decode(request(:get, path, build_request_headers(headers)).body)
84
+ end
85
+
86
+ # Execute a DELETE request (see HTTP protocol documentation if unfamiliar).
87
+ # Used to delete resources.
88
+ def delete(path, headers = {})
89
+ request(:delete, path, build_request_headers(headers))
90
+ end
91
+
92
+ # Execute a PUT request (see HTTP protocol documentation if unfamiliar).
93
+ # Used to update resources.
94
+ def put(path, body = '', headers = {})
95
+ request(:put, path, body.to_s, build_request_headers(headers))
96
+ end
97
+
98
+ # Execute a POST request.
99
+ # Used to create new resources.
100
+ def post(path, body = '', headers = {})
101
+ request(:post, path, body.to_s, build_request_headers(headers))
102
+ end
103
+
104
+
105
+ private
106
+ # Makes request to remote service.
107
+ def request(method, path, *arguments)
108
+ logger.info "#{method.to_s.upcase} #{site.scheme}://#{site.host}:#{site.port}#{path}" if logger
109
+ result = nil
110
+ time = Benchmark.realtime { result = http.send(method, path, *arguments) }
111
+ logger.info "--> #{result.code} #{result.message} (#{result.body ? result.body : 0}b %.2fs)" % time if logger
112
+ handle_response(result)
113
+ end
114
+
115
+ # Handles response and error codes from remote service.
116
+ def handle_response(response)
117
+ case response.code.to_i
118
+ when 301,302
119
+ raise(Redirection.new(response))
120
+ when 200...400
121
+ response
122
+ when 400
123
+ raise(BadRequest.new(response))
124
+ when 401
125
+ raise(UnauthorizedAccess.new(response))
126
+ when 403
127
+ raise(ForbiddenAccess.new(response))
128
+ when 404
129
+ raise(ResourceNotFound.new(response))
130
+ when 405
131
+ raise(MethodNotAllowed.new(response))
132
+ when 409
133
+ raise(ResourceConflict.new(response))
134
+ when 422
135
+ raise(ResourceInvalid.new(response))
136
+ when 401...500
137
+ raise(ClientError.new(response))
138
+ when 500...600
139
+ raise(ServerError.new(response))
140
+ else
141
+ raise(ConnectionError.new(response, "Unknown response code: #{response.code}"))
142
+ end
143
+ end
144
+
145
+ # Creates new Net::HTTP instance for communication with
146
+ # remote service and resources.
147
+ def http
148
+ http = Net::HTTP.new(@site.host, @site.port)
149
+ http.use_ssl = @site.is_a?(URI::HTTPS)
150
+ http.verify_mode = OpenSSL::SSL::VERIFY_NONE if http.use_ssl
151
+ http
152
+ end
153
+
154
+ def default_header
155
+ @default_header ||= { 'Content-Type' => format.mime_type }
156
+ end
157
+
158
+ # Builds headers for request to remote service.
159
+ def build_request_headers(headers)
160
+ authorization_header.update(default_header).update(headers)
161
+ end
162
+
163
+ # Sets authorization header; authentication information is pulled from credentials provided with site URI.
164
+ def authorization_header
165
+ (@site.user || @site.password ? { 'Authorization' => 'Basic ' + ["#{@site.user}:#{ @site.password}"].pack('m').delete("\r\n") } : {})
166
+ end
167
+
168
+ def logger #:nodoc:
169
+ ActiveResource::Base.logger
170
+ end
171
+ end
172
+ end
@@ -0,0 +1,105 @@
1
+ # A module to support custom REST methods and sub-resources, allowing you to break out
2
+ # of the "default" REST methods with your own custom resource requests. For example,
3
+ # say you use Rails to expose a REST service and configure your routes with:
4
+ #
5
+ # map.resources :people, :new => { :register => :post },
6
+ # :element => { :promote => :put, :deactivate => :delete }
7
+ # :collection => { :active => :get }
8
+ #
9
+ # This route set creates routes for the following http requests:
10
+ #
11
+ # POST /people/new/register.xml #=> PeopleController.register
12
+ # PUT /people/1/promote.xml #=> PeopleController.promote with :id => 1
13
+ # DELETE /people/1/deactivate.xml #=> PeopleController.deactivate with :id => 1
14
+ # GET /people/active.xml #=> PeopleController.active
15
+ #
16
+ # Using this module, Active Resource can use these custom REST methods just like the
17
+ # standard methods.
18
+ #
19
+ # class Person < ActiveResource::Base
20
+ # self.site = "http://37s.sunrise.i:3000"
21
+ # end
22
+ #
23
+ # Person.new(:name => 'Ryan).post(:register) # POST /people/new/register.xml
24
+ # # => { :id => 1, :name => 'Ryan' }
25
+ #
26
+ # Person.find(1).put(:promote, :position => 'Manager') # PUT /people/1/promote.xml
27
+ # Person.find(1).delete(:deactivate) # DELETE /people/1/deactivate.xml
28
+ #
29
+ # Person.get(:active) # GET /people/active.xml
30
+ # # => [{:id => 1, :name => 'Ryan'}, {:id => 2, :name => 'Joe'}]
31
+ #
32
+ module ActiveResource
33
+ module CustomMethods
34
+ def self.included(within)
35
+ within.class_eval do
36
+ extend ActiveResource::CustomMethods::ClassMethods
37
+ include ActiveResource::CustomMethods::InstanceMethods
38
+
39
+ class << self
40
+ alias :orig_delete :delete
41
+
42
+ def get(method_name, options = {})
43
+ connection.get(custom_method_collection_url(method_name, options), headers)
44
+ end
45
+
46
+ def post(method_name, options = {}, body = '')
47
+ connection.post(custom_method_collection_url(method_name, options), body, headers)
48
+ end
49
+
50
+ def put(method_name, options = {}, body = '')
51
+ connection.put(custom_method_collection_url(method_name, options), body, headers)
52
+ end
53
+
54
+ # Need to jump through some hoops to retain the original class 'delete' method
55
+ def delete(custom_method_name, options = {})
56
+ if (custom_method_name.is_a?(Symbol))
57
+ connection.delete(custom_method_collection_url(custom_method_name, options), headers)
58
+ else
59
+ orig_delete(custom_method_name, options)
60
+ end
61
+ end
62
+ end
63
+ end
64
+ end
65
+
66
+ module ClassMethods
67
+ def custom_method_collection_url(method_name, options = {})
68
+ prefix_options, query_options = split_options(options)
69
+ "#{prefix(prefix_options)}#{collection_name}/#{method_name}.xml#{query_string(query_options)}"
70
+ end
71
+ end
72
+
73
+ module InstanceMethods
74
+ def get(method_name, options = {})
75
+ connection.get(custom_method_element_url(method_name, options), self.class.headers)
76
+ end
77
+
78
+ def post(method_name, options = {}, body = '')
79
+ if new?
80
+ connection.post(custom_method_new_element_url(method_name, options), (body.nil? ? to_xml : body), self.class.headers)
81
+ else
82
+ connection.post(custom_method_element_url(method_name, options), body, self.class.headers)
83
+ end
84
+ end
85
+
86
+ def put(method_name, options = {}, body = '')
87
+ connection.put(custom_method_element_url(method_name, options), body, self.class.headers)
88
+ end
89
+
90
+ def delete(method_name, options = {})
91
+ connection.delete(custom_method_element_url(method_name, options), self.class.headers)
92
+ end
93
+
94
+
95
+ private
96
+ def custom_method_element_url(method_name, options = {})
97
+ "#{self.class.prefix(prefix_options)}#{self.class.collection_name}/#{id}/#{method_name}.xml#{self.class.send!(:query_string, options)}"
98
+ end
99
+
100
+ def custom_method_new_element_url(method_name, options = {})
101
+ "#{self.class.prefix(prefix_options)}#{self.class.collection_name}/new/#{method_name}.xml#{self.class.send!(:query_string, options)}"
102
+ end
103
+ end
104
+ end
105
+ end
@@ -0,0 +1,14 @@
1
+ module ActiveResource
2
+ module Formats
3
+ # Lookup the format class from a mime type reference symbol. Example:
4
+ #
5
+ # ActiveResource::Formats[:xml] # => ActiveResource::Formats::XmlFormat
6
+ # ActiveResource::Formats[:json] # => ActiveResource::Formats::JsonFormat
7
+ def self.[](mime_type_reference)
8
+ ActiveResource::Formats.const_get(mime_type_reference.to_s.camelize + "Format")
9
+ end
10
+ end
11
+ end
12
+
13
+ require 'active_resource/formats/xml_format'
14
+ require 'active_resource/formats/json_format'
@@ -0,0 +1,23 @@
1
+ module ActiveResource
2
+ module Formats
3
+ module JsonFormat
4
+ extend self
5
+
6
+ def extension
7
+ "json"
8
+ end
9
+
10
+ def mime_type
11
+ "application/json"
12
+ end
13
+
14
+ def encode(hash)
15
+ hash.to_json
16
+ end
17
+
18
+ def decode(json)
19
+ ActiveSupport::JSON.decode(json)
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,34 @@
1
+ module ActiveResource
2
+ module Formats
3
+ module XmlFormat
4
+ extend self
5
+
6
+ def extension
7
+ "xml"
8
+ end
9
+
10
+ def mime_type
11
+ "application/xml"
12
+ end
13
+
14
+ def encode(hash)
15
+ hash.to_xml
16
+ end
17
+
18
+ def decode(xml)
19
+ from_xml_data(Hash.from_xml(xml))
20
+ end
21
+
22
+ private
23
+ # Manipulate from_xml Hash, because xml_simple is not exactly what we
24
+ # want for ActiveResource.
25
+ def from_xml_data(data)
26
+ if data.is_a?(Hash) && data.keys.size == 1
27
+ data.values.first
28
+ else
29
+ data
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,147 @@
1
+ require 'active_resource/connection'
2
+
3
+ module ActiveResource
4
+ class InvalidRequestError < StandardError; end #:nodoc:
5
+
6
+ class HttpMock
7
+ class Responder
8
+ def initialize(responses)
9
+ @responses = responses
10
+ end
11
+
12
+ for method in [ :post, :put, :get, :delete ]
13
+ module_eval <<-EOE
14
+ def #{method}(path, request_headers = {}, body = nil, status = 200, response_headers = {})
15
+ @responses[Request.new(:#{method}, path, nil, request_headers)] = Response.new(body || "", status, response_headers)
16
+ end
17
+ EOE
18
+ end
19
+ end
20
+
21
+ class << self
22
+ def requests
23
+ @@requests ||= []
24
+ end
25
+
26
+ def responses
27
+ @@responses ||= {}
28
+ end
29
+
30
+ def respond_to(pairs = {})
31
+ reset!
32
+ pairs.each do |(path, response)|
33
+ responses[path] = response
34
+ end
35
+
36
+ if block_given?
37
+ yield Responder.new(responses)
38
+ else
39
+ Responder.new(responses)
40
+ end
41
+ end
42
+
43
+ def reset!
44
+ requests.clear
45
+ responses.clear
46
+ end
47
+ end
48
+
49
+ for method in [ :post, :put ]
50
+ module_eval <<-EOE
51
+ def #{method}(path, body, headers)
52
+ request = ActiveResource::Request.new(:#{method}, path, body, headers)
53
+ self.class.requests << request
54
+ self.class.responses[request] || raise(InvalidRequestError.new("No response recorded for: \#{request.inspect}"))
55
+ end
56
+ EOE
57
+ end
58
+
59
+ for method in [ :get, :delete ]
60
+ module_eval <<-EOE
61
+ def #{method}(path, headers)
62
+ request = ActiveResource::Request.new(:#{method}, path, nil, headers)
63
+ self.class.requests << request
64
+ self.class.responses[request] || raise(InvalidRequestError.new("No response recorded for: \#{request.inspect}"))
65
+ end
66
+ EOE
67
+ end
68
+
69
+ def initialize(site)
70
+ @site = site
71
+ end
72
+ end
73
+
74
+ class Request
75
+ attr_accessor :path, :method, :body, :headers
76
+
77
+ def initialize(method, path, body = nil, headers = {})
78
+ @method, @path, @body, @headers = method, path, body, headers.dup
79
+ @headers.update('Content-Type' => 'application/xml')
80
+ end
81
+
82
+ def ==(other_request)
83
+ other_request.hash == hash
84
+ end
85
+
86
+ def eql?(other_request)
87
+ self == other_request
88
+ end
89
+
90
+ def to_s
91
+ "<#{method.to_s.upcase}: #{path} [#{headers}] (#{body})>"
92
+ end
93
+
94
+ def hash
95
+ "#{path}#{method}#{headers}".hash
96
+ end
97
+ end
98
+
99
+ class Response
100
+ attr_accessor :body, :message, :code, :headers
101
+
102
+ def initialize(body, message = 200, headers = {})
103
+ @body, @message, @headers = body, message.to_s, headers
104
+ @code = @message[0,3].to_i
105
+
106
+ resp_cls = Net::HTTPResponse::CODE_TO_OBJ[@code.to_s]
107
+ if resp_cls && !resp_cls.body_permitted?
108
+ @body = nil
109
+ end
110
+
111
+ if @body.nil?
112
+ self['Content-Length'] = "0"
113
+ else
114
+ self['Content-Length'] = body.size.to_s
115
+ end
116
+ end
117
+
118
+ def success?
119
+ (200..299).include?(code)
120
+ end
121
+
122
+ def [](key)
123
+ headers[key]
124
+ end
125
+
126
+ def []=(key, value)
127
+ headers[key] = value
128
+ end
129
+
130
+ def ==(other)
131
+ if (other.is_a?(Response))
132
+ other.body == body && other.message == message && other.headers == headers
133
+ else
134
+ false
135
+ end
136
+ end
137
+ end
138
+
139
+ class Connection
140
+ private
141
+ silence_warnings do
142
+ def http
143
+ @http ||= HttpMock.new(@site)
144
+ end
145
+ end
146
+ end
147
+ end