almodovar 0.5.6 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (43) hide show
  1. data/README.rdoc +4 -4
  2. data/lib/almodovar.rb +15 -181
  3. data/lib/almodovar/digest_auth.rb +4 -0
  4. data/lib/almodovar/http_accessor.rb +26 -0
  5. data/lib/almodovar/resource.rb +56 -0
  6. data/lib/almodovar/resource_collection.rb +31 -0
  7. data/lib/almodovar/resource_presenter.rb +110 -0
  8. data/lib/almodovar/resource_presenter/collection.rb +24 -0
  9. data/lib/almodovar/resource_presenter/link.rb +103 -0
  10. data/lib/almodovar/single_resource.rb +79 -0
  11. data/lib/almodovar/to_xml.rb +21 -0
  12. metadata +47 -91
  13. data/lib/to_xml.rb +0 -24
  14. data/vendor/resourceful-0.5.3-patched/MIT-LICENSE +0 -21
  15. data/vendor/resourceful-0.5.3-patched/Manifest +0 -29
  16. data/vendor/resourceful-0.5.3-patched/README.markdown +0 -84
  17. data/vendor/resourceful-0.5.3-patched/Rakefile +0 -71
  18. data/vendor/resourceful-0.5.3-patched/lib/resourceful.rb +0 -18
  19. data/vendor/resourceful-0.5.3-patched/lib/resourceful/authentication_manager.rb +0 -108
  20. data/vendor/resourceful-0.5.3-patched/lib/resourceful/cache_manager.rb +0 -240
  21. data/vendor/resourceful-0.5.3-patched/lib/resourceful/exceptions.rb +0 -34
  22. data/vendor/resourceful-0.5.3-patched/lib/resourceful/header.rb +0 -126
  23. data/vendor/resourceful-0.5.3-patched/lib/resourceful/http_accessor.rb +0 -98
  24. data/vendor/resourceful-0.5.3-patched/lib/resourceful/memcache_cache_manager.rb +0 -75
  25. data/vendor/resourceful-0.5.3-patched/lib/resourceful/net_http_adapter.rb +0 -70
  26. data/vendor/resourceful-0.5.3-patched/lib/resourceful/options_interpreter.rb +0 -78
  27. data/vendor/resourceful-0.5.3-patched/lib/resourceful/request.rb +0 -230
  28. data/vendor/resourceful-0.5.3-patched/lib/resourceful/resource.rb +0 -165
  29. data/vendor/resourceful-0.5.3-patched/lib/resourceful/response.rb +0 -221
  30. data/vendor/resourceful-0.5.3-patched/lib/resourceful/stubbed_resource_proxy.rb +0 -47
  31. data/vendor/resourceful-0.5.3-patched/lib/resourceful/util.rb +0 -6
  32. data/vendor/resourceful-0.5.3-patched/resourceful.gemspec +0 -48
  33. data/vendor/resourceful-0.5.3-patched/spec/acceptance/authorization_spec.rb +0 -16
  34. data/vendor/resourceful-0.5.3-patched/spec/acceptance/caching_spec.rb +0 -192
  35. data/vendor/resourceful-0.5.3-patched/spec/acceptance/header_spec.rb +0 -24
  36. data/vendor/resourceful-0.5.3-patched/spec/acceptance/redirecting_spec.rb +0 -12
  37. data/vendor/resourceful-0.5.3-patched/spec/acceptance/resource_spec.rb +0 -84
  38. data/vendor/resourceful-0.5.3-patched/spec/acceptance_shared_specs.rb +0 -44
  39. data/vendor/resourceful-0.5.3-patched/spec/old_acceptance_specs.rb +0 -378
  40. data/vendor/resourceful-0.5.3-patched/spec/simple_sinatra_server.rb +0 -74
  41. data/vendor/resourceful-0.5.3-patched/spec/simple_sinatra_server_spec.rb +0 -98
  42. data/vendor/resourceful-0.5.3-patched/spec/spec.opts +0 -3
  43. data/vendor/resourceful-0.5.3-patched/spec/spec_helper.rb +0 -28
