diff options
Diffstat (limited to 'test/test_extras_try_gzip_static.rb')
-rw-r--r-- | test/test_extras_try_gzip_static.rb | 177 |
1 files changed, 177 insertions, 0 deletions
diff --git a/test/test_extras_try_gzip_static.rb b/test/test_extras_try_gzip_static.rb new file mode 100644 index 0000000..416af71 --- /dev/null +++ b/test/test_extras_try_gzip_static.rb @@ -0,0 +1,177 @@ +# Copyright (C) 2013, Eric Wong <normalperson@yhbt.net> and all contributors +# License: GPLv3 or later (https://www.gnu.org/licenses/gpl-3.0.txt) +require_relative 'server_helper' +require 'zlib' +require 'time' + +class TestExtrasTryGzipStatic < Testcase + ENV["N"].to_i > 1 and parallelize_me! + include ServerHelper + GPL_TEXT = IO.binread("COPYING").freeze + + def setup + @tmpdir = Dir.mktmpdir + server_helper_setup + end + + def teardown + server_helper_teardown + FileUtils.rm_rf @tmpdir + end + + def test_gzip_static + err, cfg, host, port = @err, Yahns::Config.new, @srv.addr[3], @srv.addr[1] + tmpdir = @tmpdir + pid = mkserver(cfg) do + require './extras/try_gzip_static' + cfg.instance_eval do + app(:rack, TryGzipStatic.new(tmpdir)) do + listen "#{host}:#{port}" + end + stderr_path err.path + end + end + + begin # setup + gpl = "#{tmpdir}/COPYING" + gplgz = "#{tmpdir}/COPYING.gz" + FileUtils.cp("COPYING", gpl) + _, status = Process.waitpid2(fork do + File.open(gplgz, "w") do |fp| + Zlib::GzipWriter.wrap(fp.dup) { |io| io.write(GPL_TEXT) } + end + exit!(0) + end) + assert status.success?, status.inspect + st = File.stat(gpl) + gz_st = File.stat(gplgz) + assert_equal GPL_TEXT, `zcat #{gplgz}`, "Eric screwed up using zlib" + File.utime(st.atime, st.mtime, gplgz) + end + + check = lambda do |req, &blk| + c = get_tcp_client(host, port) + begin + c.write "#{req}\r\n\r\n" + head, body = c.read.split(/\r\n\r\n/) + blk.call(head) + body + ensure + c.close + end + end + + Timeout.timeout(30) do # basic tests + %w(GET HEAD).each do |m| + body = check.call("#{m} /COPYING HTTP/1.0") do |head| + refute_match %r{^Content-Encoding: gzip\b}, head + assert_match %r{^Content-Type: text/plain\b}, head + assert_match %r{^Content-Length: #{st.size}\b}, head + end + case m + when "GET" then assert_equal GPL_TEXT, body + when "HEAD" then assert_nil body + end + + req = "#{m} /COPYING HTTP/1.0\r\nAccept-Encoding: gzip" + body = check.call(req) do |head| + assert_match %r{^Content-Encoding: gzip\b}, head + assert_match %r{^Content-Type: text/plain\b}, head + assert_match %r{^Content-Length: #{gz_st.size}\b}, head + end + case m + when "GET" + assert_equal GPL_TEXT, Zlib::GzipReader.new(StringIO.new(body)).read + when "HEAD" then assert_nil body + end + end + end + + Timeout.timeout(30) do # range tests + %w(HEAD GET).each do |m| + req = "#{m} /COPYING HTTP/1.0\r\n" \ + "Range: bytes=5-46\r\nAccept-Encoding: gzip" + body = check.call(req) do |head| + assert_match %r{\AHTTP/1\.1 206 Partial Content\r\n}, head + refute_match %r{^Content-Encoding: gzip\b}, head + assert_match %r{^Content-Type: text/plain\b}, head + assert_match %r{^Content-Length: 42\b}, head + assert_match %r{^Content-Range: bytes 5-46/#{st.size}\r\n}, head + end + case m + when "GET" then assert_equal GPL_TEXT[5..46], body + when "HEAD" then assert_nil body + end + + req = "#{m} /COPYING HTTP/1.0\r\n" \ + "Range: bytes=66666666-\r\nAccept-Encoding: gzip" + body = check.call(req) do |head| + assert_match %r{^Content-Range: bytes \*/#{st.size}\r\n}, head + assert_match %r{\AHTTP/1\.1 416 }, head + end + assert_nil body + end + end + + Timeout.timeout(30) do # gzip counterpart is nonexistent + File.link(gpl, "#{gpl}.hardlink") + %w(GET HEAD).each do |m| + req = "#{m} /COPYING.hardlink HTTP/1.0\r\nAccept-Encoding: gzip" + body = check.call(req) do |head| + refute_match %r{^Content-Encoding: gzip\b}, head + assert_match %r{^Content-Type: text/plain\b}, head + assert_match %r{^Content-Length: #{st.size}\b}, head + end + case m + when "GET" then assert_equal GPL_TEXT, body + when "HEAD" then assert_nil body + end + end + end + + Timeout.timeout(30) do # If-Modified-Since + %w(GET HEAD).each do |m| + req = "#{m} /COPYING HTTP/1.0\r\n" \ + "If-Modified-Since: #{st.mtime.httpdate}" + body = check.call(req) do |head| + assert_match %r{\AHTTP/1\.1 304 Not Modified}, head + end + assert_nil body + end + end + + # skew the times of the gzip file, should now fail to use gzipped + Timeout.timeout(30) do + File.utime(Time.at(0), Time.at(0), gplgz) + + %w(GET HEAD).each do |m| + req = "#{m} /COPYING HTTP/1.0\r\nAccept-Encoding: gzip" + body = check.call(req) do |head| + refute_match %r{^Content-Encoding: gzip\b}, head + assert_match %r{^Content-Type: text/plain\b}, head + assert_match %r{^Content-Length: #{st.size}\b}, head + end + case m + when "GET" then assert_equal GPL_TEXT, body + when "HEAD" then assert_nil body + end + end + end + + Timeout.timeout(30) do # 404 + %w(GET HEAD).each do |m| + req = "#{m} /cp-ing HTTP/1.0\r\nAccept-Encoding: gzip" + body = check.call(req) do |head| + assert_match %r{HTTP/1\.1 404 }, head + end + assert_nil body + end + body = check.call("FOO /COPYING HTTP/1.0") do |head| + assert_match %r{HTTP/1\.1 405 }, head + end + assert_nil body + end + ensure + quit_wait(pid) + end +end |