From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on dcvr.yhbt.net X-Spam-Level: X-Spam-ASN: X-Spam-Status: No, score=-4.0 required=3.0 tests=ALL_TRUSTED,BAYES_00 shortcircuit=no autolearn=ham autolearn_force=no version=3.4.0 Received: from localhost (dcvr.yhbt.net [127.0.0.1]) by dcvr.yhbt.net (Postfix) with ESMTP id 933AC20451 for ; Wed, 14 Dec 2016 06:59:55 +0000 (UTC) From: Eric Wong To: yahns-public@yhbt.net Subject: [PATCH 1/2] response: do not set chunked header on bodyless responses Date: Wed, 14 Dec 2016 06:59:51 +0000 Message-Id: <20161214065952.28950-2-e@80x24.org> In-Reply-To: <20161214065952.28950-1-e@80x24.org> References: <20161214065952.28950-1-e@80x24.org> List-Id: Setting "Transfer-Encoding: chunked" on responses will confuse clients which see a 204 response and do not expect a body. This follows Rack::Chunked behavior, as yahns should function without Rack::Chunked middleware. This regression appeared in yahns v1.13.0 (2016-08-05) --- lib/yahns/http_response.rb | 4 ++-- test/test_auto_chunk.rb | 22 +++++++++++++++++++++- 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/lib/yahns/http_response.rb b/lib/yahns/http_response.rb index a31ab70..bde4b3f 100644 --- a/lib/yahns/http_response.rb +++ b/lib/yahns/http_response.rb @@ -165,12 +165,12 @@ def http_response_write(res, opt) end count ||= clen - if !term && chunk_ok + if !term && chunk_ok && !hdr_only term = true body = Yahns::ChunkBody.new(body, opt) buf << "Transfer-Encoding: chunked\r\n".freeze end - alive &&= term + alive &&= (term || hdr_only) buf << (alive ? "Connection: keep-alive\r\n\r\n".freeze : "Connection: close\r\n\r\n".freeze) case rv = kgio_syssend(buf, flags) diff --git a/test/test_auto_chunk.rb b/test/test_auto_chunk.rb index a97fe26..e1847f6 100644 --- a/test/test_auto_chunk.rb +++ b/test/test_auto_chunk.rb @@ -18,7 +18,12 @@ def test_auto_head app = Rack::Builder.new do use Rack::ContentType, "text/plain" run(lambda do |env| - [ 200, {}, %w(a b c) ] + case env['PATH_INFO'] + when '/204' + [ 204, {}, [] ] + else + [ 200, {}, %w(a b c) ] + end end) end app(:rack, app) { listen "#{host}:#{port}" } @@ -50,6 +55,21 @@ def test_auto_head assert_equal 200, res.code.to_i assert_equal 'abc', res.body end + + s = TCPSocket.new(host, port) + s.write("GET /204 HTTP/1.1\r\nHost: example.com\r\n\r\n") + buf = s.readpartial(1024) + assert_match %r{\r\n\r\n\z}, buf + refute_match %r{^Transfer-Encoding}i, buf + assert_match %r{^Connection: keep-alive\r\n}, buf + assert_nil IO.select([s], nil, nil, 1), 'connection persists..' + + # maek sure another on the same connection works + s.write("GET / HTTP/1.1\r\nHost: example.com\r\n\r\n") + buf = s.readpartial(1024) + assert_match %r{\AHTTP/1\.1 200}, buf + assert_match(%r{^Transfer-Encoding: chunked\r\n}, buf) + s.close ensure quit_wait(pid) end -- EW