arachni-reactor 0.1.1 → 0.1.3.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 6c421c44ae454d55db1adc102b4c9d0819375ff0
4
- data.tar.gz: b05b9f1ddf6048d8e0df60684b738e879628e48c
2
+ SHA256:
3
+ metadata.gz: a0cfc973e123c07b625b3905feeb383626a4e24808844ea30aa3ecbf2dc44d5e
4
+ data.tar.gz: 47925771a19ffe849fb8fc8c0982db5ccc75dde6156c16441ab16ea8399f6759
5
5
  SHA512:
6
- metadata.gz: 83ba17f94bed4e8d8d8b6125ed06288051a3bc59bd34733f355db80757e01f65d7074459670c1cedb95ffc2c0242dfc8219ea4988199f5fb0c63139152e6182c
7
- data.tar.gz: e7a6690fa5d3c8f496e19a34e6d7d942548dc5dbb3ef62905a1e2c7a29c9fbd5b3923527ad2cf60c3ed707666ec6854577f6e135ef30eabe87ca9d3db50b18ec
6
+ metadata.gz: 0b960c5e0711aa617712c13ec9cae4dd8f5678df9957db8d198133aeed66f4e5be0791f3098b609c0492bb9728f477600c75a15f445e851b6b07adf1a9b8d3b4
7
+ data.tar.gz: a1410d7d143c52bae10978f83b10003c27b690e1b274de944173c4d8d78ace4a894fadb6026f7b099d42b4311d281a8717e2480051b132f71b763fe66918c924
data/CHANGELOG.md CHANGED
@@ -1,5 +1,23 @@
1
1
  # ChangeLog
2
2
 
3
+ ## Version 0.1.3.2
4
+
5
+ - `Error.translate` updated to handle `Errno::EBADF`.
6
+
7
+ ## Version 0.1.3.1
8
+
9
+ - Fixed strange `private method` error on Ruby 2.6.9.
10
+
11
+ ## Version 0.1.3
12
+
13
+ - `Reactor` -- Reduced object allocations.
14
+ - `Connection::TLS#_read` -- Handle `OpenSSL::SSL::SSLErrorWaitReadable`.
15
+
16
+ ## Version 0.1.2
17
+
18
+ - `Reactor` -- Reduced object allocations.
19
+ - `Connection::Error.translate` -- Handle `Errno::ENOTSOCK` errors.
20
+
3
21
  ## Version 0.1.1
4
22
 
5
23
  - `Connection`
data/LICENSE.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # License
2
2
 
3
- Copyright (C) 2014-2016, Tasos Laskos <tasos.laskos@gmail.com>
3
+ Copyright (C) 2014-2017, Sarosys LLC <http://www.sarosys.com/>
4
4
  All rights reserved.
5
5
 
6
6
  Redistribution and use in source and binary forms, with or without modification,
data/README.md CHANGED
@@ -3,7 +3,7 @@
3
3
  <table>
4
4
  <tr>
5
5
  <th>Version</th>
6
- <td>0.1.1</td>
6
+ <td>0.1.2</td>
7
7
  </tr>
8
8
  <tr>
9
9
  <th>Github page</th>
@@ -23,7 +23,7 @@
23
23
  </tr>
24
24
  <tr>
25
25
  <th>Copyright</th>
26
- <td>2014-2016</td>
26
+ <td>2014-2017 <a href="http://www.sarosys.com">Sarosys LLC</a></td>
27
27
  </tr>
28
28
  <tr>
29
29
  <th>License</th>
@@ -24,7 +24,7 @@ class Error < Arachni::Reactor::Error
24
24
  # @param [Block] block Block to run.
25
25
  def translate( &block )
26
26
  block.call
27
- rescue IOError, Errno::ENOTCONN => e
27
+ rescue IOError, Errno::ENOTCONN, Errno::ENOTSOCK => e
28
28
  raise_with_proper_backtrace( e, Closed )
29
29
  rescue SocketError, Errno::ENOENT => e
30
30
  raise_with_proper_backtrace( e, HostNotFound )
@@ -39,6 +39,8 @@ class Error < Arachni::Reactor::Error
39
39
  raise_with_proper_backtrace( e, Reset )
40
40
  rescue Errno::EACCES => e
41
41
  raise_with_proper_backtrace( e, Permission )
42
+ rescue Errno::EBADF => e
43
+ raise_with_proper_backtrace( e, BadSocket )
42
44
 
43
45
  # Catch and forward these before handling OpenSSL::OpenSSLError because
