about summary refs log tree commit homepage
path: root/lib/yahns/proxy_http_response.rb
diff options
context:
space:
mode:
Diffstat (limited to 'lib/yahns/proxy_http_response.rb')
-rw-r--r--lib/yahns/proxy_http_response.rb37
1 files changed, 21 insertions, 16 deletions
diff --git a/lib/yahns/proxy_http_response.rb b/lib/yahns/proxy_http_response.rb
index c8a2a42..c5e7be5 100644
--- a/lib/yahns/proxy_http_response.rb
+++ b/lib/yahns/proxy_http_response.rb
@@ -43,7 +43,12 @@ module Yahns::HttpResponse # :nodoc:
                      Rack::Utils::HTTP_STATUS_CODES[code]}\r\n\r\n") rescue nil
 
     shutdown rescue nil
-    req_res.shutdown rescue nil
+    @input = @input.close if @input
+
+    # this is safe ONLY because we are in an :ignore state after
+    # Fdmap#forget when we got hijacked:
+    close
+
     nil # signal close of req_res from yahns_step in yahns/proxy_pass.rb
   ensure
     wbuf.wbuf_abort if wbuf
@@ -56,6 +61,7 @@ module Yahns::HttpResponse # :nodoc:
     :wait_readable # self remains in :ignore, wait on upstream
   end
 
+  # start streaming the response once upstream is done sending headers to us.
   # returns :wait_readable if we need to read more from req_res
   # returns :ignore if we yield control to the client(self)
   # returns nil if completely done
@@ -101,7 +107,6 @@ module Yahns::HttpResponse # :nodoc:
     # but the backend does not terminate properly
     if alive && ! term && (env['HTTP_VERSION'] == 'HTTP/1.1'.freeze)
       res << "Transfer-Encoding: chunked\r\n".freeze
-      alive = true
     end
     res << (alive ? "Connection: keep-alive\r\n\r\n".freeze
                   : "Connection: close\r\n\r\n".freeze)
@@ -178,9 +183,9 @@ module Yahns::HttpResponse # :nodoc:
       end
     end
 
-    return proxy_busy_mod_done(alive) unless wbuf
-    req_res.resbuf = wbuf
-    proxy_busy_mod_blocked(wbuf, wbuf.busy)
+    # all done reading response from upstream, req_res will be discarded
+    # when we return nil:
+    wbuf ? proxy_busy_mod_blocked(wbuf, wbuf.busy) : proxy_busy_mod_done(alive)
   rescue => e
     proxy_err_response(502, req_res, e, wbuf)
   end
@@ -248,7 +253,7 @@ module Yahns::HttpResponse # :nodoc:
     end
 
     busy = wbuf.busy and return proxy_busy_mod_blocked(wbuf, busy)
-    proxy_busy_mod_done(wbuf.wbuf_persist) # returns nil
+    proxy_busy_mod_done(wbuf.wbuf_persist) # returns nil to close req_res
   end
 
   def proxy_wait_next(qflags)
@@ -289,23 +294,23 @@ module Yahns::HttpResponse # :nodoc:
     when :close then close
     end
 
-    nil # close the req_res, too
+    nil # signal close for ReqRes#yahns_step
   end
 
   def proxy_busy_mod_blocked(wbuf, busy)
-    q = Thread.current[:yahns_queue]
     # we are completely done reading and buffering the upstream response,
     # but have not completely written the response to the client,
     # yield control to the client socket:
     @state = wbuf
-    case busy
-    when :wait_readable then q.queue_mod(self, Yahns::Queue::QEV_RD)
-    when :wait_writable then q.queue_mod(self, Yahns::Queue::QEV_WR)
-    else
-      abort "BUG: invalid wbuf.busy: #{busy.inspect}"
-    end
-    # no touching self after queue_mod
-    :ignore
+    proxy_wait_next(case busy
+      when :wait_readable then Yahns::Queue::QEV_RD
+      when :wait_writable then Yahns::Queue::QEV_WR
+      else
+        abort "BUG: invalid wbuf.busy: #{busy.inspect}"
+      end)
+    # no touching self after proxy_wait_next, we may be running
+    # HttpClient#yahns_step in a different thread at this point
+    nil # signal close for ReqRes#yahns_step
   end
 
   # n.b.: we can use String#size for optimized dispatch under YARV instead