sonixlabs-eventmachine-java 1.0.0.rc.7-java → 1.0.3.1-java

Sign up to get free protection for your applications and to get access to all the features.
Files changed (58) hide show
  1. checksums.yaml +4 -12
  2. data/.travis.yml +12 -0
  3. data/CHANGELOG.md +33 -0
  4. data/Gemfile +0 -1
  5. data/README.md +2 -2
  6. data/README_JP.md +10 -2
  7. data/eventmachine.gemspec +10 -7
  8. data/ext/binder.cpp +1 -1
  9. data/ext/cmain.cpp +11 -0
  10. data/ext/ed.cpp +22 -7
  11. data/ext/ed.h +5 -5
  12. data/ext/em.cpp +64 -66
  13. data/ext/em.h +10 -5
  14. data/ext/eventmachine.h +1 -0
  15. data/ext/extconf.rb +4 -3
  16. data/ext/fastfilereader/extconf.rb +1 -1
  17. data/ext/rubymain.cpp +22 -1
  18. data/ext/ssl.cpp +1 -1
  19. data/java/.classpath +1 -3
  20. data/java/.gitignore +1 -0
  21. data/java/src/com/rubyeventmachine/DatagramPacket.java +13 -0
  22. data/java/src/com/rubyeventmachine/EmReactor.java +502 -561
  23. data/java/src/com/rubyeventmachine/EventCallback.java +7 -0
  24. data/java/src/com/rubyeventmachine/EventCode.java +26 -0
  25. data/java/src/com/rubyeventmachine/EventableChannel.java +102 -42
  26. data/java/src/com/rubyeventmachine/EventableDatagramChannel.java +146 -161
  27. data/java/src/com/rubyeventmachine/EventableSocketChannel.java +371 -334
  28. data/java/src/com/rubyeventmachine/SslBox.java +310 -0
  29. data/lib/em/iterator.rb +5 -44
  30. data/lib/em/processes.rb +1 -1
  31. data/lib/em/protocols/httpclient.rb +2 -2
  32. data/lib/em/protocols/line_protocol.rb +2 -2
  33. data/lib/em/protocols/smtpclient.rb +1 -1
  34. data/lib/em/protocols/smtpserver.rb +10 -7
  35. data/lib/em/protocols/stomp.rb +5 -2
  36. data/lib/em/protocols.rb +1 -0
  37. data/lib/em/version.rb +1 -1
  38. data/lib/eventmachine.rb +35 -14
  39. data/lib/jeventmachine.rb +65 -18
  40. data/rakelib/package.rake +15 -18
  41. data/tests/server.crt +36 -0
  42. data/tests/server.key +51 -0
  43. data/tests/test_attach.rb +24 -0
  44. data/tests/test_connection_count.rb +21 -1
  45. data/tests/test_epoll.rb +15 -0
  46. data/tests/test_httpclient2.rb +5 -0
  47. data/tests/test_idle_connection.rb +6 -4
  48. data/tests/test_iterator.rb +97 -0
  49. data/tests/test_line_protocol.rb +33 -0
  50. data/tests/test_pause.rb +24 -0
  51. data/tests/test_set_sock_opt.rb +1 -1
  52. data/tests/test_ssl_echo_data.rb +60 -0
  53. data/tests/test_ssl_methods.rb +15 -7
  54. data/tests/test_ssl_verify.rb +4 -4
  55. data/tests/test_stomp.rb +37 -0
  56. data/tests/test_system.rb +42 -0
  57. metadata +45 -42
  58. data/lib/rubyeventmachine.jar +0 -0
data/lib/jeventmachine.rb CHANGED
@@ -30,6 +30,7 @@
30
30
  require 'java'
31
31
  require 'rubyeventmachine'
32
32
  require 'socket'
33
+ require 'openssl'
33
34
 
34
35
  java_import java.io.FileDescriptor
35
36
  java_import java.nio.channels.SocketChannel
@@ -77,6 +78,8 @@ module EventMachine
77
78
  ConnectionNotifyWritable = 107
78
79
  # @private
79
80
  SslHandshakeCompleted = 108
81
+ # @private
82
+ SslVerify = 109
80
83
 