data/lib/to_xml.rb DELETED
@@ -1,24 +0,0 @@
1
- require 'active_support/all'
2
-
3
- module Almodovar
4
-
5
- module ToXml
6
-
7
- def to_xml_with_links(options = {})
8
- if options[:convert_links] && options[:builder]
9
- options[:builder].tag!(:link, :rel => options[:root]) do
10
- to_xml_without_links(options)
11
- end
12
- else
13
- to_xml_without_links(options)
14
- end
15
- end
16
-
17
- end
18
-
19
- end
20
-
21
- class Array
22
- include Almodovar::ToXml
23
- alias_method_chain :to_xml, :links
24
- end
@@ -1,21 +0,0 @@
1
- Copyright (c) 2008 Absolute-Performance, Inc
2
- Copyright (c) 2008 Peter Williams
3
-
4
- Permission is hereby granted, free of charge, to any person obtaining
5
- a copy of this software and associated documentation files (the
6
- "Software"), to deal in the Software without restriction, including
7
- without limitation the rights to use, copy, modify, merge, publish,
8
- distribute, sublicense, and/or sell copies of the Software, and to
9
- permit persons to whom the Software is furnished to do so, subject to
10
- the following conditions:
11
-
12
- The above copyright notice and this permission notice shall be
13
- included in all copies or substantial portions of the Software.
14
-
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
- NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19
- LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20
- OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21
- WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -1,29 +0,0 @@
1
- lib/resourceful.rb
2
- lib/resourceful/net_http_adapter.rb
3
- lib/resourceful/stubbed_resource_proxy.rb
4
- lib/resourceful/header.rb
5
- lib/resourceful/memcache_cache_manager.rb
6
- lib/resourceful/response.rb
7
- lib/resourceful/util.rb
8
- lib/resourceful/options_interpreter.rb
9
- lib/resourceful/cache_manager.rb
10
- lib/resourceful/request.rb
11
- lib/resourceful/resource.rb
12
- lib/resourceful/exceptions.rb
13
- lib/resourceful/http_accessor.rb
14
- lib/resourceful/authentication_manager.rb
15
- README.markdown
16
- MIT-LICENSE
17
- Rakefile
18
- Manifest
19
- spec/simple_sinatra_server_spec.rb
20
- spec/old_acceptance_specs.rb
21
- spec/acceptance_shared_specs.rb
22
- spec/spec_helper.rb
23
- spec/simple_sinatra_server.rb
24
- spec/acceptance/authorization_spec.rb
25
- spec/acceptance/header_spec.rb
26
- spec/acceptance/resource_spec.rb
27
- spec/acceptance/caching_spec.rb
28
- spec/acceptance/redirecting_spec.rb
29
- spec/spec.opts
@@ -1,84 +0,0 @@
1
- Resourceful
2
- ===========
3
-
4
- Resourceful provides a convenient Ruby API for making HTTP requests.
5
-
6
- Features:
7
-
8
- * GET, PUT, POST and DELETE HTTP requests
9
- * HTTP Basic and Digest authentication
10
- * HTTP Caching with pluggable backends
11
- * Follow redirects based on the results of a callback
12
-
13
- More Info
14
- =========
15
-
16
- * Source: [Github](http://github.com/paul/resourceful/tree/master)
17
- * Bug Tracking: [Lighthouse](http://resourceful.lighthouseapp.com)
18
- * Project Page: [Rubyforge](http://rubyforge.org/projects/resourceful/)
19
- * Documentation: [API Docs](http://resourceful.rubyforge.org)
20
-
21
- Examples
22
- ========
23
-
24
- Getting started
25
- ---------------
26
-
27
- gem install resourceful
28
-
29
- Simplest example
30
- ---------------
31
-
32
- require 'resourceful'
33
- http = Resourceful::HttpAccessor.new
34
- resp = http.resource('http://rubyforge.org').get
35
- puts resp.body
36
-
37
- Get a page requiring HTTP Authentication
38
- ----------------------------------------
39
-
40
- my_realm_authenticator = Resourceful::BasicAuthenticator.new('My Realm', 'admin', 'secret')
41
- http = Resourceful::HttpAccessor.new(:authenticator => my_realm_authenticator)
42
- resp = http.resource('http://example.com/').get
43
- puts resp.body
44
-
45
- Redirection based on callback results
46
- -------------------------------------
47
-
48
- Resourceful will by default follow redirects on read requests (GET and HEAD), but not for
49
- POST, etc. If you want to follow a redirect after a post, you will need to set the resource#on_redirect
50
- callback. If the callback evaluates to true, it will follow the redirect.
51
-
52
- resource = http.resource('http://example.com/redirect_me')
53
- resource.on_redirect { |req, resp| resp.header['Location'] =~ /example.com/ }
54
- resource.get # Will only follow the redirect if the new location is example.com
55
-
56
- Post a URL encoded form
57
- -----------------------
58
-
59
- require 'resourceful'
60
- http = Resourceful::HttpAccessor.new
61
- resp = http.resource('http://mysite.example/service').
62
- post('hostname=test&level=super', :content_type => 'application/x-www-form-urlencoded')
63
-
64
- Put an XML document
65
- -------------------
66
-
67
- require 'resourceful'
68
- http = Resourceful::HttpAccessor.new
69
- resp = http.resource('http://mysite.example/service').
70
- put('<?xml version="1.0"?><test/>', :content_type => 'application/xml')
71
-
72
- Delete a resource
73
- -----------------
74
-
75
- require 'resourceful'
76
- http = Resourceful::HttpAccessor.new
77
- resp = http.resource('http://mysite.example/service').delete
78
-
79
-
80
- Copyright
81
- ---------
82
-
83
- Copyright (c) 2008 Absolute Performance, Inc, Peter Williams. Released under the MIT License.
84
-
@@ -1,71 +0,0 @@
1
- require 'rubygems'
2
- require 'rake'
3
- require 'lib/resourceful'
4
-
5
- begin
6
- require 'echoe'
7
-
8
- Echoe.new('resourceful', Resourceful::VERSION) do |p|
9
- p.description = "An HTTP library for Ruby that takes advantage of everything HTTP has to offer."
10
- p.url = "http://github.com/paul/resourceful"
11
- p.author = "Paul Sadauskas"
12
- p.email = "psadauskas@gmail.com"
13
-
14
- p.ignore_pattern = ["pkg/*", "tmp/*"]
15
- p.dependencies = ['addressable', 'httpauth']
16
- p.development_dependencies = ['thin', 'yard', 'sinatra', 'rspec']
17
- end
18
- rescue LoadError => e
19
- puts "install 'echoe' gem to be able to build the gem"
20
- end
21
-
22
- require 'spec/rake/spectask'
23
-
24
- desc 'Run all specs'
25
- Spec::Rake::SpecTask.new(:spec) do |t|
26
- t.spec_opts << '--options' << 'spec/spec.opts' if File.exists?('spec/spec.opts')
27
- t.libs << 'lib'
28
- t.spec_files = FileList['spec/acceptance/*_spec.rb']
29
- end
30
-
31
- desc 'Run the specs for the server'
32
- Spec::Rake::SpecTask.new('spec:server') do |t|
33
- t.spec_opts << '--options' << 'spec/spec.opts' if File.exists?('spec/spec.opts')
34
- t.libs << 'lib'
35
- t.spec_files = FileList['spec/simple_sinatra_server_spec.rb']
36
- end
37
-
38
- begin
39
- require 'spec/simple_sinatra_server'
40
- desc "Run the sinatra echo server, with loggin"
41
- task :server do
42
- Sinatra::Default.set(
43
- :run => true,
44
- :logging => true
45
- )
46
- end
47
- rescue LoadError => e
48
- puts "Install 'sinatra' gem to run the server"
49
- end
50
-
51
- desc 'Default: Run Specs'
52
- task :default => :spec
53
-
54
- desc 'Run all tests'
55
- task :test => :spec
56
-
57
- begin
58
- require 'yard'
59
-
60
- desc "Generate Yardoc"
61
- YARD::Rake::YardocTask.new do |t|
62
- t.files = ['lib/**/*.rb', 'README.markdown']
63
- end
64
- rescue LoadError => e
65
- puts "Install 'yard' gem to generate docs"
66
- end
67
-
68
- desc "Update rubyforge documentation"
69
- task :update_docs => :yardoc do
70
- puts %x{rsync -aPz doc/* psadauskas@resourceful.rubyforge.org:/var/www/gforge-projects/resourceful/}
71
- end
@@ -1,18 +0,0 @@
1
-
2
- __DIR__ = File.dirname(__FILE__)
3
-
4
- $LOAD_PATH.unshift __DIR__ unless
5
- $LOAD_PATH.include?(__DIR__) ||
6
- $LOAD_PATH.include?(File.expand_path(__DIR__))
7
-
8
- require 'resourceful/util'
9
-
10
- require 'resourceful/header'
11
- require 'resourceful/http_accessor'
12
-
13
- # Resourceful is a library that provides a high level HTTP interface.
14
- module Resourceful
15
- VERSION = "0.5.3"
16
- RESOURCEFUL_USER_AGENT_TOKEN = "Resourceful/#{VERSION}(Ruby/#{RUBY_VERSION})"
17
-
18
- end
@@ -1,108 +0,0 @@
1
- #require 'rubygems'
2
- require 'httpauth'
3
- require 'addressable/uri'
4
-
5
- module Resourceful
6
-
7
- class AuthenticationManager
8
- def initialize
9
- @authenticators = []
10
- end
11
-
12
- def add_auth_handler(authenticator)
13
- @authenticators << authenticator
14
- end
15
-
16
- def associate_auth_info(challenge)
17
- @authenticators.each do |authenticator|
18
- authenticator.update_credentials(challenge) if authenticator.valid_for?(challenge)
19
- end
20
- end
21
-
22
- def add_credentials(request)
23
- @authenticators.each do |authenticator|
24
- authenticator.add_credentials_to(request) if authenticator.can_handle?(request)
25
- end
26
- end
27
-
28
- end
29
-
30
- class BasicAuthenticator
31
-
32
- def initialize(realm, username, password)
33
- @realm, @username, @password = realm, username, password
34
- @domain = nil
35
- end
36
-
37
- def valid_for?(challenge_response)
38
- return false unless challenge_response.header['WWW-Authenticate']
39
-
40
- !challenge_response.header['WWW-Authenticate'].grep(/^\s*basic/i).find do |a_challenge|
41
- @realm.downcase == /realm="([^"]+)"/i.match(a_challenge)[1].downcase
42
- end.nil?
43
- end
44
-
45
- def update_credentials(challenge)
46
- @domain = Addressable::URI.parse(challenge.uri).host
47
- end
48
-
49
- def can_handle?(request)
50
- Addressable::URI.parse(request.uri).host == @domain
51
- end
52
-
53
- def add_credentials_to(request)
54
- request.header['Authorization'] = credentials
55
- end
56
-
57
- def credentials
58
- HTTPAuth::Basic.pack_authorization(@username, @password)
59
- end
60
-
61
- end
62
-
63
- class DigestAuthenticator
64
-
65
- attr_reader :username, :password, :realm, :domain, :challenge
66
-
67
- def initialize(realm, username, password)
68
- @realm = realm
69
- @username, @password = username, password
70
- @domain = nil
71
- end
72
-
73
- def update_credentials(challenge_response)
74
- @domain = Addressable::URI.parse(challenge_response.uri).host
75
- @challenge = HTTPAuth::Digest::Challenge.from_header(challenge_response.header['WWW-Authenticate'].first)
76
- end
77
-
78
- def valid_for?(challenge_response)
79
- return false unless challenge_header = challenge_response.header['WWW-Authenticate']
80
- begin
81
- challenge = HTTPAuth::Digest::Challenge.from_header(challenge_header.first)
82
- rescue HTTPAuth::UnwellformedHeader
83
- return false
84
- end
85
- challenge.realm == @realm
86
- end
87
-
88
- def can_handle?(request)
89
- Addressable::URI.parse(request.uri).host == @domain
90
- end
91
-
92
- def add_credentials_to(request)
93
- request.header['Authorization'] = credentials_for(request)
94
- end
95
-
96
- def credentials_for(request)
97
- HTTPAuth::Digest::Credentials.from_challenge(@challenge,
98
- :username => @username,
99
- :password => @password,
100
- :method => request.method.to_s.upcase,
101
- :uri => ::URI.parse(request.uri).request_uri).to_header
102
- end
103
-
104
- end
105
-
106
-
107
- end
108
-
@@ -1,240 +0,0 @@
1
- require 'resourceful/header'
2
- require 'digest/md5'
3
-
4
- module Resourceful
5
-
6
- class AbstractCacheManager
7
- def initialize
8
- raise NotImplementedError,
9
- "Use one of CacheManager's child classes instead. Try NullCacheManager if you don't want any caching at all."
10
- end
11
-
12
- # Finds a previously cached response to the provided request. The
13
- # response returned may be stale.
14
- #
15
- # @param [Resourceful::Request] request
16
- # The request for which we are looking for a response.
17
- #
18
- # @return [Resourceful::Response]
19
- # A (possibly stale) response for the request provided.
20
- def lookup(request); end
21
-
22
- # Store a response in the cache.
23
- #
24
- # This method is smart enough to not store responses that cannot be
25
- # cached (Vary: * or Cache-Control: no-cache, private, ...)
26
- #
27
- # @param request<Resourceful::Request>
28
- # The request used to obtain the response. This is needed so the
29
- # values from the response's Vary header can be stored.
30
- # @param response<Resourceful::Response>
31
- # The response to be stored.
32
- def store(request, response); end
33
-
34
- # Invalidates a all cached entries for a uri.
35
- #
36
- # This is used, for example, to invalidate the cache for a resource
37
- # that gets POSTed to.
38
- #
39
- # @param uri<String>
40
- # The uri of the resource to be invalidated
41
- def invalidate(uri); end
42
-
43
- protected
44
-
45
- # Returns an alphanumeric hash of a URI
46
- def uri_hash(uri)
47
- Digest::MD5.hexdigest(uri)
48
- end
49
- end
50
-
51
- # This is the default cache, and does not do any caching. All lookups
52
- # result in nil, and all attempts to store a response are a no-op.
53
- class NullCacheManager < AbstractCacheManager
54
- def initialize; end
55
-
56
- def lookup(request)
57
- nil
58
- end
59
-
60
- def store(request, response); end
61
- end
62
-
63
- # This is a nieve implementation of caching. Unused entries are never
64
- # removed, and this may eventually eat up all your memory and cause your
65
- # machine to explode.
66
- class InMemoryCacheManager < AbstractCacheManager
67
-
68
- def initialize
69
- @collection = Hash.new{ |h,k| h[k] = CacheEntryCollection.new}
70
- end
71
-
72
- def lookup(request)
73
- response = @collection[request.uri.to_s][request]
74
- response.authoritative = false if response
75
- response
76
- end
77
-
78
- def store(request, response)
79
- return unless response.cacheable?
80
-
81
- @collection[request.uri.to_s][request] = response
82
- end
83
-
84
- def invalidate(uri)
85
- @collection.delete(uri)
86
- end
87
- end # class InMemoryCacheManager
88
-
89
- # Stores cache entries in a directory on the filesystem. Similarly to the
90
- # InMemoryCacheManager there are no limits on storage, so this will eventually
91
- # eat up all your disk!
92
- class FileCacheManager < AbstractCacheManager
93
- # Create a new FileCacheManager
94
- #
95
- # @param [String] location
96
- # A directory on the filesystem to store cache entries. This directory
97
- # will be created if it doesn't exist
98
- def initialize(location="/tmp/resourceful")
99
- require 'fileutils'
100
- require 'yaml'
101
- @dir = FileUtils.mkdir_p(location)
102
- end
103
-
104
- def lookup(request)
105
- response = cache_entries_for(request)[request]
106
- response.authoritative = false if response
107
- response
108
- end
109
-
110
- def store(request, response)
111
- return unless response.cacheable?
112
-
113
- entries = cache_entries_for(request)
114
- entries[request] = response
115
- File.open(cache_file(request.uri), "w") {|fh| fh.write( YAML.dump(entries) ) }
116
- end
117
-
118
- def invalidate(uri);
119
- File.unlink(cache_file(uri));
120
- end
121
-
122
- private
123
-
124
- def cache_entries_for(request)
125
- if File.readable?( cache_file(request.uri) )
126
- YAML.load_file( cache_file(request.uri) )
127
- else
128
- Resourceful::CacheEntryCollection.new
129
- end
130
- end
131
-
132
- def cache_file(uri)
133
- "#{@dir}/#{uri_hash(uri)}"
134
- end
135
- end # class FileCacheManager
136
-
137
-
138
- # The collection of cached entries. Nominally all the entry in a
139
- # collection of this sort will be for the same resource but that is
140
- # not required to be true.
141
- class CacheEntryCollection
142
- include Enumerable
143
-
144
- def initialize
145
- @entries = []
146
- end
147
-
148
- # Iterates over the entries. Needed for Enumerable
149
- def each(&block)
150
- @entries.each(&block)
151
- end
152
-
153
- # Looks of a Entry that could fullfil the request. Returns nil if none
154
- # was found.
155
- #
156
- # @param [Resourceful::Request] request
157
- # The request to use for the lookup.
158
- #
159
- # @return [Resourceful::Response]
160
- # The cached response for the specified request if one is available.
161
- def [](request)
162
- entry = find { |entry| entry.valid_for?(request) }
163
- entry.response if entry
164
- end
165
-
166
- # Saves an entry into the collection. Replaces any existing ones that could
167
- # be used with the updated response.
168
- #
169
- # @param [Resourceful::Request] request
170
- # The request that was used to obtain the response
171
- # @param [Resourceful::Response] response
172
- # The cache_entry generated from response that was obtained.
173
- def []=(request, response)
174
- @entries.delete_if { |e| e.valid_for?(request) }
175
- @entries << CacheEntry.new(request, response)
176
-
177
- response
178
- end
179
- end # class CacheEntryCollection
180
-
181
- # Represents a previous request and cached response with enough
182
- # detail to determine construct a cached response to a matching
183
- # request in the future. It also understands what a matching
184
- # request means.
185
- class CacheEntry
186
- # request_vary_headers is a HttpHeader with keys from the Vary
187
- # header of the response, plus the values from the matching fields
188
- # in the request
189
- attr_reader :request_vary_headers
190
-
191
- # The time at which the client believes the request was made.
192
- attr_reader :request_time
193
-
194
- # The URI of the request
195
- attr_reader :request_uri
196
-
197
- # The response to that we are caching
198
- attr_reader :response
199
-
200
- # @param [Resourceful::Request] request
201
- # The request whose response we are storing in the cache.
202
- # @param response<Resourceful::Response>
203
- # The Response obhect to be stored.
204
- def initialize(request, response)
205
- @request_uri = request.uri
206
- @request_time = request.request_time
207
- @request_vary_headers = select_request_headers(request, response)
208
- @response = response
209
- end
210
-
211
- # Returns true if this entry may be used to fullfil the given request,
212
- # according to the vary headers.
213
- #
214
- # @param request<Resourceful::Request>
215
- # The request to do the lookup on.
216
- def valid_for?(request)
217
- request.uri == @request_uri and
218
- @request_vary_headers.all? {|key, value| request.header[key] == value}
219
- end
220
-
221
- # Selects the headers from the request named by the response's Vary header
222
- # http://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html#sec13.5.6
223
- #
224
- # @param [Resourceful::Request] request
225
- # The request used to obtain the response.
226
- # @param [Resourceful::Response] response
227
- # The response obtained from the request.
228
- def select_request_headers(request, response)
229
- header = Resourceful::Header.new
230
-
231
- response.header['Vary'].each do |name|
232
- header[name] = request.header[name]
233
- end if response.header['Vary']
234
-
235
- header
236
- end
237
-
238
- end # class CacheEntry
239
-
240
- end