eventmachine 0.12.0-i386-mswin32
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/COPYING +60 -0
- data/DEFERRABLES +138 -0
- data/EPOLL +141 -0
- data/GNU +281 -0
- data/KEYBOARD +38 -0
- data/LEGAL +25 -0
- data/LIGHTWEIGHT_CONCURRENCY +72 -0
- data/PURE_RUBY +77 -0
- data/README +74 -0
- data/RELEASE_NOTES +96 -0
- data/SMTP +9 -0
- data/SPAWNED_PROCESSES +93 -0
- data/TODO +10 -0
- data/ext/Makefile +180 -0
- data/ext/binder.cpp +126 -0
- data/ext/binder.h +48 -0
- data/ext/cmain.cpp +527 -0
- data/ext/cplusplus.cpp +172 -0
- data/ext/ed.cpp +1442 -0
- data/ext/ed.h +351 -0
- data/ext/em.cpp +1781 -0
- data/ext/em.h +167 -0
- data/ext/emwin.cpp +300 -0
- data/ext/emwin.h +94 -0
- data/ext/epoll.cpp +26 -0
- data/ext/epoll.h +25 -0
- data/ext/eventmachine.h +83 -0
- data/ext/eventmachine_cpp.h +94 -0
- data/ext/extconf.rb +203 -0
- data/ext/files.cpp +94 -0
- data/ext/files.h +65 -0
- data/ext/kb.cpp +368 -0
- data/ext/mkmf.log +129 -0
- data/ext/page.cpp +107 -0
- data/ext/page.h +51 -0
- data/ext/pipe.cpp +327 -0
- data/ext/project.h +119 -0
- data/ext/rubyeventmachine-i386-mswin32.def +2 -0
- data/ext/rubyeventmachine-i386-mswin32.exp +0 -0
- data/ext/rubyeventmachine-i386-mswin32.lib +0 -0
- data/ext/rubyeventmachine-i386-mswin32.pdb +0 -0
- data/ext/rubyeventmachine.so +0 -0
- data/ext/rubymain.cpp +630 -0
- data/ext/sigs.cpp +89 -0
- data/ext/sigs.h +32 -0
- data/ext/ssl.cpp +408 -0
- data/ext/ssl.h +86 -0
- data/ext/vc60.pdb +0 -0
- data/lib/em/deferrable.rb +208 -0
- data/lib/em/eventable.rb +39 -0
- data/lib/em/future.rb +62 -0
- data/lib/em/messages.rb +66 -0
- data/lib/em/processes.rb +68 -0
- data/lib/em/spawnable.rb +88 -0
- data/lib/em/streamer.rb +112 -0
- data/lib/eventmachine.rb +1621 -0
- data/lib/eventmachine_version.rb +31 -0
- data/lib/evma.rb +32 -0
- data/lib/evma/callback.rb +32 -0
- data/lib/evma/container.rb +75 -0
- data/lib/evma/factory.rb +77 -0
- data/lib/evma/protocol.rb +87 -0
- data/lib/evma/reactor.rb +48 -0
- data/lib/jeventmachine.rb +106 -0
- data/lib/pr_eventmachine.rb +1011 -0
- data/lib/protocols/buftok.rb +127 -0
- data/lib/protocols/header_and_content.rb +123 -0
- data/lib/protocols/httpcli2.rb +784 -0
- data/lib/protocols/httpclient.rb +253 -0
- data/lib/protocols/line_and_text.rb +122 -0
- data/lib/protocols/linetext2.rb +145 -0
- data/lib/protocols/saslauth.rb +179 -0
- data/lib/protocols/smtpclient.rb +308 -0
- data/lib/protocols/smtpserver.rb +543 -0
- data/lib/protocols/stomp.rb +127 -0
- data/lib/protocols/tcptest.rb +57 -0
- data/lib/rubyeventmachine.so +0 -0
- data/tests/test_basic.rb +142 -0
- data/tests/test_defer.rb +63 -0
- data/tests/test_epoll.rb +168 -0
- data/tests/test_errors.rb +82 -0
- data/tests/test_eventables.rb +78 -0
- data/tests/test_exc.rb +58 -0
- data/tests/test_futures.rb +214 -0
- data/tests/test_hc.rb +221 -0
- data/tests/test_httpclient.rb +194 -0
- data/tests/test_httpclient2.rb +133 -0
- data/tests/test_kb.rb +61 -0
- data/tests/test_ltp.rb +190 -0
- data/tests/test_ltp2.rb +261 -0
- data/tests/test_next_tick.rb +58 -0
- data/tests/test_processes.rb +56 -0
- data/tests/test_pure.rb +128 -0
- data/tests/test_running.rb +47 -0
- data/tests/test_sasl.rb +73 -0
- data/tests/test_send_file.rb +238 -0
- data/tests/test_servers.rb +90 -0
- data/tests/test_smtpclient.rb +81 -0
- data/tests/test_smtpserver.rb +93 -0
- data/tests/test_spawn.rb +329 -0
- data/tests/test_timers.rb +138 -0
- data/tests/test_ud.rb +43 -0
- data/tests/testem.rb +5 -0
- metadata +170 -0
@@ -0,0 +1,82 @@
|
|
1
|
+
# $Id: test_errors.rb 668 2008-01-04 23:00:34Z blackhedd $
|
2
|
+
#
|
3
|
+
# Author:: Francis Cianfrocca (gmail: blackhedd)
|
4
|
+
# Homepage:: http://rubyeventmachine.com
|
5
|
+
# Date:: 8 April 2006
|
6
|
+
#
|
7
|
+
# See EventMachine and EventMachine::Connection for documentation and
|
8
|
+
# usage examples.
|
9
|
+
#
|
10
|
+
#----------------------------------------------------------------------------
|
11
|
+
#
|
12
|
+
# Copyright (C) 2006-07 by Francis Cianfrocca. All Rights Reserved.
|
13
|
+
# Gmail: blackhedd
|
14
|
+
#
|
15
|
+
# This program is free software; you can redistribute it and/or modify
|
16
|
+
# it under the terms of either: 1) the GNU General Public License
|
17
|
+
# as published by the Free Software Foundation; either version 2 of the
|
18
|
+
# License, or (at your option) any later version; or 2) Ruby's License.
|
19
|
+
#
|
20
|
+
# See the file COPYING for complete licensing information.
|
21
|
+
#
|
22
|
+
#---------------------------------------------------------------------------
|
23
|
+
#
|
24
|
+
#
|
25
|
+
#
|
26
|
+
|
27
|
+
|
28
|
+
###### THIS TEST IS NOW OBSOLETE.
|
29
|
+
###### As of 27Dec07, the hookable error handling is obsolete because
|
30
|
+
###### of its performance impact.
|
31
|
+
|
32
|
+
|
33
|
+
$:.unshift "../lib"
|
34
|
+
require 'eventmachine'
|
35
|
+
require 'test/unit'
|
36
|
+
|
37
|
+
class TestErrors < Test::Unit::TestCase
|
38
|
+
|
39
|
+
Localhost = "127.0.0.1"
|
40
|
+
Localport = 9801
|
41
|
+
|
42
|
+
def setup
|
43
|
+
end
|
44
|
+
|
45
|
+
def teardown
|
46
|
+
# Calling #set_runtime_error_hook with no block restores the
|
47
|
+
# default handling of runtime_errors.
|
48
|
+
#
|
49
|
+
EM.set_runtime_error_hook
|
50
|
+
end
|
51
|
+
|
52
|
+
def test_a
|
53
|
+
end
|
54
|
+
|
55
|
+
# EM has a default handler for RuntimeErrors that are emitted from
|
56
|
+
# user written code. You can override the handler if you wish, but it's
|
57
|
+
# easier to call #set_runtime_error_hook.
|
58
|
+
# Ordinarily, an error in user code invoked by the reactor aborts the
|
59
|
+
# run.
|
60
|
+
#
|
61
|
+
def obsolete_test_unhandled_error
|
62
|
+
assert_raise( RuntimeError ) {
|
63
|
+
EM.run {
|
64
|
+
EM.add_timer(0) {raise "AAA"}
|
65
|
+
}
|
66
|
+
}
|
67
|
+
|
68
|
+
end
|
69
|
+
|
70
|
+
def obsolete_test_handled_error
|
71
|
+
err = nil
|
72
|
+
EM.run {
|
73
|
+
EM.set_runtime_error_hook {
|
74
|
+
err = true
|
75
|
+
EM.stop
|
76
|
+
}
|
77
|
+
EM.add_timer(0) {raise "AAA"}
|
78
|
+
}
|
79
|
+
assert err
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
@@ -0,0 +1,78 @@
|
|
1
|
+
# $Id: test_eventables.rb 668 2008-01-04 23:00:34Z blackhedd $
|
2
|
+
#
|
3
|
+
# Author:: Francis Cianfrocca (gmail: blackhedd)
|
4
|
+
# Homepage:: http://rubyeventmachine.com
|
5
|
+
# Date:: 8 April 2006
|
6
|
+
#
|
7
|
+
# See EventMachine and EventMachine::Connection for documentation and
|
8
|
+
# usage examples.
|
9
|
+
#
|
10
|
+
#----------------------------------------------------------------------------
|
11
|
+
#
|
12
|
+
# Copyright (C) 2006-07 by Francis Cianfrocca. All Rights Reserved.
|
13
|
+
# Gmail: blackhedd
|
14
|
+
#
|
15
|
+
# This program is free software; you can redistribute it and/or modify
|
16
|
+
# it under the terms of either: 1) the GNU General Public License
|
17
|
+
# as published by the Free Software Foundation; either version 2 of the
|
18
|
+
# License, or (at your option) any later version; or 2) Ruby's License.
|
19
|
+
#
|
20
|
+
# See the file COPYING for complete licensing information.
|
21
|
+
#
|
22
|
+
#---------------------------------------------------------------------------
|
23
|
+
#
|
24
|
+
#
|
25
|
+
#
|
26
|
+
|
27
|
+
$:.unshift "../lib"
|
28
|
+
require 'eventmachine'
|
29
|
+
|
30
|
+
require 'test/unit/testsuite'
|
31
|
+
require 'test/unit/ui/console/testrunner'
|
32
|
+
|
33
|
+
|
34
|
+
class TestEventables < Test::Unit::TestCase
|
35
|
+
|
36
|
+
class EvTest
|
37
|
+
include EventMachine::Eventable
|
38
|
+
end
|
39
|
+
|
40
|
+
def setup
|
41
|
+
end
|
42
|
+
|
43
|
+
def teardown
|
44
|
+
end
|
45
|
+
|
46
|
+
def test_a; end # shut up rake until we define a test.
|
47
|
+
|
48
|
+
# TODO, this idea is still half-baked.
|
49
|
+
def xxx_test_a
|
50
|
+
n = 0
|
51
|
+
tester = EvTest.new
|
52
|
+
tester.listen_event( :fire1 ) {|arg|
|
53
|
+
n = 1 if arg == "$"
|
54
|
+
EventMachine.stop
|
55
|
+
}
|
56
|
+
tester.post_event( :fire1, "$" )
|
57
|
+
|
58
|
+
EventMachine.run {
|
59
|
+
EventMachine::add_timer(1) {EventMachine.stop}
|
60
|
+
}
|
61
|
+
|
62
|
+
assert_equal( 1, n )
|
63
|
+
end
|
64
|
+
|
65
|
+
end
|
66
|
+
|
67
|
+
|
68
|
+
#--------------------------------------
|
69
|
+
|
70
|
+
if __FILE__ == $0
|
71
|
+
runner = Test::Unit::UI::Console::TestRunner
|
72
|
+
suite = Test::Unit::TestSuite.new("name")
|
73
|
+
ObjectSpace.each_object(Class) do |testcase|
|
74
|
+
suite << testcase.suite if testcase < Test::Unit::TestCase
|
75
|
+
end
|
76
|
+
runner.run(suite)
|
77
|
+
end
|
78
|
+
|
data/tests/test_exc.rb
ADDED
@@ -0,0 +1,58 @@
|
|
1
|
+
# $Id: test_exc.rb 668 2008-01-04 23:00:34Z blackhedd $
|
2
|
+
#
|
3
|
+
# Author:: Francis Cianfrocca (gmail: blackhedd)
|
4
|
+
# Homepage:: http://rubyeventmachine.com
|
5
|
+
# Date:: 8 April 2006
|
6
|
+
#
|
7
|
+
# See EventMachine and EventMachine::Connection for documentation and
|
8
|
+
# usage examples.
|
9
|
+
#
|
10
|
+
#----------------------------------------------------------------------------
|
11
|
+
#
|
12
|
+
# Copyright (C) 2006-07 by Francis Cianfrocca. All Rights Reserved.
|
13
|
+
# Gmail: blackhedd
|
14
|
+
#
|
15
|
+
# This program is free software; you can redistribute it and/or modify
|
16
|
+
# it under the terms of either: 1) the GNU General Public License
|
17
|
+
# as published by the Free Software Foundation; either version 2 of the
|
18
|
+
# License, or (at your option) any later version; or 2) Ruby's License.
|
19
|
+
#
|
20
|
+
# See the file COPYING for complete licensing information.
|
21
|
+
#
|
22
|
+
#---------------------------------------------------------------------------
|
23
|
+
#
|
24
|
+
#
|
25
|
+
|
26
|
+
$:.unshift "../lib"
|
27
|
+
require 'eventmachine'
|
28
|
+
require 'test/unit'
|
29
|
+
|
30
|
+
class TestSomeExceptions < Test::Unit::TestCase
|
31
|
+
|
32
|
+
|
33
|
+
# Read the commentary in EventMachine#run.
|
34
|
+
# This test exercises the ensure block in #run that makes sure
|
35
|
+
# EventMachine#release_machine gets called even if an exception is
|
36
|
+
# thrown within the user code. Without the ensured call to release_machine,
|
37
|
+
# the second call to EventMachine#run will fail with a C++ exception
|
38
|
+
# because the machine wasn't cleaned up properly.
|
39
|
+
|
40
|
+
def test_a
|
41
|
+
assert_raise(RuntimeError) {
|
42
|
+
EventMachine.run {
|
43
|
+
raise "some exception"
|
44
|
+
}
|
45
|
+
}
|
46
|
+
end
|
47
|
+
|
48
|
+
def test_b
|
49
|
+
assert_raise(RuntimeError) {
|
50
|
+
EventMachine.run {
|
51
|
+
raise "some exception"
|
52
|
+
}
|
53
|
+
}
|
54
|
+
end
|
55
|
+
|
56
|
+
|
57
|
+
end
|
58
|
+
|
@@ -0,0 +1,214 @@
|
|
1
|
+
# $Id: test_futures.rb 668 2008-01-04 23:00:34Z blackhedd $
|
2
|
+
#
|
3
|
+
# Author:: Francis Cianfrocca (gmail: blackhedd)
|
4
|
+
# Homepage:: http://rubyeventmachine.com
|
5
|
+
# Date:: 8 April 2006
|
6
|
+
#
|
7
|
+
# See EventMachine and EventMachine::Connection for documentation and
|
8
|
+
# usage examples.
|
9
|
+
#
|
10
|
+
#----------------------------------------------------------------------------
|
11
|
+
#
|
12
|
+
# Copyright (C) 2006-07 by Francis Cianfrocca. All Rights Reserved.
|
13
|
+
# Gmail: blackhedd
|
14
|
+
#
|
15
|
+
# This program is free software; you can redistribute it and/or modify
|
16
|
+
# it under the terms of either: 1) the GNU General Public License
|
17
|
+
# as published by the Free Software Foundation; either version 2 of the
|
18
|
+
# License, or (at your option) any later version; or 2) Ruby's License.
|
19
|
+
#
|
20
|
+
# See the file COPYING for complete licensing information.
|
21
|
+
#
|
22
|
+
#---------------------------------------------------------------------------
|
23
|
+
#
|
24
|
+
#
|
25
|
+
#
|
26
|
+
|
27
|
+
$:.unshift "../lib"
|
28
|
+
require 'eventmachine'
|
29
|
+
require 'test/unit'
|
30
|
+
|
31
|
+
|
32
|
+
|
33
|
+
class TestFutures < Test::Unit::TestCase
|
34
|
+
|
35
|
+
def setup
|
36
|
+
end
|
37
|
+
|
38
|
+
def teardown
|
39
|
+
end
|
40
|
+
|
41
|
+
def test_future
|
42
|
+
assert_equal(100, EventMachine::Deferrable.future(100) )
|
43
|
+
|
44
|
+
p1 = proc { 100 + 1 }
|
45
|
+
assert_equal(101, EventMachine::Deferrable.future(p1) )
|
46
|
+
end
|
47
|
+
|
48
|
+
|
49
|
+
|
50
|
+
class MyFuture
|
51
|
+
include EventMachine::Deferrable
|
52
|
+
def initialize *args
|
53
|
+
super
|
54
|
+
set_deferred_status :succeeded, 40
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
class MyErrorFuture
|
59
|
+
include EventMachine::Deferrable
|
60
|
+
def initialize *args
|
61
|
+
super
|
62
|
+
set_deferred_status :failed, 41
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
|
67
|
+
def test_future_1
|
68
|
+
# Call future with one additional argument and it will be treated as a callback.
|
69
|
+
def my_future
|
70
|
+
MyFuture.new
|
71
|
+
end
|
72
|
+
|
73
|
+
value = nil
|
74
|
+
EventMachine::Deferrable.future my_future, proc {|v| value=v}
|
75
|
+
assert_equal( 40, value )
|
76
|
+
end
|
77
|
+
|
78
|
+
|
79
|
+
def test_future_2
|
80
|
+
# Call future with two additional arguments and they will be treated as a callback
|
81
|
+
# and an errback.
|
82
|
+
value = nil
|
83
|
+
EventMachine::Deferrable.future MyErrorFuture.new, nil, proc {|v| value=v}
|
84
|
+
assert_equal( 41, value )
|
85
|
+
end
|
86
|
+
|
87
|
+
|
88
|
+
def test_future_3
|
89
|
+
# Call future with no additional arguments but with a block, and the block will be
|
90
|
+
# treated as a callback.
|
91
|
+
value = nil
|
92
|
+
EventMachine::Deferrable.future MyFuture.new do |v|
|
93
|
+
value=v
|
94
|
+
end
|
95
|
+
assert_equal( 40, value )
|
96
|
+
end
|
97
|
+
|
98
|
+
|
99
|
+
class RecursiveCallback
|
100
|
+
include EventMachine::Deferrable
|
101
|
+
end
|
102
|
+
|
103
|
+
# A Deferrable callback can call #set_deferred_status to change the values
|
104
|
+
# passed to subsequent callbacks.
|
105
|
+
#
|
106
|
+
def test_recursive_callbacks
|
107
|
+
n = 0 # counter assures that all the tests actually run.
|
108
|
+
rc = RecursiveCallback.new
|
109
|
+
rc.callback {|a|
|
110
|
+
assert_equal(100, a)
|
111
|
+
n += 1
|
112
|
+
rc.set_deferred_status :succeeded, 101, 101
|
113
|
+
}
|
114
|
+
rc.callback {|a,b|
|
115
|
+
assert_equal(101, a)
|
116
|
+
assert_equal(101, b)
|
117
|
+
n += 1
|
118
|
+
rc.set_deferred_status :succeeded, 102, 102, 102
|
119
|
+
}
|
120
|
+
rc.callback {|a,b,c|
|
121
|
+
assert_equal(102, a)
|
122
|
+
assert_equal(102, b)
|
123
|
+
assert_equal(102, c)
|
124
|
+
n += 1
|
125
|
+
}
|
126
|
+
rc.set_deferred_status :succeeded, 100
|
127
|
+
assert_equal(3, n)
|
128
|
+
end
|
129
|
+
|
130
|
+
|
131
|
+
|
132
|
+
def test_syntactic_sugar
|
133
|
+
rc = RecursiveCallback.new
|
134
|
+
rc.set_deferred_success 100
|
135
|
+
rc.set_deferred_failure 200
|
136
|
+
end
|
137
|
+
|
138
|
+
|
139
|
+
|
140
|
+
# It doesn't raise an error to set deferred status more than once.
|
141
|
+
# In fact, this is a desired and useful idiom when it happens INSIDE
|
142
|
+
# a callback or errback.
|
143
|
+
# However, it's less useful otherwise, and in fact would generally be
|
144
|
+
# indicative of a programming error. However, we would like to be resistant
|
145
|
+
# to such errors. So whenever we set deferred status, we also clear BOTH
|
146
|
+
# stacks of handlers.
|
147
|
+
#
|
148
|
+
def test_double_calls
|
149
|
+
s = 0
|
150
|
+
e = 0
|
151
|
+
|
152
|
+
d = EM::DefaultDeferrable.new
|
153
|
+
d.callback {s += 1}
|
154
|
+
d.errback {e += 1}
|
155
|
+
|
156
|
+
d.succeed # We expect the callback to be called, and the errback to be DISCARDED.
|
157
|
+
d.fail # Presumably an error. We expect the errback NOT to be called.
|
158
|
+
d.succeed # We expect the callback to have been discarded and NOT to be called again.
|
159
|
+
|
160
|
+
assert_equal(1, s)
|
161
|
+
assert_equal(0, e)
|
162
|
+
end
|
163
|
+
|
164
|
+
|
165
|
+
# Adding a callback to a Deferrable that is already in a success state executes the callback
|
166
|
+
# immediately. The same applies to a an errback added to an already-failed Deferrable.
|
167
|
+
# HOWEVER, we expect NOT to be able to add errbacks to succeeded Deferrables, or callbacks
|
168
|
+
# to failed ones.
|
169
|
+
#
|
170
|
+
# We illustrate this with a rather contrived test. The test calls #fail after #succeed,
|
171
|
+
# which ordinarily would not happen in a real program.
|
172
|
+
#
|
173
|
+
# What we're NOT attempting to specify is what happens if a Deferrable is succeeded and then
|
174
|
+
# failed (or vice-versa). Should we then be able to add callbacks/errbacks of the appropriate
|
175
|
+
# type for immediate execution? For now at least, the official answer is "don't do that."
|
176
|
+
#
|
177
|
+
def test_delayed_callbacks
|
178
|
+
s1 = 0
|
179
|
+
s2 = 0
|
180
|
+
e = 0
|
181
|
+
|
182
|
+
d = EM::DefaultDeferrable.new
|
183
|
+
d.callback {s1 += 1}
|
184
|
+
|
185
|
+
d.succeed # Triggers and discards the callback.
|
186
|
+
|
187
|
+
d.callback {s2 += 1} # This callback is executed immediately and discarded.
|
188
|
+
|
189
|
+
d.errback {e += 1} # This errback should be DISCARDED and never execute.
|
190
|
+
d.fail # To prove it, let's
|
191
|
+
|
192
|
+
assert_equal( [1,1], [s1,s2] )
|
193
|
+
assert_equal( 0, e )
|
194
|
+
end
|
195
|
+
|
196
|
+
|
197
|
+
|
198
|
+
|
199
|
+
#
|
200
|
+
#
|
201
|
+
#
|
202
|
+
def test_timeout
|
203
|
+
n = 0
|
204
|
+
EM.run {
|
205
|
+
d = EM::DefaultDeferrable.new
|
206
|
+
d.callback {n = 1; EM.stop}
|
207
|
+
d.errback {n = 2; EM.stop}
|
208
|
+
d.timeout(1)
|
209
|
+
}
|
210
|
+
assert_equal( 2, n )
|
211
|
+
end
|
212
|
+
|
213
|
+
end
|
214
|
+
|
data/tests/test_hc.rb
ADDED
@@ -0,0 +1,221 @@
|
|
1
|
+
# $Id: test_hc.rb 668 2008-01-04 23:00:34Z blackhedd $
|
2
|
+
#
|
3
|
+
# Author:: Francis Cianfrocca (gmail: blackhedd)
|
4
|
+
# Homepage:: http://rubyeventmachine.com
|
5
|
+
# Date:: 8 April 2006
|
6
|
+
#
|
7
|
+
# See EventMachine and EventMachine::Connection for documentation and
|
8
|
+
# usage examples.
|
9
|
+
#
|
10
|
+
#----------------------------------------------------------------------------
|
11
|
+
#
|
12
|
+
# Copyright (C) 2006-07 by Francis Cianfrocca. All Rights Reserved.
|
13
|
+
# Gmail: blackhedd
|
14
|
+
#
|
15
|
+
# This program is free software; you can redistribute it and/or modify
|
16
|
+
# it under the terms of either: 1) the GNU General Public License
|
17
|
+
# as published by the Free Software Foundation; either version 2 of the
|
18
|
+
# License, or (at your option) any later version; or 2) Ruby's License.
|
19
|
+
#
|
20
|
+
# See the file COPYING for complete licensing information.
|
21
|
+
#
|
22
|
+
#---------------------------------------------------------------------------
|
23
|
+
#
|
24
|
+
#
|
25
|
+
#
|
26
|
+
|
27
|
+
$:.unshift "../lib"
|
28
|
+
require 'eventmachine'
|
29
|
+
require 'socket'
|
30
|
+
require 'test/unit'
|
31
|
+
|
32
|
+
# This doesn't completely work under Ruby 1.9.
|
33
|
+
# Part of it is thread race conditions. I added some sleeps to make these
|
34
|
+
# tests work. Native threads do strange things when you do I/O on them.
|
35
|
+
#
|
36
|
+
|
37
|
+
|
38
|
+
class TestHeaderAndContentProtocol < Test::Unit::TestCase
|
39
|
+
|
40
|
+
TestHost = "127.0.0.1"
|
41
|
+
TestPort = 8905
|
42
|
+
|
43
|
+
|
44
|
+
#--------------------------------------------------------------------
|
45
|
+
|
46
|
+
class SimpleTest < EventMachine::Protocols::HeaderAndContentProtocol
|
47
|
+
attr_reader :first_header, :my_headers, :request
|
48
|
+
|
49
|
+
def receive_first_header_line hdr
|
50
|
+
@first_header ||= []
|
51
|
+
@first_header << hdr
|
52
|
+
end
|
53
|
+
def receive_headers hdrs
|
54
|
+
@my_headers ||= []
|
55
|
+
@my_headers << hdrs
|
56
|
+
end
|
57
|
+
def receive_request hdrs, content
|
58
|
+
@request ||= []
|
59
|
+
@request << [hdrs, content]
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def test_no_content
|
64
|
+
Thread.abort_on_exception = true
|
65
|
+
the_connection = nil
|
66
|
+
EventMachine.run {
|
67
|
+
EventMachine.start_server( TestHost, TestPort, SimpleTest ) do |conn|
|
68
|
+
the_connection = conn
|
69
|
+
end
|
70
|
+
EventMachine.add_timer(4) {raise "test timed out"}
|
71
|
+
EventMachine.defer proc {
|
72
|
+
t = TCPSocket.new TestHost, TestPort
|
73
|
+
t.write [
|
74
|
+
"aaa\n", "bbb\r\n", "ccc\n", "\n"
|
75
|
+
].join
|
76
|
+
t.close
|
77
|
+
if RUBY_VERSION =~ /\A1\.9\./
|
78
|
+
sleep 0.1
|
79
|
+
STDERR.puts "Introducing extraneous sleep for Ruby 1.9"
|
80
|
+
end
|
81
|
+
}, proc {
|
82
|
+
EventMachine.stop
|
83
|
+
}
|
84
|
+
}
|
85
|
+
assert_equal( ["aaa"], the_connection.first_header )
|
86
|
+
assert_equal( [%w(aaa bbb ccc)], the_connection.my_headers )
|
87
|
+
assert_equal( [[%w(aaa bbb ccc), ""]], the_connection.request )
|
88
|
+
end
|
89
|
+
|
90
|
+
def test_content
|
91
|
+
Thread.abort_on_exception = true
|
92
|
+
the_connection = nil
|
93
|
+
content = "A" * 50
|
94
|
+
headers = ["aaa", "bbb", "Content-length: #{content.length}", "ccc"]
|
95
|
+
EventMachine.run {
|
96
|
+
EventMachine.start_server( TestHost, TestPort, SimpleTest ) do |conn|
|
97
|
+
the_connection = conn
|
98
|
+
end
|
99
|
+
EventMachine.add_timer(4) {raise "test timed out"}
|
100
|
+
EventMachine.defer proc {
|
101
|
+
t = TCPSocket.new TestHost, TestPort
|
102
|
+
headers.each {|h| t.write "#{h}\r\n" }
|
103
|
+
t.write "\n"
|
104
|
+
t.write content
|
105
|
+
t.close
|
106
|
+
if RUBY_VERSION =~ /\A1\.9\./
|
107
|
+
sleep 0.1
|
108
|
+
STDERR.puts "Introducing extraneous sleep for Ruby 1.9"
|
109
|
+
end
|
110
|
+
}, proc {
|
111
|
+
EM.stop
|
112
|
+
}
|
113
|
+
}
|
114
|
+
assert_equal( ["aaa"], the_connection.first_header )
|
115
|
+
assert_equal( [headers], the_connection.my_headers )
|
116
|
+
assert_equal( [[headers, content]], the_connection.request )
|
117
|
+
end
|
118
|
+
|
119
|
+
def test_several_requests
|
120
|
+
Thread.abort_on_exception = true
|
121
|
+
the_connection = nil
|
122
|
+
content = "A" * 50
|
123
|
+
headers = ["aaa", "bbb", "Content-length: #{content.length}", "ccc"]
|
124
|
+
EventMachine.run {
|
125
|
+
EventMachine.start_server( TestHost, TestPort, SimpleTest ) do |conn|
|
126
|
+
the_connection = conn
|
127
|
+
end
|
128
|
+
EventMachine.add_timer(4) {raise "test timed out"}
|
129
|
+
EventMachine.defer proc {
|
130
|
+
t = TCPSocket.new TestHost, TestPort
|
131
|
+
5.times {
|
132
|
+
headers.each {|h| t.write "#{h}\r\n" }
|
133
|
+
t.write "\n"
|
134
|
+
t.write content
|
135
|
+
}
|
136
|
+
t.close
|
137
|
+
if RUBY_VERSION =~ /\A1\.9\./
|
138
|
+
sleep 0.1
|
139
|
+
STDERR.puts "Introducing extraneous sleep for Ruby 1.9"
|
140
|
+
end
|
141
|
+
}, proc {
|
142
|
+
EventMachine.stop
|
143
|
+
}
|
144
|
+
}
|
145
|
+
assert_equal( ["aaa"] * 5, the_connection.first_header )
|
146
|
+
assert_equal( [headers] * 5, the_connection.my_headers )
|
147
|
+
assert_equal( [[headers, content]] * 5, the_connection.request )
|
148
|
+
end
|
149
|
+
|
150
|
+
|
151
|
+
def x_test_multiple_content_length_headers
|
152
|
+
# This is supposed to throw a RuntimeError but it throws a C++ exception instead.
|
153
|
+
Thread.abort_on_exception = true
|
154
|
+
the_connection = nil
|
155
|
+
content = "A" * 50
|
156
|
+
headers = ["aaa", "bbb", ["Content-length: #{content.length}"]*2, "ccc"].flatten
|
157
|
+
EventMachine.run {
|
158
|
+
EventMachine.start_server( TestHost, TestPort, SimpleTest ) do |conn|
|
159
|
+
the_connection = conn
|
160
|
+
end
|
161
|
+
EventMachine.add_timer(4) {raise "test timed out"}
|
162
|
+
EventMachine.defer proc {
|
163
|
+
t = TCPSocket.new TestHost, TestPort
|
164
|
+
headers.each {|h| t.write "#{h}\r\n" }
|
165
|
+
t.write "\n"
|
166
|
+
t.write content
|
167
|
+
t.close
|
168
|
+
}, proc {
|
169
|
+
EventMachine.stop
|
170
|
+
}
|
171
|
+
}
|
172
|
+
end
|
173
|
+
|
174
|
+
def test_interpret_headers
|
175
|
+
Thread.abort_on_exception = true
|
176
|
+
the_connection = nil
|
177
|
+
content = "A" * 50
|
178
|
+
headers = [
|
179
|
+
"GET / HTTP/1.0",
|
180
|
+
"Accept: aaa",
|
181
|
+
"User-Agent: bbb",
|
182
|
+
"Host: ccc",
|
183
|
+
"x-tempest-header:ddd"
|
184
|
+
]
|
185
|
+
EventMachine.run {
|
186
|
+
EventMachine.start_server( TestHost, TestPort, SimpleTest ) do |conn|
|
187
|
+
the_connection = conn
|
188
|
+
end
|
189
|
+
EventMachine.add_timer(4) {raise "test timed out"}
|
190
|
+
EventMachine.defer proc {
|
191
|
+
t = TCPSocket.new TestHost, TestPort
|
192
|
+
headers.each {|h| t.write "#{h}\r\n" }
|
193
|
+
t.write "\n"
|
194
|
+
t.write content
|
195
|
+
t.close
|
196
|
+
if RUBY_VERSION =~ /\A1\.9\./
|
197
|
+
sleep 0.1
|
198
|
+
STDERR.puts "Introducing extraneous sleep for Ruby 1.9"
|
199
|
+
end
|
200
|
+
}, proc {
|
201
|
+
EventMachine.stop
|
202
|
+
}
|
203
|
+
}
|
204
|
+
|
205
|
+
hsh = the_connection.headers_2_hash( the_connection.my_headers.shift )
|
206
|
+
assert_equal(
|
207
|
+
{
|
208
|
+
:accept => "aaa",
|
209
|
+
:user_agent => "bbb",
|
210
|
+
:host => "ccc",
|
211
|
+
:x_tempest_header => "ddd"
|
212
|
+
},
|
213
|
+
hsh
|
214
|
+
)
|
215
|
+
end
|
216
|
+
|
217
|
+
#--------------------------------------------------------------------
|
218
|
+
|
219
|
+
end
|
220
|
+
|
221
|
+
|