81
84
  # Exceptions that are defined in rubymain.cpp
82
85
  class ConnectionError < RuntimeError; end
@@ -84,23 +87,23 @@ module EventMachine
84
87
  class UnknownTimerFired < RuntimeError; end
85
88
  class Unsupported < RuntimeError; end
86
89
 
87
- # This thunk class used to be called EM, but that caused conflicts with
88
- # the alias "EM" for module EventMachine. (FC, 20Jun08)
89
- class JEM < com.rubyeventmachine.EmReactor
90
- def eventCallback a1, a2, a3, a4
91
- s = String.from_java_bytes(a3.array[a3.position...a3.limit]) if a3
92
- EventMachine::event_callback a1, a2, s || a4
90
+ def self.initialize_event_machine
91
+ @em = com.rubyeventmachine.EmReactor.new do |sig, event, buf, data|
92
+ s = String.from_java_bytes(buf.array[buf.position...buf.limit]) if buf
93
+ begin
94
+ EventMachine::event_callback sig, event.int_value, s || data
95
+ rescue java.lang.Exception => t
96
+ if instance_variable_defined? :@error_handler
97
+ @error_handler.call t
98
+ end
99
+ rescue StandardError => e
100
+ if instance_variable_defined? :@error_handler
101
+ @error_handler.call e
102
+ end
103
+ end
93
104
  nil
94
105
  end
95
106
  end
96
- # class Connection < com.rubyeventmachine.Connection
97
- # def associate_callback_target sig
98
- # # No-op for the time being.
99
- # end
100
- # end
101
- def self.initialize_event_machine
102
- @em = JEM.new
103
- end
104
107
  def self.release_machine
105
108
  @em = nil
106
109
  end
@@ -149,7 +152,15 @@ module EventMachine
149
152
  @em.startTls sig
150
153
  end
151
154
  def self.ssl?
152
- false
155
+ true
156
+ end
157
+ def self.ssl_verify_peer conn, der_data
158
+ data = OpenSSL::X509::Certificate.new(der_data).to_pem
159
+ @em.acceptSslPeer conn.signature if conn.ssl_verify_peer data
160
+ end
161
+ def self.get_peer_cert sig
162
+ der_data = @em.getPeerCert sig
163
+ OpenSSL::X509::Certificate.new(String.from_java_bytes(der_data)).to_pem
153
164
  end
154
165
  def self.signal_loopbreak
155
166
  @em.signalLoopbreak
@@ -268,9 +279,9 @@ module EventMachine
268
279
  @em.getConnectionCount
269
280
  end
270
281
 
271
- def self.set_tls_parms(sig, params)
272
- end
273
- def self.start_tls(sig)
282
+ def self.set_tls_parms(sig, privkeyfile, certchainfile, verify_peer)
283
+ keystore = KeyStoreBuilder.create privkeyfile, certchainfile unless (privkeyfile.empty? or certchainfile.empty?)
284
+ @em.setTlsParms(sig, keystore, (!!verify_peer))
274
285
  end
275
286
  def self.send_file_data(sig, filename)
276
287
  end
@@ -282,3 +293,39 @@ module EventMachine
282
293
  end
283
294
  end
284
295
 
296
+ module KeyStoreBuilder
297
+ require 'bouncy-castle-java'
298
+ java_import java.io.FileReader
299
+ java_import java.io.FileInputStream
300
+ java_import java.security.cert.Certificate
301
+ java_import java.security.cert.CertificateFactory
302
+ java_import java.security.KeyStore
303
+ java_import java.security.Security
304
+ java_import org.bouncycastle.openssl.PEMReader
305
+ java_import org.bouncycastle.jce.provider.BouncyCastleProvider
306
+ @name = 'em_java_tls_key' # TODO - find a correct value, or whether it even really matters.
307
+ @initialized = false
308
+
309
+ def self.init
310
+ unless @initialized
311
+ Security.add_provider BouncyCastleProvider.new
312
+ @initialized = true
313
+ end
314
+ end
315
+
316
+ def self.create(privkeyfile, certchainfile)
317
+ self.init
318
+
319
+ key_reader = FileReader.new privkeyfile
320
+ key_pair = PEMReader.new(key_reader).read_object
321
+
322
+ cert_stream = FileInputStream.new certchainfile
323
+ certs = CertificateFactory.get_instance('X.509', 'BC').generate_certificates cert_stream
324
+
325
+ store = KeyStore.get_instance 'PKCS12', 'BC'
326
+ store.load nil, nil
327
+ store.set_key_entry @name, key_pair.get_private, nil, certs.to_array(Certificate[certs.size].new)
328
+
329
+ store
330
+ end
331
+ end
data/rakelib/package.rake CHANGED
@@ -1,3 +1,4 @@
1
+ require 'rubygems'
1
2
  require 'rubygems/package_task'
