m2r 1.0.0 → 2.0.0
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/README.md +64 -1
- data/example/config.sqlite +0 -0
- data/example/http_0mq.rb +10 -3
- data/example/tmp/access.log +215 -0
- data/lib/m2r.rb +1 -0
- data/lib/m2r/connection.rb +21 -10
- data/lib/m2r/connection_factory.rb +20 -17
- data/lib/m2r/handler.rb +40 -3
- data/lib/m2r/headers.rb +9 -1
- data/lib/m2r/http/close.rb +30 -0
- data/lib/m2r/rack_handler.rb +3 -3
- data/lib/m2r/reply.rb +15 -0
- data/lib/m2r/request.rb +38 -31
- data/lib/m2r/request/base.rb +0 -8
- data/lib/m2r/request/upload.rb +0 -10
- data/lib/m2r/response.rb +64 -18
- data/lib/m2r/response/always_close.rb +26 -0
- data/lib/m2r/response/content_length.rb +8 -2
- data/lib/m2r/response/to_request.rb +26 -0
- data/lib/m2r/version.rb +1 -1
- data/lib/rack/handler/mongrel2.rb +17 -3
- data/test/support/test_handler.rb +5 -1
- data/test/unit/connection_factory_test.rb +3 -3
- data/test/unit/connection_test.rb +60 -9
- data/test/unit/handler_test.rb +46 -9
- data/test/unit/headers_test.rb +13 -0
- data/test/unit/rack_handler_test.rb +26 -2
- data/test/unit/request_test.rb +1 -0
- data/test/unit/response_test.rb +76 -5
- metadata +7 -3
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'm2r/response'
|
2
|
+
|
3
|
+
module M2R
|
4
|
+
class Response
|
5
|
+
# Use to disable persisent connections even though
|
6
|
+
# your client would prefer otherwise.
|
7
|
+
#
|
8
|
+
# @api public
|
9
|
+
module AlwaysClose
|
10
|
+
def close?
|
11
|
+
true
|
12
|
+
end
|
13
|
+
|
14
|
+
def headers(value = GETTER)
|
15
|
+
if value == GETTER
|
16
|
+
h = super
|
17
|
+
h['Connection'] = 'close'
|
18
|
+
h
|
19
|
+
else
|
20
|
+
super
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
@@ -10,8 +10,14 @@ module M2R
|
|
10
10
|
#
|
11
11
|
# @api public
|
12
12
|
module ContentLength
|
13
|
-
def headers
|
14
|
-
|
13
|
+
def headers(value = GETTER)
|
14
|
+
if value == GETTER
|
15
|
+
h = super
|
16
|
+
h['Content-Length'] ||= body.bytesize
|
17
|
+
h
|
18
|
+
else
|
19
|
+
super
|
20
|
+
end
|
15
21
|
end
|
16
22
|
end
|
17
23
|
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'm2r/response'
|
2
|
+
|
3
|
+
module M2R
|
4
|
+
class Response
|
5
|
+
|
6
|
+
# Handles the logic of having response with proper
|
7
|
+
# http version and 'Connection' header in relation to
|
8
|
+
# given request
|
9
|
+
#
|
10
|
+
# @api public
|
11
|
+
module ToRequest
|
12
|
+
# params [Request] request Request that response handles
|
13
|
+
# params [true, false] identical Whether http version in response should be identical
|
14
|
+
# to the received one.
|
15
|
+
# @return [self] Response object
|
16
|
+
# @api public
|
17
|
+
def to(request, identical = false)
|
18
|
+
# http://www.ietf.org/rfc/rfc2145.txt
|
19
|
+
# 2.3 Which version number to send in a message
|
20
|
+
http_version(request.http_version) if identical
|
21
|
+
headers['Connection'] = 'close' if request.close?
|
22
|
+
self
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
data/lib/m2r/version.rb
CHANGED
@@ -14,8 +14,8 @@ module Rack
|
|
14
14
|
|
15
15
|
def self.run(app, options = {})
|
16
16
|
options = OpenStruct.new( DEFAULT_OPTIONS.merge(options) )
|
17
|
-
|
18
|
-
adapter = M2R::RackHandler.new(app,
|
17
|
+
parser = M2R::Request
|
18
|
+
adapter = M2R::RackHandler.new(app, connection_factory(options), parser)
|
19
19
|
adapter.listen
|
20
20
|
end
|
21
21
|
|
@@ -23,9 +23,23 @@ module Rack
|
|
23
23
|
{
|
24
24
|
'recv_addr=RECV_ADDR' => 'Receive address',
|
25
25
|
'send_addr=SEND_ADDR' => 'Send address',
|
26
|
-
'sender_id=UUID'
|
26
|
+
'sender_id=UUID' => 'Sender UUID'
|
27
27
|
}
|
28
28
|
end
|
29
|
+
|
30
|
+
def self.connection_factory(options)
|
31
|
+
klass = if custom = options.connection_factory
|
32
|
+
begin
|
33
|
+
M2R::ConnectionFactory.const_get(custom.classify)
|
34
|
+
rescue NameError
|
35
|
+
require "m2r/connection_factory/#{custom.underscore}"
|
36
|
+
M2R::ConnectionFactory.const_get(custom.classify)
|
37
|
+
end
|
38
|
+
else
|
39
|
+
M2R::ConnectionFactory
|
40
|
+
end
|
41
|
+
klass.new(options)
|
42
|
+
end
|
29
43
|
end
|
30
44
|
|
31
45
|
register :mongrel2, ::Rack::Handler::Mongrel2
|
@@ -2,7 +2,7 @@ require 'm2r/handler'
|
|
2
2
|
|
3
3
|
class TestHandler < M2R::Handler
|
4
4
|
attr_reader :called_methods
|
5
|
-
def initialize(connection)
|
5
|
+
def initialize(connection, parser)
|
6
6
|
super
|
7
7
|
@called_methods = []
|
8
8
|
end
|
@@ -48,4 +48,8 @@ class TestHandler < M2R::Handler
|
|
48
48
|
def after_all(request, response)
|
49
49
|
@called_methods << :all
|
50
50
|
end
|
51
|
+
|
52
|
+
def on_error(request, response, error)
|
53
|
+
@called_methods << :error
|
54
|
+
end
|
51
55
|
end
|
@@ -7,7 +7,6 @@ module M2R
|
|
7
7
|
sender_id = "sid"
|
8
8
|
request_addr = "req"
|
9
9
|
response_addr = "req"
|
10
|
-
request_parser = Object.new
|
11
10
|
|
12
11
|
pull = stub(:pull)
|
13
12
|
pub = stub(:pub)
|
@@ -21,9 +20,10 @@ module M2R
|
|
21
20
|
pub.expects(:connect).with(response_addr)
|
22
21
|
pub.expects(:setsockopt).with(ZMQ::IDENTITY, sender_id)
|
23
22
|
|
24
|
-
Connection.expects(:new).with(pull, pub
|
25
|
-
cf = ConnectionFactory.new sender_id, request_addr, response_addr,
|
23
|
+
Connection.expects(:new).with(pull, pub)
|
24
|
+
cf = ConnectionFactory.new ConnectionFactory::Options.new(sender_id, request_addr, response_addr), context
|
26
25
|
cf.connection
|
27
26
|
end
|
27
|
+
|
28
28
|
end
|
29
29
|
end
|
@@ -13,6 +13,7 @@ module M2R
|
|
13
13
|
|
14
14
|
@sub = M2R.zmq_context.socket(ZMQ::SUB)
|
15
15
|
assert_equal 0, @sub.bind(@response_addr), "Could not bind sub socket in tests"
|
16
|
+
@sub.setsockopt(ZMQ::SUBSCRIBE, "")
|
16
17
|
|
17
18
|
|
18
19
|
@request_socket = M2R.zmq_context.socket(ZMQ::PULL)
|
@@ -32,17 +33,67 @@ module M2R
|
|
32
33
|
|
33
34
|
def test_receive_message
|
34
35
|
connection = Connection.new(@request_socket, @response_socket)
|
35
|
-
@push.send_string("1c5fd481-1121-49d8-a706-69127975db1a ebb407b2-49aa-48a5-9f96-9db121051484 / 2:{},0:,", ZMQ::NOBLOCK)
|
36
|
-
|
36
|
+
@push.send_string(msg = "1c5fd481-1121-49d8-a706-69127975db1a ebb407b2-49aa-48a5-9f96-9db121051484 / 2:{},0:,", ZMQ::NOBLOCK)
|
37
|
+
assert_equal msg, connection.receive
|
37
38
|
end
|
38
39
|
|
39
|
-
def
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
40
|
+
def test_deliver_message
|
41
|
+
connection = Connection.new(@request_socket, @response_socket)
|
42
|
+
connection.deliver('uuid', ['conn1', 'conn2'], 'ddaattaa')
|
43
|
+
assert_equal 0, @sub.recv_string(msg = "")
|
44
|
+
assert_equal "uuid 11:conn1 conn2, ddaattaa", msg
|
45
|
+
end
|
46
|
+
|
47
|
+
def test_string_replay_non_close
|
48
|
+
connection = Connection.new(@request_socket, @response_socket)
|
49
|
+
connection.reply( stub(sender: 'uuid', conn_id: 'conn1', close?: false), 'ddaattaa')
|
50
|
+
assert_equal 0, @sub.recv_string(msg = "")
|
51
|
+
assert_equal "uuid 5:conn1, ddaattaa", msg
|
52
|
+
assert_equal -1, @sub.recv_string(msg = "", ZMQ::NOBLOCK)
|
53
|
+
end
|
54
|
+
|
55
|
+
def test_string_replay_close
|
56
|
+
connection = Connection.new(@request_socket, @response_socket)
|
57
|
+
connection.reply( stub(sender: 'uuid', conn_id: 'conn1', close?: true), 'ddaattaa')
|
58
|
+
assert_equal 0, @sub.recv_string(msg = "")
|
59
|
+
assert_equal "uuid 5:conn1, ddaattaa", msg
|
60
|
+
assert_equal 0, @sub.recv_string(msg = "")
|
61
|
+
assert_equal "uuid 5:conn1, ", msg
|
62
|
+
end
|
63
|
+
|
64
|
+
def test_response_replay_non_close
|
65
|
+
connection = Connection.new(@request_socket, @response_socket)
|
66
|
+
connection.reply( stub(sender: 'uuid', conn_id: 'conn1'), mock(to_s: 'ddaattaa', close?: false))
|
67
|
+
assert_equal 0, @sub.recv_string(msg = "")
|
68
|
+
assert_equal "uuid 5:conn1, ddaattaa", msg
|
69
|
+
assert_equal -1, @sub.recv_string(msg = "", ZMQ::NOBLOCK)
|
70
|
+
end
|
71
|
+
|
72
|
+
def test_response_replay_close
|
73
|
+
connection = Connection.new(@request_socket, @response_socket)
|
74
|
+
connection.reply( stub(sender: 'uuid', conn_id: 'conn1'), mock(to_s: 'ddaattaa', close?: true))
|
75
|
+
assert_equal 0, @sub.recv_string(msg = "")
|
76
|
+
assert_equal "uuid 5:conn1, ddaattaa", msg
|
77
|
+
assert_equal 0, @sub.recv_string(msg = "")
|
78
|
+
assert_equal "uuid 5:conn1, ", msg
|
79
|
+
end
|
80
|
+
|
81
|
+
def test_exception_when_receiving
|
82
|
+
request_socket = mock(:recv_string => -1)
|
83
|
+
connection = Connection.new request_socket, nil
|
84
|
+
assert_raises(Connection::Error) { connection.receive }
|
85
|
+
end
|
86
|
+
|
87
|
+
def test_exception_when_deliverying
|
88
|
+
response_socket = mock(:send_string => -1)
|
89
|
+
connection = Connection.new nil, response_socket
|
90
|
+
assert_raises(Connection::Error) { connection.deliver('uuid', ['connection_ids'], 'data') }
|
91
|
+
end
|
92
|
+
|
93
|
+
def test_exception_when_replying
|
94
|
+
response_socket = mock(:send_string => -1)
|
95
|
+
connection = Connection.new nil, response_socket
|
96
|
+
assert_raises(Connection::Error) { connection.reply( Struct.new(:sender, :conn_id).new('sender', 'conn_id') , 'data' ) }
|
46
97
|
end
|
47
98
|
|
48
99
|
end
|
data/test/unit/handler_test.rb
CHANGED
@@ -2,40 +2,77 @@ require 'test_helper'
|
|
2
2
|
|
3
3
|
module M2R
|
4
4
|
class HandlerTest < MiniTest::Unit::TestCase
|
5
|
+
|
5
6
|
def test_lifecycle_for_disconnect
|
6
|
-
connection = stub(:receive =>
|
7
|
+
connection = stub(:receive => "")
|
7
8
|
connection.stubs(:connection).returns(connection)
|
8
|
-
|
9
|
+
parser = stub(:parse => disconnect_request)
|
10
|
+
h = TestHandler.new(connection, parser)
|
9
11
|
h.listen
|
10
12
|
assert_equal [:wait, :request, :disconnect, :all], h.called_methods
|
11
13
|
end
|
12
14
|
|
13
15
|
def test_lifecycle_for_upload_start
|
14
|
-
connection = stub(:receive =>
|
16
|
+
connection = stub(:receive => "")
|
15
17
|
connection.stubs(:connection).returns(connection)
|
16
|
-
|
18
|
+
parser = stub(:parse => upload_start_request)
|
19
|
+
h = TestHandler.new(connection, parser)
|
17
20
|
h.listen
|
18
21
|
assert_equal [:wait, :request, :start, :all], h.called_methods
|
19
22
|
end
|
20
23
|
|
21
24
|
def test_lifecycle_for_upload_done
|
22
|
-
connection = stub(:receive =>
|
25
|
+
connection = stub(:receive => "", :reply => nil)
|
23
26
|
connection.stubs(:connection).returns(connection)
|
24
|
-
|
27
|
+
parser = stub(:parse => upload_done_request)
|
28
|
+
h = TestHandler.new(connection, parser)
|
25
29
|
h.listen
|
26
30
|
assert_equal [:wait, :request, :done, :process, :after, :reply, :all], h.called_methods
|
27
31
|
end
|
28
32
|
|
33
|
+
def test_lifecycle_for_exception_when_getting_request
|
34
|
+
connection = stub()
|
35
|
+
connection.stubs(:receive).raises(StandardError)
|
36
|
+
connection.stubs(:connection).returns(connection)
|
37
|
+
h = TestHandler.new(connection, nil)
|
38
|
+
h.listen
|
39
|
+
assert_equal [:wait, :error], h.called_methods
|
40
|
+
end
|
41
|
+
|
42
|
+
def test_lifecycle_for_exception_when_processing
|
43
|
+
connection = stub(:receive => "", :reply => nil)
|
44
|
+
connection.stubs(:connection).returns(connection)
|
45
|
+
parser = stub(:parse => request)
|
46
|
+
h = TestHandler.new(connection, parser)
|
47
|
+
h.extend(Module.new(){
|
48
|
+
def process(request)
|
49
|
+
super
|
50
|
+
raise StandardError
|
51
|
+
end
|
52
|
+
})
|
53
|
+
h.listen
|
54
|
+
assert_equal [:wait, :request, :process, :all, :error], h.called_methods
|
55
|
+
end
|
56
|
+
|
57
|
+
|
58
|
+
private
|
59
|
+
|
60
|
+
|
29
61
|
def disconnect_request
|
30
|
-
Request.new("sender", "conn_id", "/path", Headers.new({"METHOD" => "JSON"}), '{"type":"disconnect"}')
|
62
|
+
Request.new("sender", "conn_id", "/path", Headers.new({}), Headers.new({"METHOD" => "JSON"}), '{"type":"disconnect"}')
|
31
63
|
end
|
32
64
|
|
33
65
|
def upload_start_request
|
34
|
-
Request.new("sender", "conn_id", "/path", Headers.new({"x-mongrel2-upload-start" => "/tmp/file"}), '')
|
66
|
+
Request.new("sender", "conn_id", "/path", Headers.new({}), Headers.new({"x-mongrel2-upload-start" => "/tmp/file"}), '')
|
35
67
|
end
|
36
68
|
|
37
69
|
def upload_done_request
|
38
|
-
Request.new("sender", "conn_id", "/path", Headers.new({"x-mongrel2-upload-start" => "/tmp/file", "x-mongrel2-upload-done" => "/tmp/file"}), '')
|
70
|
+
Request.new("sender", "conn_id", "/path", Headers.new({}), Headers.new({"x-mongrel2-upload-start" => "/tmp/file", "x-mongrel2-upload-done" => "/tmp/file"}), '')
|
39
71
|
end
|
72
|
+
|
73
|
+
def request
|
74
|
+
Request.new("sender", "conn_id", "/path", Headers.new({}), Headers.new({}), '')
|
75
|
+
end
|
76
|
+
|
40
77
|
end
|
41
78
|
end
|
data/test/unit/headers_test.rb
CHANGED
@@ -46,5 +46,18 @@ module M2R
|
|
46
46
|
}, env)
|
47
47
|
end
|
48
48
|
|
49
|
+
def test_compatibility_trust
|
50
|
+
headers = Headers.new({"Content-Type" => "CT"}, true)
|
51
|
+
assert_equal nil, headers['content-type']
|
52
|
+
end
|
53
|
+
|
54
|
+
def test_compatibility_direct_access
|
55
|
+
headers = Headers.new(source = {"content-type" => "CT"}, true)
|
56
|
+
assert_equal "CT", headers['content-type']
|
57
|
+
headers['Content-type'] = "NEW"
|
58
|
+
assert_equal "NEW", headers['content-Type']
|
59
|
+
assert_equal "NEW", source['content-type']
|
60
|
+
end
|
61
|
+
|
49
62
|
end
|
50
63
|
end
|
@@ -1,5 +1,6 @@
|
|
1
1
|
require 'test_helper'
|
2
2
|
require 'm2r/rack_handler'
|
3
|
+
require 'm2r/connection_factory'
|
3
4
|
|
4
5
|
class HelloWorld
|
5
6
|
def call(env)
|
@@ -8,6 +9,13 @@ class HelloWorld
|
|
8
9
|
end
|
9
10
|
|
10
11
|
module M2R
|
12
|
+
class ConnectionFactory
|
13
|
+
class Custom
|
14
|
+
def initialize(*)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
11
19
|
class RackHandlerTest < MiniTest::Unit::TestCase
|
12
20
|
def test_discoverability
|
13
21
|
handler = ::Rack::Handler.get(:mongrel2)
|
@@ -26,20 +34,36 @@ module M2R
|
|
26
34
|
'sender_id' => id = SecureRandom.uuid
|
27
35
|
}
|
28
36
|
cf = mock(:connection)
|
29
|
-
ConnectionFactory.expects(:new).with(
|
37
|
+
ConnectionFactory.expects(:new).with(responds_with(:sender_id, id)).returns(cf)
|
30
38
|
RackHandler.any_instance.stubs(:stop? => true)
|
31
39
|
handler.run(HelloWorld.new, options)
|
32
40
|
end
|
33
41
|
|
34
42
|
def test_lint_rack_adapter
|
35
43
|
factory = stub(:connection)
|
36
|
-
handler = RackHandler.new(app, factory)
|
44
|
+
handler = RackHandler.new(app, factory, Request)
|
37
45
|
response = handler.process(root_request)
|
38
46
|
|
39
47
|
assert_equal "Hello world!", response.body
|
40
48
|
assert_equal 200, response.status
|
41
49
|
end
|
42
50
|
|
51
|
+
def test_custom_connection_factory
|
52
|
+
require 'rack/handler/mongrel2'
|
53
|
+
handler = ::Rack::Handler::Mongrel2
|
54
|
+
options = {
|
55
|
+
'connection_factory' => 'custom'
|
56
|
+
}
|
57
|
+
cf = mock(:connection)
|
58
|
+
ConnectionFactory::Custom.expects(:new).with(responds_with(:connection_factory, 'custom')).returns(cf)
|
59
|
+
RackHandler.any_instance.stubs(:stop? => true)
|
60
|
+
handler.run(HelloWorld.new, options)
|
61
|
+
end
|
62
|
+
|
63
|
+
|
64
|
+
private
|
65
|
+
|
66
|
+
|
43
67
|
def root_request
|
44
68
|
data = %q("1c5fd481-1121-49d8-a706-69127975db1a ebb407b2-49aa-48a5-9f96-9db121051484 / 96:{"PATH":"/","host":"127.0.0.1:6767","PATTERN":"/","METHOD":"GET","VERSION":"HTTP/1.1","URI":"/"},0:,)
|
45
69
|
Request.parse(data)
|
data/test/unit/request_test.rb
CHANGED
data/test/unit/response_test.rb
CHANGED
@@ -3,28 +3,99 @@ require 'test_helper'
|
|
3
3
|
module M2R
|
4
4
|
class ResponseTest < MiniTest::Unit::TestCase
|
5
5
|
def test_response_with_nil_body
|
6
|
-
ok = Response.new(200
|
6
|
+
ok = Response.new.status(200).headers({"Transfer-Encoding" => "chunked"}).body(nil)
|
7
7
|
http = "HTTP/1.1 200 OK\r\nTransfer-Encoding: chunked\r\n\r\n"
|
8
8
|
assert_equal http, ok.to_s
|
9
9
|
end
|
10
10
|
|
11
11
|
def test_response_with_empty_body
|
12
|
-
ok = Response.new(200
|
12
|
+
ok = Response.new.status(200).headers({"Transfer-Encoding" => "chunked"}).body("")
|
13
13
|
http = "HTTP/1.1 200 OK\r\nTransfer-Encoding: chunked\r\n\r\n"
|
14
14
|
assert_equal http, ok.to_s
|
15
15
|
end
|
16
16
|
|
17
17
|
def test_response_with_no_body
|
18
|
-
ok = Response.new(200
|
18
|
+
ok = Response.new.status(200).headers({"Transfer-Encoding" => "chunked"})
|
19
19
|
http = "HTTP/1.1 200 OK\r\nTransfer-Encoding: chunked\r\n\r\n"
|
20
20
|
assert_equal http, ok.to_s
|
21
21
|
end
|
22
22
|
|
23
23
|
def test_response_with_content_length
|
24
|
-
ok = Response.new(
|
24
|
+
ok = Response.new.body('data')
|
25
25
|
ok.extend Response::ContentLength
|
26
|
-
http = "HTTP/1.1 200 OK\r\
|
26
|
+
http = "HTTP/1.1 200 OK\r\ncontent-length: 4\r\n\r\ndata"
|
27
27
|
assert_equal http, ok.to_s
|
28
28
|
end
|
29
|
+
|
30
|
+
def test_response_with_header
|
31
|
+
ok = Response.new.body('data').header('X-Man', 'Wolverine')
|
32
|
+
ok.extend Response::ContentLength
|
33
|
+
http = "HTTP/1.1 200 OK\r\nx-man: Wolverine\r\ncontent-length: 4\r\n\r\ndata"
|
34
|
+
assert_equal http, ok.to_s
|
35
|
+
end
|
36
|
+
|
37
|
+
def test_response_with_old_version
|
38
|
+
ok = Response.new.http_version('HTTP/1.0').body('data')
|
39
|
+
ok.extend Response::ContentLength
|
40
|
+
http = "HTTP/1.0 200 OK\r\ncontent-length: 4\r\n\r\ndata"
|
41
|
+
assert_equal http, ok.to_s
|
42
|
+
end
|
43
|
+
|
44
|
+
def test_getters
|
45
|
+
ok = Response.new.http_version(v = 'HTTP/1.0').status(s = 300).headers({'X-Man' => xman = 'Summers'}).header("X-Angel", angel = "Warren").body(data = 'data')
|
46
|
+
assert_equal v, ok.http_version
|
47
|
+
assert_equal s, ok.status
|
48
|
+
assert_equal xman, ok.header("X-Man")
|
49
|
+
assert_equal angel, ok.header("X-Angel")
|
50
|
+
assert_equal data , ok.body
|
51
|
+
assert_equal 2, ok.headers.size
|
52
|
+
end
|
53
|
+
|
54
|
+
def test_default_close
|
55
|
+
ok = Response.new
|
56
|
+
refute ok.close?
|
57
|
+
end
|
58
|
+
|
59
|
+
def test_http10_close
|
60
|
+
ok = Response.new.http_version('HTTP/1.0')
|
61
|
+
assert ok.close?
|
62
|
+
end
|
63
|
+
|
64
|
+
def test_header_close
|
65
|
+
ok = Response.new.header('Connection', 'close')
|
66
|
+
assert ok.close?
|
67
|
+
end
|
68
|
+
|
69
|
+
def test_response_to_http10_identical
|
70
|
+
ok = Response.new
|
71
|
+
ok.extend(Response::ToRequest)
|
72
|
+
ok.to(stub(http_version: 'HTTP/1.0', close?:true), true)
|
73
|
+
assert_equal 'HTTP/1.0', ok.http_version
|
74
|
+
assert_equal 'close', ok.header('Connection')
|
75
|
+
end
|
76
|
+
|
77
|
+
def test_response_to_http10_rfc2145
|
78
|
+
ok = Response.new
|
79
|
+
ok.extend(Response::ToRequest)
|
80
|
+
ok.to(stub(http_version: 'HTTP/1.0', close?:true))
|
81
|
+
assert_equal 'HTTP/1.1', ok.http_version
|
82
|
+
assert_equal 'close', ok.header('Connection')
|
83
|
+
end
|
84
|
+
|
85
|
+
def test_response_to_http11
|
86
|
+
ok = Response.new
|
87
|
+
ok.extend(Response::ToRequest)
|
88
|
+
ok.to(stub(http_version: 'HTTP/1.1', close?:false))
|
89
|
+
assert_equal 'HTTP/1.1', ok.http_version
|
90
|
+
assert_equal nil, ok.header('Connection')
|
91
|
+
end
|
92
|
+
|
93
|
+
def test_response_to_http11_with_close
|
94
|
+
ok = Response.new
|
95
|
+
ok.extend(Response::ToRequest)
|
96
|
+
ok.to(stub(http_version: 'HTTP/1.1', close?:true))
|
97
|
+
assert_equal 'HTTP/1.1', ok.http_version
|
98
|
+
assert_equal 'close', ok.header('Connection')
|
99
|
+
end
|
29
100
|
end
|
30
101
|
end
|