This commit is contained in:
HoneyryderChuck 2018-03-18 01:25:46 +00:00
commit fb31512c29
10 changed files with 40 additions and 47 deletions

View File

@ -20,14 +20,20 @@ test_ruby21:
script:
./spec.sh ruby 2.1
test_ruby22:
only:
- master
stage: test
script:
./spec.sh ruby 2.2
test_ruby23:
only:
- master
stage: test
script:
./spec.sh ruby 2.3
test_ruby24:
only:
- master
stage: test
script:
./spec.sh ruby 2.4

View File

@ -7,7 +7,7 @@ gemspec
gem "hanna-nouveau", require: false
gem "rake", "~> 12.3"
gem "rubocop", require: false
gem "rubocop", "~> 0.52.1", require: false
gem "simplecov", require: false
platform :mri do

View File

@ -90,6 +90,10 @@ It means that it loads the bare minimum to perform requests, and the user has to
It also means that it ships with the minimum amount of dependencies.
## Easy to test
The test suite runs against [httpbin proxied over nghttp2](https://nghttp2.org/httpbin/), so there is no mocking/stubbing going on. The test suite uses [minitest](https://github.com/seattlerb/minitest), but its matchers usage is limit to assert (assert is all you need).
## Supported Rubies
All Rubies greater or equal to 2.1, and always latest JRuby.

View File

@ -1,5 +1,6 @@
# frozen_string_literal: true
require "resolv"
require "forwardable"
require "httpx/io"
require "httpx/buffer"
@ -68,13 +69,13 @@ module HTTPX
end
def match?(uri)
ip = begin
TCPSocket.getaddress(uri.host)
rescue StandardError
uri.host
end
ips = begin
Resolv.getaddresses(uri.host)
rescue StandardError
[uri.host]
end
ip == @io.ip &&
ips.include?(@io.ip) &&
uri.port == @io.port &&
uri.scheme == @io.scheme
end
@ -98,18 +99,9 @@ module HTTPX
@io.to_io
end
def close(hard = false)
pr = @parser
def close
@parser.close
transition(:closing)
if hard || (pr && pr.empty?)
pr.close
@parser = nil
else
transition(:idle)
@parser = pr
parser.reenqueue!
return
end
end
def reset
@ -154,7 +146,10 @@ module HTTPX
def dread(wsize = @window_size)
loop do
siz = @io.read(wsize, @read_buffer)
throw(:close, self) unless siz
unless siz
emit(:close)
return
end
return if siz.zero?
log { "READ: #{siz} bytes..." }
parser << @read_buffer.to_s
@ -165,7 +160,10 @@ module HTTPX
loop do
return if @write_buffer.empty?
siz = @io.write(@write_buffer)
throw(:close, self) unless siz
unless siz
emit(:close)
return
end
log { "WRITE: #{siz} bytes..." }
return if siz.zero?
end
@ -190,11 +188,8 @@ module HTTPX
parser.on(:promise) do |*args|
emit(:promise, *args)
end
# parser.inherit_callbacks(self)
parser.on(:complete) { throw(:close, self) }
parser.on(:close) do
transition(:closed)
emit(:close)
transition(:closing)
end
parser
end

View File

@ -151,7 +151,7 @@ module HTTPX
# 1 keep alive request.
@max_concurrent_requests = 1
end
emit(:complete)
emit(:close)
end
private

View File

@ -170,7 +170,7 @@ module HTTPX
def on_close(*)
return unless @connection.state == :closed && @connection.active_stream_count.zero?
emit(:complete)
emit(:close)
end
def on_frame_sent(frame)

View File

@ -19,19 +19,15 @@ module HTTPX
def next_tick(timeout: @timeout.timeout)
@selector.select(timeout) do |monitor|
if (channel = monitor.value)
consume(channel)
channel.call
end
monitor.interests = channel.interests
end
end
def close(channel = nil)
if channel
channel.close
else
@channels.each(&:close)
next_tick until @selector.empty?
end
def close
@channels.each(&:close)
next_tick until @channels.empty?
end
def reset
@ -65,10 +61,5 @@ module HTTPX
end
@channels << channel
end
def consume(channel)
ch = catch(:close) { channel.call }
close(ch) if ch
end
end
end

View File

@ -1,5 +1,6 @@
# frozen_string_literal: true
require "resolv"
require "socket"
require "openssl"
require "ipaddr"
@ -19,7 +20,7 @@ module HTTPX
if @options.io
@io = case @options.io
when Hash
@ip = TCPSocket.getaddress(hostname)
@ip = Resolv.getaddress(@hostname)
@options.io[@ip] || @options.io["#{@ip}:#{@port}"]
else
@ip = hostname
@ -30,7 +31,7 @@ module HTTPX
@state = :connected
end
else
@ip = TCPSocket.getaddress(hostname)
@ip = Resolv.getaddress(@hostname)
end
@io ||= build_socket
end

View File

@ -34,7 +34,7 @@ module HTTPX
return if @io.closed?
@parser = ConnectProxyParser.new(@write_buffer, @options.merge(max_concurrent_requests: 1))
@parser.once(:response, &method(:on_connect))
@parser.on(:complete) { throw(:close, self) }
@parser.on(:close) { transition(:closing) }
proxy_connect
return if @state == :open
when :open
@ -45,7 +45,7 @@ module HTTPX
when :idle
@parser = ProxyParser.new(@write_buffer, @options)
@parser.inherit_callbacks(self)
@parser.on(:complete) { throw(:close, self) }
@parser.on(:close) { transition(:closing) }
end
end
super

View File

@ -48,10 +48,6 @@ class HTTPX::Selector
@closed = false
end
def empty?
@readers.empty? && @writers.empty?
end
# deregisters +io+ from selectables.
def deregister(io)
@lock.synchronize do