]> git.donarmstrong.com Git - dsa-puppet.git/blobdiff - 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
diff --git a/3rdparty/modules/aviator/lib/puppet/feature/faraday/adapter/typhoeus.rb b/3rdparty/modules/aviator/lib/puppet/feature/faraday/adapter/typhoeus.rb
new file mode 100644 (file)
index 0000000..69b6a51
--- /dev/null
@@ -0,0 +1,123 @@
+module Faraday
+  class Adapter
+    class Typhoeus < Faraday::Adapter
+      self.supports_parallel = true
+
+      def self.setup_parallel_manager(options = {})
+        options.empty? ? ::Typhoeus::Hydra.hydra : ::Typhoeus::Hydra.new(options)
+      end
+
+      dependency 'typhoeus'
+
+      def call(env)
+        super
+        perform_request env
+        @app.call env
+      end
+
+      def perform_request(env)
+        read_body env
+
+        hydra = env[:parallel_manager] || self.class.setup_parallel_manager
+        hydra.queue request(env)
+        hydra.run unless parallel?(env)
+      rescue Errno::ECONNREFUSED
+        raise Error::ConnectionFailed, $!
+      end
+
+      # TODO: support streaming requests
+      def read_body(env)
+        env[:body] = env[:body].read if env[:body].respond_to? :read
+      end
+
+      def request(env)
+        method = env[:method]
+        # For some reason, prevents Typhoeus from using "100-continue".
+        # We want this because Webrick 1.3.1 can't seem to handle it w/ PUT.
+        method = method.to_s.upcase if method == :put
+
+        req = ::Typhoeus::Request.new env[:url].to_s,
+          :method  => method,
+          :body    => env[:body],
+          :headers => env[:request_headers],
+          :disable_ssl_peer_verification => (env[:ssl] && env[:ssl].disable?)
+
+        configure_ssl     req, env
+        configure_proxy   req, env
+        configure_timeout req, env
+        configure_socket  req, env
+
+        req.on_complete do |resp|
+          if resp.timed_out?
+            if parallel?(env)
+              # TODO: error callback in async mode
+            else
+              raise Faraday::Error::TimeoutError, "request timed out"
+            end
+          end
+
+          case resp.curl_return_code
+          when 0
+            # everything OK
+          when 7
+            raise Error::ConnectionFailed, resp.curl_error_message
+          when 60
+            raise Faraday::SSLError, resp.curl_error_message
+          else
+            raise Error::ClientError, resp.curl_error_message
+          end
+
+          save_response(env, resp.code, resp.body) do |response_headers|
+            response_headers.parse resp.headers
+          end
+          # in async mode, :response is initialized at this point
+          env[:response].finish(env) if parallel?(env)
+        end
+
+        req
+      end
+
+      def configure_ssl(req, env)
+        ssl = env[:ssl]
+
+        req.ssl_version = ssl[:version]          if ssl[:version]
+        req.ssl_cert    = ssl[:client_cert] if ssl[:client_cert]
+        req.ssl_key     = ssl[:client_key]  if ssl[:client_key]
+        req.ssl_cacert  = ssl[:ca_file]          if ssl[:ca_file]
+        req.ssl_capath  = ssl[:ca_path]          if ssl[:ca_path]
+      end
+
+      def configure_proxy(req, env)
+        proxy = request_options(env)[:proxy]
+        return unless proxy
+
+        req.proxy = "#{proxy[:uri].host}:#{proxy[:uri].port}"
+
+        if proxy[:user] && proxy[:password]
+          req.proxy_username = proxy[:user]
+          req.proxy_password = proxy[:password]
+        end
+      end
+
+      def configure_timeout(req, env)
+        env_req = request_options(env)
+        req.timeout = req.connect_timeout = (env_req[:timeout] * 1000) if env_req[:timeout]
+        req.connect_timeout = (env_req[:open_timeout] * 1000)          if env_req[:open_timeout]
+      end
+
+      def configure_socket(req, env)
+        if bind = request_options(env)[:bind]
+          req.interface = bind[:host]
+        end
+      end
+
+      def request_options(env)
+        env[:request]
+      end
+
+      def parallel?(env)
+        !!env[:parallel_manager]
+      end
+    end
+  end
+end