masyo 0.0.1 → 0.0.2
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 +7 -0
- data/README.md +7 -3
- data/bin/masyo +9 -2
- data/lib/masyo.rb +2 -25
- data/lib/masyo/proxy.rb +83 -0
- data/lib/masyo/version.rb +1 -1
- data/spec/masyo/proxy_spec.rb +26 -0
- data/spec/masyo_spec.rb +3 -10
- metadata +13 -25
- data/lib/masyo/buffer.rb +0 -33
- data/lib/masyo/client.rb +0 -50
- data/lib/masyo/event.rb +0 -29
- data/lib/masyo/server.rb +0 -73
- data/spec/masyo/buffer_spec.rb +0 -54
- data/spec/masyo/client_spec.rb +0 -36
- data/spec/masyo/event_spec.rb +0 -65
- data/spec/masyo/server_spec.rb +0 -87
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: ae12169befcce209c36fdc9159fd4a40a68dbc63
|
4
|
+
data.tar.gz: 2245f2c03c5ed7aaadb8aafa6deb3d53a829d469
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: b29e9d59053d5460a1ed347896ceb8c12e3b9aaa6cdeebcab3806620b7b450b1f1c477aac22b8acd6cf8b5b4c4a7caa57467e9f60190ef2a945391e719e1c4e1
|
7
|
+
data.tar.gz: bf8c1af6efbceec09099b08096616b4ac7ba7ec278219c56854160ed7abeac5cb5f25667bdc450d6eaed1a78af7ad505bb8dce5e0571d0e0ab684bc0261ad208
|
data/README.md
CHANGED
@@ -3,10 +3,14 @@
|
|
3
3
|
## Description
|
4
4
|
Casual TCP Proxy
|
5
5
|
|
6
|
+
## Install
|
7
|
+
|
8
|
+
```sh
|
9
|
+
$ gem install masyo
|
10
|
+
```
|
11
|
+
|
6
12
|
## Usage
|
7
13
|
|
8
14
|
```sh
|
9
|
-
$
|
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}
|
15
|
+
$ masyo -h
|
12
16
|
```
|
data/bin/masyo
CHANGED
@@ -5,10 +5,10 @@ require "slop"
|
|
5
5
|
argv = ARGV.dup
|
6
6
|
slop = Slop.new(:strict => true, :help => true)
|
7
7
|
slop.banner "$ bundle exec ruby bin/masyo [options]\n"
|
8
|
-
slop.on :b, :buffer_size=, "buffer byte size(default is 0)"
|
9
8
|
slop.on :listen_port=, "listen port (default is 2000)"
|
10
9
|
slop.on :server_host=, "target server host (default is \"0.0.0.0\")"
|
11
10
|
slop.on :server_port=, "target server port (default is 24224)"
|
11
|
+
slop.on :v, :version, "show masyo version"
|
12
12
|
|
13
13
|
begin
|
14
14
|
slop.parse!(argv)
|
@@ -16,18 +16,25 @@ rescue => e
|
|
16
16
|
puts e
|
17
17
|
exit!
|
18
18
|
end
|
19
|
+
|
19
20
|
options = slop.to_hash
|
21
|
+
|
20
22
|
unless options[:help]
|
21
23
|
options.delete(:help)
|
22
24
|
options[:listen_port] = (options[:listen_port] || 2000).to_i
|
23
25
|
options[:server_host] ||= "0.0.0.0"
|
24
26
|
options[:server_port] = (options[:server_port] || 24224).to_i
|
25
|
-
options[:buffer_size] = (options[:buffer_size] || 0).to_i
|
26
27
|
|
27
28
|
root = File.expand_path("../..", __FILE__)
|
28
29
|
$LOAD_PATH.unshift root
|
29
30
|
$LOAD_PATH.unshift File.join(root, 'lib')
|
30
31
|
|
31
32
|
require "masyo"
|
33
|
+
|
34
|
+
if options[:version]
|
35
|
+
puts Masyo::VERSION
|
36
|
+
exit
|
37
|
+
end
|
38
|
+
|
32
39
|
Masyo.run options
|
33
40
|
end
|
data/lib/masyo.rb
CHANGED
@@ -4,38 +4,15 @@ require 'logger'
|
|
4
4
|
require 'forwardable'
|
5
5
|
|
6
6
|
require 'masyo/version'
|
7
|
-
require 'masyo/
|
8
|
-
require 'masyo/client'
|
9
|
-
require 'masyo/buffer'
|
7
|
+
require 'masyo/proxy'
|
10
8
|
require 'extentions/tcp_socket'
|
11
9
|
|
12
10
|
module Masyo
|
13
11
|
extend self
|
14
12
|
|
15
13
|
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
14
|
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
|
15
|
+
Proxy.run(opts[:listen_port], opts[:server_host], opts[:server_port])
|
39
16
|
end
|
40
17
|
|
41
18
|
def logger
|
data/lib/masyo/proxy.rb
ADDED
@@ -0,0 +1,83 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
require 'socket'
|
4
|
+
|
5
|
+
module Masyo
|
6
|
+
class Proxy
|
7
|
+
attr_accessor :proxy
|
8
|
+
TIMEOUT = 3
|
9
|
+
MAX_RECV_LEN = 1 * 1024 * 1024 * 1024
|
10
|
+
|
11
|
+
class << self
|
12
|
+
def run(listen_port, server_host, server_port)
|
13
|
+
p = new(listen_port, server_host, server_port)
|
14
|
+
p.run
|
15
|
+
rescue Interrupt
|
16
|
+
Masyo.logger.info "Stopping..."
|
17
|
+
# for sending buffer to receiver before socket close.
|
18
|
+
p.stop
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def initialize(listen_port, server_host, server_port)
|
23
|
+
Masyo.logger.info "Proxy 0.0.0.0:#{listen_port} -> #{server_host}:#{server_port}"
|
24
|
+
|
25
|
+
@server_host = server_host
|
26
|
+
@server_port = server_port
|
27
|
+
@proxy = ::TCPServer.new(listen_port)
|
28
|
+
end
|
29
|
+
|
30
|
+
def run
|
31
|
+
loop {
|
32
|
+
break if proxy.closed?
|
33
|
+
|
34
|
+
Thread.start(proxy.accept) do |client|
|
35
|
+
handle client
|
36
|
+
end
|
37
|
+
}
|
38
|
+
end
|
39
|
+
|
40
|
+
def stop
|
41
|
+
proxy.close unless proxy.closed?
|
42
|
+
end
|
43
|
+
|
44
|
+
def handle client
|
45
|
+
input = receive_from client
|
46
|
+
response = request input
|
47
|
+
client.write response unless response.nil?
|
48
|
+
ensure
|
49
|
+
client.close unless client.closed?
|
50
|
+
end
|
51
|
+
|
52
|
+
def request msg
|
53
|
+
::TCPSocket.open(@server_host, @server_port) { |socket|
|
54
|
+
socket.write msg
|
55
|
+
|
56
|
+
receive_from socket
|
57
|
+
}
|
58
|
+
rescue Errno::ECONNREFUSED
|
59
|
+
Masyo.logger.error "Fail to request to server"
|
60
|
+
nil
|
61
|
+
end
|
62
|
+
|
63
|
+
private
|
64
|
+
|
65
|
+
def receive_from socket
|
66
|
+
loop {
|
67
|
+
begin
|
68
|
+
s = socket.recv_nonblock(MAX_RECV_LEN)
|
69
|
+
rescue ::IO::WaitReadable
|
70
|
+
if ::IO.select([ socket ], nil, nil, TIMEOUT)
|
71
|
+
retry
|
72
|
+
else
|
73
|
+
# timeout!
|
74
|
+
break
|
75
|
+
end
|
76
|
+
else
|
77
|
+
break if !s || s == "" || s == "quit"
|
78
|
+
return s
|
79
|
+
end
|
80
|
+
}
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
data/lib/masyo/version.rb
CHANGED
@@ -0,0 +1,26 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
describe Masyo::Proxy do
|
6
|
+
describe 'request' do
|
7
|
+
context 'when fail to connect to server' do
|
8
|
+
before do
|
9
|
+
::TCPSocket.stub(:open).and_raise(Errno::ECONNREFUSED)
|
10
|
+
::TCPServer.stub(:new)
|
11
|
+
end
|
12
|
+
|
13
|
+
let(:generate_proxy) do
|
14
|
+
proc { described_class.new(7777, "0.0.0.0", 7779) }
|
15
|
+
end
|
16
|
+
|
17
|
+
it 'log error' do
|
18
|
+
Masyo.logger.should_receive(:error).with("Fail to request to server")
|
19
|
+
generate_proxy.call.request('msg')
|
20
|
+
end
|
21
|
+
it 'return nil' do
|
22
|
+
expect(generate_proxy.call.request('msg')).to eq(nil)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
data/spec/masyo_spec.rb
CHANGED
@@ -5,19 +5,12 @@ require 'spec_helper'
|
|
5
5
|
describe Masyo do
|
6
6
|
describe "#run" do
|
7
7
|
before :each do
|
8
|
-
Masyo::
|
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
|
8
|
+
Masyo::Proxy.stub(:run)
|
16
9
|
end
|
17
10
|
|
18
11
|
it "should call Server.open with port" do
|
19
|
-
Masyo::
|
20
|
-
described_class.run
|
12
|
+
Masyo::Proxy.should_receive(:run).with(7777, "0.0.0.0", 7779)
|
13
|
+
described_class.run(listen_port: 7777, server_host: "0.0.0.0", server_port: 7779)
|
21
14
|
end
|
22
15
|
end
|
23
16
|
|
metadata
CHANGED
@@ -1,30 +1,27 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: masyo
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
5
|
-
prerelease:
|
4
|
+
version: 0.0.2
|
6
5
|
platform: ruby
|
7
6
|
authors:
|
8
7
|
- Takatoshi Matsumoto
|
9
8
|
autorequire:
|
10
9
|
bindir: bin
|
11
10
|
cert_chain: []
|
12
|
-
date:
|
11
|
+
date: 2013-09-05 00:00:00.000000000 Z
|
13
12
|
dependencies:
|
14
13
|
- !ruby/object:Gem::Dependency
|
15
14
|
name: slop
|
16
15
|
requirement: !ruby/object:Gem::Requirement
|
17
|
-
none: false
|
18
16
|
requirements:
|
19
|
-
- -
|
17
|
+
- - '>='
|
20
18
|
- !ruby/object:Gem::Version
|
21
19
|
version: '0'
|
22
20
|
type: :runtime
|
23
21
|
prerelease: false
|
24
22
|
version_requirements: !ruby/object:Gem::Requirement
|
25
|
-
none: false
|
26
23
|
requirements:
|
27
|
-
- -
|
24
|
+
- - '>='
|
28
25
|
- !ruby/object:Gem::Version
|
29
26
|
version: '0'
|
30
27
|
description: simple tcp proxy server written in ruby
|
@@ -46,49 +43,40 @@ files:
|
|
46
43
|
- bin/masyo
|
47
44
|
- lib/extentions/tcp_socket.rb
|
48
45
|
- lib/masyo.rb
|
49
|
-
- lib/masyo/
|
50
|
-
- lib/masyo/client.rb
|
51
|
-
- lib/masyo/event.rb
|
52
|
-
- lib/masyo/server.rb
|
46
|
+
- lib/masyo/proxy.rb
|
53
47
|
- lib/masyo/version.rb
|
54
48
|
- masyo.gemspec
|
55
49
|
- sample.god
|
56
|
-
- spec/masyo/
|
57
|
-
- spec/masyo/client_spec.rb
|
58
|
-
- spec/masyo/event_spec.rb
|
59
|
-
- spec/masyo/server_spec.rb
|
50
|
+
- spec/masyo/proxy_spec.rb
|
60
51
|
- spec/masyo_spec.rb
|
61
52
|
- spec/spec_helper.rb
|
62
53
|
- tmp/.gitkeep
|
63
54
|
- vendor/bundles/.gitkeep
|
64
55
|
homepage: https://github.com/ToQoz/Masyo
|
65
56
|
licenses: []
|
57
|
+
metadata: {}
|
66
58
|
post_install_message:
|
67
59
|
rdoc_options: []
|
68
60
|
require_paths:
|
69
61
|
- lib
|
70
62
|
required_ruby_version: !ruby/object:Gem::Requirement
|
71
|
-
none: false
|
72
63
|
requirements:
|
73
|
-
- -
|
64
|
+
- - '>='
|
74
65
|
- !ruby/object:Gem::Version
|
75
66
|
version: '0'
|
76
67
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
77
|
-
none: false
|
78
68
|
requirements:
|
79
|
-
- -
|
69
|
+
- - '>='
|
80
70
|
- !ruby/object:Gem::Version
|
81
71
|
version: '0'
|
82
72
|
requirements: []
|
83
73
|
rubyforge_project:
|
84
|
-
rubygems_version:
|
74
|
+
rubygems_version: 2.0.2
|
85
75
|
signing_key:
|
86
|
-
specification_version:
|
76
|
+
specification_version: 4
|
87
77
|
summary: masyo
|
88
78
|
test_files:
|
89
|
-
- spec/masyo/
|
90
|
-
- spec/masyo/client_spec.rb
|
91
|
-
- spec/masyo/event_spec.rb
|
92
|
-
- spec/masyo/server_spec.rb
|
79
|
+
- spec/masyo/proxy_spec.rb
|
93
80
|
- spec/masyo_spec.rb
|
94
81
|
- spec/spec_helper.rb
|
82
|
+
has_rdoc:
|
data/lib/masyo/buffer.rb
DELETED
@@ -1,33 +0,0 @@
|
|
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
|
data/lib/masyo/client.rb
DELETED
@@ -1,50 +0,0 @@
|
|
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
|
data/lib/masyo/event.rb
DELETED
@@ -1,29 +0,0 @@
|
|
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
|
data/lib/masyo/server.rb
DELETED
@@ -1,73 +0,0 @@
|
|
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
|
data/spec/masyo/buffer_spec.rb
DELETED
@@ -1,54 +0,0 @@
|
|
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
|
data/spec/masyo/client_spec.rb
DELETED
@@ -1,36 +0,0 @@
|
|
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
|
data/spec/masyo/event_spec.rb
DELETED
@@ -1,65 +0,0 @@
|
|
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
|
data/spec/masyo/server_spec.rb
DELETED
@@ -1,87 +0,0 @@
|
|
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
|