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

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.
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?