From: Eric Wong <e@80x24.org>
To: yahns-public@yhbt.net
Subject: [PATCH] proxy_pass: attempt to forward premature upstream responses
Date: Sat, 11 Apr 2015 00:41:14 +0000 [thread overview]
Message-ID: <1428712874-27356-1-git-send-email-e@80x24.org> (raw)
Upstreams may shut us down while we're writing a request body,
attempt to forward any responses from the upstream back to the
client which may explain the rejection reason for giant uploads.
---
lib/yahns/proxy_pass.rb | 5 +++++
test/test_proxy_pass.rb | 48 +++++++++++++++++++++++++++++++++++++++++++-----
2 files changed, 48 insertions(+), 5 deletions(-)
diff --git a/lib/yahns/proxy_pass.rb b/lib/yahns/proxy_pass.rb
index d02bb40..e86e9c9 100644
--- a/lib/yahns/proxy_pass.rb
+++ b/lib/yahns/proxy_pass.rb
@@ -139,6 +139,11 @@ def send_req_body(req)
close_req_body(input)
prepare_wait_readable
end
+ rescue Errno::EPIPE, Errno::ECONNRESET, Errno::ENOTCONN
+ # 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)
+ prepare_wait_readable
end
def prepare_wait_readable
diff --git a/test/test_proxy_pass.rb b/test/test_proxy_pass.rb
index eb866b3..840ad1c 100644
--- a/test/test_proxy_pass.rb
+++ b/test/test_proxy_pass.rb
@@ -141,11 +141,21 @@ def chunky.each
[ 200, h, [] ]
end
when 'PUT'
- buf = env['rack.input'].read
- [ 201, {
- 'Content-Length' => buf.bytesize.to_s,
- 'Content-Type' => 'text/plain',
- }, [ buf ] ]
+ case env['PATH_INFO']
+ when '/forbidden-put'
+ # ignore rack.input
+ [ 403, [ %w(Content-Type text/html), %w(Content-Length 0) ], [] ]
+ when '/forbidden-put-abort'
+ env['rack.hijack'].call.close
+ # should not be seen:
+ [ 123, [ %w(Content-Type text/html), %w(Content-Length 0) ], [] ]
+ else
+ buf = env['rack.input'].read
+ [ 201, {
+ 'Content-Length' => buf.bytesize.to_s,
+ 'Content-Type' => 'text/plain',
+ }, [ buf ] ]
+ end
end
end
end
@@ -249,11 +259,13 @@ def test_proxy_pass
app(:rack, ProxiedApp.new) do
listen "#{host2}:#{port2}"
client_max_body_size nil
+ input_buffering :lazy
end
stderr_path err.path
end
end
+ check_forbidden_put(host, port)
check_eof_body(host, port)
check_pipelining(host, port)
check_response_trailer(host, port)
@@ -560,4 +572,30 @@ def check_eof_body(host, port)
s.close
end
end
+
+ def check_forbidden_put(host, port)
+ to_close = []
+ Timeout.timeout(60) do
+ s = TCPSocket.new(host, port)
+ to_close << s
+ s.write("PUT /forbidden-put HTTP/1.1\r\nHost: example.com\r\n" \
+ "Content-Length: #{OMFG.size}\r\n\r\n")
+ assert_equal OMFG.size, s.write(OMFG),
+ "proxy fully buffers, upstream does not"
+ assert_match %r{\AHTTP/1\.1 403 }, s.readpartial(1024)
+ assert_raises(EOFError) { s.readpartial(1) }
+
+ s = TCPSocket.new(host, port)
+ to_close << s
+ s.write("PUT /forbidden-put-abort HTTP/1.1\r\nHost: example.com\r\n" \
+ "Content-Length: #{OMFG.size}\r\n\r\n")
+ assert_equal OMFG.size, s.write(OMFG),
+ "proxy fully buffers, upstream does not"
+ assert_match %r{\AHTTP/1\.1 502 Bad Gateway}, s.readpartial(1024)
+ assert_raises(EOFError) { s.readpartial(1) }
+ @err.truncate(0)
+ end
+ ensure
+ to_close.each(&:close)
+ end
end
--
EW
reply other threads:[~2015-04-11 0:41 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
List information: https://yhbt.net/yahns/README
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1428712874-27356-1-git-send-email-e@80x24.org \
--to=e@80x24.org \
--cc=yahns-public@yhbt.net \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this public inbox
https://yhbt.net/yahns.git/
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).