diff options
author | Eric Wong <e@80x24.org> | 2013-11-02 01:00:00 +0000 |
---|---|---|
committer | Eric Wong <normalperson@yhbt.net> | 2013-11-02 01:19:45 +0000 |
commit | 13a09dec6c029e01e8d959b0bf0feb94d72ae32d (patch) | |
tree | 05222cbf7927ce114320beaa0bf5a7a9bb3e676d /test/test_serve_static.rb | |
parent | 1ffa99f4f8f653fc016affecbe41d91a0b85f90d (diff) | |
download | yahns-13a09dec6c029e01e8d959b0bf0feb94d72ae32d.tar.gz |
When running a static file server, we must account for filesystem activity outside of our control where files may grow/shrink as they're being served. For truncated files, we must abort any persistent connections downloading a truncated file to avoid confusing clients because the Content-Length header was already set to the big value. We also must ensure (we already did so before this commit, this just adds a test for it) we do not send additional data when a file grows on us after we've started sending the response.
Diffstat (limited to 'test/test_serve_static.rb')
-rw-r--r-- | test/test_serve_static.rb | 61 |
1 files changed, 61 insertions, 0 deletions
diff --git a/test/test_serve_static.rb b/test/test_serve_static.rb index b1817f7..4f33b6f 100644 --- a/test/test_serve_static.rb +++ b/test/test_serve_static.rb @@ -73,4 +73,65 @@ class TestServeStatic < Testcase ensure quit_wait(pid) end + + def mksparse(tmpdir) + sparse = "#{tmpdir}/sparse" + off = 100 * 1024 * 1024 + File.open(sparse, "w") do |fp| + fp.sysseek(off) + fp.syswrite '.' + end + [ off + 1, sparse ] + end + + def test_truncated_sendfile + tmpdir = Dir.mktmpdir + size, sparse = mksparse(tmpdir) + err, cfg, host, port = @err, Yahns::Config.new, @srv.addr[3], @srv.addr[1] + pid = mkserver(cfg) do + cfg.instance_eval do + app(:rack, Rack::File.new(tmpdir)) { listen "#{host}:#{port}" } + stderr_path err.path + end + end + c = get_tcp_client(host, port) + c.write "GET /sparse HTTP/1.1\r\nHost: example.com\r\n\r\n" + wait_for_full(c) + File.truncate(sparse, 5) + buf = Timeout.timeout(60) { c.read } + c.close + assert_operator buf.size, :<, size + ensure + quit_wait(pid) + FileUtils.rm_rf(tmpdir) + end + + def test_expanded_sendfile + tmpdir = Dir.mktmpdir + size, sparse = mksparse(tmpdir) + err, cfg, host, port = @err, Yahns::Config.new, @srv.addr[3], @srv.addr[1] + pid = mkserver(cfg) do + cfg.instance_eval do + app(:rack, Rack::File.new(tmpdir)) { listen "#{host}:#{port}" } + stderr_path err.path + end + end + c = get_tcp_client(host, port) + c.write "GET /sparse\r\n\r\n" + wait_for_full(c) + + File.open(sparse, "w") do |fp| + fp.sysseek(size * 2) + fp.syswrite '.' + end + Timeout.timeout(60) do + bytes = IO.copy_stream(c, "/dev/null") + assert_equal bytes, size + assert_raises(EOFError) { c.readpartial 1 } + end + c.close + ensure + quit_wait(pid) + FileUtils.rm_rf(tmpdir) + end end |