diff options
-rw-r--r-- | lib/yahns/http_response.rb | 8 | ||||
-rw-r--r-- | test/test_response.rb | 84 |
2 files changed, 91 insertions, 1 deletions
diff --git a/lib/yahns/http_response.rb b/lib/yahns/http_response.rb index e257feb..8965fd0 100644 --- a/lib/yahns/http_response.rb +++ b/lib/yahns/http_response.rb @@ -31,6 +31,8 @@ module Yahns::HttpResponse # :nodoc: R100_RAW = "HTTP/1.1 100 Continue\r\n\r\n" R100_CCC = "100 Continue\r\n\r\nHTTP/1.1 " HTTP_EXPECT = "HTTP_EXPECT" + REQUEST_METHOD = "REQUEST_METHOD" + HEAD = "HEAD" # no point in using one without the other, these have been in Linux # for ages @@ -123,6 +125,10 @@ module Yahns::HttpResponse # :nodoc: end end + def have_more?(value) + value.to_i > 0 && @hs.env[REQUEST_METHOD] != HEAD + end + # writes the rack_response to socket as an HTTP response # returns :wait_readable, :wait_writable, :forget, or nil def http_response_write(status, headers, body) @@ -149,7 +155,7 @@ module Yahns::HttpResponse # :nodoc: # allow Rack apps to tell us they want to drop the client alive = false if value =~ /\bclose\b/i when %r{\AContent-Length\z}i - flags |= MSG_MORE + flags |= MSG_MORE if have_more?(value) buf << kv_str(key, value) when "rack.hijack" hijack = value diff --git a/test/test_response.rb b/test/test_response.rb new file mode 100644 index 0000000..2e9a7ea --- /dev/null +++ b/test/test_response.rb @@ -0,0 +1,84 @@ +# 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' + +class TestResponse < Testcase + ENV["N"].to_i > 1 and parallelize_me! + include ServerHelper + alias setup server_helper_setup + alias teardown server_helper_teardown + + def test_response_time_empty_body + err = @err + cfg = Yahns::Config.new + host, port = @srv.addr[3], @srv.addr[1] + cfg.instance_eval do + GTL.synchronize do + app = Rack::Builder.new do + use Rack::ContentLength + use Rack::ContentType, "text/plain" + run lambda { |_| [ 200, {}, [] ] } + end + app(:rack, app) do + listen "#{host}:#{port}" + end + end + logger(Logger.new(err.path)) + end + pid = mkserver(cfg) + Net::HTTP.start(host, port) { |h| + # warmup request + res = h.get("/") + assert_empty res.body + + t0 = Time.now + nr = 10 + nr.times do + res = h.get("/") + assert_empty res.body + end + diff = Time.now - t0 + assert_operator diff, :<, (0.200 * nr) + } + ensure + quit_wait(pid) + end + + def test_response_time_head + err = @err + cfg = Yahns::Config.new + host, port = @srv.addr[3], @srv.addr[1] + cfg.instance_eval do + GTL.synchronize do + require 'rack/lobster' + app = Rack::Builder.new do + use Rack::Head + use Rack::ContentLength + use Rack::ContentType, "text/plain" + run Rack::Lobster.new + end + app(:rack, app) do + listen "#{host}:#{port}" + end + end + logger(Logger.new(err.path)) + end + pid = mkserver(cfg) + Net::HTTP.start(host, port) { |h| + # warmup request + res = h.head("/") + assert_equal 200, res.code.to_i + + t0 = Time.now + nr = 10 + nr.times do + res = h.head("/") + assert_equal 200, res.code.to_i + end + diff = Time.now - t0 + assert_operator diff, :<, (0.200 * nr) + } + ensure + quit_wait(pid) + end +end |