paul-resourceful 0.2.3 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.markdown CHANGED
@@ -37,8 +37,8 @@ Simplest example
37
37
  Get a page requiring HTTP Authentication
38
38
  ----------------------------------------
39
39
 
40
- basic_handler = Resourceful::BasicAuthenticator.new('My Realm', 'admin', 'secret')
41
- http.auth_manager.add_auth_hander(basic_handler)
40
+ my_realm_authenticator = Resourceful::BasicAuthenticator.new('My Realm', 'admin', 'secret')
41
+ http = Resourceful::HttpAccessor.new(:authenticator => my_realm_authenticator)
42
42
  resp = http.resource('http://example.com/').get
43
43
  puts resp.body
44
44
 
@@ -53,8 +53,6 @@ callback. If the callback evaluates to true, it will follow the redirect.
53
53
  resource.on_redirect { |req, resp| resp.header['Location'] =~ /example.com/ }
54
54
  resource.get # Will only follow the redirect if the new location is example.com
55
55
 
56
-
57
-
58
56
  Post a URL encoded form
59
57
  -----------------------
60
58
 
@@ -82,5 +80,5 @@ Delete a resource
82
80
  Copyright
83
81
  ---------
84
82
 
85
- Copyright (c) 2008 Absolute Performance, Inc, Peter Williams; released under the MIT License.
83
+ Copyright (c) 2008 Absolute Performance, Inc, Peter Williams. Released under the MIT License.
86
84
 
data/Rakefile CHANGED
@@ -1,14 +1,41 @@
1
- # -*- ruby -*-
2
-
3
1
  require 'rubygems'
4
- require 'hoe'
5
- require './lib/resourceful.rb'
2
+ require 'rake'
3
+ require 'echoe'
4
+
5
+ Echoe.new('resourceful', '0.3.0') do |p|
6
+ p.description = "An HTTP library for Ruby that takes advantage of everything HTTP has to offer."
7
+ p.url = "http://github.com/paul/resourceful"
8
+ p.author = "Paul Sadauskas"
9
+ p.email = "psadauskas@gmail.com"
10
+
11
+ p.ignore_pattern = ["pkg/*", "tmp/*"]
12
+ p.dependencies = ['addressable', 'httpauth', 'rspec', 'facets', 'andand']
13
+ p.development_dependencies = ['thin', 'yard']
14
+ end
15
+
16
+ require 'spec/rake/spectask'
6
17
 
7
- Hoe.new('resourceful', Resourceful::VERSION) do |p|
8
- p.rubyforge_name = 'resourceful' # if different than lowercase project name
9
- p.developer('Paul Sadauskas', 'psadauskas@gmail.com')
10
- p.developer('Peter Williams', 'pezra@barelyenough.org')
11
- p.summary = "An HTTP library for Ruby that takes advantage of everything HTTP has to offer."
18
+ desc 'Run all specs'
19
+ Spec::Rake::SpecTask.new(:spec) do |t|
20
+ t.spec_opts << '--options' << 'spec/spec.opts' if File.exists?('spec/spec.opts')
21
+ t.libs << 'lib'
22
+ t.spec_files = FileList['spec/**/*_spec.rb']
12
23
  end
13
24
 