44
46
  # all SSL errors inherit from it, including OpenSSL::SSL::SSLErrorWaitReadable
@@ -102,6 +104,12 @@ class Error < Arachni::Reactor::Error
102
104
  class Closed < Error
103
105
  end
104
106
 
107
+ # Like a `Errno::EBADF` exception.
108
+ #
109
+ # @author Tasos "Zapotek" Laskos <tasos.laskos@gmail.com>
110
+ class BadSocket < Error
111
+ end
112
+
105
113
  # Like a `OpenSSL::OpenSSLError` exception.
106
114
  #
107
115
  # @author Tasos "Zapotek" Laskos <tasos.laskos@gmail.com>
@@ -113,6 +113,7 @@ module TLS
113
113
  return ssl_accept if accept?
114
114
 
115
115
  super
116
+ rescue OpenSSL::SSL::SSLErrorWaitReadable
116
117
  end
117
118
 
118
119
  private
@@ -150,6 +151,7 @@ module TLS
150
151
  @ssl_context
151
152
  )
152
153
  ssl_socket.sync_close = true
154
+ ssl.accept if @start_immediately
153
155
  ssl_socket
154
156
  end
155
157
  rescue IO::WaitReadable, IO::WaitWritable
@@ -9,7 +9,7 @@
9
9
  module Arachni
10
10
  class Reactor
11
11
 
12
- VERSION = '0.1.1'
12
+ VERSION = '0.1.3.2'
13
13
 
14
14
  end
15
15
  end
@@ -414,7 +414,7 @@ class Reactor
414
414
  def schedule( &block )
415
415
  fail_if_not_running
416
416
 
417
- if running? && in_same_thread?
417
+ if in_same_thread?
418
418
  block.call
419
419
  else
420
420
  next_tick(&block)
@@ -551,32 +551,8 @@ class Reactor
551
551
  'The host OS does not support UNIX-domain sockets.'
552
552
  end
553
553
 
554
- def process_connections
555
- if @connections.empty?
556
- sleep @max_tick_interval
557
- return
558
- end
559
-
560
- # Required for OSX as it connects immediately and then #select returns
561
- # nothing as there's no activity, given that, OpenSSL doesn't get a chance
562
- # to do its handshake so explicitly connect pending sockets, bypassing #select.
563
- @connections.each do |_, connection|
564
- connection._connect if !connection.connected?
565
- end
566
-
567
- # Get connections with available events - :read, :write, :error.
568
- selected = select_connections
569
-
570
- # Close connections that have errors.
571
- [selected.delete(:error)].flatten.compact.each(&:close)
572
-
573
- # Call the corresponding event on the connections.
574
- selected.each { |event, connections| connections.each(&"_#{event}".to_sym) }
575
- end
576
-
577
554
  def determine_connection_options( *args )
578
555
  options = {}
579
- host = port = unix_socket = nil
580
556
 
581
557
  if args[1].is_a? Integer
582
558
  options[:host], options[:port], options[:handler], *handler_options = *args
@@ -634,6 +610,22 @@ class Reactor
634
610
  @connections.values.each(&:close)
635
611
  end
636
612
 
613
+ def process_connections
614
+ if @connections.empty?
615
+ sleep @max_tick_interval
616
+ return
617
+ end
618
+
619
+ # Get connections with available events - :read, :write, :error.
620
+ selected = select_connections
621
+
622
+ # Close connections that have errors.
623
+ selected.delete(:error)&.each(&:close)
624
+
625
+ # Call the corresponding event on the connections.
626
+ selected.each { |event, connections| connections.each(&"_#{event}".to_sym) }
627
+ end
628
+
637
629
  # @return [Hash]
638
630
  #
639
631
  # Connections grouped by their available events:
@@ -643,17 +635,34 @@ class Reactor
643
635
  # {Connection#has_outgoing_data? outgoing buffer).
644
636
  # * `:error`
645
637
  def select_connections
646
- readables = read_sockets
638
+ r = []
639
+ w = []
640
+ e = []
641
+
642
+ @connections.values.each do |connection|
643
+
644
+ # Required for OSX as it connects immediately and then #select returns
645
+ # nothing as there's no activity, given that, OpenSSL doesn't get a chance
646
+ # to do its handshake so explicitly connect pending sockets, bypassing #select.
647
+ connection._connect if !connection.connected?
648
+
649
+ socket = connection.socket
650
+
651
+ e << socket
652
+
653
+ if connection.listener? || connection.connected?
654
+ r << socket
655
+ end
656
+
657
+ if connection.connected? && connection.has_outgoing_data?
658
+ w << socket
659
+ end
660
+ end
647
661
 
