diff options
author | Eric Wong <e@80x24.org> | 2016-02-12 00:55:46 +0000 |
---|---|---|
committer | Eric Wong <e@80x24.org> | 2016-02-12 00:55:46 +0000 |
commit | f6dd9694b43c2625f514e89856834a633b70f91b (patch) | |
tree | 4892bb6ef45fc730adc7a78b0da551d14444e17b | |
parent | 2f820a252252152118ac126546759494d8e6eecc (diff) | |
download | yahns-f6dd9694b43c2625f514e89856834a633b70f91b.tar.gz |
We cannot use the sendfile(2) syscall when serving static files to TLS clients without breaking them. We currently rely on OpenSSL to encrypt the data before it hits the socket, so it must be read into userspace buffers before being written to the socket.
-rw-r--r-- | lib/yahns/sendfile_compat.rb | 4 | ||||
-rw-r--r-- | lib/yahns/wbuf_common.rb | 1 | ||||
-rw-r--r-- | test/test_ssl.rb | 25 |
3 files changed, 25 insertions, 5 deletions
diff --git a/lib/yahns/sendfile_compat.rb b/lib/yahns/sendfile_compat.rb index cdd2d7b..8bd4622 100644 --- a/lib/yahns/sendfile_compat.rb +++ b/lib/yahns/sendfile_compat.rb @@ -22,7 +22,3 @@ module Yahns::SendfileCompat # :nodoc: end while true end end - -class IO # :nodoc: - include Yahns::SendfileCompat -end diff --git a/lib/yahns/wbuf_common.rb b/lib/yahns/wbuf_common.rb index 21e9b3a..c51050b 100644 --- a/lib/yahns/wbuf_common.rb +++ b/lib/yahns/wbuf_common.rb @@ -7,6 +7,7 @@ begin require 'sendfile' rescue LoadError require_relative 'sendfile_compat' + IO.__send__ :include, Yahns::SendfileCompat end module Yahns::WbufCommon # :nodoc: diff --git a/test/test_ssl.rb b/test/test_ssl.rb index a8e3bea..172d8e4 100644 --- a/test/test_ssl.rb +++ b/test/test_ssl.rb @@ -64,9 +64,22 @@ AQjjxMXhwULlmuR/K+WwlaZPiLIBYalLAZQ7ZbOPeVkJ8ePao0eLAgEC def test_ssl_basic err, cfg, host, port = @err, Yahns::Config.new, @srv.addr[3], @srv.addr[1] ctx = srv_ctx + raw = File.read(__FILE__) pid = mkserver(cfg) do cfg.instance_eval do - ru = lambda { |_| [ 200, {'Content-Length'=>'2'}, ['HI'] ] } + ru = lambda do |env| + case env['PATH_INFO'] + when '/static' + f = File.open(__FILE__) + [ 200, { + 'Content-Length' => f.size.to_s, + 'Content-Type'=>'text/plain', + }, + f ] + else + [ 200, {'Content-Length'=>'2'}, ['HI'] ] + end + end app(:rack, ru) { listen "#{host}:#{port}", ssl_ctx: ctx } logger(Logger.new(err.path)) end @@ -81,6 +94,16 @@ AQjjxMXhwULlmuR/K+WwlaZPiLIBYalLAZQ7ZbOPeVkJ8ePao0eLAgEC 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") + buf.clear + Timeout.timeout(60) do + buf << client.readpartial(8192) until buf.include?(raw) + end + head, body = buf.split("\r\n\r\n", 2) + assert_match %r{\AHTTP/1\.\d 200 OK\r\n}, head + assert_equal raw, body + client.write("GET / HTTP/1.0\r\n\r\n") head, body = client.read.split("\r\n\r\n", 2) assert_equal "HI", body |