14
- # vim: syntax=Ruby
25
+ desc 'Default: Run Specs'
26
+ task :default => :spec
27
+
28
+ desc 'Run all tests'
29
+ task :test => :spec
30
+
31
+ require 'yard'
32
+
33
+ desc "Generate Yardoc"
34
+ YARD::Rake::YardocTask.new do |t|
35
+ t.files = ['lib/**/*.rb', 'README.markdown']
36
+ end
37
+
38
+ desc "Update rubyforge documentation"
39
+ task :update_docs => :yardoc do
40
+ puts %x{rsync -aPz doc/* psadauskas@resourceful.rubyforge.org:/var/www/gforge-projects/resourceful/}
41
+ end
@@ -1,20 +1,24 @@
1
1
  require 'resourceful/header'
2
+ require 'andand'
2
3
 
3
4
  module Resourceful
4
5
 
5
- class CacheManager
6
+ class AbstractCacheManager
6
7
  def initialize
7
8
  raise NotImplementedError,
8
9
  "Use one of CacheManager's child classes instead. Try NullCacheManager if you don't want any caching at all."
9
10
  end
10
11
 
11
- # Search for a cached representation that can be used to fulfill the
12
- # the given request. If none are found, returns nil.
12
+ # Finds a previously cached response to the provided request. The
13
+ # response returned may be stale.
13
14
  #
14
- # @param request<Resourceful::Request>
15
- # The request to use for searching.
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.
16
20
  def lookup(request); end
17
-
21
+
18
22
  # Store a response in the cache.
19
23
  #
20
24
  # This method is smart enough to not store responses that cannot be
@@ -35,29 +39,11 @@ module Resourceful
35
39
  # @param uri<String>
36
40
  # The uri of the resource to be invalidated
37
41
  def invalidate(uri); end
38
-
39
- # Selects the headers from the request named by the response's Vary header
40
- # http://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html#sec13.5.6
41
- #
42
- # @param request<Resourceful::Request>
43
- # The request used to obtain the response.
44
- # @param response<Resourceful::Response>
45
- # The response obtained from the request.
46
- def select_request_headers(request, response)
47
- header = Resourceful::Header.new
48
-
49
- response.header['Vary'].first.split(',').each do |name|
50
- name.strip!
51
- header[name] = request.header[name]
52
- end if response.header['Vary']
53
-
54
- header
55
- end
56
42
  end
57
43
 
58
44
  # This is the default cache, and does not do any caching. All lookups
59
45
  # result in nil, and all attempts to store a response are a no-op.
60
- class NullCacheManager < CacheManager
46
+ class NullCacheManager < AbstractCacheManager
61
47
  def initialize; end
62
48
 
63
49
  def lookup(request)
@@ -70,105 +56,128 @@ module Resourceful
70
56
  # This is a nieve implementation of caching. Unused entries are never
71
57
  # removed, and this may eventually eat up all your memory and cause your
72
58
  # machine to explode.
73
- class InMemoryCacheManager < CacheManager
59
+ class InMemoryCacheManager < AbstractCacheManager
74
60
 
75
61
  def initialize
76
62
  @collection = Hash.new{ |h,k| h[k] = CacheEntryCollection.new}
77
63
  end
78
64
 
79
65
  def lookup(request)
80
- entry = @collection[request.uri.to_s][request]
81
- response = entry.response if entry
82
- response.authoritative = false if response
83
-
84
- response
66
+ returning(@collection[request.uri.to_s][request]) do |response|
67
+ response.authoritative = false if response
68
+ end
85
69
  end
86
70
 
87
71
  def store(request, response)
88
72
  return unless response.cachable?
89
73
 
90
- entry = CacheEntry.new(request.request_time,
91
- select_request_headers(request, response),
92
- response)
93
-
94
- @collection[request.uri.to_s][request] = entry
74
+ @collection[request.uri.to_s][request] = response
95
75
  end
96
76
 
97
77
  def invalidate(uri)
98
78
  @collection.delete(uri)
99
79
  end
80
+ end # class InMemoryCacheManager
81
+
82
+ # The collection of cached entries. Nominally all the entry in a
83
+ # collection of this sort will be for the same resource but that is
84
+ # not required to be true.
85
+ class CacheEntryCollection
86
+ include Enumerable
87
+
88
+ def initialize
89
+ @entries = []
90
+ end
91
+
92
+ # Iterates over the entries. Needed for Enumerable
93
+ def each(&block)
94
+ @entries.each(&block)
95
+ end
96
+
97
+ # Looks of a Entry that could fullfil the request. Returns nil if none
98
+ # was found.
99
+ #
100
+ # @param [Resourceful::Request] request
101
+ # The request to use for the lookup.
102
+ #
103
+ # @return [Resourceful::Response]
104
+ # The cached response for the specified request if one is available.
105
+ def [](request)
106
+ find { |an_entry| an_entry.valid_for?(request) }.andand.response
107
+ end
108
+
109
+ # Saves an entry into the collection. Replaces any existing ones that could
110
+ # be used with the updated response.
111
+ #
112
+ # @param [Resourceful::Request] request
113
+ # The request that was used to obtain the response
114
+ # @param [Resourceful::Response] response
115
+ # The cache_entry generated from response that was obtained.
116
+ def []=(request, response)
117
+ @entries.delete_if { |e| e.valid_for?(request) }
118
+ @entries << CacheEntry.new(request, response)
119
+
120
+ response
121
+ end
122
+ end # class CacheEntryCollection
123
+
124
+ # Represents a previous request and cached response with enough
125
+ # detail to determine construct a cached response to a matching
126
+ # request in the future. It also understands what a matching
127
+ # request means.
128
+ class CacheEntry
129
+ # request_vary_headers is a HttpHeader with keys from the Vary
130
+ # header of the response, plus the values from the matching fields
131
+ # in the request
132
+ attr_reader :request_vary_headers
133
+
134
+ # The time at which the client believes the request was made.
135
+ attr_reader :request_time
136
+
137
+ # The URI of the request
138
+ attr_reader :request_uri
139
+
140
+ # The response to that we are caching
141
+ attr_reader :response
142
+
143
+ # @param [Resourceful::Request] request
144
+ # The request whose response we are storing in the cache.
145
+ # @param response<Resourceful::Response>
146
+ # The Response obhect to be stored.
147
+ def initialize(request, response)
148
+ @request_uri = request.uri
149
+ @request_time = request.request_time
150
+ @request_vary_headers = select_request_headers(request, response)
151
+ @response = response
152
+ end
100
153
 
101
- # The collection of all cached entries for a single resource (uri).
102
- class CacheEntryCollection
103
- include Enumerable
104
-
105
- def initialize
106
- @entries = []
107
- end
108
-
109
- # Iterates over the entries. Needed for Enumerable
110
- def each(&block)
111
- @entries.each(&block)
112
- end
113
-
114
- # Looks of a Entry that could fullfil the request. Returns nil if none
115
- # was found.
116
- #
117
- # @param request<Resourceful::Request>
118
- # The request to use for the lookup.
119
- def [](request)
120
- self.each do |entry|
121
- return entry if entry.valid_for?(request)
122
- end
123
- return nil
124
- end
125
-
126
- # Saves an entry into the collection. Replaces any existing ones that could
127
- # be used with the updated response.
128
- #
129
- # @param request<Resourceful::Request>
130
- # The request that was used to obtain the response
131
- # @param cache_entry<CacheEntry>
132
- # The cache_entry generated from response that was obtained.
133
- def []=(request, cache_entry)
134
- @entries.delete_if { |e| e.valid_for?(request) }
135
- @entries.unshift cache_entry
136
- end
154
+ # Returns true if this entry may be used to fullfil the given request,
155
+ # according to the vary headers.
156
+ #
157
+ # @param request<Resourceful::Request>
158
+ # The request to do the lookup on.
159
+ def valid_for?(request)
160
+ request.uri == @request_uri and
161
+ @request_vary_headers.all? {|key, value| request.header[key] == value}
162
+ end
137
163
 
138
- end # class CacheEntryCollection
139
-
140
- # Contains everything we need to know to build a response for a request using the
141
- # stored request.
142
- class CacheEntry
143
- # request_vary_headers is a HttpHeader with keys from the
144
- # Vary header of the response, plus the values from the matching
145
- # fields in the request
146
- attr_accessor :request_time, :request_vary_headers, :response
147
-
148
- # @param request_time<Time>
149
- # Client-generated timestamp for when the request was made
150
- # @param request_vary_headers<Resourceful::HttpHeader>
151
- # A HttpHeader constructed from the keys listed in the vary headers
152
- # of the response, and values obtained from those headers in the request
153
- # @param response<Resourceful::Response>
154
- # The Response obhect to be stored.
155
- def initialize(request_time, request_vary_headers, response)
156
- @request_time, @request_vary_headers, @response = request_time, request_vary_headers, response
157
- end
164
+ # Selects the headers from the request named by the response's Vary header
165
+ # http://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html#sec13.5.6
166
+ #
167
+ # @param [Resourceful::Request] request
168
+ # The request used to obtain the response.
169
+ # @param [Resourceful::Response] response
170
+ # The response obtained from the request.
171
+ def select_request_headers(request, response)
172
+ header = Resourceful::Header.new
158
173
 
159
- # Returns true if this entry may be used to fullfil the given request,
160
- # according to the vary headers.
161
- #
162
- # @param request<Resourceful::Request>
163
- # The request to do the lookup on.
164
- def valid_for?(request)
165
- @request_vary_headers.all? do |key, value|
166
- request.header[key] == value
167
- end
168
- end
174
+ response.header['Vary'].each do |name|
175
+ header[name] = request.header[name]
176
+ end if response.header['Vary']
169
177
 
170
- end # class CacheEntry
178
+ header
179
+ end
171
180
 
172
- end # class InMemoryCacheManager
181
+ end # class CacheEntry
173
182
 
174
183
  end
@@ -40,13 +40,14 @@ module Resourceful
40
40
  attr_accessor :logger, :cache_manager
41
41
 
42
42
  attr_reader :auth_manager
43
-
44
43
  attr_reader :user_agent_tokens
45
44
 
46
45
  INIT_OPTIONS = OptionsInterpreter.new do
47
46
  option(:logger, :default => Resourceful::BitBucketLogger.new)
48
47
  option(:user_agent, :default => []) {|ua| [ua].flatten}
49
48
  option(:cache_manager, :default => NullCacheManager.new)
49
+ option(:authenticator)
50
+ option(:authenticators, :default => [])
50
51
  end
51
52
 
52
53
  # Initializes a new HttpAccessor. Valid options:
@@ -56,6 +57,13 @@ module Resourceful
56
57
  #
57
58
  # +:user_agent+:: One or more additional user agent tokens to
58
59
  # added to the user agent string.
60
+ #
61
+ # +:cache_manager+:: The cache manager this accessor should use.
62
+ #
63
+ # +:authenticator+:: Add a single authenticator for this accessor.
64
+ #
65
+ # +:authenticators+:: Enumerable of the authenticators for this
66
+ # accessor.
59
67
  def initialize(options = {})
60
68
  @user_agent_tokens = [RESOURCEFUL_USER_AGENT_TOKEN]
61
69
 
@@ -64,6 +72,9 @@ module Resourceful
64
72
  self.logger = opts[:logger]
65
73
  @auth_manager = AuthenticationManager.new()
66
74
  @cache_manager = opts[:cache_manager]
75
+
76
+ add_authenticator(opts[:authenticator]) if opts[:authenticator]
77
+ opts[:authenticators].each { |a| add_authenticator(a) }
67
78
  end
68
79
  end
69
80
 
@@ -81,5 +92,9 @@ module Resourceful
81
92
  end
82
93
  alias [] resource
83
94
 
95
+ # Adds an Authenticator to the set used by the accessor.
96
+ def add_authenticator(an_authenticator)
97
+ auth_manager.add_auth_handler(an_authenticator)
98
+ end
84
99
  end
85
100
  end
@@ -0,0 +1,85 @@
1
+ require File.dirname(__FILE__) + "/cache_manager"
2
+
3
+ require 'memcache'
4
+ require 'facets/kernel/returning'
5
+
6
+ module Resourceful
7
+ class MemcacheCacheManager < AbstractCacheManager
8
+
9
+ # Create a new Memcached backed cache manager
10
+ #
11
+ # @param [*String] memcache_servers
12
+ # list of all Memcached servers this cache manager should use.
13
+ def initialize(*memcache_servers)
14
+ @memcache = MemCache.new(memcache_servers, :multithread => true)
15
+ end
16
+
17
+ # Finds a previously cached response to the provided request. The
18
+ # response returned may be stale.
19
+ #
20
+ # @param [Resourceful::Request] request
21
+ # The request for which we are looking for a response.
22
+ #
23
+ # @return [Resourceful::Response, nil]
24
+ # A (possibly stale) response for the request provided or nil if
25
+ # no matching response is found.
26
+ def lookup(request)
27
+ resp = cache_entries_for(request)[request]
28
+ return if resp.nil?
29
+
30
+ resp.authoritative = false
31
+
32
+ resp
33
+ end
34
+
35
+ # Store a response in the cache.
36
+ #
37
+ # This method is smart enough to not store responses that cannot be
38
+ # cached (Vary: * or Cache-Control: no-cache, private, ...)
39
+ #
40
+ # @param [Resourceful::Request] request
41
+ # The request used to obtain the response. This is needed so the
42
+ # values from the response's Vary header can be stored.
43
+ # @param [Resourceful::Response] response
44
+ # The response to be stored.
45
+ def store(request, response)
46
+ return unless response.cachable?
47
+
48
+ @memcache[request.to_mc_key] = returning(cache_entries_for(request)) do |entries|
49
+ entries[request] = response
50
+ end
51
+ end
52
+
53
+ # Invalidates a all cached entries for a uri.
54
+ #
55
+ # This is used, for example, to invalidate the cache for a resource
56
+ # that gets POSTed to.
57
+ #
58
+ # @param [String] uri
59
+ # The uri of the resource to be invalidated
60
+ def invalidate(uri)
61
+ @memcache.delete(Digest::MD5.hexdigest(uri))
62
+ end
63
+
64
+
65
+ private
66
+
67
+ ##
68
+ # The memcache proxy.
69
+ attr_reader :memcache
70
+
71
+ def cache_entries_for(a_request)
72
+ @memcache.get(a_request.to_mc_key) || Resourceful::CacheEntryCollection.new
73
+ end
74
+ end
75
+
76
+ module MemCacheKey
77
+ def to_mc_key
78
+ Digest::MD5.hexdigest(uri)
79
+ end
80
+ end
81
+
82
+ class Request
83
+ include MemCacheKey
84
+ end
85
+ end
@@ -12,6 +12,11 @@ module Resourceful
12
12
  attr_accessor :method, :resource, :body, :header
13
13
  attr_reader :request_time
14
14
 
15
+ # @param [Symbol] http_method
16
+ # :get, :put, :post, :delete or :head
17
+ # @param [Resourceful::Resource] resource
18
+ # @param [String] body
19
+ # @param [Resourceful::Header, Hash] header
15
20
  def initialize(http_method, resource, body = nil, header = nil)
16
21
  @method, @resource, @body = http_method, resource, body
17
22
  @header = header.is_a?(Resourceful::Header) ? header : Resourceful::Header.new(header || {})
@@ -50,6 +55,7 @@ module Resourceful
50
55
  @header['Cache-Control'] = 'max-age=0' if response.header.has_key?('Cache-Control') and response.header['Cache-Control'].include?('must-revalidate')
51
56
  end
52
57
 
58
+ # @return [String] The URI against which this request will be, or was, made.
53
59
  def uri
54
60
  resource.uri
55
61
  end
data/lib/resourceful.rb CHANGED
@@ -4,7 +4,6 @@ require 'resourceful/util'
4
4
 
5
5
  # Resourceful is a library that provides a high level HTTP interface.
6
6
  module Resourceful
7
- VERSION = "0.2.3"
8
7
 
9
8
  HOP_BY_HOP_HEADERS = %w{
10
9
  Connection
data/resourceful.gemspec CHANGED
@@ -1,15 +1,19 @@
1
+ # -*- encoding: utf-8 -*-
2
+
1
3
  Gem::Specification.new do |s|
2
4
  s.name = %q{resourceful}
3
- s.version = "0.2.3"
5
+ s.version = "0.3.0"
4
6
 
5
- s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
6
- s.authors = ["Paul Sadauskas", "Peter Williams"]
7
- s.date = %q{2008-11-22}
8
- s.email = ["psadauskas@gmail.com", "pezra@barelyenough.org"]
9
- s.extra_rdoc_files = ["Manifest.txt"]
10
- s.files = ["MIT-LICENSE", "Manifest.txt", "README.markdown", "Rakefile", "lib/resourceful.rb", "lib/resourceful/authentication_manager.rb", "lib/resourceful/cache_manager.rb", "lib/resourceful/header.rb", "lib/resourceful/http_accessor.rb", "lib/resourceful/net_http_adapter.rb", "lib/resourceful/options_interpreter.rb", "lib/resourceful/request.rb", "lib/resourceful/resource.rb", "lib/resourceful/response.rb", "lib/resourceful/stubbed_resource_proxy.rb", "lib/resourceful/util.rb", "lib/resourceful/version.rb", "resourceful.gemspec", "spec/acceptance_shared_specs.rb", "spec/acceptance_spec.rb", "spec/resourceful/authentication_manager_spec.rb", "spec/resourceful/cache_manager_spec.rb", "spec/resourceful/header_spec.rb", "spec/resourceful/http_accessor_spec.rb", "spec/resourceful/net_http_adapter_spec.rb", "spec/resourceful/options_interpreter_spec.rb", "spec/resourceful/request_spec.rb", "spec/resourceful/resource_spec.rb", "spec/resourceful/response_spec.rb", "spec/resourceful/stubbed_resource_proxy_spec.rb", "spec/simple_http_server_shared_spec.rb", "spec/simple_http_server_shared_spec_spec.rb", "spec/spec.opts", "spec/spec_helper.rb"]
7
+ s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
8
+ s.authors = ["Paul Sadauskas"]
9
+ s.date = %q{2008-12-05}
10
+ s.description = %q{An HTTP library for Ruby that takes advantage of everything HTTP has to offer.}
11
+ s.email = %q{psadauskas@gmail.com}
12
+ s.extra_rdoc_files = ["lib/resourceful.rb", "lib/resourceful/authentication_manager.rb", "lib/resourceful/util.rb", "lib/resourceful/resource.rb", "lib/resourceful/memcache_cache_manager.rb", "lib/resourceful/net_http_adapter.rb", "lib/resourceful/http_accessor.rb", "lib/resourceful/stubbed_resource_proxy.rb", "lib/resourceful/header.rb", "lib/resourceful/cache_manager.rb", "lib/resourceful/options_interpreter.rb", "lib/resourceful/response.rb", "lib/resourceful/request.rb", "README.markdown"]
13
+ s.files = ["lib/resourceful.rb", "lib/resourceful/authentication_manager.rb", "lib/resourceful/util.rb", "lib/resourceful/resource.rb", "lib/resourceful/memcache_cache_manager.rb", "lib/resourceful/net_http_adapter.rb", "lib/resourceful/http_accessor.rb", "lib/resourceful/stubbed_resource_proxy.rb", "lib/resourceful/header.rb", "lib/resourceful/cache_manager.rb", "lib/resourceful/options_interpreter.rb", "lib/resourceful/response.rb", "lib/resourceful/request.rb", "spec/acceptance_shared_specs.rb", "spec/spec.opts", "spec/acceptance_spec.rb", "spec/simple_http_server_shared_spec_spec.rb", "spec/spec_helper.rb", "spec/resourceful/header_spec.rb", "spec/resourceful/authentication_manager_spec.rb", "spec/resourceful/memcache_cache_manager_spec.rb", "spec/resourceful/response_spec.rb", "spec/resourceful/options_interpreter_spec.rb", "spec/resourceful/http_accessor_spec.rb", "spec/resourceful/stubbed_resource_proxy_spec.rb", "spec/resourceful/request_spec.rb", "spec/resourceful/resource_spec.rb", "spec/resourceful/cache_manager_spec.rb", "spec/resourceful/net_http_adapter_spec.rb", "spec/simple_http_server_shared_spec.rb", "Manifest", "Rakefile", "README.markdown", "MIT-LICENSE", "resourceful.gemspec"]
11
14
  s.has_rdoc = true
12
- s.rdoc_options = ["--main", "README.txt"]
15
+ s.homepage = %q{http://github.com/paul/resourceful}
16
+ s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Resourceful", "--main", "README.markdown"]
13
17
  s.require_paths = ["lib"]
14
18
  s.rubyforge_project = %q{resourceful}
15
19
  s.rubygems_version = %q{1.3.1}
@@ -20,11 +24,29 @@ Gem::Specification.new do |s|
20
24
  s.specification_version = 2
21
25
 
22
26
  if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
23
- s.add_development_dependency(%q<hoe>, [">= 1.8.2"])
27
+ s.add_runtime_dependency(%q<addressable>, [">= 0"])
28
+ s.add_runtime_dependency(%q<httpauth>, [">= 0"])
29
+ s.add_runtime_dependency(%q<rspec>, [">= 0"])
30
+ s.add_runtime_dependency(%q<facets>, [">= 0"])
31
+ s.add_runtime_dependency(%q<andand>, [">= 0"])
32
+ s.add_development_dependency(%q<thin>, [">= 0"])
33
+ s.add_development_dependency(%q<yard>, [">= 0"])
24
34
  else
25
- s.add_dependency(%q<hoe>, [">= 1.8.2"])
35
+ s.add_dependency(%q<addressable>, [">= 0"])
36
+ s.add_dependency(%q<httpauth>, [">= 0"])
37
+ s.add_dependency(%q<rspec>, [">= 0"])
38
+ s.add_dependency(%q<facets>, [">= 0"])
39
+ s.add_dependency(%q<andand>, [">= 0"])
40
+ s.add_dependency(%q<thin>, [">= 0"])
41
+ s.add_dependency(%q<yard>, [">= 0"])
26
42
  end
27
43
  else
28
- s.add_dependency(%q<hoe>, [">= 1.8.2"])
44
+ s.add_dependency(%q<addressable>, [">= 0"])
45
+ s.add_dependency(%q<httpauth>, [">= 0"])
46
+ s.add_dependency(%q<rspec>, [">= 0"])
47
+ s.add_dependency(%q<facets>, [">= 0"])
48
+ s.add_dependency(%q<andand>, [">= 0"])
49
+ s.add_dependency(%q<thin>, [">= 0"])
50
+ s.add_dependency(%q<yard>, [">= 0"])
29
51
  end
30
52
  end
@@ -2,8 +2,8 @@ require 'pathname'
2
2
  require Pathname(__FILE__).dirname + '../spec_helper'
3
3
 
4
4
  require 'resourceful/cache_manager'
5
-
6
- describe Resourceful::CacheManager do
5
+
6
+ describe Resourceful::AbstractCacheManager do
7
7
  before do
8
8
  @cm = Resourceful::InMemoryCacheManager.new #cheat, because I cant new a real one.
9
9
  end
@@ -19,40 +19,10 @@ describe Resourceful::CacheManager do
19
19
  it 'should have a store method' do
20
20
  @cm.should respond_to(:store)
21
21
  end
22
-
22
+
23
23
  it 'should have a invalidate method' do
24
24
  @cm.should respond_to(:invalidate)
25
25
  end
26
-
27
- describe '#select_request_headers' do
28
- before do
29
- @req_header = mock('header', :[] => nil)
30
- @request = mock('request', :header => @req_header)
31
-
32
- @resp_header = mock('header', :[] => nil)
33
- @response = mock('response', :header => @resp_header)
34
- end
35
-
36
- it 'should select the request headers from the Vary header' do
37
- @resp_header.should_receive(:[]).with('Vary')
38
- @cm.select_request_headers(@request, @response)
39
- end
40
-
41
- it 'should pull the values from the request that match keys in the vary header' do
42
- @resp_header.should_receive(:[]).with('Vary').twice.and_return(['foo, bar'])
43
- @req_header.should_receive(:[]).with('foo').and_return('oof')
44
- @req_header.should_receive(:[]).with('bar').and_return('rab')
45
-
46
- header = @cm.select_request_headers(@request, @response)
47
- header['foo'].should == 'oof'
48
- header['bar'].should == 'rab'
49
- end
50
-
51
- it 'should return a new Header object' do
52
- @cm.select_request_headers(@request, @response).should be_kind_of(Resourceful::Header)
53
- end
54
- end
55
-
56
26
  end
57
27
 
58
28
  describe Resourceful::NullCacheManager do
@@ -80,7 +50,7 @@ describe Resourceful::InMemoryCacheManager do
80
50
  @response = mock('response', :header => {}, :cachable? => true)
81
51
 
82
52
  @entry = mock('cache entry', :response => @response, :valid_for? => true)
83
- Resourceful::InMemoryCacheManager::CacheEntry.stub!(:new).and_return(@entry)
53
+ Resourceful::CacheEntry.stub!(:new).and_return(@entry)
84
54
 
85
55
  @imcm = Resourceful::InMemoryCacheManager.new
86
56
  end
@@ -88,7 +58,7 @@ describe Resourceful::InMemoryCacheManager do
88
58
  describe 'finding' do
89
59
  before do
90
60
  @response.stub!(:authoritative=)
91
- @imcm.instance_variable_set("@collection", {'uri' => {@request => @entry}})
61
+ @imcm.instance_variable_set("@collection", {'uri' => {@request => @response}})
92
62
  end
93
63
 
94
64
  it 'should lookup the response by request' do
@@ -103,9 +73,8 @@ describe Resourceful::InMemoryCacheManager do
103
73
 
104
74
  describe 'saving' do
105
75
  it 'should make a new cache entry' do
106
- Resourceful::InMemoryCacheManager::CacheEntry.should_receive(:new).with(
107
- Time.utc(2008,5,22,15,00),
108
- {},
76
+ Resourceful::CacheEntry.should_receive(:new).with(
77
+ @request,
109
78
  @response
110
79
  )
111
80
 
@@ -115,7 +84,7 @@ describe Resourceful::InMemoryCacheManager do
115
84
  it 'should store the response entity by request' do
116
85
  @imcm.store(@request, @response)
117
86
  col = @imcm.instance_variable_get("@collection")
118
- col['uri'][@request].response.should == @response
87
+ col['uri'][@request].should == @response
119
88
  end
120
89
 
121
90
  it 'should check if the response is cachable' do
@@ -142,20 +111,21 @@ describe Resourceful::InMemoryCacheManager do
142
111
 
143
112
  end
144
113
 
145
- describe Resourceful::InMemoryCacheManager::CacheEntryCollection do
114
+ describe Resourceful::CacheEntryCollection do
146
115
  before do
147
- @entry_valid = mock('entry', :valid_for? => true)
148
- @entry_invalid = mock('entry', :valid_for? => false)
116
+ @request = mock('request', :uri => 'this', :request_time => Time.now, :header => {})
117
+ @valid_resp = stub('valid_resp', :authoritative= => nil, :header => {})
149
118
 
150
- @request = mock('request')
119
+ @entry_valid = mock('entry', :valid_for? => true, :response => @valid_resp)
120
+ @entry_invalid = mock('entry', :valid_for? => false, :response => stub('invalid_resp'))
151
121
 
152
- @collection = Resourceful::InMemoryCacheManager::CacheEntryCollection.new
122
+ @collection = Resourceful::CacheEntryCollection.new
153
123
  end
154
124
 
155
125
  it 'should find the right entry for a request' do
156
126
  @collection.instance_variable_set('@entries', [@entry_valid, @entry_invalid])
157
127
  @entry_valid.should_receive(:valid_for?).with(@request).and_return(true)
158
- @collection[@request].should == @entry_valid
128
+ @collection[@request].should == @valid_resp
159
129
  end
160
130
 
161
131
  it 'should be nil if no matching entry was found' do
@@ -165,47 +135,89 @@ describe Resourceful::InMemoryCacheManager::CacheEntryCollection do
165
135
  end
166
136
 
167
137
  it 'should store an entry' do
168
- @collection[@request] = @entry_valid
169
- @collection.instance_variable_get("@entries").should include(@entry_valid)
138
+ @collection[@request] = @valid_resp
139
+ @collection.instance_variable_get("@entries").should have(1).items
170
140
  end
171
141
 
172
142
  it 'should replace an existing entry if the existing entry matches the request' do
173
- @new_entry = mock('entry', :valid_for? => true)
143
+ new_resp = stub('new_resp', :authoritative= => nil, :header => {})
174
144
 
175
- @collection[@request] = @entry_valid
176
- @collection[@request] = @new_entry
145
+ @collection[@request] = @valid_resp
146
+ @collection[@request] = new_resp
177
147
 
178
- @collection.instance_variable_get("@entries").should include(@new_entry)
179
- @collection.instance_variable_get("@entries").should_not include(@entry_valid)
148
+ @collection.instance_variable_get("@entries").map{|it| it.response}.should include(new_resp)
149
+ @collection.instance_variable_get("@entries").map{|it| it.response}.should_not include(@valid_resp)
180
150
  end
181
151
 
182
152
  end
183
153
 
184
- describe Resourceful::InMemoryCacheManager::CacheEntry do
154
+ describe Resourceful::CacheEntry do
185
155
  before do
186
- @entry = Resourceful::InMemoryCacheManager::CacheEntry.new(
187
- Time.utc(2008,5,16,0,0,0), {'Content-Type' => 'text/plain'}, mock('response')
156
+ @entry = Resourceful::CacheEntry.new(
157
+ mock('original_request', :header => {'Accept' => 'text/plain'} ,
158
+ :request_time => Time.utc(2008,5,16,0,0,0), :uri => 'http://foo.invalid'),
159
+ mock('response', :header => {'Vary' => 'Accept'})
188
160
  )
189
161
 
190
- @request = mock('request')
162
+ @request = mock('request', :uri => 'http://foo.invalid')
191
163
  end
192
164
 
193
- [:request_time, :request_vary_headers, :response, :valid_for?].each do |method|
194
- it "should respond to ##{method}" do
195
- @entry.should respond_to(method)
165
+ describe "#valid_for?(a_request)" do
166
+ it "should true for request to URI w/ matching header " do
167
+ @entry.valid_for?(mock("new_request",
168
+ :uri => 'http://foo.invalid',
169
+ :header => {'Accept' => 'text/plain'})).should be_true
170
+ end
171
+
172
+ it "should false for requests against different URIs even if headers match" do
173
+ @entry.valid_for?(mock("new_request", :uri => 'http://bar.invalid',
174
+ :header => {'Accept' => 'text/plain'})).should be_false
175
+ end
176
+
177
+ it "should false for requests where headers don't match" do
178
+ @entry.valid_for?(mock("new_request", :uri => 'http://foo.invalid',
179
+ :header => {'Accept' => 'application/octet-stream'})).should be_false
180
+ end
181
+
182
+ it "should be false if request has a varying header and the original request was missing that header" do
183
+ entry = Resourceful::CacheEntry.new(
184
+ mock('original_request', :header => {},
185
+ :request_time => Time.utc(2008,5,16,0,0,0), :uri => 'http://foo.invalid'),
186
+ mock('response', :header => {'Vary' => 'Accept'}))
187
+
188
+ entry.valid_for?(mock("new_request", :uri => 'http://foo.invalid',
189
+ :header => {'Accept' => 'text/plain'})).should be_false
196
190
  end
197
191
  end
198
192
 
199
- it 'should be valid for a request if all the vary headers match' do
200
- @request.stub!(:header).and_return({'Content-Type' => 'text/plain'})
201
- @entry.valid_for?(@request).should be_true
202
- end
193
+ describe '#select_request_headers' do
194
+ before do
195
+ @req_header = mock('header', :[] => nil)
196
+ @request = mock('request', :header => @req_header)
203
197
 
204
- it 'should not be valid for a request if not all the vary headers match' do
205
- @request.stub!(:header).and_return({'Content-Type' => 'text/html'})
206
- @entry.valid_for?(@request).should be_false
207
- end
198
+ @resp_header = mock('header', :[] => nil)
199
+ @response = mock('response', :header => @resp_header)
200
+ end
201
+
202
+ it 'should select the request headers from the Vary header' do
203
+ @resp_header.should_receive(:[]).with('Vary')
204
+ @entry.select_request_headers(@request, @response)
205
+ end
206
+
207
+ it 'should pull the values from the request that match keys in the vary header' do
208
+ @resp_header.should_receive(:[]).with('Vary').twice.and_return(['foo', 'bar'])
209
+ @req_header.should_receive(:[]).with('foo').and_return('oof')
210
+ @req_header.should_receive(:[]).with('bar').and_return('rab')
208
211
 
212
+ header = @entry.select_request_headers(@request, @response)
213
+ header['foo'].should == 'oof'
214
+ header['bar'].should == 'rab'
215
+ end
216
+
217
+ it 'should return a new Header object' do
218
+ @entry.select_request_headers(@request, @response).should be_kind_of(Resourceful::Header)
219
+ end
220
+ end
209
221
  end
210
222
 
211
223
 
@@ -23,20 +23,26 @@ describe Resourceful::HttpAccessor, 'init' do
23
23
 
24
24
  it 'should raise arg error if unrecognized options are passed' do
25
25
  lambda {
26
- ha = Resourceful::HttpAccessor.new(:foo => 'foo', :bar => 'bar')
26
+ Resourceful::HttpAccessor.new(:foo => 'foo', :bar => 'bar')
27
27
  }.should raise_error(ArgumentError, /Unrecognized options: (foo, bar)|(bar, foo)/)
28
28
  end
29
29
 
30
30
  it 'should allow an additional user agent token to be passed at init' do
31
- Resourceful::HttpAccessor.new(:user_agent => "Super/3000").tap do |ha|
32
- ha.user_agent_string.should match(%r{^Super/3000})
33
- end
31
+ ha = Resourceful::HttpAccessor.new(:user_agent => "Super/3000")
32
+
33
+ ha.user_agent_string.should match(%r{^Super/3000})
34
34
  end
35
35
 
36
36
  it 'should allow multiple additional user agent tokens to be passed at init' do
37
- Resourceful::HttpAccessor.new(:user_agent => ["Super/3000", "Duper/2.1"]).tap do |ha|
38
- ha.user_agent_string.should match(%r{^Super/3000 Duper/2\.1 })
39
- end
37
+ ha = Resourceful::HttpAccessor.new(:user_agent => ["Super/3000", "Duper/2.1"])
38
+
39
+ ha.user_agent_string.should match(%r{^Super/3000 Duper/2\.1 })
40
+ end
41
+
42
+ it 'should allow cache manager to be provided at init' do
43
+ ha = Resourceful::HttpAccessor.new(:cache_manager => :marker)
44
+
45
+ ha.cache_manager.should equal(:marker)
40
46
  end
41
47
 
42
48
  end
@@ -123,3 +129,36 @@ describe Resourceful::HttpAccessor do
123
129
  end
124
130
 
125
131
  end
132
+
133
+ describe Resourceful::HttpAccessor, "(authentication)" do
134
+ before do
135
+ @auth_manager = stub('auth_manager', :add_auth_handler => nil)
136
+ Resourceful::AuthenticationManager.stub!(:new).and_return(@auth_manager)
137
+ @ha = Resourceful::HttpAccessor.new()
138
+ end
139
+
140
+ it 'should allow authenticators to be registered' do
141
+ an_authenticator = stub('an_authenicator')
142
+ @auth_manager.should_receive(:add_auth_handler).with(an_authenticator)
143
+
144
+ @ha.add_authenticator(an_authenticator)
145
+ end
146
+
147
+ it 'should allow an authenicator to be specified at init' do
148
+ an_authenticator = stub('an_authenicator')
149
+ @auth_manager.should_receive(:add_auth_handler).with(an_authenticator)
150
+
151
+ Resourceful::HttpAccessor.new(:authenticator => an_authenticator)
152
+ end
153
+
154
+ it 'should allow multiple authenicators to be specified at init' do
155
+ authenticator1 = stub('authenicator1')
156
+ authenticator2 = stub('authenicator2')
157
+
158
+ @auth_manager.should_receive(:add_auth_handler).with(authenticator1)
159
+ @auth_manager.should_receive(:add_auth_handler).with(authenticator2)
160
+
161
+ Resourceful::HttpAccessor.new(:authenticators => [authenticator1, authenticator2])
162
+ end
163
+
164
+ end
@@ -0,0 +1,111 @@
1
+ require 'pathname'
2
+ require Pathname(__FILE__).dirname + '../spec_helper'
3
+
4
+ require 'resourceful/memcache_cache_manager'
5
+ require 'resourceful/request'
6
+
7
+ describe Resourceful::MemcacheCacheManager do
8
+ before do
9
+ @resource = stub('resource', :uri => 'http://foo.invalid/')
10
+
11
+ @request = Resourceful::Request.new(:get, @resource)
12
+ @response = Resourceful::Response.new('http://foo.invalid/', '200', {'Vary' => 'Accept'}, "a body")
13
+
14
+ @memcache = stub('memcache', :get => nil)
15
+ MemCache.stub!(:new).and_return(@memcache)
16
+
17
+ @cache_mngr = Resourceful::MemcacheCacheManager.new('foobar:42')
18
+ end
19
+
20
+ describe "#store(request,response)" do
21
+ it "should store the new pair in memcache" do
22
+ @memcache.should_receive(:[]=).with do |key, collection|
23
+ key.should == Digest::MD5.hexdigest('http://foo.invalid/')
24
+ collection[@request].should == @response
25
+ end
26
+
27
+ @cache_mngr.store(@request, @response)
28
+ end
29
+
30
+ it "should replace existing values if they exist" do
31
+ entries = Resourceful::CacheEntryCollection.new
32
+ entries[@request] = @response
33
+ @memcache.stub!(:[]=).and_return(entries)
34
+
35
+ new_request = Resourceful::Request.new(:get, @resource)
36
+ new_response = Resourceful::Response.new('http://foo.invalid/', '200', {}, "a different body")
37
+
38
+ @memcache.should_receive(:[]=).with do |key, collection|
39
+ collection[new_request].should == new_response
40
+ end
41
+
42
+ @cache_mngr.store(new_request, new_response)
43
+ end
44
+
45
+ it "should not store responses that are not cacheable" do
46
+ @memcache.should_not_receive(:[]=)
47
+
48
+ vary_star_response = Resourceful::Response.new('http://foo.invalid/', '200', {'Vary' => '*'}, "a different body")
49
+
50
+ @cache_mngr.store(@request, vary_star_response)
51
+ end
52
+ end
53
+
54
+ describe "#lookup" do
55
+ before do
56
+ @entries = Resourceful::CacheEntryCollection.new
57
+ @entries[@request] = @response
58
+ @memcache.stub!(:get).and_return(@entries)
59
+ end
60
+
61
+ it "should lookup the entry collection by the URI" do
62
+ @memcache.should_receive(:get).with(Digest::MD5.hexdigest('http://foo.invalid/')).and_return(@entries)
63
+
64
+ @cache_mngr.lookup(@request)
65
+ end
66
+
67
+ it "should retrieve responses that match request" do
68
+ @cache_mngr.lookup(Resourceful::Request.new(:get, @resource)).should == @response
69
+ end
70
+
71
+ it "should return nil if no responses that match request are found" do
72
+ @cache_mngr.lookup(Resourceful::Request.new(:get, @resource, "body", {'Accept' => 'text/plain'})).
73
+ should be_nil
74
+ end
75
+
76
+ it "should return nil if no responses that resource are found" do
77
+ @memcache.stub!(:get).and_return(nil)
78
+
79
+ @cache_mngr.lookup(Resourceful::Request.new(:get, @resource)).should be_nil
80
+ end
81
+ end
82
+
83
+ describe "#invalidate(url)" do
84
+ it "should remove all cached responses for that resource from memcache" do
85
+ @memcache.should_receive(:delete).with(Digest::MD5.hexdigest('http://foo.invalid/'))
86
+
87
+ @cache_mngr.invalidate('http://foo.invalid/')
88
+ end
89
+ end
90
+ end
91
+
92
+ describe Resourceful::MemcacheCacheManager, 'init' do
93
+ it 'should be createable with single memcache server' do
94
+ MemCache.should_receive(:new).with(['foobar:42'], anything)
95
+
96
+ Resourceful::MemcacheCacheManager.new('foobar:42')
97
+ end
98
+
99
+ it 'should be createable with multiple memcache servers' do
100
+ MemCache.should_receive(:new).with(['foobar:42', 'baz:32'], anything)
101
+
102
+ Resourceful::MemcacheCacheManager.new('foobar:42', 'baz:32')
103
+ end
104
+
105
+ it 'should create a thread safe memcache client' do
106
+ MemCache.should_receive(:new).with(anything, {:multithread => true})
107
+
108
+ Resourceful::MemcacheCacheManager.new('foobar:42')
109
+ end
110
+ end
111
+
@@ -62,7 +62,15 @@ describe Resourceful::OptionsInterpreter, '#interpret(options)' do
62
62
  @interpreter.interpret({}).keys.should_not include(:foo)
63
63
  end
64
64
 
65
- it 'should not invoked option value munging block if option is not specified'
65
+ it 'should not invoked option value munging block if option is not specified' do
66
+ @interpreter = Resourceful::OptionsInterpreter.new()
67
+ munging_block_executed = false
68
+ @interpreter.option(:foo) { |a| munging_block_executed = true }
69
+
70
+ lambda {
71
+ @interpreter.interpret({})
72
+ }.should_not change{munging_block_executed}
73
+ end
66
74
 
67
75
  it 'should use default if option is not specified' do
68
76
  @interpreter = Resourceful::OptionsInterpreter.new()
@@ -124,7 +124,7 @@ end unless defined? AuthorizationResponder
124
124
  describe 'simple http server', :shared => true do
125
125
  before(:all) do
126
126
  require 'rack'
127
- require 'mongrel'
127
+ require 'thin'
128
128
 
129
129
  app = Rack::Builder.new do |env|
130
130
  use Rack::ShowExceptions
@@ -145,7 +145,9 @@ describe 'simple http server', :shared => true do
145
145
 
146
146
  #spawn the server in a separate thread
147
147
  @httpd = Thread.new do
148
- Rack::Handler::Mongrel.run(app, :Host => '127.0.0.1', :Port => 3000)
148
+ Thin::Logging.silent = true
149
+ # Thin::Logging.debug = true
150
+ Thin::Server.start(app)
149
151
  end
150
152
  #give the server a chance to initialize
151
153
  sleep 0.05
metadata CHANGED
@@ -1,78 +1,147 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: paul-resourceful
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.3
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Paul Sadauskas
8
- - Peter Williams
9
8
  autorequire:
10
9
  bindir: bin
11
10
  cert_chain: []
12
11
 
13
- date: 2008-11-22 00:00:00 -08:00
12
+ date: 2008-12-05 00:00:00 -08:00
14
13
  default_executable:
15
14
  dependencies:
16
15
  - !ruby/object:Gem::Dependency
17
- name: hoe
16
+ name: addressable
18
17
  version_requirement:
19
18
  version_requirements: !ruby/object:Gem::Requirement
20
19
  requirements:
21
20
  - - ">="
22
21
  - !ruby/object:Gem::Version
23
- version: 1.8.2
22
+ version: "0"
24
23
  version:
25
- description:
26
- email:
27
- - psadauskas@gmail.com
28
- - pezra@barelyenough.org
24
+ - !ruby/object:Gem::Dependency
25
+ name: httpauth
26
+ version_requirement:
27
+ version_requirements: !ruby/object:Gem::Requirement
28
+ requirements:
29
+ - - ">="
30
+ - !ruby/object:Gem::Version
31
+ version: "0"
32
+ version:
33
+ - !ruby/object:Gem::Dependency
34
+ name: rspec
35
+ version_requirement:
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: "0"
41
+ version:
42
+ - !ruby/object:Gem::Dependency
43
+ name: facets
44
+ version_requirement:
45
+ version_requirements: !ruby/object:Gem::Requirement
46
+ requirements:
47
+ - - ">="
48
+ - !ruby/object:Gem::Version
49
+ version: "0"
50
+ version:
51
+ - !ruby/object:Gem::Dependency
52
+ name: andand
53
+ version_requirement:
54
+ version_requirements: !ruby/object:Gem::Requirement
55
+ requirements:
56
+ - - ">="
57
+ - !ruby/object:Gem::Version
58
+ version: "0"
59
+ version:
60
+ - !ruby/object:Gem::Dependency
61
+ name: thin
62
+ version_requirement:
63
+ version_requirements: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - ">="
66
+ - !ruby/object:Gem::Version
67
+ version: "0"
68
+ version:
69
+ - !ruby/object:Gem::Dependency
70
+ name: yard
71
+ version_requirement:
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ requirements:
74
+ - - ">="
75
+ - !ruby/object:Gem::Version
76
+ version: "0"
77
+ version:
78
+ description: An HTTP library for Ruby that takes advantage of everything HTTP has to offer.
79
+ email: psadauskas@gmail.com
29
80
  executables: []
30
81
 
31
82
  extensions: []
32
83
 
33
84
  extra_rdoc_files:
34
- - Manifest.txt
35
- files:
36
- - MIT-LICENSE
37
- - Manifest.txt
38
- - README.markdown
39
- - Rakefile
40
85
  - lib/resourceful.rb
41
86
  - lib/resourceful/authentication_manager.rb
42
- - lib/resourceful/cache_manager.rb
43
- - lib/resourceful/header.rb
44
- - lib/resourceful/http_accessor.rb
87
+ - lib/resourceful/util.rb
88
+ - lib/resourceful/resource.rb
89
+ - lib/resourceful/memcache_cache_manager.rb
45
90
  - lib/resourceful/net_http_adapter.rb
91
+ - lib/resourceful/http_accessor.rb
92
+ - lib/resourceful/stubbed_resource_proxy.rb
93
+ - lib/resourceful/header.rb
94
+ - lib/resourceful/cache_manager.rb
46
95
  - lib/resourceful/options_interpreter.rb
96
+ - lib/resourceful/response.rb
47
97
  - lib/resourceful/request.rb
98
+ - README.markdown
99
+ files:
100
+ - lib/resourceful.rb
101
+ - lib/resourceful/authentication_manager.rb
102
+ - lib/resourceful/util.rb
48
103
  - lib/resourceful/resource.rb
49
- - lib/resourceful/response.rb
104
+ - lib/resourceful/memcache_cache_manager.rb
105
+ - lib/resourceful/net_http_adapter.rb
106
+ - lib/resourceful/http_accessor.rb
50
107
  - lib/resourceful/stubbed_resource_proxy.rb
51
- - lib/resourceful/util.rb
52
- - lib/resourceful/version.rb
53
- - resourceful.gemspec
108
+ - lib/resourceful/header.rb
109
+ - lib/resourceful/cache_manager.rb
110
+ - lib/resourceful/options_interpreter.rb
111
+ - lib/resourceful/response.rb
112
+ - lib/resourceful/request.rb
54
113
  - spec/acceptance_shared_specs.rb
114
+ - spec/spec.opts
55
115
  - spec/acceptance_spec.rb
56
- - spec/resourceful/authentication_manager_spec.rb
57
- - spec/resourceful/cache_manager_spec.rb
116
+ - spec/simple_http_server_shared_spec_spec.rb
117
+ - spec/spec_helper.rb
58
118
  - spec/resourceful/header_spec.rb
59
- - spec/resourceful/http_accessor_spec.rb
60
- - spec/resourceful/net_http_adapter_spec.rb
119
+ - spec/resourceful/authentication_manager_spec.rb
120
+ - spec/resourceful/memcache_cache_manager_spec.rb
121
+ - spec/resourceful/response_spec.rb
61
122
  - spec/resourceful/options_interpreter_spec.rb
123
+ - spec/resourceful/http_accessor_spec.rb
124
+ - spec/resourceful/stubbed_resource_proxy_spec.rb
62
125
  - spec/resourceful/request_spec.rb
63
126
  - spec/resourceful/resource_spec.rb
64
- - spec/resourceful/response_spec.rb
65
- - spec/resourceful/stubbed_resource_proxy_spec.rb
127
+ - spec/resourceful/cache_manager_spec.rb
128
+ - spec/resourceful/net_http_adapter_spec.rb
66
129
  - spec/simple_http_server_shared_spec.rb
67
- - spec/simple_http_server_shared_spec_spec.rb
68
- - spec/spec.opts
69
- - spec/spec_helper.rb
130
+ - Manifest
131
+ - Rakefile
132
+ - README.markdown
133
+ - MIT-LICENSE
134
+ - resourceful.gemspec
70
135
  has_rdoc: true
71
- homepage:
136
+ homepage: http://github.com/paul/resourceful
72
137
  post_install_message:
73
138
  rdoc_options:
139
+ - --line-numbers
140
+ - --inline-source
141
+ - --title
142
+ - Resourceful
74
143
  - --main
75
- - README.txt
144
+ - README.markdown
76
145
  require_paths:
77
146
  - lib
78
147
  required_ruby_version: !ruby/object:Gem::Requirement
@@ -85,7 +154,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
85
154
  requirements:
86
155
  - - ">="
87
156
  - !ruby/object:Gem::Version
88
- version: "0"
157
+ version: "1.2"
89
158
  version:
90
159
  requirements: []
91
160
 
data/Manifest.txt DELETED
@@ -1,34 +0,0 @@
1
- MIT-LICENSE
2
- Manifest.txt
3
- README.markdown
4
- Rakefile
5
- lib/resourceful.rb
6
- lib/resourceful/authentication_manager.rb
7
- lib/resourceful/cache_manager.rb
8
- lib/resourceful/header.rb
9
- lib/resourceful/http_accessor.rb
10
- lib/resourceful/net_http_adapter.rb
11
- lib/resourceful/options_interpreter.rb
12
- lib/resourceful/request.rb
13
- lib/resourceful/resource.rb
14
- lib/resourceful/response.rb
15
- lib/resourceful/stubbed_resource_proxy.rb
16
- lib/resourceful/util.rb
17
- lib/resourceful/version.rb
18
- resourceful.gemspec
19
- spec/acceptance_shared_specs.rb
20
- spec/acceptance_spec.rb
21
- spec/resourceful/authentication_manager_spec.rb
22
- spec/resourceful/cache_manager_spec.rb
23
- spec/resourceful/header_spec.rb
24
- spec/resourceful/http_accessor_spec.rb
25
- spec/resourceful/net_http_adapter_spec.rb
26
- spec/resourceful/options_interpreter_spec.rb
27
- spec/resourceful/request_spec.rb
28
- spec/resourceful/resource_spec.rb
29
- spec/resourceful/response_spec.rb
30
- spec/resourceful/stubbed_resource_proxy_spec.rb
31
- spec/simple_http_server_shared_spec.rb
32
- spec/simple_http_server_shared_spec_spec.rb
33
- spec/spec.opts
34
- spec/spec_helper.rb
@@ -1 +0,0 @@
1
- RESOURCEFUL_VERSION = '0.2'