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,34 @@
1
+
2
+ module Resourceful
3
+
4
+ # This exception used to indicate that the request did not succeed.
5
+ # The HTTP response is included so that the appropriate actions can
6
+ # be taken based on the details of that response
7
+ class UnsuccessfulHttpRequestError < Exception
8
+ attr_reader :http_response, :http_request
9
+
10
+ # Initialize new error from the HTTP request and response attributes.
11
+ def initialize(http_request, http_response)
12
+ super("#{http_request.method} request to <#{http_request.uri}> failed with code #{http_response.code}")
13
+ @http_request = http_request
14
+ @http_response = http_response
15
+ end
16
+ end
17
+
18
+ class MalformedServerResponse < UnsuccessfulHttpRequestError
19
+ end
20
+
21
+
22
+ # Exception indicating that the server used a content coding scheme
23
+ # that Resourceful is unable to handle.
24
+ class UnsupportedContentCoding < Exception
25
+ end
26
+
27
+ # Raised when a body is supplied, but not a content-type header
28
+ class MissingContentType < ArgumentError
29
+ def initialize
30
+ super("A Content-Type must be specified when an entity-body is supplied.")
31
+ end
32
+ end
33
+
34
+ end
@@ -0,0 +1,126 @@
1
+ # A case-normalizing Hash, adjusting on [] and []=.
2
+ # Shamelessly swiped from Rack
3
+ module Resourceful
4
+ class Header < Hash
5
+ def initialize(hash={})
6
+ hash.each { |k, v| self[k] = v }
7
+ end
8
+
9
+ def to_hash
10
+ {}.replace(self)
11
+ end
12
+
13
+ def [](k)
14
+ super capitalize(k)
15
+ end
16
+
17
+ def []=(k, v)
18
+ super capitalize(k), v
19
+ end
20
+
21
+ def has_key?(k)
22
+ super capitalize(k)
23
+ end
24
+
25
+ def capitalize(k)
26
+ k.to_s.downcase.gsub(/^.|[-_\s]./) { |x| x.upcase }.gsub('_', '-')
27
+ end
28
+
29
+ def each_field(&blk)
30
+ to_hash.each { |k,v|
31
+ blk.call capitalize(k), v
32
+ }
33
+ end
34
+
35
+ HEADERS = %w[
36
+ Accept
37
+ Accept-Charset
38
+ Accept-Encoding
39
+ Accept-Language
40
+ Accept-Ranges
41
+ Age
42
+ Allow
43
+ Authorization
44
+ Cache-Control
45
+ Connection
46
+ Content-Encoding
47
+ Content-Language
48
+ Content-Length
49
+ Content-Location
50
+ Content-MD5
51
+ Content-Range
52
+ Content-Type
53
+ Date
54
+ ETag
55
+ Expect
56
+ Expires
57
+ From
58
+ Host
59
+ If-Match
60
+ If-Modified-Since
61
+ If-None-Match
62
+ If-Range
63
+ If-Unmodified-Since
64
+ Keep-Alive
65
+ Last-Modified
66
+ Location
67
+ Max-Forwards
68
+ Pragma
69
+ Proxy-Authenticate
70
+ Proxy-Authorization
71
+ Range
72
+ Referer
73
+ Retry-After
74
+ Server
75
+ TE
76
+ Trailer
77
+ Transfer-Encoding
78
+ Upgrade
79
+ User-Agent
80
+ Vary
81
+ Via
82
+ Warning
83
+ WWW-Authenticate
84
+ ]
85
+
86
+ HEADERS.each do |header|
87
+ const = header.upcase.gsub('-', '_')
88
+ meth = header.downcase.gsub('-', '_')
89
+
90
+ class_eval <<-RUBY, __FILE__, __LINE__
91
+ #{const} = "#{header}".freeze # ACCEPT = "accept".freeze
92
+
93
+ def #{meth} # def accept
94
+ self[#{const}] # self[ACCEPT]
95
+ end # end
96
+
97
+ def #{meth}=(str) # def accept=(str)
98
+ self[#{const}] = str # self[ACCEPT] = str
99
+ end # end
100
+ RUBY
101
+
102
+ end
103
+
104
+ HOP_BY_HOP_HEADERS = [
105
+ CONNECTION,
106
+ KEEP_ALIVE,
107
+ PROXY_AUTHENTICATE,
108
+ PROXY_AUTHORIZATION,
109
+ TE,
110
+ TRAILER,
111
+ TRANSFER_ENCODING,
112
+ UPGRADE
113
+ ].freeze
114
+
115
+ NON_MODIFIABLE_HEADERS = [
116
+ CONTENT_LOCATION,
117
+ CONTENT_MD5,
118
+ ETAG,
119
+ LAST_MODIFIED,
120
+ EXPIRES
121
+ ].freeze
122
+
123
+ end
124
+ end
125
+
126
+
@@ -0,0 +1,98 @@
1
+ require 'net/http'
2
+
3
+ require 'resourceful/options_interpreter'
4
+ require 'resourceful/authentication_manager'
5
+ require 'resourceful/cache_manager'
6
+ require 'resourceful/resource'
7
+ require 'resourceful/stubbed_resource_proxy'
8
+
9
+ module Resourceful
10
+ # This is an imitation Logger used when no real logger is
11
+ # registered. This allows most of the code to assume that there
12
+ # is always a logger available, which significantly improved the
13
+ # readability of the logging related code.
14
+ class BitBucketLogger
15
+ def warn(*args); end
16
+ def info(*args); end
17
+ def debug(*args); end
18
+ end
19
+
20
+ # This is the simplest logger. It just writes everything to STDOUT.
21
+ class StdOutLogger
22
+ def warn(*args); puts args; end
23
+ def info(*args); puts args; end
24
+ def debug(*args); puts args; end
25
+ end
26
+
27
+ # This class provides a simple interface to the functionality
28
+ # provided by the Resourceful library. Conceptually this object
29
+ # acts a collection of all the resources available via HTTP.
30
+ class HttpAccessor
31
+
32
+ # A logger object to which messages about the activities of this
33
+ # object will be written. This should be an object that responds
34
+ # to +#info(message)+ and +#debug(message)+.
35
+ #
36
+ # Errors will not be logged. Instead an exception will be raised
37
+ # and the application code should log it if appropriate.
38
+ attr_accessor :logger, :cache_manager
39
+
40
+ attr_reader :auth_manager
41
+ attr_reader :user_agent_tokens
42
+
43
+ INIT_OPTIONS = OptionsInterpreter.new do
44
+ option(:logger, :default => Resourceful::BitBucketLogger.new)
45
+ option(:user_agent, :default => []) {|ua| [ua].flatten}
46
+ option(:cache_manager, :default => NullCacheManager.new)
47
+ option(:authenticator)
48
+ option(:authenticators, :default => [])
49
+ end
50
+
51
+ # Initializes a new HttpAccessor. Valid options:
52
+ #
53
+ # +:logger+:: A Logger object that the new HTTP accessor should
54
+ # send log messages
55
+ #
56
+ # +:user_agent+:: One or more additional user agent tokens to
57
+ # added to the user agent string.
58
+ #
59
+ # +:cache_manager+:: The cache manager this accessor should use.
60
+ #
61
+ # +:authenticator+:: Add a single authenticator for this accessor.
62
+ #
63
+ # +:authenticators+:: Enumerable of the authenticators for this
64
+ # accessor.
65
+ def initialize(options = {})
66
+ @user_agent_tokens = [RESOURCEFUL_USER_AGENT_TOKEN]
67
+
68
+ INIT_OPTIONS.interpret(options) do |opts|
69
+ @user_agent_tokens.push(*opts[:user_agent].reverse)
70
+ self.logger = opts[:logger]
71
+ @auth_manager = AuthenticationManager.new()
72
+ @cache_manager = opts[:cache_manager]
73
+
74
+ add_authenticator(opts[:authenticator]) if opts[:authenticator]
75
+ opts[:authenticators].each { |a| add_authenticator(a) }
76
+ end
77
+ end
78
+
79
+ # Returns the string that identifies this HTTP accessor. If you
80
+ # want to add a token to the user agent string simply add the new
81
+ # token to the end of +#user_agent_tokens+.
82
+ def user_agent_string
83
+ user_agent_tokens.reverse.join(' ')
84
+ end
85
+
86
+ # Returns a resource object representing the resource indicated
87
+ # by the specified URI. A resource object will be created if necessary.
88
+ def resource(uri, opts = {})
89
+ resource = Resource.new(self, uri, opts)
90
+ end
91
+ alias [] resource
92
+
93
+ # Adds an Authenticator to the set used by the accessor.
94
+ def add_authenticator(an_authenticator)
95
+ auth_manager.add_auth_handler(an_authenticator)
96
+ end
97
+ end
98
+ end
@@ -0,0 +1,75 @@
1
+ require "resourceful/cache_manager"
2
+
3
+ require 'memcache'
4
+
5
+ module Resourceful
6
+ class MemcacheCacheManager < AbstractCacheManager
7
+
8
+ # Create a new Memcached backed cache manager
9
+ #
10
+ # @param [*String] memcache_servers
11
+ # list of all Memcached servers this cache manager should use.
12
+ def initialize(*memcache_servers)
13
+ @memcache = MemCache.new(memcache_servers, :multithread => true)
14
+ end
15
+
16
+ # Finds a previously cached response to the provided request. The
17
+ # response returned may be stale.
18
+ #
19
+ # @param [Resourceful::Request] request
20
+ # The request for which we are looking for a response.
21
+ #
22
+ # @return [Resourceful::Response, nil]
23
+ # A (possibly stale) response for the request provided or nil if
24
+ # no matching response is found.
25
+ def lookup(request)
26
+ resp = cache_entries_for(request)[request]
27
+ return if resp.nil?
28
+
29
+ resp.authoritative = false
30
+
31
+ resp
32
+ end
33
+
34
+ # Store a response in the cache.
35
+ #
36
+ # This method is smart enough to not store responses that cannot be
37
+ # cached (Vary: * or Cache-Control: no-cache, private, ...)
38
+ #
39
+ # @param [Resourceful::Request] request
40
+ # The request used to obtain the response. This is needed so the
41
+ # values from the response's Vary header can be stored.
42
+ # @param [Resourceful::Response] response
43
+ # The response to be stored.
44
+ def store(request, response)
45
+ return unless response.cachable?
46
+
47
+ entries = cache_entries_for(request)
48
+ entries[request] = response
49
+
50
+ @memcache[request.to_mc_key] = entries
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(uri_hash(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(uri_hash(a_request.uri)) || Resourceful::CacheEntryCollection.new
73
+ end
74
+ end
75
+ end
@@ -0,0 +1,70 @@
1
+ require 'net/http'
2
+ require 'net/https'
3
+ require 'addressable/uri'
4
+
5
+ require 'pathname'
6
+ require 'resourceful/header'
7
+
8
+ module Addressable
9
+ class URI
10
+ def absolute_path
11
+ absolute_path = ""
12
+ absolute_path << self.path.to_s
13
+ absolute_path << "?#{self.query}" if self.query != nil
14
+ absolute_path << "##{self.fragment}" if self.fragment != nil
15
+ return absolute_path
16
+ end
17
+ end
18
+ end
19
+
20
+ module Resourceful
21
+
22
+ class NetHttpAdapter
23
+ # Make an HTTP request using the standard library net/http.
24
+ #
25
+ # Will use a proxy defined in the http_proxy environment variable, if set.
26
+ def self.make_request(method, uri, body = nil, header = nil)
27
+ uri = uri.is_a?(Addressable::URI) ? uri : Addressable::URI.parse(uri)
28
+
29
+ req = net_http_request_class(method).new(uri.absolute_path)
30
+ header.each_field { |k,v| req[k] = v } if header
31
+ https = ("https" == uri.scheme)
32
+ conn = Net::HTTP.Proxy(*proxy_details).new(uri.host, uri.port || (https ? 443 : 80))
33
+ conn.use_ssl = https
34
+ begin
35
+ conn.start
36
+ res = conn.request(req, body)
37
+ ensure
38
+ conn.finish if conn.started?
39
+ end
40
+
41
+ [ Integer(res.code),
42
+ Resourceful::Header.new(res.header.to_hash),
43
+ res.body
44
+ ]
45
+ ensure
46
+
47
+ end
48
+
49
+ private
50
+
51
+ # Parse proxy details from http_proxy environment variable
52
+ def self.proxy_details
53
+ proxy = Addressable::URI.parse(ENV["http_proxy"])
54
+ [proxy.host, proxy.port, proxy.user, proxy.password] if proxy
55
+ end
56
+
57
+ def self.net_http_request_class(method)
58
+ case method
59
+ when :get then Net::HTTP::Get
60
+ when :head then Net::HTTP::Head
61
+ when :post then Net::HTTP::Post
62
+ when :put then Net::HTTP::Put
63
+ when :delete then Net::HTTP::Delete
64
+ end
65
+
66
+ end
67
+
68
+ end
69
+
70
+ end
@@ -0,0 +1,78 @@
1
+ require 'set'
2
+
3
+ module Resourceful
4
+ # Class that supports a declarative way to pick apart an options
5
+ # hash.
6
+ #
7
+ # OptionsInterpreter.new do
8
+ # option(:accept) { |accept| [accept].flatten.map{|m| m.to_str} }
9
+ # option(:http_header_fields, :default => {})
10
+ # end.interpret(:accept => 'this/that')
11
+ # # => {:accept => ['this/that'], :http_header_fields => { } }
12
+ #
13
+ # The returned hash contains :accept with the pass accept option
14
+ # value transformed into an array and :http_header_fields with its
15
+ # default value.
16
+ #
17
+ # OptionsInterpreter.new do
18
+ # option(:max_redirects)
19
+ # end.interpret(:foo => 1, :bar => 2)
20
+ # # Raises ArgumentError: Unrecognized options: foo, bar
21
+ #
22
+ # If options are passed that are not defined an exception is raised.
23
+ #
24
+ class OptionsInterpreter
25
+ def self.interpret(options_hash, &block)
26
+ interpreter = self.new(options_hash)
27
+ interpreter.instance_eval(&block)
28
+
29
+ interpreter.interpret
30
+ end
31
+
32
+ def initialize(&block)
33
+ @handlers = Hash.new
34
+
35
+ instance_eval(&block) if block_given?
36
+ end
37
+
38
+ def interpret(options_hash, &block)
39
+ unless (unrecognized_options = (options_hash.keys - supported_options)).empty?
40
+ raise ArgumentError, "Unrecognized options: #{unrecognized_options.join(", ")}"
41
+ end
42
+
43
+ options = Hash.new
44
+ handlers.each do |opt_name, a_handler|
45
+ opt_val = a_handler.call(options_hash)
46
+ options[opt_name] = opt_val if opt_val
47
+ end
48
+
49
+ yield(options) if block_given?
50
+
51
+ options
52
+ end
53
+
54
+ def option(name, opts = {}, &block)
55
+
56
+ passed_value_fetcher = if opts[:default]
57
+ default_value = opts[:default]
58
+ lambda{|options_hash| options_hash[name] || default_value}
59
+ else
60
+ lambda{|options_hash| options_hash[name]}
61
+ end
62
+
63
+ handlers[name] = if block_given?
64
+ lambda{|options_hash| (val = passed_value_fetcher.call(options_hash)) ? block.call(val) : nil}
65
+ else
66
+ passed_value_fetcher
67
+ end
68
+ end
69
+
70
+ def supported_options
71
+ handlers.keys
72
+ end
73
+
74
+ private
75
+
76
+ attr_reader :handlers
77
+ end
78
+ end