masyo 0.0.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.
data/.gitignore ADDED
@@ -0,0 +1,6 @@
1
+ /.bundle
2
+ /vendor/bundles/*
3
+ /tmp/*
4
+ /pkg
5
+
6
+ !.gitkeep
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --color
2
+ --colour
3
+ --drb
data/.travis.yml ADDED
@@ -0,0 +1,13 @@
1
+ language: ruby
2
+ rvm:
3
+ - 1.9.3
4
+
5
+ script:
6
+ - RAILS_ENV=test bundle exec rspec spec
7
+
8
+ notifications:
9
+ email:
10
+ recipients:
11
+ - toqoz403@gmail.com
12
+ on_success: change
13
+ on_failure: always
data/Gemfile ADDED
@@ -0,0 +1,11 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
4
+
5
+ group :test do
6
+ gem 'rspec'
7
+ end
8
+
9
+ group :development, :test do
10
+ gem 'pry'
11
+ end
data/Gemfile.lock ADDED
@@ -0,0 +1,33 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ masyo (0.0.1)
5
+ slop
6
+
7
+ GEM
8
+ remote: https://rubygems.org/
9
+ specs:
10
+ coderay (1.0.7)
11
+ diff-lcs (1.1.3)
12
+ method_source (0.8)
13
+ pry (0.9.10)
14
+ coderay (~> 1.0.5)
15
+ method_source (~> 0.8)
16
+ slop (~> 3.3.1)
17
+ rspec (2.11.0)
18
+ rspec-core (~> 2.11.0)
19
+ rspec-expectations (~> 2.11.0)
20
+ rspec-mocks (~> 2.11.0)
21
+ rspec-core (2.11.1)
22
+ rspec-expectations (2.11.3)
23
+ diff-lcs (~> 1.1.3)
24
+ rspec-mocks (2.11.2)
25
+ slop (3.3.3)
26
+
27
+ PLATFORMS
28
+ ruby
29
+
30
+ DEPENDENCIES
31
+ masyo!
32
+ pry
33
+ rspec
data/LICENSE ADDED
@@ -0,0 +1,19 @@
1
+ Copyright (c) 2012 Takatoshi Matsumoto <toqoz403@gmail.com>
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ of this software and associated documentation files (the "Software"), to deal
5
+ in the Software without restriction, including without limitation the rights
6
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ copies of the Software, and to permit persons to whom the Software is furnished
8
+ to do so, subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in all
11
+ copies or substantial portions of the Software.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,12 @@
1
+ # Masyo(魔性)
2
+
3
+ ## Description
4
+ Casual TCP Proxy
5
+
6
+ ## Usage
7
+
8
+ ```sh
9
+ $ cd /path-to-masyo
10
+ $ bundle install --path=vendor/bundles
11
+ $ bundle exec ruby bin/masyo -listen_port #{LISTEN_PORT} --server_host #{PROXY_TARGET_HOST} --server_port #{PROXY_TARGET_PORT}
12
+ ```
data/Rakefile ADDED
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env rake
2
+ require "bundler/gem_tasks"
data/bin/masyo ADDED
@@ -0,0 +1,33 @@
1
+ #!/usr/bin/env ruby
2
+ # -*- coding: utf-8 -*-
3
+
4
+ require "slop"
5
+ argv = ARGV.dup
6
+ slop = Slop.new(:strict => true, :help => true)
7
+ slop.banner "$ bundle exec ruby bin/masyo [options]\n"
8
+ slop.on :b, :buffer_size=, "buffer byte size(default is 0)"
9
+ slop.on :listen_port=, "listen port (default is 2000)"
10
+ slop.on :server_host=, "target server host (default is \"0.0.0.0\")"
11
+ slop.on :server_port=, "target server port (default is 24224)"
12
+
13
+ begin
14
+ slop.parse!(argv)
15
+ rescue => e
16
+ puts e
17
+ exit!
18
+ end
19
+ options = slop.to_hash
20
+ unless options[:help]
21
+ options.delete(:help)
22
+ options[:listen_port] = (options[:listen_port] || 2000).to_i
23
+ options[:server_host] ||= "0.0.0.0"
24
+ options[:server_port] = (options[:server_port] || 24224).to_i
25
+ options[:buffer_size] = (options[:buffer_size] || 0).to_i
26
+
27
+ root = File.expand_path("../..", __FILE__)
28
+ $LOAD_PATH.unshift root
29
+ $LOAD_PATH.unshift File.join(root, 'lib')
30
+
31
+ require "masyo"
32
+ Masyo.run options
33
+ end
@@ -0,0 +1,8 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ class TCPSocket
4
+ def close_immediately
5
+ setsockopt(::Socket::SOL_SOCKET, ::Socket::SO_LINGER, [1,0].pack('ii'))
6
+ close
7
+ end
8
+ end
@@ -0,0 +1,33 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ module Masyo
4
+ class BufferOverflowException < StandardError; end
5
+
6
+ class Buffer
7
+ attr_accessor :maxlen, :buffer
8
+
9
+ def initialize(maxlen = 0)
10
+ @maxlen = maxlen
11
+ @buffer = ""
12
+ end
13
+
14
+ def take!
15
+ b = buffer
16
+ clear!
17
+ b
18
+ end
19
+
20
+ def push(str)
21
+ if buffer.bytesize + str.bytesize <= maxlen
22
+ self.buffer += str
23
+ else
24
+ raise BufferOverflowException
25
+ end
26
+ end
27
+ alias_method :<<, :push
28
+
29
+ def clear!
30
+ self.buffer = ""
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,50 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ require 'socket'
4
+
5
+ module Masyo
6
+ class Client
7
+ def initialize(host, port, buffer)
8
+ @host = host
9
+ @port = port
10
+ @buffer = buffer
11
+
12
+ if buffer.maxlen > 0
13
+ extend BufferedClient
14
+ else
15
+ extend PlainClient
16
+ end
17
+ end
18
+
19
+ extend ::Forwardable
20
+ def_delegators :Masyo, :logger
21
+ end
22
+
23
+ module PlainClient
24
+ def post(msg)
25
+ ::TCPSocket.open(@host, @port) { |socket|
26
+ socket.write msg
27
+ }
28
+ end
29
+ end
30
+
31
+ module BufferedClient
32
+ def post(msg)
33
+ ::TCPSocket.open(@host, @port) { |socket|
34
+ begin
35
+ buffer << msg
36
+ rescue BufferOverflowException
37
+ # clear buffer
38
+ socket.write buffer.take!
39
+ begin
40
+ buffer << msg
41
+ rescue BufferOverflowException
42
+ # post without using buffer
43
+ #
44
+ socket.write msg
45
+ end
46
+ end
47
+ }
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,29 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ module Masyo
4
+ module Event
5
+
6
+ def self.included(base)
7
+ base.event_types.each do |e|
8
+ base.class_eval {
9
+ define_method("on_#{e}") do |&handler|
10
+ events[e] ||= []
11
+ events[e] << handler
12
+ end
13
+ }
14
+ end
15
+ end
16
+
17
+ def events
18
+ @events ||= {}
19
+ end
20
+
21
+ def trigger_event(name, *arg)
22
+ if events[name]
23
+ events[name].each do |f|
24
+ f.call *arg
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,73 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ require 'socket'
4
+ require 'masyo/event'
5
+
6
+ module Masyo
7
+ class Server
8
+ attr_accessor :tcp_server, :socket_to_client
9
+ TO_CLIENT_SOCKET_TIMEOUT = 3
10
+
11
+ class << self
12
+ def event_types
13
+ [ :read, :close ]
14
+ end
15
+
16
+ def open(*args)
17
+ raise ArgumentError, "wrong number of arguments (#{args.size} for 1..2)" if args.size <= 0 || args.size >= 2
18
+
19
+ server = new(args.first)
20
+ return server unless block_given?
21
+ begin
22
+ yield server
23
+ ensure
24
+ # for sending buffer to server before socket close.
25
+ server.trigger_event :close
26
+ server.close unless server.closed?
27
+ end
28
+ end
29
+ end
30
+
31
+ include Event
32
+
33
+ def initialize(port)
34
+ raise ArgumentError, "#{port} is not a Integer" unless port.is_a? Integer
35
+ @tcp_server = ::TCPServer.new(port)
36
+ end
37
+
38
+ def start
39
+ loop {
40
+ Thread.start(tcp_server.accept) do |to_client|
41
+ handle_request to_client
42
+ end
43
+ }
44
+ end
45
+
46
+ def handle_request(to_client)
47
+ begin
48
+ loop {
49
+ begin
50
+ input = to_client.recv_nonblock(2048)
51
+ rescue ::IO::WaitReadable
52
+ if ::IO.select([ to_client ], nil, nil, TO_CLIENT_SOCKET_TIMEOUT)
53
+ retry
54
+ else
55
+ # timeout!
56
+ break
57
+ end
58
+ else
59
+ break if !input || input == "" || input == "quit"
60
+
61
+ trigger_event :read, input
62
+ end
63
+ }
64
+ ensure
65
+ to_client.close_immediately unless to_client.closed?
66
+ end
67
+ end
68
+
69
+ extend ::Forwardable
70
+ def_delegators :tcp_server, :close, :closed?
71
+ def_delegators :Masyo, :logger
72
+ end
73
+ end
@@ -0,0 +1,3 @@
1
+ module Masyo
2
+ VERSION = "0.0.1"
3
+ end
data/lib/masyo.rb ADDED
@@ -0,0 +1,44 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ require 'logger'
4
+ require 'forwardable'
5
+
6
+ require 'masyo/version'
7
+ require 'masyo/server'
8
+ require 'masyo/client'
9
+ require 'masyo/buffer'
10
+ require 'extentions/tcp_socket'
11
+
12
+ module Masyo
13
+ extend self
14
+
15
+ def run(opts = {})
16
+ opts = {
17
+ listen_port: 2000,
18
+ server_host: "0.0.0.0",
19
+ server_port: 24224 ,
20
+ buffer_size: 0
21
+ }.merge(opts)
22
+ Thread.abort_on_exception = true
23
+
24
+ buffer = Buffer.new opts[:buffer_size]
25
+ client = Client.new(opts[:server_host], opts[:server_port], buffer)
26
+ Server.open(opts[:listen_port]) do |server|
27
+ logger.info "listen #{opts[:listen_port]} port."
28
+
29
+ server.on_read do |msg|
30
+ client.post msg
31
+ end
32
+
33
+ server.on_close {
34
+ client.post buffer.take!
35
+ }
36
+
37
+ server.start
38
+ end
39
+ end
40
+
41
+ def logger
42
+ @logger ||= Logger.new STDOUT
43
+ end
44
+ end
data/masyo.gemspec ADDED
@@ -0,0 +1,19 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require File.expand_path('../lib/masyo/version', __FILE__)
3
+
4
+ Gem::Specification.new do |gem|
5
+ gem.authors = ["Takatoshi Matsumoto"]
6
+ gem.email = ["toqoz403@gmail.com"]
7
+ gem.description = "simple tcp proxy server written in ruby"
8
+ gem.summary = "masyo"
9
+ gem.homepage = "https://github.com/ToQoz/Masyo"
10
+
11
+ gem.files = `git ls-files`.split($\)
12
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
13
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
14
+ gem.name = "masyo"
15
+ gem.require_paths = ["lib"]
16
+ gem.version = Masyo::VERSION
17
+
18
+ gem.add_dependency "slop"
19
+ end
data/sample.god ADDED
@@ -0,0 +1,16 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ God.watch do |w|
4
+ root = File.expand_path("../", __FILE__)
5
+
6
+ w.name = "Masyo"
7
+ w.start = "bundle exec ruby #{File.join(root, 'bin', 'masyo')} --listen_port 2001 --server_host 0.0.0.0 --server_port 24224"
8
+ w.interval = 180.second
9
+ w.keepalive
10
+
11
+ w.start_if do |start|
12
+ start.condition(:process_running) do |c|
13
+ c.running = false
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,54 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ require 'spec_helper'
4
+
5
+ describe Masyo::Buffer do
6
+ let (:instance) { described_class.new 100 }
7
+
8
+ describe '#initialize' do
9
+ context 'when given a number for args' do
10
+ it 'should set it to maxlen' do
11
+ described_class.new(100).maxlen.should eq(100)
12
+ end
13
+ end
14
+ context 'when given none for args' do
15
+ it 'should set 0 to maxlen' do
16
+ described_class.new.maxlen.should eq(0)
17
+ end
18
+ end
19
+ end
20
+
21
+ describe '#clear!' do
22
+ it 'should clear buffer' do
23
+ instance.buffer = "toqoz.should be_cool."
24
+ instance.clear!
25
+ instance.buffer.should eq("")
26
+
27
+ end
28
+ end
29
+
30
+ describe '#take!' do
31
+ it 'should return buffer and clear buffer' do
32
+ instance.buffer = "toqoz.should be_cool."
33
+ instance.take!.should eq("toqoz.should be_cool.")
34
+ instance.buffer.should eq("")
35
+ end
36
+ end
37
+
38
+ describe '#push' do
39
+ context 'when given string `don\'t` over buffer' do
40
+ it 'should add string as buffer' do
41
+ str = Array.new(100, "a").join("")
42
+ instance.push str
43
+ instance.buffer.should eq(str)
44
+ end
45
+ end
46
+ context 'when given string over buffer' do
47
+ it 'raise error' do
48
+ proc {
49
+ instance.push Array.new(101, "a").join("")
50
+ }.should raise_error(Masyo::BufferOverflowException)
51
+ end
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,36 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ require 'spec_helper'
4
+
5
+ describe Masyo::Client do
6
+ describe '#initialize' do
7
+ let(:buffered_client) {
8
+ buffer = double(maxlen: 100)
9
+ described_class.new("0.0.0.0", 8080, buffer)
10
+ }
11
+ let(:plain_client) {
12
+ buffer = double(maxlen: 0)
13
+ described_class.new("0.0.0.0", 8080, buffer)
14
+ }
15
+
16
+ context 'when buffer_size > 0' do
17
+ it 'should use BufferedClient#post as #post' do
18
+ buffered_client.method("post").owner.should eq(Masyo::BufferedClient)
19
+ end
20
+ end
21
+
22
+ context 'when buffer_size == 0' do
23
+ it 'should use PlainClient#post as #post' do
24
+ plain_client.method("post").owner.should eq(Masyo::PlainClient)
25
+ end
26
+ end
27
+ end
28
+
29
+ describe '#post' do
30
+ let (:instance) { described_class.new("0.0.0.0", 8212, double(maxlen: 10)) }
31
+ it 'should call TCPSocket.open' do
32
+ TCPSocket.should_receive(:open).with(kind_of(String), kind_of(Numeric))
33
+ instance.post("dummy message")
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,65 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ require 'spec_helper'
4
+
5
+ describe Masyo::Event do
6
+ let(:instance) do
7
+ mod = described_class
8
+ Class.new {
9
+ class << self
10
+ def event_types
11
+ [ :xxx ]
12
+ end
13
+ end
14
+
15
+ include mod
16
+ }.new
17
+ end
18
+
19
+ describe '.included' do
20
+ context 'when included' do
21
+ it 'define methods for event_types(return by base class methods)' do
22
+ instance.respond_to?(:on_xxx).should be_true
23
+ end
24
+ end
25
+ end
26
+
27
+ describe '#on_*' do
28
+ describe '#on_xxx' do
29
+ it 'should store given block as event callback' do
30
+ callback = proc {}
31
+ instance.on_xxx(&callback)
32
+ instance.events.should eq({ xxx: [ callback ] })
33
+ end
34
+ end
35
+ context '#on_invalid_event' do
36
+ it 'should `not` store given block as event callback' do
37
+ proc {
38
+ callback = proc {}
39
+ instance.on_invalid_event(&callback)
40
+ }.should raise_error(NoMethodError)
41
+
42
+ instance.events.should eq({})
43
+ end
44
+ end
45
+ end
46
+
47
+ describe '#trigger_event' do
48
+ context 'when given exist event anme' do
49
+ it 'should trigger all event for #{name}(first args)' do
50
+ callback = proc {}
51
+ callback.should_receive(:call)
52
+ instance.on_xxx(&callback)
53
+ instance.trigger_event :xxx
54
+ end
55
+ end
56
+ context 'when given `not` exist event anme' do
57
+ it 'should not trigger all event for #{name}(first args)' do
58
+ callback = proc {}
59
+ callback.should_not_receive(:call)
60
+ instance.on_invalid_event(&callback) rescue
61
+ instance.trigger_event :invalid_event
62
+ end
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,87 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ require 'spec_helper'
4
+
5
+ describe Masyo::Server do
6
+ let (:instance) { described_class.new(8183) }
7
+ let (:logger) { double(info: true, error: true) }
8
+
9
+ after(:each) do
10
+ instance.close
11
+ end
12
+
13
+ describe '.open' do
14
+ context 'when given over 2 args' do
15
+ it 'should recieve ArgumentError' do
16
+ proc { described_class.open(8183, "hoge", "foo") }.should raise_error(ArgumentError)
17
+ end
18
+ end
19
+ context 'when given non-number value as first arg' do
20
+ it 'should recieve ArgumentError' do
21
+ proc { described_class.open("9090") }.should raise_error(ArgumentError)
22
+ end
23
+ end
24
+ end
25
+
26
+ describe '#initialize' do
27
+ it 'store ::TCPServer as instance variable' do
28
+ instance.tcp_server.is_a?(::TCPServer).should be_true
29
+ end
30
+ end
31
+
32
+ describe '#handle_request' do
33
+ let (:socket) { double(close_immediately: nil, closed?: false) }
34
+
35
+ context 'when BasicSocket#recv_nonblock raise IO::WaitReadable' do
36
+ before :each do
37
+ socket.stub(:recv_nonblock).and_raise(StandardError.new.extend(IO::WaitReadable))
38
+ end
39
+
40
+ it 'should call IO.select.' do
41
+ IO.should_receive(:select).
42
+ with([ socket ], nil, nil, described_class::TO_CLIENT_SOCKET_TIMEOUT).
43
+ and_return(false)
44
+ instance.handle_request(socket)
45
+ end
46
+ end
47
+
48
+ context "when BasicSocket#recv_nonblock don't raise IO::WaitReadable" do
49
+ let (:input) { "dummy_input" }
50
+
51
+ before :each do
52
+ socket.stub(:recv_nonblock).and_return(input, "")
53
+ end
54
+
55
+ context 'and when input is not false, nil, "", "quit"' do
56
+ it 'should call trigger_event with :read as first arg, and input as second arg' do
57
+ instance.should_receive(:trigger_event).with(:read, input)
58
+ proc {
59
+ instance.handle_request(socket)
60
+ }.should_not raise_error
61
+ end
62
+ end
63
+ end
64
+
65
+ context 'when raise Exception except IO::WaitReadable' do
66
+ it 'should close socket and not catch Exceptions.' do
67
+ socket.stub(:recv_nonblock).and_raise(StandardError)
68
+ socket.should_receive(:close_immediately)
69
+
70
+ proc {
71
+ instance.handle_request(socket)
72
+ }.should raise_error(StandardError)
73
+ end
74
+ end
75
+ end
76
+ end
77
+
78
+ describe ::TCPServer do
79
+ describe '#close_immediately' do
80
+ it 'should receive setsockopt with relavant options and close' do
81
+ socket = described_class.new(8183)
82
+ socket.should_receive(:setsockopt).with(Socket::SOL_SOCKET, Socket::SO_LINGER, [1,0].pack('ii'))
83
+ socket.should_receive(:close)
84
+ socket.close_immediately
85
+ end
86
+ end
87
+ end
@@ -0,0 +1,29 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ require 'spec_helper'
4
+
5
+ describe Masyo do
6
+ describe "#run" do
7
+ before :each do
8
+ Masyo::Buffer.stub(:new)
9
+ Masyo::Client.stub(:new)
10
+ Masyo::Server.stub(:open)
11
+ end
12
+
13
+ it "should set Thread.abort_on_exception = true" do
14
+ Thread.should_receive(:abort_on_exception=).with(true)
15
+ described_class.run
16
+ end
17
+
18
+ it "should call Server.open with port" do
19
+ Masyo::Server.should_receive(:open).with(kind_of(Numeric))
20
+ described_class.run
21
+ end
22
+ end
23
+
24
+ describe "#logger" do
25
+ it 'should return Logger instance.' do
26
+ described_class.logger.is_a?(Logger).should be_true
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,2 @@
1
+ $LOAD_PATH.unshift File.expand_path("../../lib", __FILE__)
2
+ require "masyo"
data/tmp/.gitkeep ADDED
File without changes
File without changes
metadata ADDED
@@ -0,0 +1,94 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: masyo
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Takatoshi Matsumoto
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-12-06 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: slop
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
30
+ description: simple tcp proxy server written in ruby
31
+ email:
32
+ - toqoz403@gmail.com
33
+ executables:
34
+ - masyo
35
+ extensions: []
36
+ extra_rdoc_files: []
37
+ files:
38
+ - .gitignore
39
+ - .rspec
40
+ - .travis.yml
41
+ - Gemfile
42
+ - Gemfile.lock
43
+ - LICENSE
44
+ - README.md
45
+ - Rakefile
46
+ - bin/masyo
47
+ - lib/extentions/tcp_socket.rb
48
+ - lib/masyo.rb
49
+ - lib/masyo/buffer.rb
50
+ - lib/masyo/client.rb
51
+ - lib/masyo/event.rb
52
+ - lib/masyo/server.rb
53
+ - lib/masyo/version.rb
54
+ - masyo.gemspec
55
+ - sample.god
56
+ - spec/masyo/buffer_spec.rb
57
+ - spec/masyo/client_spec.rb
58
+ - spec/masyo/event_spec.rb
59
+ - spec/masyo/server_spec.rb
60
+ - spec/masyo_spec.rb
61
+ - spec/spec_helper.rb
62
+ - tmp/.gitkeep
63
+ - vendor/bundles/.gitkeep
64
+ homepage: https://github.com/ToQoz/Masyo
65
+ licenses: []
66
+ post_install_message:
67
+ rdoc_options: []
68
+ require_paths:
69
+ - lib
70
+ required_ruby_version: !ruby/object:Gem::Requirement
71
+ none: false
72
+ requirements:
73
+ - - ! '>='
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ required_rubygems_version: !ruby/object:Gem::Requirement
77
+ none: false
78
+ requirements:
79
+ - - ! '>='
80
+ - !ruby/object:Gem::Version
81
+ version: '0'
82
+ requirements: []
83
+ rubyforge_project:
84
+ rubygems_version: 1.8.23
85
+ signing_key:
86
+ specification_version: 3
87
+ summary: masyo
88
+ test_files:
89
+ - spec/masyo/buffer_spec.rb
90
+ - spec/masyo/client_spec.rb
91
+ - spec/masyo/event_spec.rb
92
+ - spec/masyo/server_spec.rb
93
+ - spec/masyo_spec.rb
94
+ - spec/spec_helper.rb