2
3
 
3
4
  begin
@@ -25,24 +26,32 @@ else
25
26
  unless RUBY_PLATFORM =~ /mswin|mingw/
26
27
  ext.cross_compile = true
27
28
  ext.cross_platform = ['x86-mingw32', 'x86-mswin32-60']
28
-
29
- # inject 1.8/1.9 pure-ruby entry point
30
- ext.cross_compiling do |spec|
31
- spec.files += ["lib/#{ext.name}.rb"]
29
+ end
30
+ end
31
+ def hack_cross_compilation(ext)
32
+ # inject 1.8/1.9 pure-ruby entry point
33
+ # HACK: add these dependencies to the task instead of using cross_compiling
34
+ ext.cross_platform.each do |platform|
35
+ task = "native:#{GEMSPEC.name}:#{platform}"
36
+ if Rake::Task.task_defined?(task)
37
+ Rake::Task[task].prerequisites.unshift "lib/#{ext.name}.rb"
32
38
  end
33
39
  end
34
40
  end
35
41
 
36
- Rake::ExtensionTask.new("rubyeventmachine", GEMSPEC) do |ext|
42
+ em = Rake::ExtensionTask.new("rubyeventmachine", GEMSPEC) do |ext|
37
43
  ext.ext_dir = 'ext'
38
44
  ext.source_pattern = '*.{h,c,cpp}'
39
45
  setup_cross_compilation(ext)
40
46
  end
41
- Rake::ExtensionTask.new("fastfilereaderext", GEMSPEC) do |ext|
47
+ hack_cross_compilation em
48
+
49
+ ff = Rake::ExtensionTask.new("fastfilereaderext", GEMSPEC) do |ext|
42
50
  ext.ext_dir = 'ext/fastfilereader'
43
51
  ext.source_pattern = '*.{h,c,cpp}'
44
52
  setup_cross_compilation(ext)
45
53
  end
54
+ hack_cross_compilation ff
46
55
  end
47
56
 
48
57
  # Setup shim files that require 1.8 vs 1.9 extensions in win32 bin gems
@@ -85,15 +94,3 @@ def gem_cmd(action, name, *args)
85
94
  end
86
95
 
87
96
  Rake::Task[:clean].enhance [:clobber_package]
88
-
89
- namespace :gem do
90
- desc 'Install gem (and sudo if required)'
91
- task :install => :package do
92
- gem_cmd(:install, "pkg/#{GEMSPEC.name}-#{GEMSPEC.version}.gem")
93
- end
94
-
95
- desc 'Uninstall gem (and sudo if required)'
96
- task :uninstall do
97
- gem_cmd(:uninstall, "#{GEMSPEC.name}", "-v=#{GEMSPEC.version}")
98
- end
99
- end
data/tests/server.crt ADDED
@@ -0,0 +1,36 @@
1
+ -----BEGIN CERTIFICATE-----
2
+ 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
36
+ -----END CERTIFICATE-----
data/tests/server.key ADDED
@@ -0,0 +1,51 @@
1
+ -----BEGIN RSA PRIVATE KEY-----
2
+ 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
51
+ -----END RSA PRIVATE KEY-----
data/tests/test_attach.rb CHANGED
@@ -4,6 +4,7 @@ require 'socket'
4
4
  class TestAttach < Test::Unit::TestCase
5
5
  class EchoServer < EM::Connection
6
6
  def receive_data data
7
+ $received_data << data
7
8
  send_data data
