engineyard-mongrel 1.1.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGELOG +16 -0
- data/CONTRIBUTORS +17 -0
- data/COPYING +55 -0
- data/LICENSE +55 -0
- data/Manifest +71 -0
- data/README +74 -0
- data/bin/mongrel_rails +285 -0
- data/examples/builder.rb +29 -0
- data/examples/camping/README +3 -0
- data/examples/camping/blog.rb +294 -0
- data/examples/camping/tepee.rb +149 -0
- data/examples/httpd.conf +474 -0
- data/examples/mime.yaml +3 -0
- data/examples/mongrel.conf +9 -0
- data/examples/mongrel_simple_ctrl.rb +92 -0
- data/examples/mongrel_simple_service.rb +116 -0
- data/examples/monitrc +57 -0
- data/examples/random_thrash.rb +19 -0
- data/examples/simpletest.rb +52 -0
- data/examples/webrick_compare.rb +20 -0
- data/ext/http11/ext_help.h +15 -0
- data/ext/http11/extconf.rb +6 -0
- data/ext/http11/http11.c +527 -0
- data/ext/http11/http11_parser.c +1243 -0
- data/ext/http11/http11_parser.h +49 -0
- data/ext/http11/http11_parser.java.rl +171 -0
- data/ext/http11/http11_parser.rl +152 -0
- data/ext/http11/http11_parser_common.rl +54 -0
- data/ext/http11_java/Http11Service.java +13 -0
- data/ext/http11_java/org/jruby/mongrel/Http11.java +266 -0
- data/ext/http11_java/org/jruby/mongrel/Http11Parser.java +474 -0
- data/lib/mongrel.rb +360 -0
- data/lib/mongrel/camping.rb +107 -0
- data/lib/mongrel/cgi.rb +181 -0
- data/lib/mongrel/command.rb +222 -0
- data/lib/mongrel/configurator.rb +389 -0
- data/lib/mongrel/const.rb +110 -0
- data/lib/mongrel/debug.rb +203 -0
- data/lib/mongrel/gems.rb +22 -0
- data/lib/mongrel/handlers.rb +468 -0
- data/lib/mongrel/header_out.rb +28 -0
- data/lib/mongrel/http_request.rb +155 -0
- data/lib/mongrel/http_response.rb +166 -0
- data/lib/mongrel/init.rb +10 -0
- data/lib/mongrel/mime_types.yml +616 -0
- data/lib/mongrel/rails.rb +214 -0
- data/lib/mongrel/stats.rb +89 -0
- data/lib/mongrel/tcphack.rb +18 -0
- data/lib/mongrel/uri_classifier.rb +76 -0
- data/mongrel-public_cert.pem +20 -0
- data/setup.rb +1585 -0
- data/test/benchmark/previous.rb +11 -0
- data/test/benchmark/simple.rb +11 -0
- data/test/benchmark/utils.rb +82 -0
- data/test/mime.yaml +3 -0
- data/test/mongrel.conf +1 -0
- data/test/test_helper.rb +79 -0
- data/test/tools/trickletest.rb +45 -0
- data/test/unit/test_cgi_wrapper.rb +26 -0
- data/test/unit/test_command.rb +86 -0
- data/test/unit/test_conditional.rb +107 -0
- data/test/unit/test_configurator.rb +88 -0
- data/test/unit/test_debug.rb +25 -0
- data/test/unit/test_handlers.rb +136 -0
- data/test/unit/test_http_parser.rb +156 -0
- data/test/unit/test_redirect_handler.rb +45 -0
- data/test/unit/test_request_progress.rb +100 -0
- data/test/unit/test_response.rb +127 -0
- data/test/unit/test_stats.rb +35 -0
- data/test/unit/test_uriclassifier.rb +261 -0
- data/test/unit/test_ws.rb +116 -0
- metadata +158 -0
@@ -0,0 +1,11 @@
|
|
1
|
+
# Benchmark to compare Mongrel performance against
|
2
|
+
# previous Mongrel version (the one installed as a gem).
|
3
|
+
#
|
4
|
+
# Run with:
|
5
|
+
#
|
6
|
+
# ruby previous.rb [num of request]
|
7
|
+
#
|
8
|
+
|
9
|
+
require File.dirname(__FILE__) + '/utils'
|
10
|
+
|
11
|
+
benchmark "print", %w(current gem), 1000, [1, 10, 100]
|
@@ -0,0 +1,11 @@
|
|
1
|
+
#
|
2
|
+
# Simple benchmark to compare Mongrel performance against
|
3
|
+
# other webservers supported by Rack.
|
4
|
+
#
|
5
|
+
|
6
|
+
require File.dirname(__FILE__) + '/utils'
|
7
|
+
|
8
|
+
libs = %w(current gem WEBrick EMongrel Thin)
|
9
|
+
libs = ARGV if ARGV.any?
|
10
|
+
|
11
|
+
benchmark "print", libs, 1000, [1, 10, 100]
|
@@ -0,0 +1,82 @@
|
|
1
|
+
|
2
|
+
require 'rubygems'
|
3
|
+
require 'rack'
|
4
|
+
require 'rack/lobster'
|
5
|
+
|
6
|
+
def run(handler_name, n=1000, c=1)
|
7
|
+
port = 7000
|
8
|
+
|
9
|
+
server = fork do
|
10
|
+
[STDOUT, STDERR].each { |o| o.reopen "/dev/null" }
|
11
|
+
|
12
|
+
case handler_name
|
13
|
+
when 'EMongrel'
|
14
|
+
require 'swiftcore/evented_mongrel'
|
15
|
+
handler_name = 'Mongrel'
|
16
|
+
|
17
|
+
when 'Thin'
|
18
|
+
require 'thin'
|
19
|
+
hander_name = 'Thin'
|
20
|
+
|
21
|
+
when 'gem' # Load the current Mongrel gem
|
22
|
+
require 'mongrel'
|
23
|
+
handler_name = 'Mongrel'
|
24
|
+
|
25
|
+
when 'current' # Load the current Mongrel version under /lib
|
26
|
+
require File.dirname(__FILE__) + '/../lib/mongrel'
|
27
|
+
handler_name = 'Mongrel'
|
28
|
+
|
29
|
+
end
|
30
|
+
|
31
|
+
app = Rack::Lobster.new
|
32
|
+
|
33
|
+
handler = Rack::Handler.const_get(handler_name)
|
34
|
+
handler.run app, :Host => '0.0.0.0', :Port => port
|
35
|
+
end
|
36
|
+
|
37
|
+
sleep 2
|
38
|
+
|
39
|
+
out = `nice -n20 ab -c #{c} -n #{n} http://127.0.0.1:#{port}/ 2> /dev/null`
|
40
|
+
|
41
|
+
Process.kill('SIGKILL', server)
|
42
|
+
Process.wait
|
43
|
+
|
44
|
+
if requests = out.match(/^Requests.+?(\d+\.\d+)/)
|
45
|
+
requests[1].to_i
|
46
|
+
else
|
47
|
+
0
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def benchmark(type, servers, request, concurrency_levels)
|
52
|
+
send "#{type}_benchmark", servers, request, concurrency_levels
|
53
|
+
end
|
54
|
+
|
55
|
+
def graph_benchmark(servers, request, concurrency_levels)
|
56
|
+
require '/usr/local/lib/ruby/gems/1.8/gems/gruff-0.2.9/lib/gruff'
|
57
|
+
g = Gruff::Area.new
|
58
|
+
g.title = "Server benchmark"
|
59
|
+
|
60
|
+
servers.each do |server|
|
61
|
+
g.data(server, concurrency_levels.collect { |c| print '.'; run(server, request, c) })
|
62
|
+
end
|
63
|
+
puts
|
64
|
+
|
65
|
+
g.x_axis_label = 'Concurrency'
|
66
|
+
g.y_axis_label = 'Requests / sec'
|
67
|
+
g.labels = {}
|
68
|
+
concurrency_levels.each_with_index { |c, i| g.labels[i] = c.to_s }
|
69
|
+
|
70
|
+
g.write('bench.png')
|
71
|
+
`open bench.png`
|
72
|
+
end
|
73
|
+
|
74
|
+
def print_benchmark(servers, request, concurrency_levels)
|
75
|
+
puts 'server request concurrency req/s'
|
76
|
+
puts '=' * 42
|
77
|
+
concurrency_levels.each do |c|
|
78
|
+
servers.each do |server|
|
79
|
+
puts "#{server.ljust(8)} #{request} #{c.to_s.ljust(4)} #{run(server, request, c)}"
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
data/test/mime.yaml
ADDED
data/test/mongrel.conf
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
uri "/fromconf", :handler => Mongrel::Error404Handler.new("test")
|
data/test/test_helper.rb
ADDED
@@ -0,0 +1,79 @@
|
|
1
|
+
# Copyright (c) 2005 Zed A. Shaw
|
2
|
+
# You can redistribute it and/or modify it under the same terms as Ruby.
|
3
|
+
#
|
4
|
+
# Additional work donated by contributors. See http://mongrel.rubyforge.org/attributions.html
|
5
|
+
# for more information.
|
6
|
+
|
7
|
+
|
8
|
+
HERE = File.dirname(__FILE__)
|
9
|
+
%w(lib ext bin test).each do |dir|
|
10
|
+
$LOAD_PATH.unshift "#{HERE}/../#{dir}"
|
11
|
+
end
|
12
|
+
|
13
|
+
require 'rubygems'
|
14
|
+
require 'test/unit'
|
15
|
+
require 'net/http'
|
16
|
+
require 'timeout'
|
17
|
+
require 'cgi/session'
|
18
|
+
require 'fileutils'
|
19
|
+
require 'benchmark'
|
20
|
+
require 'digest/sha1'
|
21
|
+
require 'uri'
|
22
|
+
require 'stringio'
|
23
|
+
require 'pp'
|
24
|
+
|
25
|
+
require 'mongrel'
|
26
|
+
require 'mongrel/stats'
|
27
|
+
|
28
|
+
if ENV['DEBUG']
|
29
|
+
require 'ruby-debug'
|
30
|
+
Debugger.start
|
31
|
+
end
|
32
|
+
|
33
|
+
def redirect_test_io
|
34
|
+
orig_err = STDERR.dup
|
35
|
+
orig_out = STDOUT.dup
|
36
|
+
STDERR.reopen("test_stderr.log")
|
37
|
+
STDOUT.reopen("test_stdout.log")
|
38
|
+
|
39
|
+
begin
|
40
|
+
yield
|
41
|
+
ensure
|
42
|
+
STDERR.reopen(orig_err)
|
43
|
+
STDOUT.reopen(orig_out)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
# Either takes a string to do a get request against, or a tuple of [URI, HTTP] where
|
48
|
+
# HTTP is some kind of Net::HTTP request object (POST, HEAD, etc.)
|
49
|
+
def hit(uris)
|
50
|
+
results = []
|
51
|
+
uris.each do |u|
|
52
|
+
res = nil
|
53
|
+
|
54
|
+
if u.kind_of? String
|
55
|
+
res = Net::HTTP.get(URI.parse(u))
|
56
|
+
else
|
57
|
+
url = URI.parse(u[0])
|
58
|
+
res = Net::HTTP.new(url.host, url.port).start {|h| h.request(u[1]) }
|
59
|
+
end
|
60
|
+
|
61
|
+
assert res != nil, "Didn't get a response: #{u}"
|
62
|
+
results << res
|
63
|
+
end
|
64
|
+
|
65
|
+
return results
|
66
|
+
end
|
67
|
+
|
68
|
+
# process_based_port provides a port number, usable for TCP and UDP
|
69
|
+
# connections based on $$ and with a 5000 as base.
|
70
|
+
# this is required if you perform several builds of mongrel in parallel
|
71
|
+
# (like continuous integration systems)
|
72
|
+
def process_based_port
|
73
|
+
5000 + $$ % 1000
|
74
|
+
end
|
75
|
+
|
76
|
+
# Platform check helper ;-)
|
77
|
+
def windows?
|
78
|
+
result = RUBY_PLATFORM =~ /djgpp|(cyg|ms|bcc)win|mingw/
|
79
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
require 'socket'
|
2
|
+
require 'stringio'
|
3
|
+
|
4
|
+
def do_test(st, chunk)
|
5
|
+
s = TCPSocket.new('127.0.0.1',ARGV[0].to_i);
|
6
|
+
req = StringIO.new(st)
|
7
|
+
nout = 0
|
8
|
+
randstop = rand(st.length / 10)
|
9
|
+
STDERR.puts "stopping after: #{randstop}"
|
10
|
+
|
11
|
+
begin
|
12
|
+
while data = req.read(chunk)
|
13
|
+
nout += s.write(data)
|
14
|
+
s.flush
|
15
|
+
sleep 0.1
|
16
|
+
if nout > randstop
|
17
|
+
STDERR.puts "BANG! after #{nout} bytes."
|
18
|
+
break
|
19
|
+
end
|
20
|
+
end
|
21
|
+
rescue Object => e
|
22
|
+
STDERR.puts "ERROR: #{e}"
|
23
|
+
ensure
|
24
|
+
s.close
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
content = "-" * (1024 * 240)
|
29
|
+
st = "GET / HTTP/1.1\r\nHost: www.zedshaw.com\r\nContent-Type: text/plain\r\nContent-Length: #{content.length}\r\n\r\n#{content}"
|
30
|
+
|
31
|
+
puts "length: #{content.length}"
|
32
|
+
|
33
|
+
threads = []
|
34
|
+
ARGV[1].to_i.times do
|
35
|
+
t = Thread.new do
|
36
|
+
size = 100
|
37
|
+
puts ">>>> #{size} sized chunks"
|
38
|
+
do_test(st, size)
|
39
|
+
end
|
40
|
+
|
41
|
+
t.abort_on_exception = true
|
42
|
+
threads << t
|
43
|
+
end
|
44
|
+
|
45
|
+
threads.each {|t| t.join}
|
@@ -0,0 +1,26 @@
|
|
1
|
+
|
2
|
+
require 'test/test_helper'
|
3
|
+
|
4
|
+
class MockHttpRequest
|
5
|
+
attr_reader :body
|
6
|
+
|
7
|
+
def params
|
8
|
+
return { 'REQUEST_METHOD' => 'GET'}
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
class CGIWrapperTest < Test::Unit::TestCase
|
13
|
+
|
14
|
+
def test_set_cookies_output_cookies
|
15
|
+
request = MockHttpRequest.new
|
16
|
+
response = nil # not needed for this test
|
17
|
+
output_headers = {}
|
18
|
+
|
19
|
+
cgi = Mongrel::CGIWrapper.new(request, response)
|
20
|
+
session = CGI::Session.new(cgi, 'database_manager' => CGI::Session::MemoryStore)
|
21
|
+
cgi.send_cookies(output_headers)
|
22
|
+
|
23
|
+
assert(output_headers.has_key?("Set-Cookie"))
|
24
|
+
assert_equal("_session_id="+session.session_id+"; path=", output_headers["Set-Cookie"])
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,86 @@
|
|
1
|
+
# Copyright (c) 2005 Zed A. Shaw
|
2
|
+
# You can redistribute it and/or modify it under the same terms as Ruby.
|
3
|
+
#
|
4
|
+
# Additional work donated by contributors. See http://mongrel.rubyforge.org/attributions.html
|
5
|
+
# for more information.
|
6
|
+
|
7
|
+
require 'test/test_helper'
|
8
|
+
|
9
|
+
class TestCommand < GemPlugin::Plugin "/commands"
|
10
|
+
include Mongrel::Command::Base
|
11
|
+
|
12
|
+
def configure
|
13
|
+
options [
|
14
|
+
["-e", "--environment ENV", "Rails environment to run as", :@environment, ENV['RAILS_ENV'] || "development"],
|
15
|
+
['', '--user USER', "User to run as", :@user, nil],
|
16
|
+
["-d", "--daemonize", "Whether to run in the background or not", :@daemon, false],
|
17
|
+
["-x", "--test", "Used to let the test run failures", :@test, false],
|
18
|
+
]
|
19
|
+
end
|
20
|
+
|
21
|
+
def validate
|
22
|
+
valid_dir? ".", "Can't validate current directory."
|
23
|
+
valid_exists? "Rakefile", "Rakefile not there, test is invalid."
|
24
|
+
if @test
|
25
|
+
valid_exist? "BADFILE", "Yeah, badfile"
|
26
|
+
valid_file? "BADFILE", "Not even a file"
|
27
|
+
valid_dir? "BADDIR", "No dir here"
|
28
|
+
valid? false, "Total failure"
|
29
|
+
end
|
30
|
+
|
31
|
+
return @valid
|
32
|
+
end
|
33
|
+
|
34
|
+
|
35
|
+
def run
|
36
|
+
$test_command_ran = true
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
class CommandTest < Test::Unit::TestCase
|
41
|
+
|
42
|
+
def setup
|
43
|
+
$test_command_ran = false
|
44
|
+
end
|
45
|
+
|
46
|
+
def teardown
|
47
|
+
end
|
48
|
+
|
49
|
+
def run_cmd(args)
|
50
|
+
Mongrel::Command::Registry.instance.run args
|
51
|
+
end
|
52
|
+
|
53
|
+
def test_run_command
|
54
|
+
redirect_test_io do
|
55
|
+
run_cmd ["testcommand"]
|
56
|
+
assert $test_command_ran, "command didn't run"
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def test_command_error
|
61
|
+
redirect_test_io do
|
62
|
+
run_cmd ["crapcommand"]
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def test_command_listing
|
67
|
+
redirect_test_io do
|
68
|
+
run_cmd ["help"]
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
def test_options
|
73
|
+
redirect_test_io do
|
74
|
+
run_cmd ["testcommand","-h"]
|
75
|
+
run_cmd ["testcommand","--help"]
|
76
|
+
run_cmd ["testcommand","-e","test","-d","--user"]
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
def test_version
|
81
|
+
redirect_test_io do
|
82
|
+
run_cmd ["testcommand", "--version"]
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
end
|
@@ -0,0 +1,107 @@
|
|
1
|
+
# Copyright (c) 2005 Zed A. Shaw
|
2
|
+
# You can redistribute it and/or modify it under the same terms as Ruby.
|
3
|
+
#
|
4
|
+
# Additional work donated by contributors. See http://mongrel.rubyforge.org/attributions.html
|
5
|
+
# for more information.
|
6
|
+
|
7
|
+
require 'test/test_helper'
|
8
|
+
|
9
|
+
include Mongrel
|
10
|
+
|
11
|
+
class ConditionalResponseTest < Test::Unit::TestCase
|
12
|
+
def setup
|
13
|
+
@server = HttpServer.new('127.0.0.1', process_based_port)
|
14
|
+
@server.register('/', Mongrel::DirHandler.new('.'))
|
15
|
+
@server.run
|
16
|
+
|
17
|
+
@http = Net::HTTP.new(@server.host, @server.port)
|
18
|
+
|
19
|
+
# get the ETag and Last-Modified headers
|
20
|
+
@path = '/README'
|
21
|
+
res = @http.start { |http| http.get(@path) }
|
22
|
+
assert_not_nil @etag = res['ETag']
|
23
|
+
assert_not_nil @last_modified = res['Last-Modified']
|
24
|
+
assert_not_nil @content_length = res['Content-Length']
|
25
|
+
end
|
26
|
+
|
27
|
+
def teardown
|
28
|
+
@server.stop(true)
|
29
|
+
end
|
30
|
+
|
31
|
+
# status should be 304 Not Modified when If-None-Match is the matching ETag
|
32
|
+
def test_not_modified_via_if_none_match
|
33
|
+
assert_status_for_get_and_head Net::HTTPNotModified, 'If-None-Match' => @etag
|
34
|
+
end
|
35
|
+
|
36
|
+
# status should be 304 Not Modified when If-Modified-Since is the matching Last-Modified date
|
37
|
+
def test_not_modified_via_if_modified_since
|
38
|
+
assert_status_for_get_and_head Net::HTTPNotModified, 'If-Modified-Since' => @last_modified
|
39
|
+
end
|
40
|
+
|
41
|
+
# status should be 304 Not Modified when If-None-Match is the matching ETag
|
42
|
+
# and If-Modified-Since is the matching Last-Modified date
|
43
|
+
def test_not_modified_via_if_none_match_and_if_modified_since
|
44
|
+
assert_status_for_get_and_head Net::HTTPNotModified, 'If-None-Match' => @etag, 'If-Modified-Since' => @last_modified
|
45
|
+
end
|
46
|
+
|
47
|
+
# status should be 200 OK when If-None-Match is invalid
|
48
|
+
def test_invalid_if_none_match
|
49
|
+
assert_status_for_get_and_head Net::HTTPOK, 'If-None-Match' => 'invalid'
|
50
|
+
assert_status_for_get_and_head Net::HTTPOK, 'If-None-Match' => 'invalid', 'If-Modified-Since' => @last_modified
|
51
|
+
end
|
52
|
+
|
53
|
+
# status should be 200 OK when If-Modified-Since is invalid
|
54
|
+
def test_invalid_if_modified_since
|
55
|
+
assert_status_for_get_and_head Net::HTTPOK, 'If-Modified-Since' => 'invalid'
|
56
|
+
assert_status_for_get_and_head Net::HTTPOK, 'If-None-Match' => @etag, 'If-Modified-Since' => 'invalid'
|
57
|
+
end
|
58
|
+
|
59
|
+
# status should be 304 Not Modified when If-Modified-Since is greater than the Last-Modified header, but less than the system time
|
60
|
+
def test_if_modified_since_greater_than_last_modified
|
61
|
+
sleep 2
|
62
|
+
last_modified_plus_1 = (Time.httpdate(@last_modified) + 1).httpdate
|
63
|
+
assert_status_for_get_and_head Net::HTTPNotModified, 'If-Modified-Since' => last_modified_plus_1
|
64
|
+
assert_status_for_get_and_head Net::HTTPNotModified, 'If-None-Match' => @etag, 'If-Modified-Since' => last_modified_plus_1
|
65
|
+
end
|
66
|
+
|
67
|
+
# status should be 200 OK when If-Modified-Since is less than the Last-Modified header
|
68
|
+
def test_if_modified_since_less_than_last_modified
|
69
|
+
last_modified_minus_1 = (Time.httpdate(@last_modified) - 1).httpdate
|
70
|
+
assert_status_for_get_and_head Net::HTTPOK, 'If-Modified-Since' => last_modified_minus_1
|
71
|
+
assert_status_for_get_and_head Net::HTTPOK, 'If-None-Match' => @etag, 'If-Modified-Since' => last_modified_minus_1
|
72
|
+
end
|
73
|
+
|
74
|
+
# status should be 200 OK when If-Modified-Since is a date in the future
|
75
|
+
def test_future_if_modified_since
|
76
|
+
the_future = Time.at(2**31-1).httpdate
|
77
|
+
assert_status_for_get_and_head Net::HTTPOK, 'If-Modified-Since' => the_future
|
78
|
+
assert_status_for_get_and_head Net::HTTPOK, 'If-None-Match' => @etag, 'If-Modified-Since' => the_future
|
79
|
+
end
|
80
|
+
|
81
|
+
# status should be 200 OK when If-None-Match is a wildcard
|
82
|
+
def test_wildcard_match
|
83
|
+
assert_status_for_get_and_head Net::HTTPOK, 'If-None-Match' => '*'
|
84
|
+
assert_status_for_get_and_head Net::HTTPOK, 'If-None-Match' => '*', 'If-Modified-Since' => @last_modified
|
85
|
+
end
|
86
|
+
|
87
|
+
private
|
88
|
+
|
89
|
+
# assert the response status is correct for GET and HEAD
|
90
|
+
def assert_status_for_get_and_head(response_class, headers = {})
|
91
|
+
%w{ get head }.each do |method|
|
92
|
+
res = @http.send(method, @path, headers)
|
93
|
+
assert_kind_of response_class, res
|
94
|
+
assert_equal @etag, res['ETag']
|
95
|
+
case response_class.to_s
|
96
|
+
when 'Net::HTTPNotModified' then
|
97
|
+
assert_nil res['Last-Modified']
|
98
|
+
assert_nil res['Content-Length']
|
99
|
+
when 'Net::HTTPOK' then
|
100
|
+
assert_equal @last_modified, res['Last-Modified']
|
101
|
+
assert_equal @content_length, res['Content-Length']
|
102
|
+
else
|
103
|
+
fail "Incorrect response class: #{response_class}"
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|