wj_eventmachine 1.3.0.dev.1

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 (180) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +179 -0
  3. data/GNU +281 -0
  4. data/LICENSE +60 -0
  5. data/README.md +110 -0
  6. data/docs/DocumentationGuidesIndex.md +27 -0
  7. data/docs/GettingStarted.md +520 -0
  8. data/docs/old/ChangeLog +211 -0
  9. data/docs/old/DEFERRABLES +246 -0
  10. data/docs/old/EPOLL +141 -0
  11. data/docs/old/INSTALL +13 -0
  12. data/docs/old/KEYBOARD +42 -0
  13. data/docs/old/LEGAL +25 -0
  14. data/docs/old/LIGHTWEIGHT_CONCURRENCY +130 -0
  15. data/docs/old/PURE_RUBY +75 -0
  16. data/docs/old/RELEASE_NOTES +94 -0
  17. data/docs/old/SMTP +4 -0
  18. data/docs/old/SPAWNED_PROCESSES +148 -0
  19. data/docs/old/TODO +8 -0
  20. data/examples/guides/getting_started/01_eventmachine_echo_server.rb +18 -0
  21. data/examples/guides/getting_started/02_eventmachine_echo_server_that_recognizes_exit_command.rb +22 -0
  22. data/examples/guides/getting_started/03_simple_chat_server.rb +149 -0
  23. data/examples/guides/getting_started/04_simple_chat_server_step_one.rb +27 -0
  24. data/examples/guides/getting_started/05_simple_chat_server_step_two.rb +43 -0
  25. data/examples/guides/getting_started/06_simple_chat_server_step_three.rb +98 -0
  26. data/examples/guides/getting_started/07_simple_chat_server_step_four.rb +121 -0
  27. data/examples/guides/getting_started/08_simple_chat_server_step_five.rb +141 -0
  28. data/examples/old/ex_channel.rb +43 -0
  29. data/examples/old/ex_queue.rb +2 -0
  30. data/examples/old/ex_tick_loop_array.rb +15 -0
  31. data/examples/old/ex_tick_loop_counter.rb +32 -0
  32. data/examples/old/helper.rb +2 -0
  33. data/ext/binder.cpp +124 -0
  34. data/ext/binder.h +52 -0
  35. data/ext/cmain.cpp +1046 -0
  36. data/ext/ed.cpp +2238 -0
  37. data/ext/ed.h +460 -0
  38. data/ext/em.cpp +2378 -0
  39. data/ext/em.h +266 -0
  40. data/ext/eventmachine.h +152 -0
  41. data/ext/extconf.rb +285 -0
  42. data/ext/fastfilereader/extconf.rb +120 -0
  43. data/ext/fastfilereader/mapper.cpp +214 -0
  44. data/ext/fastfilereader/mapper.h +59 -0
  45. data/ext/fastfilereader/rubymain.cpp +126 -0
  46. data/ext/kb.cpp +79 -0
  47. data/ext/page.cpp +107 -0
  48. data/ext/page.h +51 -0
  49. data/ext/pipe.cpp +354 -0
  50. data/ext/project.h +174 -0
  51. data/ext/rubymain.cpp +1610 -0
  52. data/ext/ssl.cpp +627 -0
  53. data/ext/ssl.h +103 -0
  54. data/ext/wait_for_single_fd.h +36 -0
  55. data/java/.classpath +8 -0
  56. data/java/.project +17 -0
  57. data/java/src/com/rubyeventmachine/EmReactor.java +625 -0
  58. data/java/src/com/rubyeventmachine/EmReactorException.java +40 -0
  59. data/java/src/com/rubyeventmachine/EmReactorInterface.java +70 -0
  60. data/java/src/com/rubyeventmachine/EventableChannel.java +72 -0
  61. data/java/src/com/rubyeventmachine/EventableDatagramChannel.java +201 -0
  62. data/java/src/com/rubyeventmachine/EventableSocketChannel.java +415 -0
  63. data/java/src/com/rubyeventmachine/NullEmReactor.java +157 -0
  64. data/java/src/com/rubyeventmachine/NullEventableChannel.java +81 -0
  65. data/lib/em/buftok.rb +59 -0
  66. data/lib/em/callback.rb +58 -0
  67. data/lib/em/channel.rb +69 -0
  68. data/lib/em/completion.rb +307 -0
  69. data/lib/em/connection.rb +776 -0
  70. data/lib/em/deferrable.rb +210 -0
  71. data/lib/em/deferrable/pool.rb +2 -0
  72. data/lib/em/file_watch.rb +73 -0
  73. data/lib/em/future.rb +61 -0
  74. data/lib/em/io_streamer.rb +68 -0
  75. data/lib/em/iterator.rb +252 -0
  76. data/lib/em/messages.rb +66 -0
  77. data/lib/em/pool.rb +151 -0
  78. data/lib/em/process_watch.rb +45 -0
  79. data/lib/em/processes.rb +123 -0
  80. data/lib/em/protocols.rb +37 -0
  81. data/lib/em/protocols/header_and_content.rb +138 -0
  82. data/lib/em/protocols/httpclient.rb +303 -0
  83. data/lib/em/protocols/httpclient2.rb +602 -0
  84. data/lib/em/protocols/line_and_text.rb +125 -0
  85. data/lib/em/protocols/line_protocol.rb +33 -0
  86. data/lib/em/protocols/linetext2.rb +179 -0
  87. data/lib/em/protocols/memcache.rb +331 -0
  88. data/lib/em/protocols/object_protocol.rb +46 -0
  89. data/lib/em/protocols/postgres3.rb +246 -0
  90. data/lib/em/protocols/saslauth.rb +175 -0
  91. data/lib/em/protocols/smtpclient.rb +394 -0
  92. data/lib/em/protocols/smtpserver.rb +666 -0
  93. data/lib/em/protocols/socks4.rb +66 -0
  94. data/lib/em/protocols/stomp.rb +205 -0
  95. data/lib/em/protocols/tcptest.rb +54 -0
  96. data/lib/em/pure_ruby.rb +1299 -0
  97. data/lib/em/queue.rb +80 -0
  98. data/lib/em/resolver.rb +232 -0
  99. data/lib/em/spawnable.rb +84 -0
  100. data/lib/em/streamer.rb +118 -0
  101. data/lib/em/threaded_resource.rb +90 -0
  102. data/lib/em/tick_loop.rb +85 -0
  103. data/lib/em/timers.rb +61 -0
  104. data/lib/em/version.rb +3 -0
  105. data/lib/eventmachine.rb +1602 -0
  106. data/lib/jeventmachine.rb +318 -0
  107. data/rakelib/package.rake +120 -0
  108. data/rakelib/test.rake +6 -0
  109. data/rakelib/test_pure.rake +11 -0
  110. data/tests/client.crt +31 -0
  111. data/tests/client.key +51 -0
  112. data/tests/dhparam.pem +13 -0
  113. data/tests/em_ssl_handlers.rb +153 -0
  114. data/tests/em_test_helper.rb +198 -0
  115. data/tests/jruby/test_jeventmachine.rb +38 -0
  116. data/tests/test_attach.rb +199 -0
  117. data/tests/test_basic.rb +321 -0
  118. data/tests/test_channel.rb +75 -0
  119. data/tests/test_completion.rb +178 -0
  120. data/tests/test_connection_count.rb +83 -0
  121. data/tests/test_connection_write.rb +35 -0
  122. data/tests/test_defer.rb +35 -0
  123. data/tests/test_deferrable.rb +35 -0
  124. data/tests/test_epoll.rb +141 -0
  125. data/tests/test_error_handler.rb +38 -0
  126. data/tests/test_exc.rb +37 -0
  127. data/tests/test_file_watch.rb +86 -0
  128. data/tests/test_fork.rb +75 -0
  129. data/tests/test_futures.rb +170 -0
  130. data/tests/test_handler_check.rb +35 -0
  131. data/tests/test_hc.rb +155 -0
  132. data/tests/test_httpclient.rb +238 -0
  133. data/tests/test_httpclient2.rb +132 -0
  134. data/tests/test_idle_connection.rb +31 -0
  135. data/tests/test_inactivity_timeout.rb +102 -0
  136. data/tests/test_io_streamer.rb +47 -0
  137. data/tests/test_ipv4.rb +96 -0
  138. data/tests/test_ipv6.rb +107 -0
  139. data/tests/test_iterator.rb +122 -0
  140. data/tests/test_kb.rb +28 -0
  141. data/tests/test_keepalive.rb +113 -0
  142. data/tests/test_line_protocol.rb +33 -0
  143. data/tests/test_ltp.rb +155 -0
  144. data/tests/test_ltp2.rb +332 -0
  145. data/tests/test_many_fds.rb +21 -0
  146. data/tests/test_next_tick.rb +104 -0
  147. data/tests/test_object_protocol.rb +36 -0
  148. data/tests/test_pause.rb +109 -0
  149. data/tests/test_pending_connect_timeout.rb +52 -0
  150. data/tests/test_pool.rb +196 -0
  151. data/tests/test_process_watch.rb +50 -0
  152. data/tests/test_processes.rb +128 -0
  153. data/tests/test_proxy_connection.rb +180 -0
  154. data/tests/test_pure.rb +156 -0
  155. data/tests/test_queue.rb +64 -0
  156. data/tests/test_resolver.rb +129 -0
  157. data/tests/test_running.rb +14 -0
  158. data/tests/test_sasl.rb +46 -0
  159. data/tests/test_send_file.rb +217 -0
  160. data/tests/test_servers.rb +32 -0
  161. data/tests/test_shutdown_hooks.rb +23 -0
  162. data/tests/test_smtpclient.rb +75 -0
  163. data/tests/test_smtpserver.rb +90 -0
  164. data/tests/test_sock_opt.rb +53 -0
  165. data/tests/test_spawn.rb +290 -0
  166. data/tests/test_ssl_args.rb +41 -0
  167. data/tests/test_ssl_dhparam.rb +57 -0
  168. data/tests/test_ssl_ecdh_curve.rb +57 -0
  169. data/tests/test_ssl_extensions.rb +24 -0
  170. data/tests/test_ssl_methods.rb +31 -0
  171. data/tests/test_ssl_protocols.rb +190 -0
  172. data/tests/test_ssl_verify.rb +52 -0
  173. data/tests/test_stomp.rb +38 -0
  174. data/tests/test_system.rb +46 -0
  175. data/tests/test_threaded_resource.rb +68 -0
  176. data/tests/test_tick_loop.rb +58 -0
  177. data/tests/test_timers.rb +150 -0
  178. data/tests/test_ud.rb +8 -0
  179. data/tests/test_unbind_reason.rb +40 -0
  180. metadata +384 -0
