added debug_level option, which can make logs more verbose

This commit is contained in:
HoneyryderChuck 2017-12-19 12:59:52 +02:00
parent 0f42c368c7
commit 193828527b
4 changed files with 33 additions and 18 deletions

View File

@ -61,7 +61,7 @@ module HTTPX
# must be public methods, or else they won't be reachable
def on_message_begin
log { "parsing begins" }
log(2) { "parsing begins" }
end
def on_headers_complete(h)
@ -70,7 +70,7 @@ module HTTPX
request = @requests.last
return if request.response
log { "headers received" }
log(2) { "headers received" }
headers = @options.headers_class.new(h)
response = @options.response_class.new(@requests.last, @parser.status_code, headers, @options)
log { "-> HEADLINE: #{response.status} HTTP/#{@parser.http_version.join(".")}" }
@ -84,11 +84,12 @@ module HTTPX
def on_body(chunk)
log { "-> DATA: #{chunk.bytesize} bytes..." }
log(2) { "-> #{chunk.inspect}" }
@requests.last.response << chunk
end
def on_message_complete
log { "parsing complete" }
log(2) { "parsing complete" }
@parser.reset!
request = @requests.first
return handle(request) if request.expects?
@ -106,7 +107,7 @@ module HTTPX
# 1 keep alive request.
@max_concurrent_requests = 1
end
log { "connection: close" }
log(2) { "connection: close" }
emit(:close)
end
end
@ -145,6 +146,7 @@ module HTTPX
return if request.empty?
while chunk = request.drain_body
log { "<- DATA: #{chunk.bytesize} bytes..." }
log(2) { "<- #{chunk.inspect}" }
@buffer << chunk
throw(:buffer_full, request) if @buffer.full?
end
@ -154,8 +156,9 @@ module HTTPX
field.to_s.split("-").map(&:capitalize).join("-")
end
def log(&msg)
return unless @options.debug
def log(level=@options.debug_level, &msg)
return unless @options.debug
return unless @options.debug_level >= level
@options.debug << (+"" << msg.call << "\n")
end
end

View File

@ -42,17 +42,19 @@ module HTTPX
end
response = request.response || ErrorResponse.new(error, retries)
emit(:response, request, response)
log(stream.id) { "closing stream" }
log(stream.id, 2) { "closing stream" }
@streams.delete(request)
send(@pending.shift) unless @pending.empty?
end
stream.on(:half_close) do
log(stream.id) { "waiting for response..." }
log(stream.id, 2) { "waiting for response..." }
end
# stream.on(:altsvc)
stream.on(:headers) do |h|
log(stream.id) { "received headers: #{h.inspect}" }
log(stream.id) do
h.map { |k, v| "<- HEADER: #{k}: #{v}" }.join("\n")
end
_, status = h.shift
headers = @options.headers_class.new(h)
response = @options.response_class.new(request, status, headers, @options)
@ -60,6 +62,8 @@ module HTTPX
@streams[request] = stream
end
stream.on(:data) do |data|
log(stream.id) { "<- DATA: #{data.bytesize} bytes..." }
log(stream.id, 2) { "<- #{data.inspect}" }
request.response << data
end
@streams[request] = stream
@ -112,6 +116,9 @@ module HTTPX
headers[":path"] = request.path
headers[":authority"] = request.authority
headers = headers.merge(request.headers)
log(stream.id) do
headers.map { |k, v| "-> HEADER: #{k}: #{v}" }.join("\n")
end
stream.headers(headers, end_stream: request.empty?)
end
@ -119,6 +126,8 @@ module HTTPX
chunk = @drains.delete(request) || request.drain_body
while chunk
next_chunk = request.drain_body
log(stream.id) { "-> DATA: #{chunk.bytesize} bytes..." }
log(stream.id, 2) { "-> #{chunk.inspect}" }
stream.data(chunk, end_stream: !next_chunk)
if next_chunk && @buffer.full?
@drains[request] = next_chunk
@ -147,8 +156,8 @@ module HTTPX
end
def on_frame_sent(frame)
log(frame[:stream]) { "frame was sent!" }
log(frame[:stream]) do
log(frame[:stream], 2) { "frame was sent!" }
log(frame[:stream], 2) do
case frame[:type]
when :data
frame.merge(payload: frame[:payload].bytesize).inspect
@ -161,8 +170,8 @@ module HTTPX
end
def on_frame_received(frame)
log(frame[:stream]) { "frame was received!" }
log(frame[:stream]) do
log(frame[:stream], 2) { "frame was received!" }
log(frame[:stream], 2) do
case frame[:type]
when :data
frame.merge(payload: frame[:payload].bytesize).inspect
@ -173,18 +182,19 @@ module HTTPX
end
def on_altsvc(frame)
log(frame[:stream]) { "altsvc frame was received" }
log(frame[:stream]) { frame.inspect }
log(frame[:stream], 2) { "altsvc frame was received" }
log(frame[:stream], 2) { frame.inspect }
end
def on_promise(stream)
log(stream.id) { "refusing stream!" }
log(stream.id, 2) { "refusing stream!" }
stream.refuse
# TODO: policy for handling promises
end
def log(stream=nil, &msg)
def log(stream=nil, level = @options.debug_level, &msg)
return unless @options.debug
return unless @options.debug_level >= level
prefix = +"connection (HTTP/2, stream: #{stream || 0}):"
@options.debug << (prefix << msg.call << "\n")
end

View File

@ -40,6 +40,7 @@ module HTTPX
def initialize(options = {})
defaults = {
:debug => ENV.key?("HTTPX_DEBUG") ? $stderr : nil,
:debug_level => (ENV["HTTPX_DEBUG"] || 1).to_i,
:proxy => {},
:ssl => { alpn_protocols: %w[h2 http/1.1] },
:fallback_protocol => "http/1.1",
@ -86,7 +87,7 @@ module HTTPX
params form json body
proxy follow ssl max_retries
request_class response_class headers_class response_body_class
io fallback_protocol debug
io fallback_protocol debug debug_level
].each do |method_name|
def_option(method_name)
end

View File

@ -59,6 +59,7 @@ class OptionsSpec < Minitest::Test
assert foo.merge(bar).to_hash == {
:io => ENV.key?("HTTPX_DEBUG") ? $stderr : nil,
:debug => nil,
:debug_level => 1,
:params => nil,
:json => nil,
:body => nil,