yahns Ruby server user/dev discussion
 help / color / mirror / code / Atom feed
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).