masyo 0.0.1 → 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- 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
|