648
662
  selected_sockets =
649
663
  begin
650
664
  Connection::Error.translate do
651
- select(
652
- readables,
653
- write_sockets,
654
- all_sockets,
655
- @select_timeout
656
- )
665
+ select( r, w, e, @select_timeout )
657
666
  end
658
667
  rescue Connection::Error => e
659
668
  nil
@@ -668,8 +677,8 @@ class Reactor
668
677
  # So force a read for SSL sockets to cover all our bases.
669
678
  #
670
679
  # This is apparent especially on JRuby.
671
- if readables.size != selected_sockets[0].size
672
- (readables - selected_sockets[0]).each do |socket|
680
+ if r.size != selected_sockets[0].size
681
+ (r - selected_sockets[0]).each do |socket|
673
682
  next if !socket.is_a?( OpenSSL::SSL::SSLSocket )
674
683
  selected_sockets[0] << socket
675
684
  end
@@ -689,35 +698,8 @@ class Reactor
689
698
  }
690
699
  end
691
700
 
692
- # @return [Array<Socket>]
693
- # Sockets of all connections, we want to be ready to read at any time.
694
- def read_sockets
695
- @connections.map do |_, connection|
696
- next if !connection.listener? && !connection.connected?
697
- connection.socket
698
- end.compact
699
- end
700
-
701
- def all_sockets
702
- @connections.values.map(&:socket)
703
- end
704
-
705
- # @return [Array<Socket>]
706
- # Sockets of connections with
707
- # {Connection#has_outgoing_data? outgoing data}.
708
- def write_sockets
709
- @connections.map do |_, connection|
710
- next if connection.connected? && !connection.has_outgoing_data?
711
- connection.socket
712
- end.compact
713
- end
714
-
715
701
  def connections_from_sockets( sockets )
716
- sockets.map { |s| connection_from_socket( s ) }
717
- end
718
-
719
- def connection_from_socket( socket )
720
- @connections[socket.to_io]
702
+ sockets.map { |s| @connections[s.to_io] }
721
703
  end
722
704
 
723
705
  end
@@ -129,10 +129,12 @@ describe Arachni::Reactor::Connection::TLS do
129
129
  reactor.listen( host, port, TLSHandler, options )
130
130
 
131
131
  client.write data
132
+ sleep 1
133
+
132
134
  reactor.stop
133
135
  reactor.wait rescue Arachni::Reactor::Error::NotRunning
134
136
 
135
- received_data.should == data
137
+ expect(received_data).to eq data
136
138
  end
137
139
  end
138
140
 
@@ -324,7 +326,8 @@ describe Arachni::Reactor::Connection::TLS do
324
326
  connection.write data
325
327
  end
326
328
 
327
- received.should == data
329
+ sleep 1
330
+ expect(received).to eq data
328
331
  end
329
332
  end
330
333
 
@@ -25,7 +25,7 @@ describe Arachni::Reactor::Iterator do
25
25
  end
26
26
 
27
27
  context 'when the concurrency is' do
28
- context 0 do
28
+ context '0' do
29
29
  let(:concurrency) { 0 }
30
30
 
31
31
  it "raises #{ArgumentError}" do
@@ -25,14 +25,14 @@ describe Arachni::Reactor::Tasks do
25
25
  context 'when it includes the given task' do
26
26
  it 'returns true' do
27
27
  subject << task
28
- subject.should include task
28
+ expect(subject.include?( task )).to be_truthy
29
29
  end
30
30
  end
31
31
 
32
32
  context 'when it does not includes the given task' do
33
33
  it 'returns false' do
34
34
  subject << task
35
- subject.should_not include another_task
35
+ expect(subject.include?( another_task )).to be_falsey
36
36
  end
37
37
  end
38
38
  end
@@ -125,8 +125,8 @@ describe Arachni::Reactor::Tasks do
125
125
 
126
126
  subject.call
127
127
 
128
- called_one.should be_true
129
- called_two.should be_true
128
+ called_one.should be_truthy
129
+ called_two.should be_truthy
130
130
  end
131
131
 
132
132
  it 'returns self' do
@@ -114,7 +114,7 @@ def convert_server_to_ssl( server, options = {} )
114
114
  context.cert.version = 2
115
115
  context.cert.serial = 1
116
116
 
