mirror of
https://github.com/HoneyryderChuck/httpx.git
synced 2025-08-10 00:01:27 -04:00
ssl: allowing non-blocking connects, finally
This commit is contained in:
parent
7b8d0d89f7
commit
4c9b16740f
@ -127,12 +127,8 @@ module HTTPX
|
||||
dwrite
|
||||
transition(:closed)
|
||||
emit(:close)
|
||||
else
|
||||
catch(:called) do
|
||||
dread
|
||||
dwrite
|
||||
parser.consume
|
||||
end
|
||||
when :open
|
||||
consume
|
||||
end
|
||||
nil
|
||||
end
|
||||
@ -144,6 +140,14 @@ module HTTPX
|
||||
|
||||
private
|
||||
|
||||
def consume
|
||||
catch(:called) do
|
||||
dread
|
||||
dwrite
|
||||
parser.consume
|
||||
end
|
||||
end
|
||||
|
||||
def dread(wsize = @window_size)
|
||||
loop do
|
||||
siz = @io.read(wsize, @read_buffer)
|
||||
@ -202,7 +206,7 @@ module HTTPX
|
||||
when :open
|
||||
return if @state == :closed
|
||||
@io.connect
|
||||
return if @io.closed?
|
||||
return unless @io.connected?
|
||||
send_pending
|
||||
when :closing
|
||||
return unless @state == :open
|
||||
|
@ -175,6 +175,10 @@ module HTTPX
|
||||
@negotiated = false
|
||||
end
|
||||
|
||||
def connected?
|
||||
@state == :negotiated
|
||||
end
|
||||
|
||||
def connect
|
||||
super
|
||||
if @keep_open
|
||||
@ -183,11 +187,16 @@ module HTTPX
|
||||
end
|
||||
return if @state == :negotiated ||
|
||||
@state != :connected
|
||||
@io = OpenSSL::SSL::SSLSocket.new(@io, @ctx)
|
||||
@io.hostname = @hostname
|
||||
@io.sync_close = true
|
||||
@io.connect
|
||||
unless @io.is_a?(OpenSSL::SSL::SSLSocket)
|
||||
@io = OpenSSL::SSL::SSLSocket.new(@io, @ctx)
|
||||
@io.hostname = @hostname
|
||||
@io.sync_close = true
|
||||
end
|
||||
# TODO: this might block it all
|
||||
@io.connect_nonblock
|
||||
transition(:negotiated)
|
||||
rescue ::IO::WaitReadable,
|
||||
::IO::WaitWritable
|
||||
end
|
||||
|
||||
if RUBY_VERSION < "2.3"
|
||||
|
@ -92,9 +92,22 @@ module HTTPX
|
||||
end
|
||||
|
||||
def to_io
|
||||
transition(:connecting) if @state == :idle
|
||||
case @state
|
||||
when :idle
|
||||
transition(:connecting)
|
||||
when :connected
|
||||
transition(:open)
|
||||
end
|
||||
@io.to_io
|
||||
end
|
||||
|
||||
def call
|
||||
super
|
||||
case @state
|
||||
when :connecting
|
||||
consume
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
class ProxySSL < SSL
|
||||
|
@ -22,7 +22,7 @@ module HTTPX
|
||||
end
|
||||
parser.send(connect_request)
|
||||
else
|
||||
transition(:open)
|
||||
transition(:connected)
|
||||
end
|
||||
end
|
||||
|
||||
@ -31,13 +31,14 @@ module HTTPX
|
||||
when :connecting
|
||||
return unless @state == :idle
|
||||
@io.connect
|
||||
return if @io.closed?
|
||||
return unless @io.connected?
|
||||
@parser = ConnectProxyParser.new(@write_buffer, @options.merge(max_concurrent_requests: 1))
|
||||
@parser.once(:response, &method(:on_connect))
|
||||
@parser.on(:close) { transition(:closing) }
|
||||
proxy_connect
|
||||
return if @state == :open
|
||||
when :open
|
||||
return if @state == :connected
|
||||
when :connected
|
||||
return unless @state == :idle || @state == :connecting
|
||||
case @state
|
||||
when :connecting
|
||||
@parser.close
|
||||
@ -56,7 +57,7 @@ module HTTPX
|
||||
req, _ = @pending.first
|
||||
request_uri = req.uri
|
||||
@io = ProxySSL.new(@io, request_uri, @options)
|
||||
transition(:open)
|
||||
transition(:connected)
|
||||
throw(:called)
|
||||
else
|
||||
pending = @pending.map(&:first) + @parser.pending
|
||||
|
@ -27,7 +27,7 @@ module HTTPX
|
||||
req, _ = @pending.first
|
||||
request_uri = req.uri
|
||||
@io = ProxySSL.new(@io, request_uri, @options) if request_uri.scheme == "https"
|
||||
transition(:open)
|
||||
transition(:connected)
|
||||
throw(:called)
|
||||
else
|
||||
response = ErrorResponse.new(Error.new("socks error: #{status}"), 0, @options)
|
||||
@ -43,13 +43,13 @@ module HTTPX
|
||||
when :connecting
|
||||
return unless @state == :idle
|
||||
@io.connect
|
||||
return if @io.closed?
|
||||
return unless @io.connected?
|
||||
req, _ = @pending.first
|
||||
return unless req
|
||||
request_uri = req.uri
|
||||
@write_buffer << Packet.connect(@parameters, request_uri)
|
||||
proxy_connect
|
||||
when :open
|
||||
when :connected
|
||||
return unless @state == :connecting
|
||||
@parser = nil
|
||||
end
|
||||
|
@ -17,6 +17,16 @@ module HTTPX
|
||||
Error = Class.new(Error)
|
||||
|
||||
class Socks5ProxyChannel < ProxyChannel
|
||||
def call
|
||||
super
|
||||
case @state
|
||||
when :connecting,
|
||||
:negotiating,
|
||||
:authenticating
|
||||
consume
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def proxy_connect
|
||||
@ -51,7 +61,7 @@ module HTTPX
|
||||
req, _ = @pending.first
|
||||
request_uri = req.uri
|
||||
@io = ProxySSL.new(@io, request_uri, @options) if request_uri.scheme == "https"
|
||||
transition(:open)
|
||||
transition(:connected)
|
||||
throw(:called)
|
||||
end
|
||||
end
|
||||
@ -61,7 +71,7 @@ module HTTPX
|
||||
when :connecting
|
||||
return unless @state == :idle
|
||||
@io.connect
|
||||
return if @io.closed?
|
||||
return unless @io.connected?
|
||||
@write_buffer << Packet.negotiate(@parameters)
|
||||
proxy_connect
|
||||
when :authenticating
|
||||
@ -72,7 +82,7 @@ module HTTPX
|
||||
req, _ = @pending.first
|
||||
request_uri = req.uri
|
||||
@write_buffer << Packet.connect(request_uri)
|
||||
when :open
|
||||
when :connected
|
||||
return unless @state == :negotiating
|
||||
@parser = nil
|
||||
end
|
||||
|
Loading…
x
Reference in New Issue
Block a user