From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.2 (2011-06-06) on dcvr.yhbt.net X-Spam-Level: X-Spam-ASN: X-Spam-Status: No, score=-3.1 required=3.0 tests=ALL_TRUSTED,AWL,BAYES_00, RP_MATCHES_RCVD shortcircuit=no autolearn=unavailable version=3.3.2 X-Original-To: yahns-public@yhbt.net Received: from localhost (dcvr.yhbt.net [127.0.0.1]) by dcvr.yhbt.net (Postfix) with ESMTP id 5F94D202EB for ; Fri, 12 Feb 2016 01:47:25 +0000 (UTC) From: Eric Wong To: yahns-public@yhbt.net Subject: [PATCH 2/3] properly emulate sendfile for OpenSSL sockets Date: Fri, 12 Feb 2016 01:47:12 +0000 Message-Id: <20160212014713.32163-3-e@80x24.org> In-Reply-To: <20160212014713.32163-1-e@80x24.org> References: <20160212014713.32163-1-e@80x24.org> List-Id: 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. --- lib/yahns/sendfile_compat.rb | 4 ---- lib/yahns/wbuf_common.rb | 1 + 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 @@ def trysendfile(io, offset, count) 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 @@ 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 @@ def srv_ctx 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 @@ def test_ssl_basic 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 -- EW