eventmachine_httpserver 0.1.1-x86-mswin32-60
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/Rakefile +92 -0
- data/docs/COPYING +281 -0
- data/docs/README +8 -0
- data/docs/RELEASE_NOTES +3 -0
- data/eventmachine_httpserver.gemspec +33 -0
- data/eventmachine_httpserver.gemspec.tmpl +23 -0
- data/ext/extconf.rb +133 -0
- data/ext/http.cpp +584 -0
- data/ext/http.h +115 -0
- data/ext/rubyhttp.cpp +281 -0
- data/lib/eventmachine_httpserver.so +0 -0
- data/lib/evma_httpserver.rb +35 -0
- data/lib/evma_httpserver/response.rb +313 -0
- data/test/test_app.rb +239 -0
- data/test/test_delegated.rb +187 -0
- data/test/test_response.rb +178 -0
- metadata +73 -0
data/test/test_app.rb
ADDED
@@ -0,0 +1,239 @@
|
|
1
|
+
require 'test/unit'
|
2
|
+
require 'evma_httpserver'
|
3
|
+
|
4
|
+
begin
|
5
|
+
once = false
|
6
|
+
require 'eventmachine'
|
7
|
+
rescue LoadError => e
|
8
|
+
raise e if once
|
9
|
+
once = true
|
10
|
+
require 'rubygems'
|
11
|
+
retry
|
12
|
+
end
|
13
|
+
|
14
|
+
|
15
|
+
|
16
|
+
#--------------------------------------
|
17
|
+
|
18
|
+
module EventMachine
|
19
|
+
module HttpServer
|
20
|
+
def process_http_request
|
21
|
+
send_data generate_response()
|
22
|
+
close_connection_after_writing
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
#--------------------------------------
|
28
|
+
|
29
|
+
require 'socket'
|
30
|
+
|
31
|
+
class TestApp < Test::Unit::TestCase
|
32
|
+
|
33
|
+
TestHost = "127.0.0.1"
|
34
|
+
TestPort = 8911
|
35
|
+
|
36
|
+
TestResponse_1 = <<EORESP
|
37
|
+
HTTP/1.0 200 ...
|
38
|
+
Content-length: 4
|
39
|
+
Content-type: text/plain
|
40
|
+
Connection: close
|
41
|
+
|
42
|
+
1234
|
43
|
+
EORESP
|
44
|
+
|
45
|
+
Thread.abort_on_exception = true
|
46
|
+
|
47
|
+
def test_simple_get
|
48
|
+
received_response = nil
|
49
|
+
|
50
|
+
EventMachine::HttpServer.module_eval do
|
51
|
+
def generate_response
|
52
|
+
TestResponse_1
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
|
57
|
+
EventMachine.run do
|
58
|
+
EventMachine.start_server TestHost, TestPort, EventMachine::HttpServer
|
59
|
+
EventMachine.add_timer(1) {raise "timed out"} # make sure the test completes
|
60
|
+
|
61
|
+
cb = proc do
|
62
|
+
tcp = TCPSocket.new TestHost, TestPort
|
63
|
+
tcp.write "GET / HTTP/1.0\r\n\r\n"
|
64
|
+
received_response = tcp.read
|
65
|
+
end
|
66
|
+
eb = proc { EventMachine.stop }
|
67
|
+
EventMachine.defer cb, eb
|
68
|
+
end
|
69
|
+
|
70
|
+
assert_equal( TestResponse_1, received_response )
|
71
|
+
end
|
72
|
+
|
73
|
+
|
74
|
+
|
75
|
+
|
76
|
+
# This frowsy-looking protocol handler allows the test harness to make some
|
77
|
+
# its local variables visible, so we can set them here and they can be asserted later.
|
78
|
+
class MyTestServer < EventMachine::Connection
|
79
|
+
include EventMachine::HttpServer
|
80
|
+
def initialize *args
|
81
|
+
super
|
82
|
+
end
|
83
|
+
def generate_response
|
84
|
+
@assertions.call
|
85
|
+
TestResponse_1
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
|
90
|
+
|
91
|
+
def test_parameters
|
92
|
+
path_info = "/test.html"
|
93
|
+
query_string = "a=b&c=d"
|
94
|
+
cookie = "eat_me=I'm a cookie"
|
95
|
+
etag = "12345"
|
96
|
+
|
97
|
+
# collect all the stuff we want to assert outside the actual test,
|
98
|
+
# to ensure it gets asserted even if the test catches some exception.
|
99
|
+
received_response = nil
|
100
|
+
request_parms = {}
|
101
|
+
|
102
|
+
|
103
|
+
EventMachine.run do
|
104
|
+
EventMachine.start_server(TestHost, TestPort, MyTestServer) do |conn|
|
105
|
+
# In each accepted connection, set up a procedure that will copy
|
106
|
+
# the request parameters into a local variable visible here, so
|
107
|
+
# we can assert the values later.
|
108
|
+
conn.instance_eval do
|
109
|
+
@assertions = proc {
|
110
|
+
parms = %w( PATH_INFO QUERY_STRING HTTP_COOKIE IF_NONE_MATCH
|
111
|
+
CONTENT_TYPE REQUEST_METHOD REQUEST_URI )
|
112
|
+
parms.each {|parm|
|
113
|
+
# request_parms is bound to a local variable visible in this context.
|
114
|
+
request_parms[parm] = ENV[parm]
|
115
|
+
}
|
116
|
+
}
|
117
|
+
end
|
118
|
+
end
|
119
|
+
EventMachine.add_timer(1) {raise "timed out"} # make sure the test completes
|
120
|
+
|
121
|
+
cb = proc do
|
122
|
+
tcp = TCPSocket.new TestHost, TestPort
|
123
|
+
data = [
|
124
|
+
"GET #{path_info}?#{query_string} HTTP/1.1\r\n",
|
125
|
+
"Cookie: #{cookie}\r\n",
|
126
|
+
"If-none-match: #{etag}\r\n",
|
127
|
+
"\r\n"
|
128
|
+
].join
|
129
|
+
tcp.write(data)
|
130
|
+
received_response = tcp.read
|
131
|
+
end
|
132
|
+
eb = proc { EventMachine.stop }
|
133
|
+
EventMachine.defer cb, eb
|
134
|
+
end
|
135
|
+
|
136
|
+
assert_equal( TestResponse_1, received_response )
|
137
|
+
assert_equal( path_info, request_parms["PATH_INFO"] )
|
138
|
+
assert_equal( query_string, request_parms["QUERY_STRING"] )
|
139
|
+
assert_equal( cookie, request_parms["HTTP_COOKIE"] )
|
140
|
+
assert_equal( etag, request_parms["IF_NONE_MATCH"] )
|
141
|
+
assert_equal( nil, request_parms["CONTENT_TYPE"] )
|
142
|
+
assert_equal( "GET", request_parms["REQUEST_METHOD"] )
|
143
|
+
assert_equal( path_info, request_parms["REQUEST_URI"] )
|
144
|
+
end
|
145
|
+
|
146
|
+
|
147
|
+
def test_headers
|
148
|
+
received_header_string = nil
|
149
|
+
received_header_ary = nil
|
150
|
+
|
151
|
+
EventMachine.run do
|
152
|
+
EventMachine.start_server(TestHost, TestPort, MyTestServer) do |conn|
|
153
|
+
# In each accepted connection, set up a procedure that will copy
|
154
|
+
# the request parameters into a local variable visible here, so
|
155
|
+
# we can assert the values later.
|
156
|
+
# The @http_headers is set automatically and can easily be parsed.
|
157
|
+
# It isn't automatically parsed into Ruby values because that is
|
158
|
+
# a costly operation, but we should provide an optional method that
|
159
|
+
# does the parsing so it doesn't need to be done by users.
|
160
|
+
conn.instance_eval do
|
161
|
+
@assertions = proc do
|
162
|
+
received_header_string = @http_headers
|
163
|
+
received_header_ary = @http_headers.split(/\0/).map {|line| line.split(/:\s*/, 2) }
|
164
|
+
end
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
168
|
+
cb = proc do
|
169
|
+
tcp = TCPSocket.new TestHost, TestPort
|
170
|
+
data = [
|
171
|
+
"GET / HTTP/1.1\r\n",
|
172
|
+
"aaa: 111\r\n",
|
173
|
+
"bbb: 222\r\n",
|
174
|
+
"ccc: 333\r\n",
|
175
|
+
"ddd: 444\r\n",
|
176
|
+
"\r\n"
|
177
|
+
].join
|
178
|
+
tcp.write data
|
179
|
+
received_response = tcp.read
|
180
|
+
end
|
181
|
+
eb = proc { EventMachine.stop }
|
182
|
+
EventMachine.defer cb, eb
|
183
|
+
|
184
|
+
EventMachine.add_timer(1) {raise "timed out"} # make sure the test completes
|
185
|
+
end
|
186
|
+
|
187
|
+
assert_equal( "aaa: 111\0bbb: 222\0ccc: 333\0ddd: 444\0\0", received_header_string )
|
188
|
+
assert_equal( [["aaa","111"], ["bbb","222"], ["ccc","333"], ["ddd","444"]], received_header_ary )
|
189
|
+
end
|
190
|
+
|
191
|
+
|
192
|
+
|
193
|
+
|
194
|
+
|
195
|
+
def test_post
|
196
|
+
received_header_string = nil
|
197
|
+
post_content = "1234567890"
|
198
|
+
content_type = "text/plain"
|
199
|
+
received_post_content = ""
|
200
|
+
received_content_type = ""
|
201
|
+
|
202
|
+
EventMachine.run do
|
203
|
+
EventMachine.start_server(TestHost, TestPort, MyTestServer) do |conn|
|
204
|
+
# In each accepted connection, set up a procedure that will copy
|
205
|
+
# the request parameters into a local variable visible here, so
|
206
|
+
# we can assert the values later.
|
207
|
+
# The @http_post_content variable is set automatically.
|
208
|
+
conn.instance_eval do
|
209
|
+
@assertions = proc do
|
210
|
+
received_post_content = @http_post_content
|
211
|
+
received_content_type = ENV["CONTENT_TYPE"]
|
212
|
+
end
|
213
|
+
end
|
214
|
+
end
|
215
|
+
EventMachine.add_timer(1) {raise "timed out"} # make sure the test completes
|
216
|
+
|
217
|
+
cb = proc do
|
218
|
+
tcp = TCPSocket.new TestHost, TestPort
|
219
|
+
data = [
|
220
|
+
"POST / HTTP/1.1\r\n",
|
221
|
+
"Content-type: #{content_type}\r\n",
|
222
|
+
"Content-length: #{post_content.length}\r\n",
|
223
|
+
"\r\n",
|
224
|
+
post_content
|
225
|
+
].join
|
226
|
+
tcp.write(data)
|
227
|
+
received_response = tcp.read
|
228
|
+
end
|
229
|
+
eb = proc do
|
230
|
+
EventMachine.stop
|
231
|
+
end
|
232
|
+
EventMachine.defer cb, eb
|
233
|
+
end
|
234
|
+
|
235
|
+
assert_equal( received_post_content, post_content )
|
236
|
+
assert_equal( received_content_type, content_type )
|
237
|
+
end
|
238
|
+
|
239
|
+
end
|
@@ -0,0 +1,187 @@
|
|
1
|
+
require 'test/unit'
|
2
|
+
require 'evma_httpserver'
|
3
|
+
|
4
|
+
begin
|
5
|
+
once = false
|
6
|
+
require 'eventmachine'
|
7
|
+
rescue LoadError => e
|
8
|
+
raise e if once
|
9
|
+
once = true
|
10
|
+
require 'rubygems'
|
11
|
+
retry
|
12
|
+
end
|
13
|
+
|
14
|
+
|
15
|
+
#--------------------------------------
|
16
|
+
|
17
|
+
|
18
|
+
class TestDelegatedHttpResponse < Test::Unit::TestCase
|
19
|
+
|
20
|
+
# This is a delegate class that (trivially) implements the
|
21
|
+
# several classes needed to work with HttpResponse.
|
22
|
+
#
|
23
|
+
class D
|
24
|
+
attr_reader :output_data
|
25
|
+
attr_reader :closed_after_writing
|
26
|
+
|
27
|
+
def send_data data
|
28
|
+
@output_data ||= ""
|
29
|
+
@output_data << data
|
30
|
+
end
|
31
|
+
def close_connection_after_writing
|
32
|
+
@closed_after_writing = true
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def setup
|
37
|
+
end
|
38
|
+
|
39
|
+
|
40
|
+
def teardown
|
41
|
+
end
|
42
|
+
|
43
|
+
|
44
|
+
def test_properties
|
45
|
+
a = EM::DelegatedHttpResponse.new( D.new )
|
46
|
+
a.status = 200
|
47
|
+
a.content = "Some content"
|
48
|
+
a.headers["Content-type"] = "text/xml"
|
49
|
+
end
|
50
|
+
|
51
|
+
def test_header_sugarings
|
52
|
+
a = EM::DelegatedHttpResponse.new( D.new )
|
53
|
+
a.content_type "text/xml"
|
54
|
+
a.set_cookie "a=b"
|
55
|
+
a.headers["X-bayshore"] = "aaaa"
|
56
|
+
|
57
|
+
assert_equal({
|
58
|
+
"Content-type" => "text/xml",
|
59
|
+
"Set-cookie" => ["a=b"],
|
60
|
+
"X-bayshore" => "aaaa"
|
61
|
+
}, a.headers)
|
62
|
+
end
|
63
|
+
|
64
|
+
def test_send_response
|
65
|
+
d = D.new
|
66
|
+
a = EM::DelegatedHttpResponse.new( d )
|
67
|
+
a.status = 200
|
68
|
+
a.send_response
|
69
|
+
assert_equal([
|
70
|
+
"HTTP/1.1 200 ...\r\n",
|
71
|
+
"Content-length: 0\r\n",
|
72
|
+
"\r\n"
|
73
|
+
].join, d.output_data)
|
74
|
+
assert_equal( true, d.closed_after_writing )
|
75
|
+
end
|
76
|
+
|
77
|
+
def test_send_response_1
|
78
|
+
d = D.new
|
79
|
+
a = EM::DelegatedHttpResponse.new( d )
|
80
|
+
a.status = 200
|
81
|
+
a.content_type "text/plain"
|
82
|
+
a.content = "ABC"
|
83
|
+
a.send_response
|
84
|
+
assert_equal([
|
85
|
+
"HTTP/1.1 200 ...\r\n",
|
86
|
+
"Content-length: 3\r\n",
|
87
|
+
"Content-type: text/plain\r\n",
|
88
|
+
"\r\n",
|
89
|
+
"ABC"
|
90
|
+
].join, d.output_data)
|
91
|
+
assert( d.closed_after_writing )
|
92
|
+
end
|
93
|
+
|
94
|
+
def test_send_response_no_close
|
95
|
+
d = D.new
|
96
|
+
a = EM::DelegatedHttpResponse.new( d )
|
97
|
+
a.status = 200
|
98
|
+
a.content_type "text/plain"
|
99
|
+
a.content = "ABC"
|
100
|
+
a.keep_connection_open
|
101
|
+
a.send_response
|
102
|
+
assert_equal([
|
103
|
+
"HTTP/1.1 200 ...\r\n",
|
104
|
+
"Content-length: 3\r\n",
|
105
|
+
"Content-type: text/plain\r\n",
|
106
|
+
"\r\n",
|
107
|
+
"ABC"
|
108
|
+
].join, d.output_data)
|
109
|
+
assert( ! d.closed_after_writing )
|
110
|
+
end
|
111
|
+
|
112
|
+
def test_send_response_multiple_times
|
113
|
+
a = EM::DelegatedHttpResponse.new( D.new )
|
114
|
+
a.status = 200
|
115
|
+
a.send_response
|
116
|
+
assert_raise( RuntimeError ) {
|
117
|
+
a.send_response
|
118
|
+
}
|
119
|
+
end
|
120
|
+
|
121
|
+
def test_send_headers
|
122
|
+
d = D.new
|
123
|
+
a = EM::DelegatedHttpResponse.new( d )
|
124
|
+
a.status = 200
|
125
|
+
a.send_headers
|
126
|
+
assert_equal([
|
127
|
+
"HTTP/1.1 200 ...\r\n",
|
128
|
+
"Content-length: 0\r\n",
|
129
|
+
"\r\n"
|
130
|
+
].join, d.output_data)
|
131
|
+
assert( ! d.closed_after_writing )
|
132
|
+
assert_raise( RuntimeError ) {
|
133
|
+
a.send_headers
|
134
|
+
}
|
135
|
+
end
|
136
|
+
|
137
|
+
def test_send_chunks
|
138
|
+
d = D.new
|
139
|
+
a = EM::DelegatedHttpResponse.new( d )
|
140
|
+
a.chunk "ABC"
|
141
|
+
a.chunk "DEF"
|
142
|
+
a.chunk "GHI"
|
143
|
+
a.keep_connection_open
|
144
|
+
a.send_response
|
145
|
+
assert_equal([
|
146
|
+
"HTTP/1.1 200 ...\r\n",
|
147
|
+
"Transfer-encoding: chunked\r\n",
|
148
|
+
"\r\n",
|
149
|
+
"3\r\n",
|
150
|
+
"ABC\r\n",
|
151
|
+
"3\r\n",
|
152
|
+
"DEF\r\n",
|
153
|
+
"3\r\n",
|
154
|
+
"GHI\r\n",
|
155
|
+
"0\r\n",
|
156
|
+
"\r\n"
|
157
|
+
].join, d.output_data)
|
158
|
+
assert( !d.closed_after_writing )
|
159
|
+
end
|
160
|
+
|
161
|
+
def test_send_chunks_with_close
|
162
|
+
d = D.new
|
163
|
+
a = EM::DelegatedHttpResponse.new( d )
|
164
|
+
a.chunk "ABC"
|
165
|
+
a.chunk "DEF"
|
166
|
+
a.chunk "GHI"
|
167
|
+
a.send_response
|
168
|
+
assert_equal([
|
169
|
+
"HTTP/1.1 200 ...\r\n",
|
170
|
+
"Transfer-encoding: chunked\r\n",
|
171
|
+
"\r\n",
|
172
|
+
"3\r\n",
|
173
|
+
"ABC\r\n",
|
174
|
+
"3\r\n",
|
175
|
+
"DEF\r\n",
|
176
|
+
"3\r\n",
|
177
|
+
"GHI\r\n",
|
178
|
+
"0\r\n",
|
179
|
+
"\r\n"
|
180
|
+
].join, d.output_data)
|
181
|
+
assert( d.closed_after_writing )
|
182
|
+
end
|
183
|
+
|
184
|
+
end
|
185
|
+
|
186
|
+
|
187
|
+
|
@@ -0,0 +1,178 @@
|
|
1
|
+
require 'test/unit'
|
2
|
+
require 'evma_httpserver'
|
3
|
+
|
4
|
+
begin
|
5
|
+
once = false
|
6
|
+
require 'eventmachine'
|
7
|
+
rescue LoadError => e
|
8
|
+
raise e if once
|
9
|
+
once = true
|
10
|
+
require 'rubygems'
|
11
|
+
retry
|
12
|
+
end
|
13
|
+
|
14
|
+
|
15
|
+
#--------------------------------------
|
16
|
+
|
17
|
+
module EventMachine
|
18
|
+
|
19
|
+
# This is a test harness wired into the HttpResponse class so we
|
20
|
+
# can test it without requiring any actual network communication.
|
21
|
+
#
|
22
|
+
class HttpResponse
|
23
|
+
attr_reader :output_data
|
24
|
+
attr_reader :closed_after_writing
|
25
|
+
|
26
|
+
def send_data data
|
27
|
+
@output_data ||= ""
|
28
|
+
@output_data << data
|
29
|
+
end
|
30
|
+
def close_connection_after_writing
|
31
|
+
@closed_after_writing = true
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
#--------------------------------------
|
37
|
+
|
38
|
+
|
39
|
+
class TestHttpResponse < Test::Unit::TestCase
|
40
|
+
|
41
|
+
def test_properties
|
42
|
+
a = EventMachine::HttpResponse.new
|
43
|
+
a.status = 200
|
44
|
+
a.content = "Some content"
|
45
|
+
a.headers["Content-type"] = "text/xml"
|
46
|
+
end
|
47
|
+
|
48
|
+
def test_header_sugarings
|
49
|
+
a = EventMachine::HttpResponse.new
|
50
|
+
a.content_type "text/xml"
|
51
|
+
a.set_cookie "a=b"
|
52
|
+
a.headers["X-bayshore"] = "aaaa"
|
53
|
+
|
54
|
+
assert_equal({
|
55
|
+
"Content-type" => "text/xml",
|
56
|
+
"Set-cookie" => ["a=b"],
|
57
|
+
"X-bayshore" => "aaaa"
|
58
|
+
}, a.headers)
|
59
|
+
end
|
60
|
+
|
61
|
+
def test_send_response
|
62
|
+
a = EventMachine::HttpResponse.new
|
63
|
+
a.status = 200
|
64
|
+
a.send_response
|
65
|
+
assert_equal([
|
66
|
+
"HTTP/1.1 200 ...\r\n",
|
67
|
+
"Content-length: 0\r\n",
|
68
|
+
"\r\n"
|
69
|
+
].join, a.output_data)
|
70
|
+
assert_equal( true, a.closed_after_writing )
|
71
|
+
end
|
72
|
+
|
73
|
+
def test_send_response_1
|
74
|
+
a = EventMachine::HttpResponse.new
|
75
|
+
a.status = 200
|
76
|
+
a.content_type "text/plain"
|
77
|
+
a.content = "ABC"
|
78
|
+
a.send_response
|
79
|
+
assert_equal([
|
80
|
+
"HTTP/1.1 200 ...\r\n",
|
81
|
+
"Content-length: 3\r\n",
|
82
|
+
"Content-type: text/plain\r\n",
|
83
|
+
"\r\n",
|
84
|
+
"ABC"
|
85
|
+
].join, a.output_data)
|
86
|
+
assert( a.closed_after_writing )
|
87
|
+
end
|
88
|
+
|
89
|
+
def test_send_response_no_close
|
90
|
+
a = EventMachine::HttpResponse.new
|
91
|
+
a.status = 200
|
92
|
+
a.content_type "text/plain"
|
93
|
+
a.content = "ABC"
|
94
|
+
a.keep_connection_open
|
95
|
+
a.send_response
|
96
|
+
assert_equal([
|
97
|
+
"HTTP/1.1 200 ...\r\n",
|
98
|
+
"Content-length: 3\r\n",
|
99
|
+
"Content-type: text/plain\r\n",
|
100
|
+
"\r\n",
|
101
|
+
"ABC"
|
102
|
+
].join, a.output_data)
|
103
|
+
assert( ! a.closed_after_writing )
|
104
|
+
end
|
105
|
+
|
106
|
+
def test_send_response_multiple_times
|
107
|
+
a = EventMachine::HttpResponse.new
|
108
|
+
a.status = 200
|
109
|
+
a.send_response
|
110
|
+
assert_raise( RuntimeError ) {
|
111
|
+
a.send_response
|
112
|
+
}
|
113
|
+
end
|
114
|
+
|
115
|
+
def test_send_headers
|
116
|
+
a = EventMachine::HttpResponse.new
|
117
|
+
a.status = 200
|
118
|
+
a.send_headers
|
119
|
+
assert_equal([
|
120
|
+
"HTTP/1.1 200 ...\r\n",
|
121
|
+
"Content-length: 0\r\n",
|
122
|
+
"\r\n"
|
123
|
+
].join, a.output_data)
|
124
|
+
assert( ! a.closed_after_writing )
|
125
|
+
assert_raise( RuntimeError ) {
|
126
|
+
a.send_headers
|
127
|
+
}
|
128
|
+
end
|
129
|
+
|
130
|
+
def test_send_chunks
|
131
|
+
a = EventMachine::HttpResponse.new
|
132
|
+
a.chunk "ABC"
|
133
|
+
a.chunk "DEF"
|
134
|
+
a.chunk "GHI"
|
135
|
+
a.keep_connection_open
|
136
|
+
a.send_response
|
137
|
+
assert_equal([
|
138
|
+
"HTTP/1.1 200 ...\r\n",
|
139
|
+
"Transfer-encoding: chunked\r\n",
|
140
|
+
"\r\n",
|
141
|
+
"3\r\n",
|
142
|
+
"ABC\r\n",
|
143
|
+
"3\r\n",
|
144
|
+
"DEF\r\n",
|
145
|
+
"3\r\n",
|
146
|
+
"GHI\r\n",
|
147
|
+
"0\r\n",
|
148
|
+
"\r\n"
|
149
|
+
].join, a.output_data)
|
150
|
+
assert( !a.closed_after_writing )
|
151
|
+
end
|
152
|
+
|
153
|
+
def test_send_chunks_with_close
|
154
|
+
a = EventMachine::HttpResponse.new
|
155
|
+
a.chunk "ABC"
|
156
|
+
a.chunk "DEF"
|
157
|
+
a.chunk "GHI"
|
158
|
+
a.send_response
|
159
|
+
assert_equal([
|
160
|
+
"HTTP/1.1 200 ...\r\n",
|
161
|
+
"Transfer-encoding: chunked\r\n",
|
162
|
+
"\r\n",
|
163
|
+
"3\r\n",
|
164
|
+
"ABC\r\n",
|
165
|
+
"3\r\n",
|
166
|
+
"DEF\r\n",
|
167
|
+
"3\r\n",
|
168
|
+
"GHI\r\n",
|
169
|
+
"0\r\n",
|
170
|
+
"\r\n"
|
171
|
+
].join, a.output_data)
|
172
|
+
assert( a.closed_after_writing )
|
173
|
+
end
|
174
|
+
|
175
|
+
end
|
176
|
+
|
177
|
+
|
178
|
+
|