Eric Wong <[email protected]> wrote:
> Things like rack.url_scheme, SERVER_NAME, SERVER_PORT, etc...
> will all need to be set properly.
SERVER_NAME and SERVER_PORT will be set inside the unicorn HTTP
parser based on the value of the Host: header
-----------8<-----------
Subject: [PATCH] set HTTPS and rack.url_scheme in Rack env as appropriate
env['HTTPS'] is not documented in rack SPEC, but appears to be
used by Rack::Request since 2010[*]. Also, set rack.url_scheme
as documented by rack SPEC.
[*] - commit 4defbe5d7c07b3ba721ff34a8ff59fde480a4a9f
("Improves performance by lazy loading the session.")
---
lib/yahns/http_context.rb | 2 +-
lib/yahns/server.rb | 3 +++
test/test_ssl.rb | 43 +++++++++++++++++++++++++++++++++++--------
3 files changed, 39 insertions(+), 9 deletions(-)
diff --git a/lib/yahns/http_context.rb b/lib/yahns/http_context.rb
index 10be062..c02eefd 100644
--- a/lib/yahns/http_context.rb
+++ b/lib/yahns/http_context.rb
@@ -17,7 +17,7 @@ module Yahns::HttpContext # :nodoc:
attr_accessor :qegg
attr_accessor :queue # set right before spawning acceptors
attr_reader :app
- attr_reader :app_defaults
+ attr_accessor :app_defaults
attr_writer :input_buffer_tmpdir
attr_accessor :output_buffer_tmpdir
diff --git a/lib/yahns/server.rb b/lib/yahns/server.rb
index 09ddbef..d6a03f3 100644
--- a/lib/yahns/server.rb
+++ b/lib/yahns/server.rb
@@ -382,6 +382,9 @@ def fdmap_init
ctx.__send__(:include, l.expire_mod)
if ssl_ctx = opts[:ssl_ctx]
ctx.__send__(:include, Yahns::OpenSSLClient)
+ env = ctx.app_defaults = ctx.app_defaults.dup
+ env['HTTPS'] = 'on' # undocumented, but Rack::Request uses this
+ env['rack.url_scheme'] = 'https'
# call OpenSSL::SSL::SSLContext#setup explicitly here to detect
# errors and avoid race conditions. We avoid calling this in the
diff --git a/test/test_ssl.rb b/test/test_ssl.rb
index 172d8e4..fe7e09e 100644
--- a/test/test_ssl.rb
+++ b/test/test_ssl.rb
@@ -63,12 +63,21 @@ def srv_ctx
def test_ssl_basic
err, cfg, host, port = @err, Yahns::Config.new, @srv.addr[3], @srv.addr[1]
+ insecure = TCPServer.new(ENV["TEST_HOST"] || "127.0.0.1", 0)
ctx = srv_ctx
raw = File.read(__FILE__)
pid = mkserver(cfg) do
+ ENV["YAHNS_FD"] += ",#{insecure.fileno.to_s}"
cfg.instance_eval do
ru = lambda do |env|
- case env['PATH_INFO']
+ case path_info = env['PATH_INFO']
+ when '/rack.url_scheme', '/HTTPS'
+ s = env[path_info[1..-1]] # remove leading slash
+ s = s.inspect if s.nil?
+ [ 200, {
+ 'Content-Length' => s.bytesize.to_s,
+ 'Content-Type'=>'text/plain',
+ }, [ s ] ]
when '/static'
f = File.open(__FILE__)
[ 200, {
@@ -80,19 +89,36 @@ def test_ssl_basic
[ 200, {'Content-Length'=>'2'}, ['HI'] ]
end
end
- app(:rack, ru) { listen "#{host}:#{port}", ssl_ctx: ctx }
+ app(:rack, ru) {
+ listen "#{host}:#{port}", ssl_ctx: ctx
+ listen "#{insecure.addr[3]}:#{insecure.addr[1]}"
+ }
logger(Logger.new(err.path))
end
end
client = ssl_client(host, port)
- client.write("GET / HTTP/1.1\r\nHost: example.com\r\n\r\n")
buf = ''.dup
- Timeout.timeout(60) do
- buf << client.readpartial(111) until buf =~ /HI\z/
+ { '/' => 'HI',
+ '/rack.url_scheme' => 'https',
+ '/HTTPS' => 'on'
+ }.each do |path, exp|
+ client.write("GET #{path} HTTP/1.1\r\nHost: example.com\r\n\r\n")
+ buf.clear
+ re = /#{Regexp.escape(exp)}\z/
+ Timeout.timeout(60) do
+ buf << client.readpartial(111) until buf =~ re
+ end
+ head, body = buf.split("\r\n\r\n", 2)
+ assert_equal exp, body
+ assert_match %r{\AHTTP/1\.\d 200 OK\r\n}, head
+ end
+
+ Net::HTTP.start(insecure.addr[3], insecure.addr[1]) do |h|
+ res = h.get('/rack.url_scheme')
+ assert_equal 'http', res.body
+ res = h.get('/HTTPS')
+ assert_equal 'nil', res.body
end
- head, body = buf.split("\r\n\r\n", 2)
- assert_equal "HI", body
- assert_match %r{\AHTTP/1\.\d 200 OK\r\n}, head
# read static file
client.write("GET /static HTTP/1.1\r\nHost: example.com\r\n\r\n")
@@ -109,6 +135,7 @@ def test_ssl_basic
assert_equal "HI", body
assert_match %r{\AHTTP/1\.\d 200 OK\r\n}, head
ensure
+ insecure.close if insecure
client.close if client
quit_wait(pid)
end
--
EW
--
unsubscribe: [email protected]
archive: http://yhbt.net/yahns-public/