lib/httpx/plugins/proxy/http.rb in httpx-0.3.1 vs lib/httpx/plugins/proxy/http.rb in httpx-0.4.0

- old
+ new

@@ -4,57 +4,60 @@ module HTTPX module Plugins module Proxy module HTTP - class HTTPProxyChannel < ProxyChannel + module ConnectionMethods private - def proxy_connect - req, _ = @pending.first - # if the first request after CONNECT is to an https address, it is assumed that - # all requests in the queue are not only ALL HTTPS, but they also share the certificate, - # and therefore, will share the connection. - # - if req.uri.scheme == "https" - connect_request = ConnectRequest.new(req.uri) - if @parameters.authenticated? - connect_request.headers["proxy-authentication"] = "Basic #{@parameters.token_authentication}" - end - parser.send(connect_request) - else - transition(:connected) - end - end - def transition(nextstate) + return super unless @options.proxy && @options.proxy.uri.scheme == "http" + case nextstate when :connecting return unless @state == :idle + @io.connect return unless @io.connected? + @parser = ConnectProxyParser.new(@write_buffer, @options.merge(max_concurrent_requests: 1)) - @parser.once(:response, &method(:on_connect)) + @parser.once(:response, &method(:__http_on_connect)) @parser.on(:close) { transition(:closing) } - proxy_connect + __http_proxy_connect return if @state == :connected when :connected return unless @state == :idle || @state == :connecting + case @state when :connecting @parser.close @parser = nil when :idle @parser = ProxyParser.new(@write_buffer, @options) - @parser.inherit_callbacks(self) + set_parser_callbacks(@parser) @parser.on(:close) { transition(:closing) } end end super end - def on_connect(_request, response) + def __http_proxy_connect + req, _ = @pending.first + # if the first request after CONNECT is to an https address, it is assumed that + # all requests in the queue are not only ALL HTTPS, but they also share the certificate, + # and therefore, will share the connection. + # + if req.uri.scheme == "https" + connect_request = ConnectRequest.new(req.uri, @options) + + parser.send(connect_request) + else + transition(:connected) + end + end + + def __http_on_connect(_request, response) if response.status == 200 req, _ = @pending.first request_uri = req.uri @io = ProxySSL.new(@io, request_uri, @options) transition(:connected) @@ -66,11 +69,11 @@ end end end end - class ProxyParser < Channel::HTTP1 + class ProxyParser < Connection::HTTP1 def headline_uri(request) request.uri.to_s end def set_request_headers(request) @@ -83,10 +86,11 @@ class ConnectProxyParser < ProxyParser attr_reader :pending def headline_uri(request) return super unless request.verb == :connect + uri = request.uri tunnel = "#{uri.hostname}:#{uri.port}" log { "establishing HTTP proxy tunnel to #{tunnel}" } tunnel end @@ -96,20 +100,20 @@ @requests.all? { |request| !request.response.nil? } end end class ConnectRequest < Request - def initialize(uri, options = {}) - super(:connect, uri, options) + def initialize(uri, options) + super(:connect, uri, {}) + proxy_params = options.proxy + @headers["proxy-authentication"] = "Basic #{proxy_params.token_authentication}" if proxy_params.authenticated? @headers.delete("accept") end def path "#{@uri.hostname}:#{@uri.port}" end end - - Parameters.register("http", HTTPProxyChannel) end end register_plugin :"proxy/http", Proxy::HTTP end end