]> git.donarmstrong.com Git - dsa-puppet.git/blob - 3rdparty/modules/aviator/feature/faraday/rack_builder.rb
try again, with puppetforge modules, correctly included now
[dsa-puppet.git] / 3rdparty / modules / aviator / feature / faraday / rack_builder.rb
1 module Faraday
2   # A Builder that processes requests into responses by passing through an inner
3   # middleware stack (heavily inspired by Rack).
4   #
5   #   Faraday::Connection.new(:url => 'http://sushi.com') do |builder|
6   #     builder.request  :url_encoded  # Faraday::Request::UrlEncoded
7   #     builder.adapter  :net_http     # Faraday::Adapter::NetHttp
8   #   end
9   class RackBuilder
10     attr_accessor :handlers
11
12     # Error raised when trying to modify the stack after calling `lock!`
13     class StackLocked < RuntimeError; end
14
15     # borrowed from ActiveSupport::Dependencies::Reference &
16     # ActionDispatch::MiddlewareStack::Middleware
17     class Handler
18       @@constants_mutex = Mutex.new
19       @@constants = Hash.new { |h, k|
20         value = k.respond_to?(:constantize) ? k.constantize : Object.const_get(k)
21         @@constants_mutex.synchronize { h[k] = value }
22       }
23
24       attr_reader :name
25
26       def initialize(klass, *args, &block)
27         @name = klass.to_s
28         if klass.respond_to?(:name)
29           @@constants_mutex.synchronize { @@constants[@name] = klass }
30         end
31         @args, @block = args, block
32       end
33
34       def klass() @@constants[@name] end
35       def inspect() @name end
36
37       def ==(other)
38         if other.is_a? Handler
39           self.name == other.name
40         elsif other.respond_to? :name
41           klass == other
42         else
43           @name == other.to_s
44         end
45       end
46
47       def build(app)
48         klass.new(app, *@args, &@block)
49       end
50     end
51
52     def initialize(handlers = [])
53       @handlers = handlers
54       if block_given?
55         build(&Proc.new)
56       elsif @handlers.empty?
57         # default stack, if nothing else is configured
58         self.request :url_encoded
59         self.adapter Faraday.default_adapter
60       end
61     end
62
63     def build(options = {})
64       raise_if_locked
65       @handlers.clear unless options[:keep]
66       yield(self) if block_given?
67     end
68
69     def [](idx)
70       @handlers[idx]
71     end
72
73     # Locks the middleware stack to ensure no further modifications are possible.
74     def lock!
75       @handlers.freeze
76     end
77
78     def locked?
79       @handlers.frozen?
80     end
81
82     def use(klass, *args, &block)
83       if klass.is_a? Symbol
84         use_symbol(Faraday::Middleware, klass, *args, &block)
85       else
86         raise_if_locked
87         @handlers << self.class::Handler.new(klass, *args, &block)
88       end
89     end
90
91     def request(key, *args, &block)
92       use_symbol(Faraday::Request, key, *args, &block)
93     end
94
95     def response(key, *args, &block)
96       use_symbol(Faraday::Response, key, *args, &block)
97     end
98
99     def adapter(key, *args, &block)
100       use_symbol(Faraday::Adapter, key, *args, &block)
101     end
102
103     ## methods to push onto the various positions in the stack:
104
105     def insert(index, *args, &block)
106       raise_if_locked
107       index = assert_index(index)
108       handler = self.class::Handler.new(*args, &block)
109       @handlers.insert(index, handler)
110     end
111
112     alias_method :insert_before, :insert
113
114     def insert_after(index, *args, &block)
115       index = assert_index(index)
116       insert(index + 1, *args, &block)
117     end
118
119     def swap(index, *args, &block)
120       raise_if_locked
121       index = assert_index(index)
122       @handlers.delete_at(index)
123       insert(index, *args, &block)
124     end
125
126     def delete(handler)
127       raise_if_locked
128       @handlers.delete(handler)
129     end
130
131     # Processes a Request into a Response by passing it through this Builder's
132     # middleware stack.
133     #
134     # connection - Faraday::Connection
135     # request    - Faraday::Request
136     #
137     # Returns a Faraday::Response.
138     def build_response(connection, request)
139       app.call(build_env(connection, request))
140     end
141
142     # The "rack app" wrapped in middleware. All requests are sent here.
143     #
144     # The builder is responsible for creating the app object. After this,
145     # the builder gets locked to ensure no further modifications are made
146     # to the middleware stack.
147     #
148     # Returns an object that responds to `call` and returns a Response.
149     def app
150       @app ||= begin
151         lock!
152         to_app(lambda { |env|
153           response = Response.new
154           response.finish(env) unless env.parallel?
155           env.response = response
156         })
157       end
158     end
159
160     def to_app(inner_app)
161       # last added handler is the deepest and thus closest to the inner app
162       @handlers.reverse.inject(inner_app) { |app, handler| handler.build(app) }
163     end
164
165     def ==(other)
166       other.is_a?(self.class) && @handlers == other.handlers
167     end
168
169     def dup
170       self.class.new(@handlers.dup)
171     end
172
173     # ENV Keys
174     # :method - a symbolized request method (:get, :post)
175     # :body   - the request body that will eventually be converted to a string.
176     # :url    - URI instance for the current request.
177     # :status           - HTTP response status code
178     # :request_headers  - hash of HTTP Headers to be sent to the server
179     # :response_headers - Hash of HTTP headers from the server
180     # :parallel_manager - sent if the connection is in parallel mode
181     # :request - Hash of options for configuring the request.
182     #   :timeout      - open/read timeout Integer in seconds
183     #   :open_timeout - read timeout Integer in seconds
184     #   :proxy        - Hash of proxy options
185     #     :uri        - Proxy Server URI
186     #     :user       - Proxy server username
187     #     :password   - Proxy server password
188     # :ssl - Hash of options for configuring SSL requests.
189     def build_env(connection, request)
190       Env.new(request.method, request.body,
191         connection.build_exclusive_url(request.path, request.params),
192         request.options, request.headers, connection.ssl,
193         connection.parallel_manager)
194     end
195
196     private
197
198     def raise_if_locked
199       raise StackLocked, "can't modify middleware stack after making a request" if locked?
200     end
201
202     def use_symbol(mod, key, *args, &block)
203       use(mod.lookup_middleware(key), *args, &block)
204     end
205
206     def assert_index(index)
207       idx = index.is_a?(Integer) ? index : @handlers.index(index)
208       raise "No such handler: #{index.inspect}" unless idx
209       idx
210     end
211   end
212 end