From: Eric Wong <e@80x24.org>
To: yahns-public@yhbt.net
Subject: [REJECT] proxy: return requested HTTP version for 1.0 responses
Date: Tue, 2 Feb 2016 01:50:34 +0000 [thread overview]
Message-ID: <20160202015034.25233-1-e@80x24.org> (raw)
(A work-in-progress).
Rejecting this for now, not sure if it's worth it
given how HTTP/1.0 clients tend to be able to process
Content-Length: just fine.
---
lib/yahns/proxy_http_response.rb | 69 +++++++++++++++++++++++-----------------
test/test_proxy_pass.rb | 7 ++--
2 files changed, 42 insertions(+), 34 deletions(-)
diff --git a/lib/yahns/proxy_http_response.rb b/lib/yahns/proxy_http_response.rb
index 0a7e722..8ccf20c 100644
--- a/lib/yahns/proxy_http_response.rb
+++ b/lib/yahns/proxy_http_response.rb
@@ -70,42 +70,51 @@ def proxy_response_start(res, tip, kcar, req_res)
alive = @hs.next? && self.class.persistent_connections
response_headers = env['yahns.proxy_pass.response_headers']
- res = "HTTP/1.1 #{msg ? %Q(#{code} #{msg}) : status}\r\n".dup
- headers.each do |key,value| # n.b.: headers is an Array of 2-element Arrays
- case key
- when /\A(?:Connection|Keep-Alive)\z/i
- next # do not let some upstream headers leak through
- when %r{\AContent-Length\z}i
- flags |= MSG_MORE if have_body && value.to_i > 0
+ if ver = env['HTTP_VERSION']
+ zero = ver == 'HTTP/1.0'.freeze
+ res = "#{ver} #{msg ? %Q(#{code} #{msg}) : status}\r\n".dup
+ # n.b.: headers is an Array of 2-element Arrays
+ headers.each do |key,value|
+ case key
+ when /\A(?:Connection|Keep-Alive)\z/i
+ next # do not let some upstream headers leak through
+ when %r{\AContent-Length\z}i
+ next if zero
+ flags |= MSG_MORE if have_body && value.to_i > 0
+ end
+
+ # response header mapping
+ case val = response_headers[key]
+ when :ignore
+ next
+ when String
+ value = val
+ end
+
+ res << "#{key}: #{value}\r\n"
end
- # response header mapping
- case val = response_headers[key]
- when :ignore
- next
- when String
- value = val
+ # For now, do not add a Date: header, assume upstream already did it
+ # but do not care if they did not
+ if zero
+ res << "\r\n".freeze
+ else
+ res << (alive ? "Connection: keep-alive\r\n\r\n".freeze
+ : "Connection: close\r\n\r\n".freeze)
end
- res << "#{key}: #{value}\r\n"
+ # send the headers
+ case rv = kgio_syssend(res, flags)
+ when nil then break # all done, likely
+ when String # partial write, highly unlikely
+ flags = MSG_DONTWAIT
+ res = rv # hope the skb grows
+ when :wait_writable, :wait_readable # highly unlikely in real apps
+ wbuf = proxy_write(nil, res, alive)
+ break # keep buffering as much as possible
+ end while true
end
- # For now, do not add a Date: header, assume upstream already did it
- # but do not care if they did not
- res << (alive ? "Connection: keep-alive\r\n\r\n".freeze
- : "Connection: close\r\n\r\n".freeze)
-
- # send the headers
- case rv = kgio_syssend(res, flags)
- when nil then break # all done, likely
- when String # partial write, highly unlikely
- flags = MSG_DONTWAIT
- res = rv # hope the skb grows
- when :wait_writable, :wait_readable # highly unlikely in real apps
- wbuf = proxy_write(nil, res, alive)
- break # keep buffering as much as possible
- end while true
-
rbuf = Thread.current[:yahns_rbuf]
tip = tip.empty? ? [] : [ tip ]
diff --git a/test/test_proxy_pass.rb b/test/test_proxy_pass.rb
index f6e0efd..f5dfde1 100644
--- a/test/test_proxy_pass.rb
+++ b/test/test_proxy_pass.rb
@@ -371,7 +371,6 @@ def test_proxy_pass
h10 = TCPSocket.new(host, port)
h10.write "GET /chunky-slow-#{delay} HTTP/1.0\r\n\r\n"
res = Timeout.timeout(60) { h10.read }
- assert_match %r{^Connection: close\r\n}, res
assert_match %r{^Content-Type: text/pain\r\n}, res
assert_match %r{\r\n\r\nHI!\z}, res
refute_match %r{^Transfer-Encoding:}, res
@@ -515,7 +514,7 @@ def check_slow_giant_body(host, port)
assert_raises(EOFError) { loop { str << s.readpartial(400, buf) } }
h, b = str.split(/\r\n\r\n/, 2)
assert_equal OMFG, b
- assert_match %r{\AHTTP/1\.1 200\b}, h
+ assert_match %r{\AHTTP/1\.0 200\b}, h
ensure
s.close if s
end
@@ -576,14 +575,14 @@ def check_eof_body(host, port)
s = TCPSocket.new(host, port)
s.write("GET /eof-body-fast HTTP/1.0\r\n\r\n")
res = s.read
- assert_match %r{\AHTTP/1\.1 200 OK\r\n}, res
+ assert_match %r{\AHTTP/1\.0 200 OK\r\n}, res
assert_match %r{\r\n\r\neof-body-fast\z}, res
s.close
s = TCPSocket.new(host, port)
s.write("GET /eof-body-slow HTTP/1.0\r\n\r\n")
res = s.read
- assert_match %r{\AHTTP/1\.1 200 OK\r\n}, res
+ assert_match %r{\AHTTP/1\.0 200 OK\r\n}, res
assert_match %r{\r\n\r\neof-body-slow\z}, res
s.close
end
--
EW
reply other threads:[~2016-02-02 1:50 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=20160202015034.25233-1-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).