about summary refs log tree commit homepage
diff options
context:
space:
mode:
-rw-r--r--lib/yahns/wbuf_lite.rb46
-rw-r--r--test/test_proxy_pass_no_buffering.rb7
2 files changed, 26 insertions, 27 deletions
diff --git a/lib/yahns/wbuf_lite.rb b/lib/yahns/wbuf_lite.rb
index 5f25b2e..afee1e9 100644
--- a/lib/yahns/wbuf_lite.rb
+++ b/lib/yahns/wbuf_lite.rb
@@ -2,49 +2,43 @@
 # Copyright (C) 2016 all contributors <yahns-public@yhbt.net>
 # License: GPL-3.0+ <https://www.gnu.org/licenses/gpl-3.0.txt>
 # frozen_string_literal: true
-require_relative 'wbuf_common'
+require_relative 'wbuf'
 
 # This is only used for "proxy_buffering: false"
-class Yahns::WbufLite # :nodoc:
-  include Yahns::WbufCommon
+class Yahns::WbufLite < Yahns::Wbuf # :nodoc:
   attr_reader :busy
 
   def initialize(req_res)
+    super(nil, :ignore)
     @req_res = req_res
-    @busy = false
-    @buf = nil
   end
 
-  # called only by proxy_write in proxy_http_response
   def wbuf_write(client, buf)
-    buf = buf.join if Array === buf
-    buf = @buf << buf if @buf # unlikely
-    do_write(client, buf) # try our best to avoid string copying/appending
+    super
+  rescue
+    @req_res = @req_res.close if @req_res
+    raise
   end
 
-  def do_write(client, buf)
-    case rv = client.kgio_trywrite(buf)
-    when String
-      buf = rv # continue looping
-    when :wait_writable, :wait_readable
-      @buf = buf
-      return @busy = rv
-    when nil
-      @buf = nil
-      return @busy = false
-    end while true
+  def wbuf_flush(client)
+    super
+  rescue
+    @req_res = @req_res.close if @req_res
+    raise
   end
 
   # called by Yahns::HttpClient#step_write
-  def wbuf_flush(client)
-    sym = do_write(client, @buf) and return sym # :wait_writable/:wait_readable
+  def wbuf_close(client)
+    wbuf_abort
 
-    # resume reading
-    client.hijack_cleanup
-    Thread.current[:yahns_queue].queue_mod(@req_res, Yahns::Queue::QEV_RD)
+    # resume reading when @blocked is empty
+    if @req_res
+      client.hijack_cleanup
+      Thread.current[:yahns_queue].queue_mod(@req_res, Yahns::Queue::QEV_RD)
+    end
     :ignore
   rescue
-    @req_res.close
+    @req_res = @req_res.close if @req_res
     raise
   end
 end
diff --git a/test/test_proxy_pass_no_buffering.rb b/test/test_proxy_pass_no_buffering.rb
index 48b8241..b2c8b48 100644
--- a/test/test_proxy_pass_no_buffering.rb
+++ b/test/test_proxy_pass_no_buffering.rb
@@ -79,6 +79,7 @@ class TestProxyPassNoBuffering < Testcase
     req = "GET /giant-body HTTP/1.1\r\nHost: example.com\r\n" \
           "Connection: close\r\n\r\n"
     s.write(req)
+    bufs = []
     sleep 1
     10.times do
       sleep 0.1
@@ -91,10 +92,14 @@ class TestProxyPassNoBuffering < Testcase
         [ deleted1, deleted2 ].each do |ary|
           ary.delete_if { |x| x =~ /\.(?:err|out) \(deleted\)/ }
         end
-        assert_equal 0, deleted1.size, "pid1=#{deleted1.inspect}"
+        assert_equal 1, deleted1.size, "pid1=#{deleted1.inspect}"
         assert_equal 0, deleted2.size, "pid2=#{deleted2.inspect}"
+        bufs.push(deleted1[0])
       end
     end
+    before = bufs.size
+    bufs.uniq!
+    assert bufs.size < before, 'unlinked buffer should not grow'
     buf = ''.dup
     slow = Digest::MD5.new
     ft = Thread.new do