117
- context.cert.sign( context.key, OpenSSL::Digest::SHA1.new )
117
+ context.cert.sign( context.key, OpenSSL::Digest::SHA256.new )
118
118
  end
119
119
 
120
120
  OpenSSL::SSL::SSLServer.new( server, context )
@@ -15,7 +15,7 @@ loop do
15
15
  next if (data = socket.gets).to_s.empty?
16
16
  socket.write( data )
17
17
  end
18
- rescue EOFError, Errno::EPIPE
18
+ rescue EOFError, Errno::EPIPE, Errno::ECONNRESET
19
19
  socket.close
20
20
  end
21
21
  end
@@ -7,7 +7,7 @@ loop do
7
7
  next if (data = socket.gets).to_s.empty?
8
8
  socket.write( data )
9
9
  end
10
- rescue EOFError, Errno::EPIPE
10
+ rescue EOFError, Errno::EPIPE, Errno::ECONNRESET
11
11
  socket.close
12
12
  end
13
13
  end
@@ -15,7 +15,7 @@ loop do
15
15
  next if (data = socket.gets).to_s.empty?
16
16
  socket.write( data )
17
17
  end
18
- rescue EOFError, Errno::EPIPE
18
+ rescue EOFError, Errno::EPIPE, Errno::ECONNRESET
19
19
  socket.close
20
20
  end
21
21
  end
@@ -290,10 +290,10 @@ shared_examples_for 'Arachni::Reactor::Connection' do
290
290
 
291
291
  reactor.run_in_thread
292
292
 
293
- connection.attach( reactor ).should be_true
293
+ connection.attach( reactor ).should be_truthy
294
294
  sleep 1
295
295
 
296
- reactor.attached?( configured ).should be_true
296
+ reactor.attached?( configured ).should be_truthy
297
297
  end
298
298
 
299
299
  it 'calls #on_attach' do
@@ -319,7 +319,7 @@ shared_examples_for 'Arachni::Reactor::Connection' do
319
319
  connection.attach reactor
320
320
  sleep 0.1 while connection.detached?
321
321
 
322
- connection.attach( reactor ).should be_false
322
+ connection.attach( reactor ).should be_falsey
323
323
  end
324
324
  end
325
325
 
@@ -337,11 +337,11 @@ shared_examples_for 'Arachni::Reactor::Connection' do
337
337
  r.run_in_thread
338
338
 
339
339
  configured.should receive(:on_detach)
340
- connection.attach( r ).should be_true
340
+ connection.attach( r ).should be_truthy
341
341
 
342
342
  sleep 2
343
343
 
344
- r.attached?( configured ).should be_true
344
+ r.attached?( configured ).should be_truthy
345
345
  end
346
346
  end
347
347
  end
@@ -363,7 +363,7 @@ shared_examples_for 'Arachni::Reactor::Connection' do
363
363
  connection.detach
364
364
  sleep 0.1 while connection.attached?
365
365
 
366
- reactor.attached?( configured ).should be_false
366
+ reactor.attached?( configured ).should be_falsey
367
367
  end
368
368
 
369
369
  it 'calls #on_detach' do
@@ -582,7 +582,7 @@ shared_examples_for 'Arachni::Reactor::Connection' do
582
582
  end
583
583
  end
584
584
 
585
- configured.called_on_flush.should be_true
585
+ configured.called_on_flush.should be_truthy
586
586
  end
587
587
  end
588
588
  end
@@ -601,13 +601,13 @@ shared_examples_for 'Arachni::Reactor::Connection' do
601
601
  configured.write 'test'
602
602
  sleep 0.1 while !configured.has_outgoing_data?
603
603
 
604
- configured.has_outgoing_data?.should be_true
604
+ configured.has_outgoing_data?.should be_truthy
605
605
  end
606
606
  end
607
607
 
608
608
  context 'when the send-buffer is empty' do
609
609
  it 'returns false' do
610
- configured.has_outgoing_data?.should be_false
610
+ configured.has_outgoing_data?.should be_falsey
611
611
  end
612
612
  end
613
613
  end
@@ -158,7 +158,7 @@ shared_examples_for 'Arachni::Reactor' do
158
158
  end
159
159
 
160
160
  subject.should_not be_running
161
- running.should be_true
161
+ running.should be_truthy
162
162
  end
163
163
 
164
164
  context 'when no block is given' do
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: arachni-reactor
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.1.3.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tasos Laskos
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-01-26 00:00:00.000000000 Z
11
+ date: 2022-01-27 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: |2
14
14
  Arachni::Reactor is a simple, lightweight, pure-Ruby implementation of the Reactor
