foxbat 0.0.2 → 0.2.0

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.
data/lib/em/connection.rb CHANGED
@@ -1,88 +1,57 @@
1
1
  import java.nio.ByteBuffer
2
+ import org.jboss.netty.buffer.ChannelBuffers
3
+ import org.jboss.netty.channel.SimpleChannelUpstreamHandler
2
4
 
3
5
  module EventMachine
4
6
 
5
- class Connection
6
-
7
- BUF_SIZE = 256
8
-
9
- attr_accessor :channel, :block
10
- attr_reader :open_time, :close_time
11
-
12
- def peername
13
- @channel.getRemoteAddress
14
- end
7
+ class Connection < SimpleChannelUpstreamHandler
15
8
 
16
9
  def send_data(data)
17
- arr = data.to_java_bytes
18
- buf = ByteBuffer.allocate(arr.length)
19
- buf.put(arr)
20
- buf.flip
21
-
10
+ buf = ChannelBuffers.copiedBuffer(data, "UTF-8")
22
11
  @channel.write(buf)
23
12
  end
24
13
 
25
14
  def post_init; end
26
15
 
27
- def server_post_init
28
- @open_time ||= Time.now.to_i
29
- end
30
-
31
16
  def unbind; end
32
17
 
33
- def start_tls(args={}); end
18
+ def start_tls(args={}); end
34
19
 
35
20
  def receive_data(data)
36
- p 'Incoming data...'
21
+ puts 'Incoming data...'
37
22
  end
38
23
 
39
24
  def close_connection(after_writing=false)
40
- if after_writing == false
41
- @channel.close
42
- else
43
- @channel.shutdownInput
44
- @channel.shutdownOutput
45
- end
46
- @close_time = Time.now.to_i
25
+ @channel.close
47
26
  end
48
27
 
49
28
  def close_connection_after_writing
50
29
  close_connection(true)
51
30
  end
52
31
 
53
- def read_channel(buffer=nil)
54
-
55
- @block.call(self)
56
-
57
- if buffer.nil?
58
- bb = ByteBuffer.allocate(BUF_SIZE)
59
- bb.clear
60
- return read_channel(bb)
61
- end
62
-
63
- reader = Foxbat::Handler.new(@channel) do |c,br|
64
- if br == -1
65
- c.close
66
- self.unbind
67
- else
68
- buffer.flip
69
- str = btos(buffer)
32
+ def get_peername
33
+ addr = @channel.getRemoteAddress
34
+ [addr.getPort, addr.getHostString]
35
+ end
70
36
 
71
- buffer.clear
72
- buffer.rewind
37
+ private
73
38
 
74
- self.receive_data(str)
75
- read_channel(buffer)
76
- end
77
- end
39
+ # The netty channel callbacks
78
40
 
79
- @channel.read(buffer, nil, reader)
41
+ def channelConnected(ctx, e)
42
+ @pipeline = ctx.getPipeline
43
+ @channel = e.getChannel
44
+ post_init
80
45
  end
81
46
 
82
- private
47
+ def messageReceived(ctx, e)
48
+ data = e.getMessage.toString('UTF-8')
49
+ receive_data(data)
50
+ end
83
51
 
84
- def btos(buf)
85
- return String.from_java_bytes(buf.array[buf.position..(buf.limit-1)])
52
+ def exceptionCaught(ctx, e)
53
+ p e.toString
86
54
  end
55
+
87
56
  end
88
57
  end
data/lib/eventmachine.rb CHANGED
@@ -1,9 +1,11 @@
1
+ import java.lang.Long
1
2
  import java.util.concurrent.Executors
3
+ import java.util.concurrent.TimeUnit
2
4
 
3
5
  module EventMachine
4
6
 
5
7
  def self.start_server host, port=nil, handler=nil, *args, &block
6
- s = Foxbat::Server.new(host, port, handler, args.first, block)
8
+ s = Foxbat::Server.new(host, port, handler, args.first || {}, block)
7
9
 
8
10
  @@servers ||= []
9
11
  @@servers << s
@@ -15,7 +17,7 @@ module EventMachine
15
17
  def self.epoll; end
16
18
  def self.kqueue; end
17
19
 
18
- def self.run(blk=nil, tail=nil, &block)
20
+ def self.run(blk=nil, tail=nil, &block)
19
21
  @@threadpool = Executors.newCachedThreadPool
20
22
 
21
23
  block.call
