eventmachine 1.0.7-java → 1.0.8-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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +12 -0
- data/README.md +1 -1
- data/ext/binder.cpp +9 -9
- data/ext/binder.h +5 -5
- data/ext/cmain.cpp +68 -55
- data/ext/ed.cpp +106 -70
- data/ext/ed.h +19 -13
- data/ext/em.cpp +228 -194
- data/ext/em.h +33 -28
- data/ext/eventmachine.h +53 -52
- data/ext/extconf.rb +26 -3
- data/ext/fastfilereader/rubymain.cpp +1 -1
- data/ext/kb.cpp +1 -1
- data/ext/pipe.cpp +4 -2
- data/ext/project.h +6 -0
- data/ext/rubymain.cpp +218 -188
- data/ext/ssl.cpp +7 -7
- data/ext/ssl.h +1 -1
- data/lib/em/protocols/line_and_text.rb +1 -0
- data/lib/em/protocols/linetext2.rb +44 -38
- data/lib/em/protocols/smtpclient.rb +60 -31
- data/lib/em/version.rb +1 -1
- data/lib/eventmachine.rb +9 -1
- data/tests/test_ltp2.rb +20 -0
- data/tests/test_smtpclient.rb +20 -0
- metadata +4 -4
data/ext/ssl.cpp
CHANGED
@@ -82,7 +82,7 @@ static char PrivateMaterials[] = {
|
|
82
82
|
builtin_passwd_cb
|
83
83
|
*****************/
|
84
84
|
|
85
|
-
extern "C" int builtin_passwd_cb (char *buf, int bufsize, int rwflag, void *userdata)
|
85
|
+
extern "C" int builtin_passwd_cb (char *buf UNUSED, int bufsize UNUSED, int rwflag UNUSED, void *userdata UNUSED)
|
86
86
|
{
|
87
87
|
strcpy (buf, "kittycat");
|
88
88
|
return 8;
|
@@ -216,7 +216,7 @@ SslContext_t::~SslContext_t()
|
|
216
216
|
SslBox_t::SslBox_t
|
217
217
|
******************/
|
218
218
|
|
219
|
-
SslBox_t::SslBox_t (bool is_server, const string &privkeyfile, const string &certchainfile, bool verify_peer, const
|
219
|
+
SslBox_t::SslBox_t (bool is_server, const string &privkeyfile, const string &certchainfile, bool verify_peer, const uintptr_t binding):
|
220
220
|
bIsServer (is_server),
|
221
221
|
bHandshakeCompleted (false),
|
222
222
|
bVerifyPeer (verify_peer),
|
@@ -392,7 +392,7 @@ int SslBox_t::PutPlaintext (const char *buf, int bufsize)
|
|
392
392
|
|
393
393
|
bool fatal = false;
|
394
394
|
bool did_work = false;
|
395
|
-
int pending =
|
395
|
+
int pending = BIO_pending(pbioWrite);
|
396
396
|
|
397
397
|
while (OutboundQ.HasPages() && pending < SSLBOX_WRITE_BUFFER_SIZE) {
|
398
398
|
const char *page;
|
@@ -400,7 +400,7 @@ int SslBox_t::PutPlaintext (const char *buf, int bufsize)
|
|
400
400
|
OutboundQ.Front (&page, &length);
|
401
401
|
assert (page && (length > 0));
|
402
402
|
int n = SSL_write (pSSL, page, length);
|
403
|
-
pending =
|
403
|
+
pending = BIO_pending(pbioWrite);
|
404
404
|
|
405
405
|
if (n > 0) {
|
406
406
|
did_work = true;
|
@@ -442,9 +442,9 @@ X509 *SslBox_t::GetPeerCert()
|
|
442
442
|
ssl_verify_wrapper
|
443
443
|
*******************/
|
444
444
|
|
445
|
-
extern "C" int ssl_verify_wrapper(int preverify_ok, X509_STORE_CTX *ctx)
|
445
|
+
extern "C" int ssl_verify_wrapper(int preverify_ok UNUSED, X509_STORE_CTX *ctx)
|
446
446
|
{
|
447
|
-
|
447
|
+
uintptr_t binding;
|
448
448
|
X509 *cert;
|
449
449
|
SSL *ssl;
|
450
450
|
BUF_MEM *buf;
|
@@ -453,7 +453,7 @@ extern "C" int ssl_verify_wrapper(int preverify_ok, X509_STORE_CTX *ctx)
|
|
453
453
|
|
454
454
|
cert = X509_STORE_CTX_get_current_cert(ctx);
|
455
455
|
ssl = (SSL*) X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx());
|
456
|
-
binding = (
|
456
|
+
binding = (uintptr_t) SSL_get_ex_data(ssl, 0);
|
457
457
|
|
458
458
|
out = BIO_new(BIO_s_mem());
|
459
459
|
PEM_write_bio_X509(out, cert);
|
data/ext/ssl.h
CHANGED
@@ -61,7 +61,7 @@ class SslBox_t
|
|
61
61
|
class SslBox_t
|
62
62
|
{
|
63
63
|
public:
|
64
|
-
SslBox_t (bool is_server, const string &privkeyfile, const string &certchainfile, bool verify_peer, const
|
64
|
+
SslBox_t (bool is_server, const string &privkeyfile, const string &certchainfile, bool verify_peer, const uintptr_t binding);
|
65
65
|
virtual ~SslBox_t();
|
66
66
|
|
67
67
|
int PutPlaintext (const char*, int);
|
@@ -40,7 +40,7 @@ module EventMachine
|
|
40
40
|
MaxBinaryLength = 32*1024*1024
|
41
41
|
|
42
42
|
#--
|
43
|
-
# Will
|
43
|
+
# Will loop internally until there's no data left to read.
|
44
44
|
# That way the user-defined handlers we call can modify the
|
45
45
|
# handling characteristics on a per-token basis.
|
46
46
|
#
|
@@ -52,45 +52,51 @@ module EventMachine
|
|
52
52
|
@lt2_delimiter ||= "\n"
|
53
53
|
@lt2_linebuffer ||= []
|
54
54
|
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
@
|
60
|
-
|
61
|
-
ln.
|
55
|
+
remaining_data = data
|
56
|
+
|
57
|
+
while remaining_data.length > 0
|
58
|
+
if @lt2_mode == :lines
|
59
|
+
if ix = remaining_data.index( @lt2_delimiter )
|
60
|
+
@lt2_linebuffer << remaining_data[0...ix]
|
61
|
+
ln = @lt2_linebuffer.join
|
62
|
+
@lt2_linebuffer.clear
|
63
|
+
if @lt2_delimiter == "\n"
|
64
|
+
ln.chomp!
|
65
|
+
end
|
66
|
+
receive_line ln
|
67
|
+
remaining_data = remaining_data[(ix+@lt2_delimiter.length)..-1]
|
68
|
+
else
|
69
|
+
@lt2_linebuffer << remaining_data
|
70
|
+
remaining_data = ""
|
62
71
|
end
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
72
|
+
elsif @lt2_mode == :text
|
73
|
+
if @lt2_textsize
|
74
|
+
needed = @lt2_textsize - @lt2_textpos
|
75
|
+
will_take = if remaining_data.length > needed
|
76
|
+
needed
|
77
|
+
else
|
78
|
+
remaining_data.length
|
79
|
+
end
|
80
|
+
|
81
|
+
@lt2_textbuffer << remaining_data[0...will_take]
|
82
|
+
tail = remaining_data[will_take..-1]
|
83
|
+
|
84
|
+
@lt2_textpos += will_take
|
85
|
+
if @lt2_textpos >= @lt2_textsize
|
86
|
+
# Reset line mode (the default behavior) BEFORE calling the
|
87
|
+
# receive_binary_data. This makes it possible for user code
|
88
|
+
# to call set_text_mode, enabling chains of text blocks
|
89
|
+
# (which can possibly be of different sizes).
|
90
|
+
set_line_mode
|
91
|
+
receive_binary_data @lt2_textbuffer.join
|
92
|
+
receive_end_of_binary_data
|
93
|
+
end
|
94
|
+
|
95
|
+
remaining_data = tail
|
96
|
+
else
|
97
|
+
receive_binary_data remaining_data
|
98
|
+
remaining_data = ""
|
89
99
|
end
|
90
|
-
|
91
|
-
receive_data tail
|
92
|
-
else
|
93
|
-
receive_binary_data data
|
94
100
|
end
|
95
101
|
end
|
96
102
|
end
|
@@ -48,20 +48,20 @@ module EventMachine
|
|
48
48
|
# puts 'Email failed!'
|
49
49
|
# }
|
50
50
|
#
|
51
|
-
# Sending generated emails (using
|
51
|
+
# Sending generated emails (using Mail)
|
52
52
|
#
|
53
|
-
# mail =
|
54
|
-
#
|
55
|
-
#
|
56
|
-
#
|
57
|
-
#
|
58
|
-
#
|
53
|
+
# mail = Mail.new do
|
54
|
+
# from 'alice@example.com'
|
55
|
+
# to 'bob@example.com'
|
56
|
+
# subject 'This is a test email'
|
57
|
+
# body 'Hello, world!'
|
58
|
+
# end
|
59
59
|
#
|
60
60
|
# email = EM::P::SmtpClient.send(
|
61
|
-
# :domain=>'
|
62
|
-
# :from=>mail.from,
|
61
|
+
# :domain=>'example.com',
|
62
|
+
# :from=>mail.from.first,
|
63
63
|
# :to=>mail.to,
|
64
|
-
# :
|
64
|
+
# :message=>mail.to_s
|
65
65
|
# )
|
66
66
|
#
|
67
67
|
class SmtpClient < Connection
|
@@ -108,25 +108,29 @@ module EventMachine
|
|
108
108
|
# of each requested recipient is available after the call completes. TODO, we should define
|
109
109
|
# an overridable stub that will be called on rejection of a recipient or a sender, giving
|
110
110
|
# user code the chance to try again or abort the connection.
|
111
|
-
#
|
112
|
-
#
|
113
|
-
#
|
114
|
-
#
|
111
|
+
#
|
112
|
+
# One of either :message, :content, or :header and :body is required:
|
113
|
+
#
|
114
|
+
# :message => String
|
115
|
+
# A valid RFC2822 Internet Message.
|
116
|
+
# :content => String
|
117
|
+
# Raw data which MUST be in correct SMTP body format, with escaped leading dots and a trailing
|
118
|
+
# dot line.
|
119
|
+
# :header => String or Hash of values to be transmitted in the header of the message.
|
120
|
+
# The hash keys are the names of the headers (do NOT append a trailing colon), and the values
|
121
|
+
# are strings containing the header values. TODO, support Arrays of header values, which would
|
122
|
+
# cause us to send that specific header line more than once.
|
115
123
|
#
|
116
124
|
# @example
|
117
125
|
# :header => {"Subject" => "Bogus", "CC" => "myboss@example.com"}
|
118
126
|
#
|
119
|
-
# :body => Optional
|
127
|
+
# :body => Optional String or Array of Strings, defaults blank.
|
120
128
|
# This will be passed as the body of the email message.
|
121
129
|
# TODO, this needs to be significantly beefed up. As currently written, this requires the caller
|
122
130
|
# to properly format the input into CRLF-delimited lines of 7-bit characters in the standard
|
123
131
|
# SMTP transmission format. We need to be able to automatically convert binary data, and add
|
124
|
-
# correct line-breaks to text data.
|
125
|
-
#
|
126
|
-
# Then we can check if either :body or :content is present and do the right thing.
|
127
|
-
# :content => Optional array or string
|
128
|
-
# Alternative to providing header and body, an array or string of raw data which MUST be in
|
129
|
-
# correct SMTP body format, including a trailing dot line
|
132
|
+
# correct line-breaks to text data.
|
133
|
+
#
|
130
134
|
# :verbose => Optional.
|
131
135
|
# If true, will cause a lot of information (including the server-side of the
|
132
136
|
# conversation) to be dumped to $>.
|
@@ -233,12 +237,15 @@ module EventMachine
|
|
233
237
|
close_connection_after_writing
|
234
238
|
end
|
235
239
|
|
240
|
+
def send_ehlo
|
241
|
+
send_data "EHLO #{@args[:domain]}\r\n"
|
242
|
+
end
|
243
|
+
|
236
244
|
def receive_signon
|
237
245
|
return invoke_error unless @range == 2
|
238
|
-
|
246
|
+
send_ehlo
|
239
247
|
@responder = :receive_ehlo_response
|
240
248
|
end
|
241
|
-
|
242
249
|
def receive_ehlo_response
|
243
250
|
return invoke_error unless @range == 2
|
244
251
|
@server_caps = @msg
|
@@ -258,6 +265,15 @@ module EventMachine
|
|
258
265
|
def receive_starttls_response
|
259
266
|
return invoke_error unless @range == 2
|
260
267
|
start_tls
|
268
|
+
invoke_ehlo_over_tls
|
269
|
+
end
|
270
|
+
|
271
|
+
def invoke_ehlo_over_tls
|
272
|
+
send_ehlo
|
273
|
+
@responder = :receive_ehlo_over_tls_response
|
274
|
+
end
|
275
|
+
def receive_ehlo_over_tls_response
|
276
|
+
return invoke_error unless @range == 2
|
261
277
|
invoke_auth
|
262
278
|
end
|
263
279
|
|
@@ -316,6 +332,10 @@ module EventMachine
|
|
316
332
|
invoke_rcpt_to
|
317
333
|
end
|
318
334
|
|
335
|
+
def escape_leading_dots(s)
|
336
|
+
s.gsub(/^\./, '..')
|
337
|
+
end
|
338
|
+
|
319
339
|
def invoke_data
|
320
340
|
send_data "DATA\r\n"
|
321
341
|
@responder = :receive_data_response
|
@@ -323,25 +343,34 @@ module EventMachine
|
|
323
343
|
def receive_data_response
|
324
344
|
return invoke_error unless @range == 3
|
325
345
|
|
326
|
-
# The data to send can be given either
|
327
|
-
#
|
328
|
-
#
|
346
|
+
# The data to send can be given in either @args[:message], @args[:content], or the
|
347
|
+
# combination of @args[:header] and @args[:body].
|
348
|
+
#
|
349
|
+
# - @args[:message] (String) MUST be a valid RFC2822 Internet Message
|
329
350
|
#
|
330
|
-
|
351
|
+
# - @args[:content] (String) MUST be in correct SMTP body format, with escaped
|
352
|
+
# leading dots and a trailing dot line
|
353
|
+
#
|
354
|
+
# - @args[:header] (Hash or String)
|
355
|
+
# - @args[:body] (Array or String)
|
356
|
+
if @args[:message]
|
357
|
+
send_data escape_leading_dots(@args[:message].to_s)
|
358
|
+
send_data "\r\n.\r\n"
|
359
|
+
elsif @args[:content]
|
331
360
|
send_data @args[:content].to_s
|
332
361
|
else
|
333
362
|
# The header can be a hash or an array.
|
334
363
|
if @args[:header].is_a?(Hash)
|
335
|
-
(@args[:header] || {}).each {|k,v| send_data "#{k}: #{v}\r\n" }
|
364
|
+
(@args[:header] || {}).each {|k,v| send_data escape_leading_dots("#{k}: #{v}\r\n") }
|
336
365
|
else
|
337
|
-
send_data @args[:header].to_s
|
366
|
+
send_data escape_leading_dots(@args[:header].to_s)
|
338
367
|
end
|
339
368
|
send_data "\r\n"
|
340
369
|
|
341
370
|
if @args[:body].is_a?(Array)
|
342
|
-
@args[:body].each {|e| send_data e}
|
371
|
+
@args[:body].each {|e| send_data escape_leading_dots(e)}
|
343
372
|
else
|
344
|
-
send_data @args[:body].to_s
|
373
|
+
send_data escape_leading_dots(@args[:body].to_s)
|
345
374
|
end
|
346
375
|
|
347
376
|
send_data "\r\n.\r\n"
|
data/lib/em/version.rb
CHANGED
data/lib/eventmachine.rb
CHANGED
@@ -184,7 +184,15 @@ module EventMachine
|
|
184
184
|
add_timer(0) { signal_loopbreak }
|
185
185
|
end
|
186
186
|
@reactor_thread = Thread.current
|
187
|
-
|
187
|
+
|
188
|
+
# Rubinius needs to come back into "Ruby space" for GC to work,
|
189
|
+
# so we'll crank the machine here.
|
190
|
+
if defined?(RUBY_ENGINE) && RUBY_ENGINE == "rbx"
|
191
|
+
while run_machine_once; end
|
192
|
+
else
|
193
|
+
run_machine
|
194
|
+
end
|
195
|
+
|
188
196
|
ensure
|
189
197
|
until @tails.empty?
|
190
198
|
@tails.pop.call
|
data/tests/test_ltp2.rb
CHANGED
@@ -26,6 +26,26 @@ class TestLineText2 < Test::Unit::TestCase
|
|
26
26
|
assert_equal( ["Line 1", "Line 2", "Line 3"], a.lines )
|
27
27
|
end
|
28
28
|
|
29
|
+
# The basic test above shows that extra newlines are chomped
|
30
|
+
# This test shows that newlines are preserved if the delimiter isn't \n
|
31
|
+
class PreserveNewlines
|
32
|
+
include EM::Protocols::LineText2
|
33
|
+
attr_reader :lines
|
34
|
+
def initialize *args
|
35
|
+
super
|
36
|
+
@delim = "|"
|
37
|
+
set_delimiter @delim
|
38
|
+
end
|
39
|
+
def receive_line line
|
40
|
+
(@lines ||= []) << line
|
41
|
+
end
|
42
|
+
end
|
43
|
+
def test_preserve_newlines
|
44
|
+
a = PreserveNewlines.new
|
45
|
+
a.receive_data "aaa|bbb|ccc|\n|\r\n| \t ||"
|
46
|
+
assert_equal( ["aaa", "bbb", "ccc", "\n", "\r\n", " \t ", ""], a.lines )
|
47
|
+
end
|
48
|
+
|
29
49
|
class ChangeDelimiter
|
30
50
|
include EM::Protocols::LineText2
|
31
51
|
attr_reader :lines
|
data/tests/test_smtpclient.rb
CHANGED
@@ -52,4 +52,24 @@ class TestSmtpClient < Test::Unit::TestCase
|
|
52
52
|
assert(err)
|
53
53
|
end
|
54
54
|
|
55
|
+
|
56
|
+
EM::Protocols::SmtpClient.__send__(:public, :escape_leading_dots)
|
57
|
+
|
58
|
+
def test_escaping
|
59
|
+
smtp = EM::Protocols::SmtpClient.new :domain => "example.com"
|
60
|
+
|
61
|
+
expectations = {
|
62
|
+
"Hello\r\n" => "Hello\r\n",
|
63
|
+
"\r\n.whatever\r\n" => "\r\n..whatever\r\n",
|
64
|
+
"\r\n.\r\n" => "\r\n..\r\n",
|
65
|
+
"\r\n.\r\n." => "\r\n..\r\n..",
|
66
|
+
".\r\n.\r\n" => "..\r\n..\r\n",
|
67
|
+
"..\r\n" => "...\r\n"
|
68
|
+
}
|
69
|
+
|
70
|
+
expectations.each do |input, output|
|
71
|
+
assert_equal output, smtp.escape_leading_dots(input)
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
55
75
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: eventmachine
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.8
|
5
5
|
platform: java
|
6
6
|
authors:
|
7
7
|
- Francis Cianfrocca
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2015-
|
12
|
+
date: 2015-08-06 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: test-unit
|
@@ -192,6 +192,7 @@ files:
|
|
192
192
|
- lib/em/version.rb
|
193
193
|
- lib/eventmachine.rb
|
194
194
|
- lib/jeventmachine.rb
|
195
|
+
- lib/rubyeventmachine.jar
|
195
196
|
- rakelib/cpp.rake_example
|
196
197
|
- rakelib/package.rake
|
197
198
|
- rakelib/test.rake
|
@@ -254,7 +255,6 @@ files:
|
|
254
255
|
- tests/test_timers.rb
|
255
256
|
- tests/test_ud.rb
|
256
257
|
- tests/test_unbind_reason.rb
|
257
|
-
- lib/rubyeventmachine.jar
|
258
258
|
homepage: http://rubyeventmachine.com
|
259
259
|
licenses:
|
260
260
|
- Ruby
|
@@ -284,7 +284,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
284
284
|
version: '0'
|
285
285
|
requirements: []
|
286
286
|
rubyforge_project: eventmachine
|
287
|
-
rubygems_version: 2.
|
287
|
+
rubygems_version: 2.4.8
|
288
288
|
signing_key:
|
289
289
|
specification_version: 4
|
290
290
|
summary: Ruby/EventMachine library
|