Merge branch 'issue-111' into 'master'

byteslices

Closes #111

See merge request honeyryderchuck/httpx!122
This commit is contained in:
HoneyryderChuck 2021-02-17 17:56:11 +00:00
commit 7f103447ac
5 changed files with 76 additions and 12 deletions

View File

@ -163,13 +163,13 @@ module HTTPX
end
def handle_error(ex)
if ex.is_a?(EOFError) && @request && @request.response &&
if (ex.is_a?(EOFError) || ex.is_a?(TimeoutError)) && @request && @request.response &&
!@request.response.headers.key?("content-length") &&
!@request.response.headers.key?("transfer-encoding")
# if the response does not contain a content-length header, the server closing the
# connnection is the indicator of response consumed.
# https://greenbytes.de/tech/webdav/rfc2616.html#rfc.section.4.4
on_complete
catch(:called) { on_complete }
return
end

View File

@ -66,7 +66,6 @@ module HTTPX
@status_code = code.to_i
raise(Error, "wrong status code (#{@status_code})") unless (100..599).cover?(@status_code)
# @buffer.slice!(0, idx + 1)
@buffer = @buffer.byteslice((idx + 1)..-1)
nextstate(:headers)
end
@ -74,7 +73,8 @@ module HTTPX
def parse_headers
headers = @headers
while (idx = @buffer.index("\n"))
line = @buffer.slice!(0, idx + 1).sub(/\s+\z/, "")
line = @buffer.byteslice(0..idx).sub(/\s+\z/, "")
@buffer = @buffer.byteslice((idx + 1)..-1)
if line.empty?
case @state
when :headers
@ -96,11 +96,11 @@ module HTTPX
separator_index = line.index(":")
raise Error, "wrong header format" unless separator_index
key = line[0..separator_index - 1]
key = line.byteslice(0..(separator_index - 1))
raise Error, "wrong header format" if key.start_with?("\s", "\t")
key.strip!
value = line[separator_index + 1..-1]
value = line.byteslice((separator_index + 1)..-1)
value.strip!
raise Error, "wrong header format" if value.nil?

View File

@ -2,6 +2,8 @@
require "webrick"
require "logger"
require "zlib"
require "stringio"
class TestServer < WEBrick::HTTPServer
def initialize(options = {})
@ -62,3 +64,40 @@ class Expect100Server < TestServer
mount("/delay", DelayedExpect100App)
end
end
class NoContentLengthServer < TestServer
module NoContentLength
def self.extended(obj)
super
obj.singleton_class.class_eval do
alias_method(:setup_header_without_clength, :setup_header)
alias_method(:setup_header, :setup_header_with_clength)
end
end
def setup_header_with_clength
setup_header_without_clength
header.delete("content-length")
end
end
class NoContentLengthApp < WEBrick::HTTPServlet::AbstractServlet
def do_GET(_req, res) # rubocop:disable Naming/MethodName
zipped = StringIO.new
Zlib::GzipWriter.wrap(zipped) do |gz|
gz.write("helloworld")
end
res.body = zipped.string
res.status = 200
res["Content-Encoding"] = "gzip"
res.extend(NoContentLength)
end
end
def initialize(options = {})
super
mount("/", NoContentLengthApp)
end
end

View File

@ -85,6 +85,26 @@ module Requests
assert compressed_data.bytesize < 8012, "body hasn't been compressed"
end
# regression test
def test_plugin_compression_no_content_length
# run this only for http/1.1 mode, as this is a local test server
return unless origin.start_with?("http://")
server = NoContentLengthServer.new
th = Thread.new { server.start }
begin
http = HTTPX.plugin(:compression)
uri = build_uri("/", server.origin)
response = http.get(uri)
verify_status(response, 200)
body = response.body.to_s
assert body == "helloworld"
ensure
server.shutdown
th.join
end
end
unless RUBY_ENGINE == "jruby"
def test_plugin_compression_brotli
session = HTTPX.plugin(:"compression/brotli")

View File

@ -130,15 +130,20 @@ module Requests
assert !path_jar[build_uri("/cookies/set")].empty?
# Test expires
expires_jar = HTTPX::Plugins::Cookies::Jar.new
expires_jar.parse(%(a=b; Path=/; Max-Age=2))
assert !expires_jar[cookies_uri].empty?
maxage_jar = HTTPX::Plugins::Cookies::Jar.new
maxage_jar.parse(%(a=b; Path=/; Max-Age=2))
assert !maxage_jar[cookies_uri].empty?
sleep 3
assert maxage_jar[cookies_uri].empty?
expires_jar = HTTPX::Plugins::Cookies::Jar.new
expires_jar.parse(%(a=b; Path=/; Expires=Sat, 02 Nov 2019 15:24:00 GMT))
assert expires_jar[cookies_uri].empty?
maxage_jar = HTTPX::Plugins::Cookies::Jar.new
maxage_jar.parse(%(a=b; Path=/; Expires=Sat, 02 Nov 2019 15:24:00 GMT))
assert maxage_jar[cookies_uri].empty?
# regression test
rfc2616_expires_jar = HTTPX::Plugins::Cookies::Jar.new
rfc2616_expires_jar.parse(%(a=b; Path=/; Expires=Fri, 17-Feb-2023 12:43:41 GMT))
assert !rfc2616_expires_jar[cookies_uri].empty?
# Test domain
domain_jar = HTTPX::Plugins::Cookies::Jar.new