@@ -0,0 +1,29 @@
1
+ import org.jboss.netty.channel.Channels
2
+ import org.jboss.netty.channel.ChannelPipelineFactory
3
+ import org.jboss.netty.handler.ssl.SslHandler
4
+
5
+ require_relative 'security'
6
+
7
+ module Foxbat
8
+
9
+ class Pipeline
10
+ include ChannelPipelineFactory
11
+
12
+ def initialize(handler, ssl_context=nil)
13
+ @handler = handler
14
+ @context = ssl_context
15
+ end
16
+
17
+ def getPipeline
18
+ pipeline = Channels.pipeline
19
+ if @context
20
+ engine = Security.create_ssl_engine(@context)
21
+ pipeline.addLast("ssl", SslHandler.new(engine))
22
+ end
23
+ pipeline.addLast("handler", @handler.new)
24
+ pipeline
25
+ end
26
+
27
+ end
28
+
29
+ end
@@ -0,0 +1,56 @@
1
+ module Foxbat
2
+
3
+ class Security
4
+ import javax.net.ssl.SSLContext
5
+ import javax.net.ssl.KeyManagerFactory
6
+ import javax.net.ssl.TrustManagerFactory
7
+ import javax.net.ssl.SSLEngineResult
8
+ import java.security.KeyStore
9
+ import java.io.FileInputStream
10
+
11
+ def self.setup_keystore(path)
12
+ keystore = KeyStore.getInstance(KeyStore.getDefaultType)
13
+ fis = FileInputStream.new(path)
14
+
15
+ puts 'Enter passphrase for keystore:'
16
+ password = java.lang.System.console.readPassword
17
+
18
+ begin
19
+ keystore.load(fis, password)
20
+ rescue IOException
21
+ puts 'Invalid passphrase.'
22
+ fis.close
23
+ return setup_keystore(path)
24
+ end
25
+ fis.close
26
+
27
+ kmf = KeyManagerFactory.getInstance('SunX509')
28
+ tmf = TrustManagerFactory.getInstance('SunX509')
29
+
30
+ kmf.init(keystore, password)
31
+ tmf.init(keystore)
32
+
33
+ password = nil # Paranoid, per the JavaDoc
34
+
35
+ puts 'Keystore successfully loaded.'
36
+
37
+ [kmf, tmf]
38
+ end
39
+
40
+ def self.setup_ssl_context(keystore_path)
41
+ context = SSLContext.getInstance('TLSv1')
42
+ kmf, tmf = setup_keystore(keystore_path)
43
+ context.init(kmf.getKeyManagers, tmf.getTrustManagers, nil)
44
+ context
45
+ end
46
+
47
+ def self.create_ssl_engine(context)
48
+ engine = context.createSSLEngine
49
+ engine.setUseClientMode(false)
50
+ engine.setNeedClientAuth(false)
51
+ engine
52
+ end
53
+
54
+ end
55
+
56
+ end
data/lib/foxbat/server.rb CHANGED
@@ -1,53 +1,29 @@
1
1
  import java.net.InetSocketAddress
2
- import java.nio.channels.AsynchronousServerSocketChannel
3
- import java.nio.channels.AsynchronousSocketChannel
4
- import java.nio.channels.AsynchronousChannelGroup
5
- import java.util.concurrent.TimeUnit
6
- import java.lang.Long
7
- import java.io.IOException
2
+ import org.jboss.netty.channel.socket.nio.NioServerSocketChannelFactory
3
+ import org.jboss.netty.bootstrap.ServerBootstrap
4
+ require_relative 'pipeline'
5
+ require_relative 'security'
8
6
 
9
7
  module Foxbat
10
8
 
11
9
  class Server
12
10
 
13
- def create_ssl_engine(connection)
14
- engine = @ssl_context.createSSLEngine
15
- engine.setUseClientMode(false)
16
- engine.setNeedClientAuth(false)
17
- connection.ssl_engine = engine
18
- end
19
-
20
11
  def initialize(host, port, klass, options, block=nil)
21
- @bind_address = InetSocketAddress.new(host, port)
22
- @klass = klass
23
- @block = block || Proc.new {}
12
+ if options[:secure]
13
+ @context = Security.setup_ssl_context(options[:keystore])
14
+ end
15
+ @address = InetSocketAddress.new(host, port)
16
+ @pipeline = Pipeline.new(klass || block, @context)
24
17
  end
25
18
 
