mirror of
https://github.com/HoneyryderChuck/httpx.git
synced 2025-12-09 00:01:48 -05:00
added test exercising the dns error path
This commit is contained in:
parent
c71d4048af
commit
1fb4046d52
@ -132,6 +132,23 @@ module Requests
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
define_method :"test_resolver_#{resolver_type}_dns_error" do
|
||||||
|
start_test_servlet(DNSErrorServer, 0.2) do |slow_dns_server|
|
||||||
|
start_test_servlet(DNSErrorServer, 0.2) do |not_so_slow_dns_server|
|
||||||
|
nameservers = [slow_dns_server.nameserver, not_so_slow_dns_server.nameserver]
|
||||||
|
|
||||||
|
resolver_opts = options.merge(nameserver: nameservers, timeouts: [3])
|
||||||
|
|
||||||
|
HTTPX.plugin(SessionWithPool).wrap do |session|
|
||||||
|
uri = build_uri("/get")
|
||||||
|
|
||||||
|
response = session.get(uri, resolver_class: resolver_type, resolver_options: resolver_opts)
|
||||||
|
verify_error_response(response, /unknown DNS error/)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
# this test mocks a DNS server invalid messages back
|
# this test mocks a DNS server invalid messages back
|
||||||
define_method :"test_resolver_#{resolver_type}_decoding_error" do
|
define_method :"test_resolver_#{resolver_type}_decoding_error" do
|
||||||
session = HTTPX.plugin(SessionWithPool)
|
session = HTTPX.plugin(SessionWithPool)
|
||||||
|
|||||||
22
test/support/servlets/dns_error.rb
Normal file
22
test/support/servlets/dns_error.rb
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
require_relative "test"
|
||||||
|
|
||||||
|
# from https://gist.github.com/peterc/1425383
|
||||||
|
|
||||||
|
class DNSErrorServer < TestDNSResolver
|
||||||
|
private
|
||||||
|
|
||||||
|
def dns_response(query)
|
||||||
|
# Valid response header
|
||||||
|
response = "#{query[0, 2]}\x81\x02#{query[4, 2]}\x00\x00\x00\x00\x00\x00".b
|
||||||
|
|
||||||
|
# Append original question section
|
||||||
|
response << query[12..-1].b
|
||||||
|
|
||||||
|
# Use pointer to refer to domain name in question section
|
||||||
|
response << "\xc0\x0c".b
|
||||||
|
|
||||||
|
response
|
||||||
|
end
|
||||||
|
end
|
||||||
@ -1,56 +1,13 @@
|
|||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
require "resolv"
|
require "resolv"
|
||||||
require "socket"
|
require_relative "test"
|
||||||
|
|
||||||
# from https://gist.github.com/peterc/1425383
|
# from https://gist.github.com/peterc/1425383
|
||||||
|
|
||||||
class SlowDNSServer
|
class SlowDNSServer < TestDNSResolver
|
||||||
attr_reader :queries, :answers
|
|
||||||
|
|
||||||
def initialize(timeout)
|
|
||||||
@port = next_available_port
|
|
||||||
@can_log = ENV.key?("HTTPX_DEBUG")
|
|
||||||
@timeout = timeout
|
|
||||||
@queries = 0
|
|
||||||
@answers = 0
|
|
||||||
end
|
|
||||||
|
|
||||||
def nameserver
|
|
||||||
["127.0.0.1", @port]
|
|
||||||
end
|
|
||||||
|
|
||||||
def start
|
|
||||||
Socket.udp_server_loop(@port) do |query, src|
|
|
||||||
@queries += 1
|
|
||||||
sleep(@timeout)
|
|
||||||
src.reply(dns_response(query))
|
|
||||||
@answers += 1
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def extract_domain(data)
|
|
||||||
domain = +""
|
|
||||||
|
|
||||||
# Check "Opcode" of question header for valid question
|
|
||||||
if (data[2].ord & 120).zero?
|
|
||||||
# Read QNAME section of question section
|
|
||||||
# DNS header section is 12 bytes long, so data starts at offset 12
|
|
||||||
|
|
||||||
idx = 12
|
|
||||||
len = data[idx].ord
|
|
||||||
# Strings are rendered as a byte containing length, then text.. repeat until length of 0
|
|
||||||
until len.zero?
|
|
||||||
domain << "#{data[idx + 1, len]}."
|
|
||||||
idx += len + 1
|
|
||||||
len = data[idx].ord
|
|
||||||
end
|
|
||||||
end
|
|
||||||
domain
|
|
||||||
end
|
|
||||||
|
|
||||||
def dns_response(query)
|
def dns_response(query)
|
||||||
domain = extract_domain(query)
|
domain = extract_domain(query)
|
||||||
ip = Resolv.getaddress(domain)
|
ip = Resolv.getaddress(domain)
|
||||||
@ -87,12 +44,4 @@ class SlowDNSServer
|
|||||||
response << rdata.b
|
response << rdata.b
|
||||||
response
|
response
|
||||||
end
|
end
|
||||||
|
|
||||||
def next_available_port
|
|
||||||
udp = UDPSocket.new
|
|
||||||
udp.bind("127.0.0.1", 0)
|
|
||||||
udp.addr[1]
|
|
||||||
ensure
|
|
||||||
udp.close
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|||||||
@ -111,3 +111,58 @@ class TestHTTP2Server
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
class TestDNSResolver
|
||||||
|
attr_reader :queries, :answers
|
||||||
|
|
||||||
|
def initialize(timeout)
|
||||||
|
@port = next_available_port
|
||||||
|
@can_log = ENV.key?("HTTPX_DEBUG")
|
||||||
|
@timeout = timeout
|
||||||
|
@queries = 0
|
||||||
|
@answers = 0
|
||||||
|
end
|
||||||
|
|
||||||
|
def nameserver
|
||||||
|
["127.0.0.1", @port]
|
||||||
|
end
|
||||||
|
|
||||||
|
def start
|
||||||
|
Socket.udp_server_loop(@port) do |query, src|
|
||||||
|
@queries += 1
|
||||||
|
sleep(@timeout)
|
||||||
|
src.reply(dns_response(query))
|
||||||
|
@answers += 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def extract_domain(data)
|
||||||
|
domain = +""
|
||||||
|
|
||||||
|
# Check "Opcode" of question header for valid question
|
||||||
|
if (data[2].ord & 120).zero?
|
||||||
|
# Read QNAME section of question section
|
||||||
|
# DNS header section is 12 bytes long, so data starts at offset 12
|
||||||
|
|
||||||
|
idx = 12
|
||||||
|
len = data[idx].ord
|
||||||
|
# Strings are rendered as a byte containing length, then text.. repeat until length of 0
|
||||||
|
until len.zero?
|
||||||
|
domain << "#{data[idx + 1, len]}."
|
||||||
|
idx += len + 1
|
||||||
|
len = data[idx].ord
|
||||||
|
end
|
||||||
|
end
|
||||||
|
domain
|
||||||
|
end
|
||||||
|
|
||||||
|
def next_available_port
|
||||||
|
udp = UDPSocket.new
|
||||||
|
udp.bind("127.0.0.1", 0)
|
||||||
|
udp.addr[1]
|
||||||
|
ensure
|
||||||
|
udp.close
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user