mirror of
https://github.com/HoneyryderChuck/httpx.git
synced 2025-12-12 00:02:10 -05:00
Merge branch 'github-issue-5' into 'master'
fix for loop on resolution and retry on new connection See merge request honeyryderchuck/httpx!215
This commit is contained in:
commit
e691cbdf5e
1
Gemfile
1
Gemfile
@ -116,6 +116,7 @@ group :assorted do
|
|||||||
gem "pry-byebug", "~> 3.4.3"
|
gem "pry-byebug", "~> 3.4.3"
|
||||||
else
|
else
|
||||||
gem "pry-byebug"
|
gem "pry-byebug"
|
||||||
|
gem "debug" if RUBY_VERSION >= "3.1.0"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@ -1,25 +1,36 @@
|
|||||||
require "httpx"
|
require "httpx"
|
||||||
require "oga"
|
require "oga"
|
||||||
|
|
||||||
|
http = HTTPX.plugin(:compression).plugin(:persistent).with(timeout: { operation_timeut: 5, connect_timeout: 5})
|
||||||
|
|
||||||
PAGES = (ARGV.first || 10).to_i
|
PAGES = (ARGV.first || 10).to_i
|
||||||
pages = PAGES.times.map do |page|
|
pages = PAGES.times.map do |page|
|
||||||
"https://news.ycombinator.com/?p=#{page+1}"
|
"https://news.ycombinator.com/?p=#{page+1}"
|
||||||
end
|
end
|
||||||
|
|
||||||
links = []
|
links = Array.new(PAGES) { [] }
|
||||||
HTTPX.plugin(:compression).get(*pages).each_with_index.map do |response, i|
|
Array(http.get(*pages)).each_with_index.map do |response, i|
|
||||||
if response.is_a?(HTTPX::ErrorResponse)
|
if response.is_a?(HTTPX::ErrorResponse)
|
||||||
puts "error: #{response.error}"
|
puts "error: #{response.error}"
|
||||||
next
|
next
|
||||||
end
|
end
|
||||||
html = Oga.parse_html(response.to_s)
|
html = Oga.parse_html(response.to_s)
|
||||||
page_links = html.css('.itemlist a.storylink').map{|link| link.get('href') }
|
# binding.irb
|
||||||
|
page_links = html.css('.itemlist a.titlelink').map{|link| link.get('href') }
|
||||||
puts "page(#{i+1}): #{page_links.size}"
|
puts "page(#{i+1}): #{page_links.size}"
|
||||||
if page_links.size == 0
|
if page_links.size == 0
|
||||||
puts "error(#{response.status}) on page #{i+1}"
|
puts "error(#{response.status}) on page #{i+1}"
|
||||||
end
|
end
|
||||||
links << page_links
|
# page_links.each do |link|
|
||||||
|
# puts "link: #{link}"
|
||||||
|
# links[i] << http.get(link)
|
||||||
|
# end
|
||||||
|
links[i].concat(http.get(*page_links))
|
||||||
end
|
end
|
||||||
|
|
||||||
links = links.flatten
|
links = links.each_with_index do |pages, i|
|
||||||
puts "Pages: #{PAGES}\t Links: #{links.size}"
|
puts "Page: #{i+1}\t Links: #{pages.size}"
|
||||||
|
pages.each do |page|
|
||||||
|
puts "URL: #{page.uri} (#{page.status})"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|||||||
@ -83,6 +83,7 @@ module HTTPX
|
|||||||
end
|
end
|
||||||
|
|
||||||
module ArrayExtensions
|
module ArrayExtensions
|
||||||
|
module FilterMap
|
||||||
refine Array do
|
refine Array do
|
||||||
|
|
||||||
def filter_map
|
def filter_map
|
||||||
@ -92,13 +93,31 @@ module HTTPX
|
|||||||
processed = yield(item)
|
processed = yield(item)
|
||||||
res << processed if processed
|
res << processed if processed
|
||||||
end
|
end
|
||||||
|
end
|
||||||
end unless Array.method_defined?(:filter_map)
|
end unless Array.method_defined?(:filter_map)
|
||||||
|
end
|
||||||
|
|
||||||
|
module Sum
|
||||||
|
refine Array do
|
||||||
def sum(accumulator = 0, &block)
|
def sum(accumulator = 0, &block)
|
||||||
values = block_given? ? map(&block) : self
|
values = block_given? ? map(&block) : self
|
||||||
values.inject(accumulator, :+)
|
values.inject(accumulator, :+)
|
||||||
|
end
|
||||||
end unless Array.method_defined?(:sum)
|
end unless Array.method_defined?(:sum)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
module Intersect
|
||||||
|
refine Array do
|
||||||
|
def intersect?(arr)
|
||||||
|
if size < arr.size
|
||||||
|
smaller = self
|
||||||
|
else
|
||||||
|
smaller, arr = arr, self
|
||||||
|
end
|
||||||
|
(array & smaller).size > 0
|
||||||
|
end
|
||||||
|
end unless Array.method_defined?(:intersect?)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
module IOExtensions
|
module IOExtensions
|
||||||
|
|||||||
@ -72,7 +72,7 @@ module HTTPX
|
|||||||
end
|
end
|
||||||
|
|
||||||
module ResponseBodyMethods
|
module ResponseBodyMethods
|
||||||
using ArrayExtensions
|
using ArrayExtensions::FilterMap
|
||||||
|
|
||||||
attr_reader :encodings
|
attr_reader :encodings
|
||||||
|
|
||||||
|
|||||||
@ -7,7 +7,7 @@ require "httpx/resolver"
|
|||||||
|
|
||||||
module HTTPX
|
module HTTPX
|
||||||
class Pool
|
class Pool
|
||||||
using ArrayExtensions
|
using ArrayExtensions::FilterMap
|
||||||
extend Forwardable
|
extend Forwardable
|
||||||
|
|
||||||
def_delegator :@timers, :after
|
def_delegator :@timers, :after
|
||||||
|
|||||||
@ -6,7 +6,7 @@ require "resolv"
|
|||||||
module HTTPX
|
module HTTPX
|
||||||
class Resolver::Multi
|
class Resolver::Multi
|
||||||
include Callbacks
|
include Callbacks
|
||||||
using ArrayExtensions
|
using ArrayExtensions::FilterMap
|
||||||
|
|
||||||
attr_reader :resolvers
|
attr_reader :resolvers
|
||||||
|
|
||||||
|
|||||||
@ -8,6 +8,8 @@ module HTTPX
|
|||||||
include Callbacks
|
include Callbacks
|
||||||
include Loggable
|
include Loggable
|
||||||
|
|
||||||
|
using ArrayExtensions::Intersect
|
||||||
|
|
||||||
RECORD_TYPES = {
|
RECORD_TYPES = {
|
||||||
Socket::AF_INET6 => Resolv::DNS::Resource::IN::AAAA,
|
Socket::AF_INET6 => Resolv::DNS::Resource::IN::AAAA,
|
||||||
Socket::AF_INET => Resolv::DNS::Resource::IN::A,
|
Socket::AF_INET => Resolv::DNS::Resource::IN::A,
|
||||||
@ -48,6 +50,10 @@ module HTTPX
|
|||||||
addresses.map! do |address|
|
addresses.map! do |address|
|
||||||
address.is_a?(IPAddr) ? address : IPAddr.new(address.to_s)
|
address.is_a?(IPAddr) ? address : IPAddr.new(address.to_s)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# double emission check
|
||||||
|
return if connection.addresses && !addresses.intersect?(connection.addresses)
|
||||||
|
|
||||||
log { "resolver: answer #{connection.origin.host}: #{addresses.inspect}" }
|
log { "resolver: answer #{connection.origin.host}: #{addresses.inspect}" }
|
||||||
if @pool && # if triggered by early resolve, pool may not be here yet
|
if @pool && # if triggered by early resolve, pool may not be here yet
|
||||||
!connection.io &&
|
!connection.io &&
|
||||||
@ -56,9 +62,13 @@ module HTTPX
|
|||||||
addresses.first.to_s != connection.origin.host.to_s
|
addresses.first.to_s != connection.origin.host.to_s
|
||||||
log { "resolver: A response, applying resolution delay..." }
|
log { "resolver: A response, applying resolution delay..." }
|
||||||
@pool.after(0.05) do
|
@pool.after(0.05) do
|
||||||
|
# double emission check
|
||||||
|
unless connection.addresses && addresses.intersect?(connection.addresses)
|
||||||
|
|
||||||
connection.addresses = addresses
|
connection.addresses = addresses
|
||||||
emit(:resolve, connection)
|
emit(:resolve, connection)
|
||||||
end
|
end
|
||||||
|
end
|
||||||
else
|
else
|
||||||
connection.addresses = addresses
|
connection.addresses = addresses
|
||||||
emit(:resolve, connection)
|
emit(:resolve, connection)
|
||||||
|
|||||||
@ -310,9 +310,12 @@ module HTTPX
|
|||||||
|
|
||||||
class ErrorResponse
|
class ErrorResponse
|
||||||
include Loggable
|
include Loggable
|
||||||
|
extend Forwardable
|
||||||
|
|
||||||
attr_reader :request, :error
|
attr_reader :request, :error
|
||||||
|
|
||||||
|
def_delegator :@request, :uri
|
||||||
|
|
||||||
def initialize(request, error, options)
|
def initialize(request, error, options)
|
||||||
@request = request
|
@request = request
|
||||||
@error = error
|
@error = error
|
||||||
|
|||||||
@ -9,7 +9,7 @@ module HTTPX::Transcoder
|
|||||||
module_function
|
module_function
|
||||||
|
|
||||||
class Encoder
|
class Encoder
|
||||||
using HTTPX::ArrayExtensions
|
using HTTPX::ArrayExtensions::Sum
|
||||||
extend Forwardable
|
extend Forwardable
|
||||||
|
|
||||||
def_delegator :@raw, :to_s
|
def_delegator :@raw, :to_s
|
||||||
|
|||||||
@ -96,6 +96,7 @@ module HTTPX
|
|||||||
class ErrorResponse
|
class ErrorResponse
|
||||||
include _Response
|
include _Response
|
||||||
include Loggable
|
include Loggable
|
||||||
|
extend Forwardable
|
||||||
|
|
||||||
@options: Options
|
@options: Options
|
||||||
@error: Exception
|
@error: Exception
|
||||||
@ -104,6 +105,8 @@ module HTTPX
|
|||||||
|
|
||||||
def status: () -> (Integer | _ToS)
|
def status: () -> (Integer | _ToS)
|
||||||
|
|
||||||
|
def uri: () -> URI::Generic
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def initialize: (Request, Exception, options) -> untyped
|
def initialize: (Request, Exception, options) -> untyped
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user