* [PATCH 1/4] wbuf: drop persistence if writing to client fails
@ 2016-04-25 18:55 Eric Wong
2016-04-25 18:55 ` [PATCH 2/4] proxy_pass: ensure we do not persist connections on failure Eric Wong
` (2 more replies)
0 siblings, 3 replies; 4+ messages in thread
From: Eric Wong @ 2016-04-25 18:55 UTC (permalink / raw)
To: spew
We cannot maintain a persistent connection to a client if
writing to the client fails. This should fix FD leakage on
hijacked responses
---
lib/yahns/wbuf_common.rb | 1 +
1 file changed, 1 insertion(+)
diff --git a/lib/yahns/wbuf_common.rb b/lib/yahns/wbuf_common.rb
index c51050b..dc653ff 100644
--- a/lib/yahns/wbuf_common.rb
+++ b/lib/yahns/wbuf_common.rb
@@ -38,6 +38,7 @@ def wbuf_flush(client)
end while @sf_count > 0
wbuf_close(client)
rescue
+ @wbuf_persist = false
wbuf_close(client)
raise
end
--
EW
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [PATCH 2/4] proxy_pass: ensure we do not persist connections on failure
2016-04-25 18:55 [PATCH 1/4] wbuf: drop persistence if writing to client fails Eric Wong
@ 2016-04-25 18:55 ` Eric Wong
2016-04-25 18:55 ` [PATCH 3/4] fix blocking Eric Wong
2016-04-25 18:55 ` [PATCH 4/4] proxy_http_response Eric Wong
2 siblings, 0 replies; 4+ messages in thread
From: Eric Wong @ 2016-04-25 18:55 UTC (permalink / raw)
To: spew
---
lib/yahns/proxy_http_response.rb | 9 +++++++++
lib/yahns/proxy_pass.rb | 3 ++-
2 files changed, 11 insertions(+), 1 deletion(-)
diff --git a/lib/yahns/proxy_http_response.rb b/lib/yahns/proxy_http_response.rb
index c8a2a42..7320557 100644
--- a/lib/yahns/proxy_http_response.rb
+++ b/lib/yahns/proxy_http_response.rb
@@ -318,4 +318,13 @@ def chunk_out(buf)
def trailer_out(tlr)
"0\r\n#{tlr.map! do |k,v| "#{k}: #{v}\r\n" end.join}\r\n"
end
+
+ def proxy_shutdown
+ to_io.shutdown(Socket::SHUT_RD)
+
+ # hack to ensure @hs.next? returns false the next time it is called:
+ hs = Unicorn::HttpRequest.new
+ hs.env.merge!(@hs.env)
+ @hs = hs
+ end
end
diff --git a/lib/yahns/proxy_pass.rb b/lib/yahns/proxy_pass.rb
index 511db02..7ef865a 100644
--- a/lib/yahns/proxy_pass.rb
+++ b/lib/yahns/proxy_pass.rb
@@ -141,9 +141,10 @@ def send_req_body(req)
prepare_wait_readable
end
rescue Errno::EPIPE, Errno::ECONNRESET, Errno::ENOTCONN
+ # writing to the upstream got us shutdown by the upstream...
# no more reading off the client socket, just prepare to forward
# the rejection response from the upstream (if any)
- @yahns_client.to_io.shutdown(Socket::SHUT_RD)
+ @yahns_client.proxy_shutdown
prepare_wait_readable
end
--
EW
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [PATCH 3/4] fix blocking
2016-04-25 18:55 [PATCH 1/4] wbuf: drop persistence if writing to client fails Eric Wong
2016-04-25 18:55 ` [PATCH 2/4] proxy_pass: ensure we do not persist connections on failure Eric Wong
@ 2016-04-25 18:55 ` Eric Wong
2016-04-25 18:55 ` [PATCH 4/4] proxy_http_response Eric Wong
2 siblings, 0 replies; 4+ messages in thread
From: Eric Wong @ 2016-04-25 18:55 UTC (permalink / raw)
To: spew
---
lib/yahns/proxy_http_response.rb | 21 ++++++++++-----------
1 file changed, 10 insertions(+), 11 deletions(-)
diff --git a/lib/yahns/proxy_http_response.rb b/lib/yahns/proxy_http_response.rb
index 7320557..ae7bd72 100644
--- a/lib/yahns/proxy_http_response.rb
+++ b/lib/yahns/proxy_http_response.rb
@@ -179,7 +179,6 @@ def proxy_response_start(res, tip, kcar, req_res)
end
return proxy_busy_mod_done(alive) unless wbuf
- req_res.resbuf = wbuf
proxy_busy_mod_blocked(wbuf, wbuf.busy)
rescue => e
proxy_err_response(502, req_res, e, wbuf)
@@ -289,23 +288,23 @@ def proxy_busy_mod_done(alive)
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
--
EW
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [PATCH 4/4] proxy_http_response
2016-04-25 18:55 [PATCH 1/4] wbuf: drop persistence if writing to client fails Eric Wong
2016-04-25 18:55 ` [PATCH 2/4] proxy_pass: ensure we do not persist connections on failure Eric Wong
2016-04-25 18:55 ` [PATCH 3/4] fix blocking Eric Wong
@ 2016-04-25 18:55 ` Eric Wong
2 siblings, 0 replies; 4+ messages in thread
From: Eric Wong @ 2016-04-25 18:55 UTC (permalink / raw)
To: spew
---
lib/yahns/proxy_http_response.rb | 3 ++-
lib/yahns/proxy_pass.rb | 4 ++--
2 files changed, 4 insertions(+), 3 deletions(-)
diff --git a/lib/yahns/proxy_http_response.rb b/lib/yahns/proxy_http_response.rb
index ae7bd72..2be5190 100644
--- a/lib/yahns/proxy_http_response.rb
+++ b/lib/yahns/proxy_http_response.rb
@@ -43,7 +43,8 @@ def proxy_err_response(code, req_res, exc, wbuf)
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
+ close
nil # signal close of req_res from yahns_step in yahns/proxy_pass.rb
ensure
wbuf.wbuf_abort if wbuf
diff --git a/lib/yahns/proxy_pass.rb b/lib/yahns/proxy_pass.rb
index 7ef865a..2dd0a59 100644
--- a/lib/yahns/proxy_pass.rb
+++ b/lib/yahns/proxy_pass.rb
@@ -63,7 +63,7 @@ def yahns_step # yahns event loop entry point
when Yahns::WbufCommon # streaming/buffering the response body
- return c.proxy_response_finish(req, resbuf, self)
+ return c.proxy_response_finish(req, wbuf = resbuf, self)
end while true # case @resbuf
@@ -79,7 +79,7 @@ def yahns_step # yahns event loop entry point
when Errno::ECONNREFUSED, Errno::ECONNRESET, Errno::EPIPE
e.set_backtrace([])
end
- c.proxy_err_response(502, self, e, nil)
+ c.proxy_err_response(502, self, e, wbuf)
end
# returns :wait_readable if complete, :wait_writable if not
--
EW
^ permalink raw reply related [flat|nested] 4+ messages in thread
end of thread, other threads:[~2016-04-25 18:55 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2016-04-25 18:55 [PATCH 1/4] wbuf: drop persistence if writing to client fails Eric Wong
2016-04-25 18:55 ` [PATCH 2/4] proxy_pass: ensure we do not persist connections on failure Eric Wong
2016-04-25 18:55 ` [PATCH 3/4] fix blocking Eric Wong
2016-04-25 18:55 ` [PATCH 4/4] proxy_http_response Eric Wong
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).