]> git.donarmstrong.com Git - dsa-puppet.git/blob - 3rdparty/modules/aviator/lib/puppet/feature/faraday/adapter/typhoeus.rb
add aimonb/aviator to 3rdparty
[dsa-puppet.git] / 3rdparty / modules / aviator / lib / puppet / feature / faraday / adapter / typhoeus.rb
1 module Faraday
2   class Adapter
3     class Typhoeus < Faraday::Adapter
4       self.supports_parallel = true
5
6       def self.setup_parallel_manager(options = {})
7         options.empty? ? ::Typhoeus::Hydra.hydra : ::Typhoeus::Hydra.new(options)
8       end
9
10       dependency 'typhoeus'
11
12       def call(env)
13         super
14         perform_request env
15         @app.call env
16       end
17
18       def perform_request(env)
19         read_body env
20
21         hydra = env[:parallel_manager] || self.class.setup_parallel_manager
22         hydra.queue request(env)
23         hydra.run unless parallel?(env)
24       rescue Errno::ECONNREFUSED
25         raise Error::ConnectionFailed, $!
26       end
27
28       # TODO: support streaming requests
29       def read_body(env)
30         env[:body] = env[:body].read if env[:body].respond_to? :read
31       end
32
33       def request(env)
34         method = env[:method]
35         # For some reason, prevents Typhoeus from using "100-continue".
36         # We want this because Webrick 1.3.1 can't seem to handle it w/ PUT.
37         method = method.to_s.upcase if method == :put
38
39         req = ::Typhoeus::Request.new env[:url].to_s,
40           :method  => method,
41           :body    => env[:body],
42           :headers => env[:request_headers],
43           :disable_ssl_peer_verification => (env[:ssl] && env[:ssl].disable?)
44
45         configure_ssl     req, env
46         configure_proxy   req, env
47         configure_timeout req, env
48         configure_socket  req, env
49
50         req.on_complete do |resp|
51           if resp.timed_out?
52             if parallel?(env)
53               # TODO: error callback in async mode
54             else
55               raise Faraday::Error::TimeoutError, "request timed out"
56             end
57           end
58
59           case resp.curl_return_code
60           when 0
61             # everything OK
62           when 7
63             raise Error::ConnectionFailed, resp.curl_error_message
64           when 60
65             raise Faraday::SSLError, resp.curl_error_message
66           else
67             raise Error::ClientError, resp.curl_error_message
68           end
69
70           save_response(env, resp.code, resp.body) do |response_headers|
71             response_headers.parse resp.headers
72           end
73           # in async mode, :response is initialized at this point
74           env[:response].finish(env) if parallel?(env)
75         end
76
77         req
78       end
79
80       def configure_ssl(req, env)
81         ssl = env[:ssl]
82
83         req.ssl_version = ssl[:version]          if ssl[:version]
84         req.ssl_cert    = ssl[:client_cert] if ssl[:client_cert]
85         req.ssl_key     = ssl[:client_key]  if ssl[:client_key]
86         req.ssl_cacert  = ssl[:ca_file]          if ssl[:ca_file]
87         req.ssl_capath  = ssl[:ca_path]          if ssl[:ca_path]
88       end
89
90       def configure_proxy(req, env)
91         proxy = request_options(env)[:proxy]
92         return unless proxy
93
94         req.proxy = "#{proxy[:uri].host}:#{proxy[:uri].port}"
95
96         if proxy[:user] && proxy[:password]
97           req.proxy_username = proxy[:user]
98           req.proxy_password = proxy[:password]
99         end
100       end
101
102       def configure_timeout(req, env)
103         env_req = request_options(env)
104         req.timeout = req.connect_timeout = (env_req[:timeout] * 1000) if env_req[:timeout]
105         req.connect_timeout = (env_req[:open_timeout] * 1000)          if env_req[:open_timeout]
106       end
107
108       def configure_socket(req, env)
109         if bind = request_options(env)[:bind]
110           req.interface = bind[:host]
111         end
112       end
113
114       def request_options(env)
115         env[:request]
116       end
117
118       def parallel?(env)
119         !!env[:parallel_manager]
120       end
121     end
122   end
123 end