@@ -0,0 +1,41 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'em_test_helper'
4
+ require 'tempfile'
5
+
6
+ class TestSSLArgs < Test::Unit::TestCase
7
+
8
+ require_relative 'em_ssl_handlers'
9
+ include EMSSLHandlers
10
+
11
+ def test_tls_params_file_doesnt_exist
12
+ priv_file, cert_file = 'foo_priv_key', 'bar_cert_file'
13
+ [priv_file, cert_file].all? do |f|
14
+ assert(!File.exist?(f), "Cert file #{f} seems to exist, and should not for the tests")
15
+ end
16
+
17
+ assert_raises EM::FileNotFoundException do
18
+ client_server client: { private_key_file: priv_file }
19
+ end
20
+
21
+ assert_raises EM::FileNotFoundException do
22
+ client_server client: { cert_chain_file: cert_file }
23
+ end
24
+
25
+ assert_raises EM::FileNotFoundException do
26
+ client_server client: { private_key_file: priv_file, cert_chain_file: cert_file }
27
+ end
28
+ end
29
+
30
+ def _test_tls_params_file_improper
31
+ priv_file_path = Tempfile.new('em_test').path
32
+ cert_file_path = Tempfile.new('em_test').path
33
+ params = { private_key_file: priv_file_path,
34
+ cert_chain_file: cert_file_path }
35
+ begin
36
+ client_server client: params
37
+ rescue Object
38
+ assert false, 'should not have raised an exception'
39
+ end
40
+ end
41
+ end if EM.ssl?
@@ -0,0 +1,57 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'em_test_helper'
4
+
5
+ class TestSSLDhParam < Test::Unit::TestCase
6
+
7
+ require_relative 'em_ssl_handlers'
8
+ include EMSSLHandlers
9
+
10
+ DH_PARAM_FILE = File.join(__dir__, 'dhparam.pem')
11
+
12
+ DH_1_2 = { cipher_list: "DHE,EDH", ssl_version: %w(TLSv1_2) }
13
+ CLIENT_1_2 = { client_unbind: true, ssl_version: %w(TLSv1_2) }
14
+
15
+ def test_no_dhparam
16
+ omit_if(EM.library_type == :pure_ruby) # DH will work with defaults
17
+ omit_if(rbx?)
18
+
19
+ client_server client: CLIENT_1_2, server: DH_1_2
20
+
21
+ refute Client.handshake_completed?
22
+ refute Server.handshake_completed?
23
+ end
24
+
25
+ def test_dhparam_1_2
26
+ omit_if(rbx?)
27
+
28
+ client_server client: CLIENT_1_2, server: DH_1_2.merge(dhparam: DH_PARAM_FILE)
29
+
30
+ assert Client.handshake_completed?
31
+ assert Server.handshake_completed?
32
+
33
+ assert Client.cipher_name.length > 0
34
+ assert_equal Client.cipher_name, Server.cipher_name
35
+
36
+ assert_match(/^(DHE|EDH)/, Client.cipher_name)
37
+ end
38
+
39
+ def test_dhparam_1_3
40
+ omit_if(rbx?)
41
+ omit("TLSv1_3 is unavailable") unless EM.const_defined? :EM_PROTO_TLSv1_3
42
+
43
+ client = { client_unbind: true, ssl_version: %w(TLSv1_3) }
44
+ server = { dhparam: DH_PARAM_FILE, cipher_list: "DHE,EDH", ssl_version: %w(TLSv1_3) }
45
+ client_server client: client, server: server
46
+
47
+ assert Client.handshake_completed?
48
+ assert Server.handshake_completed?
49
+
50
+ assert Client.cipher_name.length > 0
51
+ assert_equal Client.cipher_name, Server.cipher_name
52
+
53
+ # see https://wiki.openssl.org/index.php/TLS1.3#Ciphersuites
54
+ # may depend on OpenSSL build options
55
+ assert_equal "TLS_AES_256_GCM_SHA384", Client.cipher_name
56
+ end
57
+ end if EM.ssl?
@@ -0,0 +1,57 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'em_test_helper'
4
+
5
+ class TestSSLEcdhCurve < Test::Unit::TestCase
6
+
7
+ require_relative 'em_ssl_handlers'
8
+ include EMSSLHandlers
9
+
10
+ def test_no_ecdh_curve
11
+ omit_if(rbx?)
12
+ omit("OpenSSL 1.1.x (and later) auto selects curve") if IS_SSL_GE_1_1
13
+
14
+ client_server server: { cipher_list: "ECDH", ssl_version: %w(TLSv1_2) }
15
+
16
+ refute Client.handshake_completed?
17
+ refute Server.handshake_completed?
18
+ end
19
+
20
+ def test_ecdh_curve_tlsv1_2
21
+ omit_if(EM.library_type == :pure_ruby && RUBY_VERSION < "2.3.0")
22
+ omit_if(rbx?)
23
+
24
+ server = { cipher_list: "ECDH", ssl_version: %w(TLSv1_2) }
25
+ server.merge!(ecdh_curve: "prime256v1") unless IS_SSL_GE_1_1
26
+
27
+ client_server server: server
28
+
29
+ assert Client.handshake_completed?
30
+ assert Server.handshake_completed?
31
+
32
+ assert Client.cipher_name.length > 0
33
+ assert_equal Client.cipher_name, Server.cipher_name
34
+
35
+ assert_match(/^(AECDH|ECDHE)/, Client.cipher_name)
36
+ end
37
+
38
+ def test_ecdh_curve_tlsv1_3
39
+ omit_if(EM.library_type == :pure_ruby && RUBY_VERSION < "2.3.0")
40
+ omit_if(rbx?)
41
+ omit("TLSv1_3 is unavailable") unless EM.const_defined? :EM_PROTO_TLSv1_3
42
+
43
+ tls = { cipher_list: "ECDH", ssl_version: %w(TLSv1_3) }
44
+
45
+ client_server server: tls
46
+
47
+ assert Client.handshake_completed?
48
+ assert Server.handshake_completed?
49
+
50
+ assert Client.cipher_name.length > 0
51
+ assert_equal Client.cipher_name, Server.cipher_name
52
+
53
+ # see https://wiki.openssl.org/index.php/TLS1.3#Ciphersuites
54
+ # may depend on OpenSSL build options
55
+ assert_equal "TLS_AES_256_GCM_SHA384", Client.cipher_name
56
+ end
57
+ end if EM.ssl?
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'em_test_helper'
4
+
5
+ class TestSSLExtensions < Test::Unit::TestCase
6
+
7
+ require_relative 'em_ssl_handlers'
8
+ include EMSSLHandlers
9
+
10
+ def test_tlsext_sni_hostname_1_2
11
+ client = { sni_hostname: 'example.com', ssl_version: %w(TLSv1_2) }
12
+ client_server client: client
13
+ assert Server.handshake_completed?
14
+ assert_equal 'example.com', Server.sni_hostname
15
+ end
16
+
17
+ def test_tlsext_sni_hostname_1_3
18
+ omit("TLSv1_3 is unavailable") unless EM.const_defined? :EM_PROTO_TLSv1_3
19
+ client = { sni_hostname: 'example.com', ssl_version: %w(TLSv1_3) }
20
+ client_server client: client
21
+ assert Server.handshake_completed?
22
+ assert_equal 'example.com', Server.sni_hostname
23
+ end
24
+ end if EM.ssl?
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'em_test_helper'
4
+
5
+ class TestSSLMethods < Test::Unit::TestCase
6
+
7
+ require_relative 'em_ssl_handlers'
8
+ include EMSSLHandlers
9
+
10
+ def test_ssl_methods
11
+ omit_if(rbx?)
12
+
13
+ client_server
14
+
15
+ assert Server.handshake_completed?
16
+ assert Client.handshake_completed?
17
+
18
+ assert Server.cert_value.is_a? NilClass
19
+ assert Client.cert_value.is_a? String
20
+
21
+ assert Client.cipher_bits > 0
22
+ assert_equal Client.cipher_bits, Server.cipher_bits
23
+
24
+ assert Client.cipher_name.length > 0
25
+ assert_match(/AES/, Client.cipher_name)
26
+ assert_equal Client.cipher_name, Server.cipher_name
27
+
28
+ assert Client.cipher_protocol.start_with? "TLS"
29
+ assert_equal Client.cipher_protocol, Server.cipher_protocol
30
+ end
31
+ end if EM.ssl?
@@ -0,0 +1,190 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'em_test_helper'
4
+
5
+ # For OpenSSL 1.1.0 and later, cipher_protocol returns single cipher, older
6
+ # versions return "TLSv1/SSLv3"
7
+ # TLSv1.1 handshake_completed Server/Client callback order is reversed from
8
+ # older protocols
9
+
10
+ class TestSSLProtocols < Test::Unit::TestCase
11
+
12
+ require_relative 'em_ssl_handlers'
13
+ include EMSSLHandlers
14
+
15
+ # We're checking for whether Context min_version= & max_version= are defined, but
16
+ # JRuby has a bug where they're defined, but the private method they call isn't
17
+ RUBY_SSL_GE_2_1 = OpenSSL::SSL::SSLContext.private_instance_methods(false).include?(:set_minmax_proto_version)
18
+
19
+ def test_invalid_ssl_version
20
+ assert_raises(RuntimeError, "Unrecognized SSL/TLS Version: badinput") do
21
+ client = { ssl_version: %w(tlsv1 badinput) }
22
+ server = { ssl_version: %w(tlsv1 badinput) }
23
+ client_server client: client, server: server
24
+ end
25
+ end
26
+
27
+ def test_any_to_v3
28
+ omit("SSLv3 is (correctly) unavailable") if EM::OPENSSL_NO_SSL3
29
+ client_server client: TLS_ALL, server: SSL_3
30
+ assert Client.handshake_completed?
31
+ assert Server.handshake_completed?
32
+ end
33
+
34
+ def test_any_to_tlsv1_2
35
+ client_server client: TLS_ALL, server: TLS_1_2
36
+ assert Client.handshake_completed?
37
+ assert Server.handshake_completed?
38
+ if IS_SSL_GE_1_1
39
+ assert_equal "TLSv1.2", Client.cipher_protocol
40
+ end
41
+ end
42
+
43
+ def test_case_insensitivity
44
+ lower_case = SSL_AVAIL.map { |p| p.downcase }
45
+ client = { ssl_version: %w(tlsv1_2) }
46
+ server = { ssl_version: lower_case }
47
+ client_server client: client, server: server
48
+ assert Client.handshake_completed?
49
+ assert Server.handshake_completed?
50
+ end
51
+
52
+ def test_v3_to_any
53
+ omit("SSLv3 is (correctly) unavailable") if EM::OPENSSL_NO_SSL3
54
+ client_server client: SSL_3, server: TLS_ALL
55
+ assert Client.handshake_completed?
56
+ assert Server.handshake_completed?
57
+ end
58
+
59
+ def test_tlsv1_2_to_any
60
+ client_server client: TLS_1_2, server: TLS_ALL
61
+ assert Client.handshake_completed?
62
+ assert Server.handshake_completed?
63
+ if IS_SSL_GE_1_1
64
+ assert_equal "TLSv1.2", Server.cipher_protocol
65
+ end
66
+ end
67
+
68
+ def test_v3_to_v3
69
+ omit("SSLv3 is (correctly) unavailable") if EM::OPENSSL_NO_SSL3
70
+ client_server client: SSL_3, server: SSL_3
71
+ assert Client.handshake_completed?
72
+ assert Server.handshake_completed?
73
+ end
74
+
75
+ def test_tlsv1_2_to_tlsv1_2
76
+ client_server client: TLS_1_2, server: TLS_1_2
77
+ assert Client.handshake_completed?
78
+ assert Server.handshake_completed?
79
+ if IS_SSL_GE_1_1
80
+ assert_equal "TLSv1.2", Client.cipher_protocol
81
+ assert_equal "TLSv1.2", Server.cipher_protocol
82
+ end
83
+ end
84
+
85
+ def test_tlsv1_3_to_tlsv1_3
86
+ omit("TLSv1_3 is unavailable") unless EM.const_defined? :EM_PROTO_TLSv1_3
87
+ client_server client: TLS_1_3, server: TLS_1_3
88
+ assert Client.handshake_completed?
89
+ assert Server.handshake_completed?
90
+ assert_equal "TLSv1.3", Client.cipher_protocol
91
+ assert_equal "TLSv1.3", Server.cipher_protocol
92
+ end
93
+
94
+ def test_any_to_any
95
+ client_server client: TLS_ALL, server: TLS_ALL
96
+ assert Client.handshake_completed?
97
+ assert Server.handshake_completed?
98
+ if IS_SSL_GE_1_1
99
+ best_protocol = SSL_AVAIL.last.tr "_", "."
100
+ assert_equal best_protocol, Client.cipher_protocol
101
+ assert_equal best_protocol, Server.cipher_protocol
102
+ end
103
+ end
104
+
105
+ def test_default_to_default
106
+ client_server
107
+ assert Client.handshake_completed?
108
+ assert Server.handshake_completed?
109
+ if IS_SSL_GE_1_1
110
+ best_protocol = SSL_AVAIL.last.tr "_", "."
111
+ assert_equal best_protocol, Client.cipher_protocol
112
+ assert_equal best_protocol, Server.cipher_protocol
113
+ end
114
+ end
115
+
116
+ def external_client(ext_min, ext_max, ext_ssl, server)
117
+ EM.run do
118
+ # setup_timeout 2
119
+ EM.start_server IP, PORT, Server, server.merge( { stop_after_handshake: true} )
120
+ EM.defer do
121
+ sock = TCPSocket.new IP, PORT
122
+ ctx = OpenSSL::SSL::SSLContext.new
123
+ if RUBY_SSL_GE_2_1
124
+ ctx.min_version = ext_min if ext_min
125
+ ctx.max_version = ext_max if ext_max
126
+ else
127
+ ctx.ssl_version = ext_ssl
128
+ end
129
+ ssl = OpenSSL::SSL::SSLSocket.new(sock, ctx)
130
+ ssl.connect
131
+ ssl.close rescue nil
132
+ sock.close rescue nil
133
+ end
134
+ end
135
+ assert Server.handshake_completed?
136
+ end
137
+
138
+ def test_v3_with_external_client
139
+ omit("SSLv3 is (correctly) unavailable") if EM::OPENSSL_NO_SSL3
140
+ external_client nil, nil, :SSLv3_client, SSL_3
141
+ end
142
+
143
+ # Fixed Server
144
+ def test_tlsv1_2_with_external_client
145
+ external_client nil, nil, :SSLv23_client, TLS_1_2
146
+ end
147
+
148
+ def test_tlsv1_3_with_external_client
149
+ omit("TLSv1_3 is unavailable") unless EM.const_defined?(:EM_PROTO_TLSv1_3) &&
150
+ OpenSSL::SSL.const_defined?(:TLS1_3_VERSION)
151
+ external_client nil, nil, :SSLv23_client, TLS_1_3
152
+ end
153
+
154
+ # Fixed Client
155
+ def test_any_with_external_client_tlsv1_2
156
+ external_client :TLS1_2, :TLS1_2, :TLSv1_2_client, TLS_ALL
157
+ end
158
+
159
+ def test_any_with_external_client_tlsv1_3
160
+ omit("TLSv1_3 is unavailable") unless EM.const_defined? :EM_PROTO_TLSv1_3
161
+ external_client :TLS1_3, :TLS1_3, :TLSv1_2_client, TLS_ALL
162
+ end
163
+
164
+ # Refuse a client?
165
+ def test_tlsv1_2_required_with_external_client
166
+ EM.run do
167
+ n = 0
168
+ EM.add_periodic_timer(0.5) do
169
+ n += 1
170
+ (EM.stop rescue nil) if n == 2
171
+ end
172
+ EM.start_server IP, PORT, Server, TLS_1_2.merge( { stop_after_handshake: true} )
173
+ EM.defer do
174
+ sock = TCPSocket.new IP, PORT
175
+ ctx = OpenSSL::SSL::SSLContext.new
176
+ if RUBY_SSL_GE_2_1
177
+ ctx.max_version = :TLS1_1
178
+ else
179
+ ctx.ssl_version = :TLSv1_client
180
+ end
181
+ ssl = OpenSSL::SSL::SSLSocket.new sock, ctx
182
+ assert_raise(OpenSSL::SSL::SSLError) { ssl.connect }
183
+ ssl.close rescue nil
184
+ sock.close rescue nil
185
+ EM.stop rescue nil
186
+ end
187
+ end
188
+ refute Server.handshake_completed?
189
+ end
190
+ end if EM.ssl?
@@ -0,0 +1,52 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'em_test_helper'
4
+
5
+ class TestSSLVerify < Test::Unit::TestCase
6
+
7
+ require_relative 'em_ssl_handlers'
8
+ include EMSSLHandlers
9
+
10
+ CERT_FROM_FILE = File.read "#{__dir__}/client.crt"
11
+
12
+ CLIENT_CERT = { private_key_file: "#{__dir__}/client.key",
13
+ cert_chain_file: "#{__dir__}/client.crt" }
14
+
15
+ def test_fail_no_peer_cert
16
+ omit_if(rbx?)
17
+
18
+ server = { verify_peer: true, fail_if_no_peer_cert: true,
19
+ ssl_verify_result: "|RAISE|Verify peer should not get called for a client without a certificate" }
20
+
21
+ client_server Client, Server, server: server
22
+
23
+ refute Client.handshake_completed? unless "TLSv1.3" == Client.cipher_protocol
24
+ refute Server.handshake_completed?
25
+ end
26
+
27
+ def test_accept_server
28
+ omit_if(EM.library_type == :pure_ruby) # Server has a default cert chain
29
+ omit_if(rbx?)
30
+
31
+ server = { verify_peer: true, ssl_verify_result: true }
32
+
33
+ client_server Client, Server, client: CLIENT_CERT, server: server
34
+
35
+ assert_equal CERT_FROM_FILE, Server.cert
36
+ assert Client.handshake_completed?
37
+ assert Server.handshake_completed?
38
+ end
39
+
40
+ def test_deny_server
41
+ omit_if(EM.library_type == :pure_ruby) # Server has a default cert chain
42
+ omit_if(rbx?)
43
+
44
+ server = { verify_peer: true, ssl_verify_result: false }
45
+
46
+ client_server Client, Server, client: CLIENT_CERT, server: server
47
+
48
+ assert_equal CERT_FROM_FILE, Server.cert
49
+ refute Client.handshake_completed? unless "TLSv1.3" == Client.cipher_protocol
50
+ refute Server.handshake_completed?
51
+ end
52
+ end if EM.ssl?