@@ -97,45 +97,44 @@ required_rubygems_version: !ruby/object:Gem::Requirement
97
97
  - !ruby/object:Gem::Version
98
98
  version: '0'
99
99
  requirements: []
100
- rubyforge_project:
101
- rubygems_version: 2.5.1
100
+ rubygems_version: 3.3.0.dev
102
101
  signing_key:
103
102
  specification_version: 4
104
103
  summary: A pure-Ruby implementation of the Reactor pattern.
105
104
  test_files:
106
- - spec/support/fixtures/pems/server/cert.pem
107
- - spec/support/fixtures/pems/server/key.pem
105
+ - spec/arachni/reactor/connection/tls_spec.rb
106
+ - spec/arachni/reactor/connection_spec.rb
107
+ - spec/arachni/reactor/iterator_spec.rb
108
+ - spec/arachni/reactor/queue_spec.rb
109
+ - spec/arachni/reactor/tasks/base.rb
110
+ - spec/arachni/reactor/tasks/delayed_spec.rb
111
+ - spec/arachni/reactor/tasks/one_off_spec.rb
112
+ - spec/arachni/reactor/tasks/periodic_spec.rb
113
+ - spec/arachni/reactor/tasks/persistent_spec.rb
114
+ - spec/arachni/reactor/tasks_spec.rb
115
+ - spec/arachni/reactor_spec.rb
116
+ - spec/arachni/reactor_tls_spec.rb
117
+ - spec/spec_helper.rb
118
+ - spec/support/fixtures/handlers/echo_client.rb
119
+ - spec/support/fixtures/handlers/echo_client_tls.rb
120
+ - spec/support/fixtures/handlers/echo_server.rb
121
+ - spec/support/fixtures/handlers/echo_server_tls.rb
108
122
  - spec/support/fixtures/pems/cacert.pem
109
- - spec/support/fixtures/pems/client/foo-key.pem
110
123
  - spec/support/fixtures/pems/client/cert.pem
111
124
  - spec/support/fixtures/pems/client/foo-cert.pem
125
+ - spec/support/fixtures/pems/client/foo-key.pem
112
126
  - spec/support/fixtures/pems/client/key.pem
113
- - spec/support/fixtures/handlers/echo_client.rb
114
- - spec/support/fixtures/handlers/echo_server.rb
115
- - spec/support/fixtures/handlers/echo_client_tls.rb
116
- - spec/support/fixtures/handlers/echo_server_tls.rb
117
- - spec/support/servers/echo_unix.rb
118
- - spec/support/servers/echo_tls.rb
119
- - spec/support/servers/echo.rb
120
- - spec/support/servers/echo_unix_tls.rb
121
- - spec/support/helpers/utilities.rb
127
+ - spec/support/fixtures/pems/server/cert.pem
128
+ - spec/support/fixtures/pems/server/key.pem
122
129
  - spec/support/helpers/paths.rb
123
- - spec/support/lib/servers.rb
124
- - spec/support/lib/servers/runner.rb
130
+ - spec/support/helpers/utilities.rb
125
131
  - spec/support/lib/server_option_parser.rb
126
- - spec/support/shared/reactor.rb
132
+ - spec/support/lib/servers/runner.rb
133
+ - spec/support/lib/servers.rb
134
+ - spec/support/servers/echo.rb
135
+ - spec/support/servers/echo_tls.rb
136
+ - spec/support/servers/echo_unix.rb
137
+ - spec/support/servers/echo_unix_tls.rb
127
138
  - spec/support/shared/connection.rb
139
+ - spec/support/shared/reactor.rb
128
140
  - spec/support/shared/task.rb
129
- - spec/spec_helper.rb
130
- - spec/arachni/reactor_tls_spec.rb
131
- - spec/arachni/reactor_spec.rb
132
- - spec/arachni/reactor/queue_spec.rb
133
- - spec/arachni/reactor/tasks_spec.rb
134
- - spec/arachni/reactor/connection_spec.rb
135
- - spec/arachni/reactor/iterator_spec.rb
136
- - spec/arachni/reactor/connection/tls_spec.rb
137
- - spec/arachni/reactor/tasks/base.rb
138
- - spec/arachni/reactor/tasks/persistent_spec.rb
139
- - spec/arachni/reactor/tasks/delayed_spec.rb
140
- - spec/arachni/reactor/tasks/one_off_spec.rb
141
- - spec/arachni/reactor/tasks/periodic_spec.rb