8
9
  end
9
10
  end
@@ -31,12 +32,14 @@ class TestAttach < Test::Unit::TestCase
31
32
  def setup
32
33
  @port = next_port
33
34
  $read, $r, $w, $fd = nil
35
+ $received_data = ""
34
36
  end
35
37
 
36
38
  def teardown
37
39
  [$r, $w].each do |io|
38
40
  io.close rescue nil
39
41
  end
42
+ $received_data = nil
40
43
  end
41
44
 
42
45
  def test_attach
@@ -63,6 +66,27 @@ class TestAttach < Test::Unit::TestCase
63
66
  end
64
67
  end
65
68
 
69
+ def test_attach_server
70
+ $before = TCPServer.new("127.0.0.1", @port)
71
+ sig = nil
72
+ EM.run {
73
+ sig = EM.attach_server $before, EchoServer
74
+
75
+ handler = Class.new(EM::Connection) do
76
+ def initialize
77
+ send_data "hello world"
78
+ close_connection_after_writing
79
+ EM.add_timer(0.1) { EM.stop }
80
+ end
81
+ end
82
+ EM.connect("127.0.0.1", @port, handler)
83
+ }
84
+
85
+ assert_equal false, $before.closed?
86
+ assert_equal "hello world", $received_data
87
+ assert sig.is_a?(Integer)
88
+ end
89
+
66
90
  def test_attach_pipe
67
91
  EM.run{
68
92
  $r, $w = IO.pipe
@@ -30,4 +30,24 @@ class TestConnectionCount < Test::Unit::TestCase
30
30
  assert_equal(1, $server_conns)
31
31
  assert_equal(4, $client_conns + $server_conns)
32
32
  end
33
- end
33
+
34
+ module DoubleCloseClient
35
+ def unbind
36
+ close_connection
37
+ $num_close_scheduled_1 = EM.num_close_scheduled
38
+ EM.next_tick do
39
+ $num_close_scheduled_2 = EM.num_close_scheduled
40
+ EM.stop
41
+ end
42
+ end
43
+ end
44
+
45
+ def test_num_close_scheduled
46
+ EM.run {
47
+ assert_equal(0, EM.num_close_scheduled)
48
+ EM.connect("127.0.0.1", 9999, DoubleCloseClient) # nothing listening on 9999
49
+ }
50
+ assert_equal(1, $num_close_scheduled_1)
51
+ assert_equal(0, $num_close_scheduled_2)
52
+ end
53
+ end
data/tests/test_epoll.rb CHANGED
@@ -126,5 +126,20 @@ class TestEpoll < Test::Unit::TestCase
126
126
  File.unlink(fn) if File.exist?(fn)
127
127
  end
128
128
 
129
+ def test_attach_detach
130
+ EM.epoll
131
+ EM.run {
132
+ EM.add_timer(0.01) { EM.stop }
133
+
134
+ r, w = IO.pipe
135
+
136
+ # This tests a regression where detach in the same tick as attach crashes EM
137
+ EM.watch(r) do |connection|
138
+ connection.detach
139
+ end
140
+ }
141
+
142
+ assert true
143
+ end
129
144
  end
130
145
 
@@ -113,11 +113,16 @@ class TestHttpClient2 < Test::Unit::TestCase
113
113
  }
114
114
  end
115
115
 
116
+ # This test fails under JRuby - but not if you use google.com instead of apple.com
117
+ # Since this client is deprecated, it's probably not worth investigating further
116
118
  def test_https_get
117
119
  d = nil
118
120
  EM.run {
119
121
  http = silent { EM::P::HttpClient2.connect :host => 'www.apple.com', :port => 443, :ssl => true }
120
122
  d = http.get "/"
123
+ d.errback {
124
+ fail "Request failed"
125
+ }
121
126
  d.callback {
122
127
  EM.stop
123
128
  }
@@ -9,15 +9,17 @@ class TestIdleConnection < Test::Unit::TestCase
9
9
  $idle_time = conn.get_idle_time
10
10
  conn.send_data "GET / HTTP/1.0\r\n\r\n"
11
11
  EM.next_tick{
12
- $idle_time_after_send = conn.get_idle_time
13
- conn.close_connection
14
- EM.stop
12
+ EM.next_tick{
13
+ $idle_time_after_send = conn.get_idle_time
14
+ conn.close_connection
15
+ EM.stop
16
+ }
15
17
  }
16
18
  }
