almodovar 0.1.0 → 0.1.2

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 (31) hide show
  1. data/vendor/resourceful-0.5.3-patched/MIT-LICENSE +21 -0
  2. data/vendor/resourceful-0.5.3-patched/Manifest +29 -0
  3. data/vendor/resourceful-0.5.3-patched/README.markdown +84 -0
  4. data/vendor/resourceful-0.5.3-patched/Rakefile +71 -0
  5. data/vendor/resourceful-0.5.3-patched/lib/resourceful.rb +18 -0
  6. data/vendor/resourceful-0.5.3-patched/lib/resourceful/authentication_manager.rb +108 -0
  7. data/vendor/resourceful-0.5.3-patched/lib/resourceful/cache_manager.rb +240 -0
  8. data/vendor/resourceful-0.5.3-patched/lib/resourceful/exceptions.rb +34 -0
  9. data/vendor/resourceful-0.5.3-patched/lib/resourceful/header.rb +126 -0
  10. data/vendor/resourceful-0.5.3-patched/lib/resourceful/http_accessor.rb +98 -0
  11. data/vendor/resourceful-0.5.3-patched/lib/resourceful/memcache_cache_manager.rb +75 -0
  12. data/vendor/resourceful-0.5.3-patched/lib/resourceful/net_http_adapter.rb +70 -0
  13. data/vendor/resourceful-0.5.3-patched/lib/resourceful/options_interpreter.rb +78 -0
  14. data/vendor/resourceful-0.5.3-patched/lib/resourceful/request.rb +230 -0
  15. data/vendor/resourceful-0.5.3-patched/lib/resourceful/resource.rb +163 -0
  16. data/vendor/resourceful-0.5.3-patched/lib/resourceful/response.rb +221 -0
  17. data/vendor/resourceful-0.5.3-patched/lib/resourceful/stubbed_resource_proxy.rb +47 -0
  18. data/vendor/resourceful-0.5.3-patched/lib/resourceful/util.rb +6 -0
  19. data/vendor/resourceful-0.5.3-patched/resourceful.gemspec +48 -0
  20. data/vendor/resourceful-0.5.3-patched/spec/acceptance/authorization_spec.rb +16 -0
  21. data/vendor/resourceful-0.5.3-patched/spec/acceptance/caching_spec.rb +192 -0
  22. data/vendor/resourceful-0.5.3-patched/spec/acceptance/header_spec.rb +24 -0
  23. data/vendor/resourceful-0.5.3-patched/spec/acceptance/redirecting_spec.rb +12 -0
  24. data/vendor/resourceful-0.5.3-patched/spec/acceptance/resource_spec.rb +84 -0
  25. data/vendor/resourceful-0.5.3-patched/spec/acceptance_shared_specs.rb +44 -0
  26. data/vendor/resourceful-0.5.3-patched/spec/old_acceptance_specs.rb +378 -0
  27. data/vendor/resourceful-0.5.3-patched/spec/simple_sinatra_server.rb +74 -0
  28. data/vendor/resourceful-0.5.3-patched/spec/simple_sinatra_server_spec.rb +98 -0
  29. data/vendor/resourceful-0.5.3-patched/spec/spec.opts +3 -0
  30. data/vendor/resourceful-0.5.3-patched/spec/spec_helper.rb +28 -0
  31. metadata +32 -2
@@ -0,0 +1,21 @@
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.
@@ -0,0 +1,29 @@
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
@@ -0,0 +1,84 @@
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
+
@@ -0,0 +1,71 @@
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
@@ -0,0 +1,18 @@
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
@@ -0,0 +1,108 @@
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
+
@@ -0,0 +1,240 @@
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