about summary refs log tree commit homepage
path: root/test/test_extras_try_gzip_static.rb
diff options
context:
space:
mode:
Diffstat (limited to 'test/test_extras_try_gzip_static.rb')
-rw-r--r--test/test_extras_try_gzip_static.rb177
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