From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.2 (2011-06-06) on dcvr.yhbt.net X-Spam-Level: X-Spam-ASN: X-Spam-Status: No, score=-2.9 required=3.0 tests=ALL_TRUSTED,AWL,BAYES_00, T_RP_MATCHES_RCVD shortcircuit=no autolearn=unavailable version=3.3.2 X-Original-To: yahns-public@yhbt.net Received: from localhost (dcvr.yhbt.net [127.0.0.1]) by dcvr.yhbt.net (Postfix) with ESMTP id 00ABF63386F for ; Sat, 14 Mar 2015 02:56:09 +0000 (UTC) From: Eric Wong To: yahns-public@yhbt.net Subject: [[RFC]] http_client: hijack after 100-continue disables HTTP response Date: Sat, 14 Mar 2015 02:56:08 +0000 Message-Id: <1426301768-3825-1-git-send-email-e@80x24.org> List-Id: While rack.hijack usage during application dispatch normally prevents yahns from writing an HTTP response out of the Rack response array, this was not correctly prevented when the application emitted a 100-continue response when the client was was too slow to read the 100-continue response without triggering response buffering the server. This bug only affects exceeding rare apps which rely on both rack.hijack use during app dispatch _and_ emits 100-continue responses, and even then it only affects slow clients which refuse to read the 100-continue response sent by yahns without blocking. --- lib/yahns/http_client.rb | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/lib/yahns/http_client.rb b/lib/yahns/http_client.rb index 1c3c8dd..235decd 100644 --- a/lib/yahns/http_client.rb +++ b/lib/yahns/http_client.rb @@ -179,8 +179,9 @@ class Yahns::HttpClient < Kgio::Socket # :nodoc: handle_error(e) end + # only called when buffering slow clients # returns :wait_readable, :wait_writable, :ignore, or nil for epoll - # returns false to keep looping inside yahns_step + # returns true to keep looping inside yahns_step def r100_done k = self.class case k.input_buffering @@ -193,7 +194,9 @@ class Yahns::HttpClient < Kgio::Socket # :nodoc: mkinput_preread # keep looping (@state == :body) true else # :lazy, false - http_response_write(*k.app.call(@hs.env)) + r = k.app.call(env = @hs.env) + return :ignore if env.include?(RACK_HIJACK_IO) + http_response_write(*r) end end -- EW