added support for connection: close, by:

* sending info on whether the session is in persistent mode to the
request;
* on parser, set keep-alive when persistent, at all times;
* when not persistent, set keep-alive on all requests til the last;
* on error recovery, when resetting to 1 request at a time, still keep
alive to all requests til the last;
* on next error recovery, set connection: close
This commit is contained in:
HoneyryderChuck 2020-04-27 01:14:02 +01:00
parent 8df9b06cd0
commit 5dee4497bf
3 changed files with 12 additions and 4 deletions

View File

@ -78,6 +78,7 @@ module HTTPX
break if idx >= requests_limit
next if request.state == :done
request.headers["connection"] ||= request.options.persistent || idx < requests_limit - 1 ? "keep-alive" : "close"
handle(request)
end
end
@ -206,7 +207,14 @@ module HTTPX
def disable_pipelining
return if @requests.empty?
@requests.each { |r| r.transition(:idle) }
@requests.each do |r|
r.transition(:idle)
# when we disable pipelining, we still want to try keep-alive.
# only when keep-alive with one request fails, do we fallback to
# connection: close.
r.headers["connection"] = "close" if @max_concurrent_requests == 1
end
# server doesn't handle pipelining, and probably
# doesn't support keep-alive. Fallback to send only
# 1 keep alive request.
@ -216,7 +224,7 @@ module HTTPX
def set_request_headers(request)
request.headers["host"] ||= request.authority
request.headers["connection"] ||= "keep-alive"
request.headers["connection"] ||= request.options.persistent ? "keep-alive" : "close"
if !request.headers.key?("content-length") &&
request.body.bytesize == Float::INFINITY
request.chunk!

View File

@ -197,7 +197,7 @@ module HTTPX
def build_request(verb, uri, options)
rklass = @options.request_class
request = rklass.new(verb, uri, @options.merge(options))
request = rklass.new(verb, uri, @options.merge(options).merge(persistent: @persistent))
request.on(:response, &method(:on_response).curry[request])
request.on(:promise, &method(:on_promise))
request

View File

@ -36,7 +36,7 @@ class HTTPTest < Minitest::Test
assert log_output.match(%r{HEADLINE: "GET .+ HTTP/1\.1"})
assert log_output.match(%r{HEADER: Accept: */*})
assert log_output.match(/HEADER: Host: \w+/)
assert log_output.match(/HEADER: Connection: keep\-alive/)
assert log_output.match(/HEADER: Connection: close/)
# assert response headers
assert log_output.match(%r{HEADLINE: 200 HTTP/1\.1})
assert log_output.match(/HEADER: content\-type: \w+/)