17
19
  }
18
20
 
19
21
  assert_in_delta 3, $idle_time, 0.2
20
- assert_equal 0, $idle_time_after_send
22
+ assert_in_delta 0, $idle_time_after_send, 0.1
21
23
  end
22
24
  end
23
25
  end
@@ -0,0 +1,97 @@
1
+ require 'em_test_helper'
2
+
3
+ class TestIterator < Test::Unit::TestCase
4
+
5
+ def get_time
6
+ EM.current_time.strftime('%H:%M:%S')
7
+ end
8
+
9
+ def test_default_concurrency
10
+ items = {}
11
+ list = 1..10
12
+ EM.run {
13
+ EM::Iterator.new(list).each( proc {|num,iter|
14
+ time = get_time
15
+ items[time] ||= []
16
+ items[time] << num
17
+ EM::Timer.new(1) {iter.next}
18
+ }, proc {EM.stop})
19
+ }
20
+ assert_equal(10, items.keys.size)
21
+ assert_equal((list).to_a, items.values.flatten)
22
+ end
23
+
24
+ def test_concurrency_bigger_than_list_size
25
+ items = {}
26
+ list = [1,2,3]
27
+ EM.run {
28
+ EM::Iterator.new(list,10).each(proc {|num,iter|
29
+ time = get_time
30
+ items[time] ||= []
31
+ items[time] << num
32
+ EM::Timer.new(1) {iter.next}
33
+ }, proc {EM.stop})
34
+ }
35
+ assert_equal(1, items.keys.size)
36
+ assert_equal((list).to_a, items.values.flatten)
37
+ end
38
+
39
+
40
+ def test_changing_concurrency_affects_active_iteration
41
+ items = {}
42
+ list = 1..25
43
+ EM.run {
44
+ i = EM::Iterator.new(list,5)
45
+ i.each(proc {|num,iter|
46
+ time = get_time
47
+ items[time] ||= []
48
+ items[time] << num
49
+ EM::Timer.new(1) {iter.next}
50
+ }, proc {EM.stop})
51
+ EM.add_timer(1){
52
+ i.concurrency = 1
53
+ }
54
+ EM.add_timer(3){
55
+ i.concurrency = 3
56
+ }
57
+ }
58
+ assert_equal(9, items.keys.size)
59
+ assert_equal((list).to_a, items.values.flatten)
60
+ end
61
+
62
+ def test_map
63
+ list = 100..150
64
+ EM.run {
65
+ EM::Iterator.new(list).map(proc{ |num,iter|
66
+ EM.add_timer(0.01){ iter.return(num) }
67
+ }, proc{ |results|
68
+ assert_equal((list).to_a.size, results.size)
69
+ EM.stop
70
+ })
71
+ }
72
+ end
73
+
74
+ def test_inject
75
+ list = %w[ pwd uptime uname date ]
76
+ EM.run {
77
+ EM::Iterator.new(list, 2).inject({}, proc{ |hash,cmd,iter|
78
+ EM.system(cmd){ |output,status|
79
+ hash[cmd] = status.exitstatus == 0 ? output.strip : nil
80
+ iter.return(hash)
81
+ }
82
+ }, proc{ |results|
83
+ assert_equal(results.keys, list)
84
+ EM.stop
85
+ })
86
+ }
87
+ end
88
+
89
+ def test_concurrency_is_0
90
+ EM.run {
91
+ assert_raise ArgumentError do
92
+ EM::Iterator.new(1..5,0)
93
+ end
94
+ EM.stop
95
+ }
96
+ end
97
+ end
@@ -0,0 +1,33 @@
1
+ require 'em_test_helper'
2
+
3
+ class TestLineProtocol < Test::Unit::TestCase
4
+ class LineProtocolTestClass
5
+ include EM::Protocols::LineProtocol
6
+
7
+ def lines
8
+ @lines ||= []
9
+ end
10
+
11
+ def receive_line(line)
12
+ lines << line
13
+ end
14
+ end
15
+
16
+ def setup
17
+ @proto = LineProtocolTestClass.new
18
+ end
19
+
20
+ def test_simple_split_line
21
+ @proto.receive_data("this is")
22
+ assert_equal([], @proto.lines)
23
+
24
+ @proto.receive_data(" a test\n")
25
+ assert_equal(["this is a test"], @proto.lines)
26
+ end
27
+
28
+ def test_simple_lines
29
+ @proto.receive_data("aaa\nbbb\r\nccc\nddd")
30
+ assert_equal(%w(aaa bbb ccc), @proto.lines)
31
+ end
32
+
33
+ end
data/tests/test_pause.rb CHANGED
@@ -67,6 +67,30 @@ class TestPause < Test::Unit::TestCase
67
67
  end