26
19
  def start(threadpool)
27
- @group = AsynchronousChannelGroup.withCachedThreadPool(threadpool, 1)
28
- @server = AsynchronousServerSocketChannel.open(@group)
29
- @server.bind(@bind_address)
30
-
31
- handler = Foxbat::Handler.new(@server) do |source,socket|
32
- source.accept(nil,handler)
33
-
34
- connection = @klass.new({})
35
- connection.channel = socket
36
- connection.block = @block
37
- connection.server_post_init
38
- connection.post_init
39
-
40
- connection.read_channel
41
- end
42
-
43
- @server.accept(nil, handler)
44
-
45
-
20
+ @factory = NioServerSocketChannelFactory.new(threadpool, threadpool)
21
+ @bootstrap = ServerBootstrap.new(@factory)
22
+ @bootstrap.setPipelineFactory(@pipeline)
23
+ @bootstrap.bind(@address)
46
24
  end
47
25
 
48
26
  def stop
49
- @server.close
50
- @group.awaitTermination(0, TimeUnit::SECONDS)
51
27
  end
52
28
  end
53
29
 
data/lib/foxbat.rb CHANGED
@@ -1,13 +1,12 @@
1
1
  require 'java'
2
+ require 'netty-3.5.0.Final.jar'
2
3
 
3
4
  require 'em/connection'
4
5
  require 'em/periodic_timer'
5
6
  require 'em/timer'
6
- require 'foxbat/barrier'
7
7
  require 'foxbat/server'
8
- require 'foxbat/handler'
9
8
  require 'foxbat/version'
10
- require File.join(File.dirname(__FILE__), 'eventmachine.rb')
9
+ require_relative 'eventmachine'
11
10
 
12
11
  module EventMachine; end
13
12
  EM = EventMachine
Binary file
metadata CHANGED
@@ -1,29 +1,31 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: foxbat
3
3
  version: !ruby/object:Gem::Version
4
+ version: 0.2.0
4
5
  prerelease:
5
- version: 0.0.2
6
6
  platform: ruby
7
7
  authors:
8
8
  - Chris Mowforth
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-03-18 00:00:00.000000000Z
12
+ date: 2012-09-18 00:00:00.000000000 Z
13
13
  dependencies: []
14
- description: A drop-in replacement for EventMachine, designed & built from the ground-up around Java 7 A/IO.
14
+ description: A drop-in replacement for EM, providing functionality missing from the Java port.
15
15
  email:
16
16
  - chris@mowforth.com
17
17
  executables: []
18
18
  extensions: []
19
19
  extra_rdoc_files: []
20
20
  files:
21
- - lib/foxbat.rb
22
21
  - lib/eventmachine.rb
22
+ - lib/netty-3.5.0.Final.jar
23
+ - lib/foxbat.rb
23
24
  - lib/foxbat/barrier.rb
24
- - lib/foxbat/server.rb
25
25
  - lib/foxbat/version.rb
26
- - lib/foxbat/handler.rb
26
+ - lib/foxbat/server.rb
27
+ - lib/foxbat/pipeline.rb
28
+ - lib/foxbat/security.rb
27
29
  - lib/em/periodic_timer.rb
28
30
  - lib/em/timer.rb
29
31
  - lib/em/connection.rb
@@ -47,7 +49,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
47
49
  none: false
48
50
  requirements: []
49
51
  rubyforge_project:
50
- rubygems_version: 1.8.15
52
+ rubygems_version: 1.8.24
51
53
  signing_key:
52
54
  specification_version: 3
53
55
  summary: EventMachine replacement for JRuby.
@@ -1,32 +0,0 @@
1
- import java.nio.channels.CompletionHandler
2
- import java.nio.channels.AsynchronousCloseException
3
-
4
- module Foxbat
5
-
6
- class Handler
7
- include CompletionHandler
8
-
9
- attr_writer :on_fail
10
-
11
- def initialize(source, &block)
12
- @source = source
13
- @completion = block
14
- end
15
-
16
- def completed(socket,attachment)
17
- @completion.call(@source,socket)
18
- end
19
-
20
- def failed(err,attachment)
21
- if !err.is_a?(AsynchronousCloseException)
22
- if @on_fail.nil?
23
- p "ERR: #{err.inspect} -> #{attachment.inspect}"
24
- else
25
- @on_fail.call(err, attachment)
26
- end
27
- end
28
- end
29
-
30
- end
31
-
32
- end