68
68
  end
69
69
  end
70
+
71
+ def test_pause_in_receive_data
72
+ incoming = []
73
+
74
+ test_server = Module.new do
75
+ define_method(:receive_data) do |data|
76
+ incoming << data
77
+ pause
78
+ EM.add_timer(0.5){ close_connection }
79
+ end
80
+ define_method(:unbind) do
81
+ EM.stop
82
+ end
83
+ end
84
+
85
+ EM.run do
86
+ EM.start_server "127.0.0.1", @port, test_server
87
+ cli = EM.connect "127.0.0.1", @port
88
+ cli.send_data 'a'*(17*1024)
89
+ end
90
+
91
+ assert_equal 1, incoming.size
92
+ assert_equal 16*1024, incoming[0].bytesize
93
+ end
70
94
  else
71
95
  warn "EM.pause_connection not implemented, skipping tests in #{__FILE__}"
72
96
 
@@ -19,7 +19,7 @@ class TestSetSockOpt < Test::Unit::TestCase
19
19
  EM.run do
20
20
  EM.connect 'google.com', 80, Module.new {
21
21
  define_method :post_init do
22
- val = set_sock_opt Socket::SOL_SOCKET, Socket::SO_DEBUG, true
22
+ val = set_sock_opt Socket::SOL_SOCKET, Socket::SO_BROADCAST, true
23
23
  test.assert_equal 0, val
24
24
  EM.stop
25
25
  end
@@ -0,0 +1,60 @@
1
+ require 'em_test_helper'
2
+
3
+ class TestSSLEchoData < Test::Unit::TestCase
4
+ def setup
5
+ $dir = File.dirname(File.expand_path(__FILE__)) + '/'
6
+ end
7
+
8
+ module SslEchoServer
9
+ def post_init
10
+ start_tls(:private_key_file => $dir+'server.key', :cert_chain_file => $dir+'server.crt')
11
+ end
12
+
13
+ def receive_data data
14
+ send_data data
15
+ end
16
+
17
+ end
18
+
19
+ module SslEchoClient
20
+ def connection_completed
21
+ start_tls
22
+ end
23
+
24
+ def ssl_handshake_completed
25
+ send_data $expected_return_data[$index]
26
+ $index += 1
27
+ end
28
+
29
+ def receive_data data
30
+ $actual_return_data ||= []
31
+ $actual_return_data << data
32
+ if $index < 10
33
+ send_data $expected_return_data[$index]
34
+ $index += 1
35
+ else
36
+ @stopping_on_purpose = true
37
+ EM.stop
38
+ end
39
+ end
40
+
41
+ def unbind
42
+ fail "unexpected socket close" unless @stopping_on_purpose
43
+ end
44
+
45
+ end
46
+
47
+ def test_ssl_echo_data
48
+ $expected_return_data = (1..10).map {|n| "Hello, world! (#{n})"}
49
+ $index = 0
50
+
51
+ EM.run {
52
+ EM.add_timer(12) { fail "TIMEOUT" }
53
+ EM.start_server("127.0.0.1", 9999, SslEchoServer)
54
+ EM.connect("127.0.0.1", 9999, SslEchoClient)
55
+ }
56
+
57
+ assert_equal($expected_return_data, $actual_return_data)
58
+ end
59
+
60
+ end if EM.ssl?