blather 0.4.14 → 0.4.15
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/blather.rb +8 -0
- data/lib/blather/client/client.rb +9 -1
- data/lib/blather/client/dsl/pubsub.rb +2 -2
- data/lib/blather/core_ext/active_support.rb +1 -0
- data/lib/blather/core_ext/eventmachine.rb +122 -0
- data/lib/blather/errors/stanza_error.rb +1 -0
- data/lib/blather/file_transfer.rb +100 -0
- data/lib/blather/file_transfer/ibb.rb +68 -0
- data/lib/blather/file_transfer/s5b.rb +104 -0
- data/lib/blather/roster_item.rb +2 -2
- data/lib/blather/stanza/disco/disco_info.rb +17 -2
- data/lib/blather/stanza/iq/ibb.rb +83 -0
- data/lib/blather/stanza/iq/s5b.rb +205 -0
- data/lib/blather/stanza/iq/si.rb +410 -0
- data/lib/blather/stanza/iq/vcard.rb +147 -0
- data/lib/blather/stanza/message.rb +10 -2
- data/lib/blather/stanza/presence/status.rb +11 -3
- data/lib/blather/stanza/pubsub.rb +3 -1
- data/lib/blather/stanza/pubsub/event.rb +18 -0
- data/lib/blather/stanza/pubsub/subscriptions.rb +4 -2
- data/lib/blather/stanza/pubsub/unsubscribe.rb +17 -1
- data/lib/blather/stanza/x.rb +12 -2
- data/lib/blather/stream/parser.rb +1 -0
- data/lib/test.rb +55 -0
- data/spec/blather/client/client_spec.rb +18 -4
- data/spec/blather/client/dsl/pubsub_spec.rb +12 -2
- data/spec/blather/client/dsl_spec.rb +1 -1
- data/spec/blather/core_ext/nokogiri_spec.rb +1 -1
- data/spec/blather/errors/sasl_error_spec.rb +1 -1
- data/spec/blather/errors/stanza_error_spec.rb +1 -1
- data/spec/blather/errors/stream_error_spec.rb +1 -1
- data/spec/blather/errors_spec.rb +1 -1
- data/spec/blather/file_transfer_spec.rb +100 -0
- data/spec/blather/jid_spec.rb +1 -1
- data/spec/blather/roster_item_spec.rb +32 -2
- data/spec/blather/roster_spec.rb +1 -1
- data/spec/blather/stanza/discos/disco_info_spec.rb +12 -3
- data/spec/blather/stanza/discos/disco_items_spec.rb +1 -1
- data/spec/blather/stanza/iq/command_spec.rb +1 -1
- data/spec/blather/stanza/iq/ibb_spec.rb +136 -0
- data/spec/blather/stanza/iq/query_spec.rb +1 -1
- data/spec/blather/stanza/iq/roster_spec.rb +1 -1
- data/spec/blather/stanza/iq/s5b_spec.rb +60 -0
- data/spec/blather/stanza/iq/si_spec.rb +101 -0
- data/spec/blather/stanza/iq/vcard_spec.rb +96 -0
- data/spec/blather/stanza/iq_spec.rb +1 -1
- data/spec/blather/stanza/message_spec.rb +48 -2
- data/spec/blather/stanza/presence/status_spec.rb +1 -1
- data/spec/blather/stanza/presence/subscription_spec.rb +1 -1
- data/spec/blather/stanza/presence_spec.rb +1 -1
- data/spec/blather/stanza/pubsub/affiliations_spec.rb +2 -2
- data/spec/blather/stanza/pubsub/create_spec.rb +2 -2
- data/spec/blather/stanza/pubsub/event_spec.rb +16 -2
- data/spec/blather/stanza/pubsub/items_spec.rb +2 -2
- data/spec/blather/stanza/pubsub/publish_spec.rb +2 -2
- data/spec/blather/stanza/pubsub/retract_spec.rb +2 -2
- data/spec/blather/stanza/pubsub/subscribe_spec.rb +2 -2
- data/spec/blather/stanza/pubsub/subscription_spec.rb +2 -2
- data/spec/blather/stanza/pubsub/subscriptions_spec.rb +3 -3
- data/spec/blather/stanza/pubsub/unsubscribe_spec.rb +15 -2
- data/spec/blather/stanza/pubsub_owner/delete_spec.rb +2 -2
- data/spec/blather/stanza/pubsub_owner/purge_spec.rb +2 -2
- data/spec/blather/stanza/pubsub_owner_spec.rb +2 -2
- data/spec/blather/stanza/pubsub_spec.rb +14 -2
- data/spec/blather/stanza/x_spec.rb +1 -1
- data/spec/blather/stanza_spec.rb +1 -1
- data/spec/blather/stream/client_spec.rb +1 -1
- data/spec/blather/stream/component_spec.rb +1 -1
- data/spec/blather/stream/parser_spec.rb +11 -1
- data/spec/blather/xmpp_node_spec.rb +1 -1
- data/spec/fixtures/pubsub.rb +2 -2
- data/spec/spec_helper.rb +27 -0
- metadata +85 -23
data/lib/blather.rb
CHANGED
@@ -8,12 +8,16 @@
|
|
8
8
|
logger
|
9
9
|
|
10
10
|
blather/core_ext/active_support
|
11
|
+
blather/core_ext/eventmachine
|
11
12
|
blather/core_ext/nokogiri
|
12
13
|
|
13
14
|
blather/errors
|
14
15
|
blather/errors/sasl_error
|
15
16
|
blather/errors/stanza_error
|
16
17
|
blather/errors/stream_error
|
18
|
+
blather/file_transfer
|
19
|
+
blather/file_transfer/ibb
|
20
|
+
blather/file_transfer/s5b
|
17
21
|
blather/jid
|
18
22
|
blather/roster
|
19
23
|
blather/roster_item
|
@@ -24,6 +28,10 @@
|
|
24
28
|
blather/stanza/iq/query
|
25
29
|
blather/stanza/iq/command
|
26
30
|
blather/stanza/iq/roster
|
31
|
+
blather/stanza/iq/ibb
|
32
|
+
blather/stanza/iq/s5b
|
33
|
+
blather/stanza/iq/si
|
34
|
+
blather/stanza/iq/vcard
|
27
35
|
blather/stanza/disco
|
28
36
|
blather/stanza/disco/disco_info
|
29
37
|
blather/stanza/disco/disco_items
|
@@ -112,9 +112,17 @@ module Blather
|
|
112
112
|
@tmp_handlers[id.to_s] = handler
|
113
113
|
end
|
114
114
|
|
115
|
+
# Clear handlers with given guards
|
116
|
+
#
|
117
|
+
# @param [Symbol, nil] type remove filters for a specific handler
|
118
|
+
# @param [guards] guards take a look at the guards documentation
|
119
|
+
def clear_handlers(type, *guards)
|
120
|
+
@handlers[type].delete_if { |g, _| g == guards }
|
121
|
+
end
|
122
|
+
|
115
123
|
# Register a handler
|
116
124
|
#
|
117
|
-
# @param [Symbol, nil]
|
125
|
+
# @param [Symbol, nil] type set the filter on a specific handler
|
118
126
|
# @param [guards] guards take a look at the guards documentation
|
119
127
|
# @yield [Blather::Stanza] stanza the incomming stanza
|
120
128
|
def register_handler(type, *guards, &handler)
|
@@ -87,9 +87,9 @@ module DSL
|
|
87
87
|
# Defaults to the stripped current JID
|
88
88
|
# @param [#to_s] host the PubSub host (defaults to the initialized host)
|
89
89
|
# @yield [Blather::Stanza] stanza the reply stanza
|
90
|
-
def unsubscribe(node, jid = nil, host = nil)
|
90
|
+
def unsubscribe(node, jid = nil, subid = nil, host = nil)
|
91
91
|
jid ||= client.jid.stripped
|
92
|
-
stanza = Stanza::PubSub::Unsubscribe.new(:set, send_to(host), node, jid)
|
92
|
+
stanza = Stanza::PubSub::Unsubscribe.new(:set, send_to(host), node, jid, subid)
|
93
93
|
request(stanza) { |n| yield n if block_given? }
|
94
94
|
end
|
95
95
|
|
@@ -0,0 +1,122 @@
|
|
1
|
+
module EventMachine
|
2
|
+
module Protocols
|
3
|
+
# Basic SOCKS v5 client implementation
|
4
|
+
#
|
5
|
+
# Use as you would any regular connection:
|
6
|
+
#
|
7
|
+
# class MyConn < EM::P::Socks5
|
8
|
+
# def post_init
|
9
|
+
# send_data("sup")
|
10
|
+
# end
|
11
|
+
#
|
12
|
+
# def receive_data(data)
|
13
|
+
# send_data("you said: #{data}")
|
14
|
+
# end
|
15
|
+
# end
|
16
|
+
#
|
17
|
+
# EM.connect socks_host, socks_port, MyConn, host, port
|
18
|
+
#
|
19
|
+
class Socks5 < Connection
|
20
|
+
def initialize(host, port)
|
21
|
+
@host = host
|
22
|
+
@port = port
|
23
|
+
@socks_error_code = nil
|
24
|
+
@buffer = ''
|
25
|
+
@socks_state = :method_negotiation
|
26
|
+
@socks_methods = [0] # TODO: other authentication methods
|
27
|
+
setup_methods
|
28
|
+
end
|
29
|
+
|
30
|
+
def setup_methods
|
31
|
+
class << self
|
32
|
+
def post_init; socks_post_init; end
|
33
|
+
def receive_data(*a); socks_receive_data(*a); end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def restore_methods
|
38
|
+
class << self
|
39
|
+
remove_method :post_init
|
40
|
+
remove_method :receive_data
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def socks_post_init
|
45
|
+
packet = [5, @socks_methods.size].pack('CC') + @socks_methods.pack('C*')
|
46
|
+
send_data(packet)
|
47
|
+
end
|
48
|
+
|
49
|
+
def socks_receive_data(data)
|
50
|
+
@buffer << data
|
51
|
+
|
52
|
+
if @socks_state == :method_negotiation
|
53
|
+
return if @buffer.size < 2
|
54
|
+
|
55
|
+
header_resp = @buffer.slice! 0, 2
|
56
|
+
_, method_code = header_resp.unpack("cc")
|
57
|
+
|
58
|
+
if @socks_methods.include?(method_code)
|
59
|
+
@socks_state = :connecting
|
60
|
+
packet = [5, 1, 0].pack("C*")
|
61
|
+
|
62
|
+
if @host =~ /^(\d+)\.(\d+)\.(\d+)\.(\d+)$/ # IPv4
|
63
|
+
packet << [1, $1.to_i, $2.to_i, $3.to_i, $4.to_i].pack("C*")
|
64
|
+
elsif @host.include?(":") # IPv6
|
65
|
+
l, r = if @host =~ /^(.*)::(.*)$/
|
66
|
+
[$1,$2].map {|i| i.split ":"}
|
67
|
+
else
|
68
|
+
[@host.split(":"),[]]
|
69
|
+
end
|
70
|
+
dec_groups = (l + Array.new(8-l.size-r.size, '0') + r).map {|i| i.hex}
|
71
|
+
packet << ([4] + dec_groups).pack("Cn8")
|
72
|
+
else # Domain
|
73
|
+
packet << [3, @host.length, @host].pack("CCA*")
|
74
|
+
end
|
75
|
+
packet << [@port].pack("n")
|
76
|
+
|
77
|
+
send_data packet
|
78
|
+
else
|
79
|
+
@socks_state = :invalid
|
80
|
+
@socks_error_code = method_code
|
81
|
+
close_connection
|
82
|
+
return
|
83
|
+
end
|
84
|
+
elsif @socks_state == :connecting
|
85
|
+
return if @buffer.size < 4
|
86
|
+
|
87
|
+
header_resp = @buffer.slice! 0, 4
|
88
|
+
_, response_code, _, address_type = header_resp.unpack("C*")
|
89
|
+
|
90
|
+
if response_code == 0
|
91
|
+
case address_type
|
92
|
+
when 1
|
93
|
+
@buffer.slice! 0, 4
|
94
|
+
when 3
|
95
|
+
len = @buffer.slice! 0, 1
|
96
|
+
@buffer.slice! 0, len.unpack("C").first
|
97
|
+
when 4
|
98
|
+
@buffer.slice! 0, 16
|
99
|
+
else
|
100
|
+
@socks_state = :invalid
|
101
|
+
@socks_error_code = address_type
|
102
|
+
close_connection
|
103
|
+
return
|
104
|
+
end
|
105
|
+
@buffer.slice! 0, 2
|
106
|
+
|
107
|
+
@socks_state = :connected
|
108
|
+
restore_methods
|
109
|
+
|
110
|
+
post_init
|
111
|
+
receive_data(@buffer) unless @buffer.empty?
|
112
|
+
else
|
113
|
+
@socks_state = :invalid
|
114
|
+
@socks_error_code = response_code
|
115
|
+
close_connection
|
116
|
+
return
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
@@ -0,0 +1,100 @@
|
|
1
|
+
module Blather
|
2
|
+
# File Transfer helper
|
3
|
+
# Takes care of accepting, declining and offering file transfers through the stream
|
4
|
+
class FileTransfer
|
5
|
+
|
6
|
+
# Set this to false if you don't want to use In-Band Bytestreams
|
7
|
+
attr_accessor :allow_ibb
|
8
|
+
|
9
|
+
# Set this to false if you don't want to use SOCKS5 Bytestreams
|
10
|
+
attr_accessor :allow_s5b
|
11
|
+
|
12
|
+
# Create a new FileTransfer
|
13
|
+
#
|
14
|
+
# @param [Blather::Stream] stream the stream the file transfer should use
|
15
|
+
# @param [Blather::Stanza::Iq::Si] iq a si iq used to stream-initiation
|
16
|
+
def initialize(stream, iq = nil)
|
17
|
+
@stream = stream
|
18
|
+
@allow_s5b = true
|
19
|
+
@allow_ibb = true
|
20
|
+
|
21
|
+
@iq = iq
|
22
|
+
end
|
23
|
+
|
24
|
+
# Accept an incoming file-transfer
|
25
|
+
#
|
26
|
+
# @param [module] handler the handler for incoming data, see Blather::FileTransfer::SimpleFileReceiver for an example
|
27
|
+
# @param [Array] params the params to be passed into the handler
|
28
|
+
def accept(handler, *params)
|
29
|
+
answer = @iq.reply
|
30
|
+
|
31
|
+
answer.si.feature.x.type = :submit
|
32
|
+
|
33
|
+
supported_methods = @iq.si.feature.x.field("stream-method").options.map(&:value)
|
34
|
+
if supported_methods.include?(Stanza::Iq::S5b::NS_S5B) and @allow_s5b
|
35
|
+
answer.si.feature.x.fields = {:var => 'stream-method', :value => Stanza::Iq::S5b::NS_S5B}
|
36
|
+
|
37
|
+
@stream.register_handler :s5b_open, :from => @iq.from do |iq|
|
38
|
+
transfer = Blather::FileTransfer::S5b.new(@stream, iq)
|
39
|
+
transfer.allow_ibb_fallback = true if @allow_ibb
|
40
|
+
transfer.accept(handler, *params)
|
41
|
+
true
|
42
|
+
end
|
43
|
+
|
44
|
+
@stream.write answer
|
45
|
+
elsif supported_methods.include?(Stanza::Iq::Ibb::NS_IBB) and @allow_ibb
|
46
|
+
answer.si.feature.x.fields = {:var => 'stream-method', :value => Stanza::Iq::Ibb::NS_IBB}
|
47
|
+
|
48
|
+
@stream.register_handler :ibb_open, :from => @iq.from do |iq|
|
49
|
+
transfer = Blather::FileTransfer::Ibb.new(@stream, iq)
|
50
|
+
transfer.accept(handler, *params)
|
51
|
+
true
|
52
|
+
end
|
53
|
+
|
54
|
+
@stream.write answer
|
55
|
+
else
|
56
|
+
reason = XMPPNode.new('no-valid-streams')
|
57
|
+
reason.namespace = Blather::Stanza::Iq::Si::NS_SI
|
58
|
+
|
59
|
+
@stream.write StanzaError.new(@iq, 'bad-request', 'cancel', nil, [reason]).to_node
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
# Decline an incoming file-transfer
|
64
|
+
def decline
|
65
|
+
answer = StanzaError.new(@iq, 'forbidden', 'cancel', 'Offer declined').to_node
|
66
|
+
|
67
|
+
@stream.write answer
|
68
|
+
end
|
69
|
+
|
70
|
+
# Offer a file to somebody, not implemented yet
|
71
|
+
def offer
|
72
|
+
# TODO: implement
|
73
|
+
end
|
74
|
+
|
75
|
+
# Simple handler for incoming file transfers
|
76
|
+
#
|
77
|
+
# You can define your own handler and pass it to the accept method.
|
78
|
+
module SimpleFileReceiver
|
79
|
+
def initialize(path, size)
|
80
|
+
@path = path
|
81
|
+
@size = size
|
82
|
+
@transferred = 0
|
83
|
+
end
|
84
|
+
|
85
|
+
def post_init
|
86
|
+
@file = File.open(@path, "w")
|
87
|
+
end
|
88
|
+
|
89
|
+
def receive_data(data)
|
90
|
+
@transferred += data.size
|
91
|
+
@file.write data
|
92
|
+
end
|
93
|
+
|
94
|
+
def unbind
|
95
|
+
@file.close
|
96
|
+
File.delete(@path) unless @transferred == @size
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
require "base64"
|
2
|
+
|
3
|
+
module Blather
|
4
|
+
class FileTransfer
|
5
|
+
# In-Band Bytestreams Transfer helper
|
6
|
+
# Takes care of accepting, declining and offering file transfers through the stream
|
7
|
+
class Ibb
|
8
|
+
def initialize(stream, iq)
|
9
|
+
@stream = stream
|
10
|
+
@iq = iq
|
11
|
+
@seq = 0
|
12
|
+
end
|
13
|
+
|
14
|
+
# Accept an incoming file-transfer
|
15
|
+
#
|
16
|
+
# @param [module] handler the handler for incoming data, see Blather::FileTransfer::SimpleFileReceiver for an example
|
17
|
+
# @param [Array] params the params to be passed into the handler
|
18
|
+
def accept(handler, *params)
|
19
|
+
@io_read, @io_write = IO.pipe
|
20
|
+
EM::attach @io_read, handler, *params
|
21
|
+
|
22
|
+
@stream.register_handler :ibb_data, :from => @iq.from, :sid => @iq.sid do |iq|
|
23
|
+
if iq.data['seq'] == @seq.to_s
|
24
|
+
begin
|
25
|
+
@io_write << Base64.decode64(iq.data.content)
|
26
|
+
|
27
|
+
@stream.write iq.reply
|
28
|
+
|
29
|
+
@seq += 1
|
30
|
+
@seq = 0 if @seq > 65535
|
31
|
+
rescue Errno::EPIPE => e
|
32
|
+
@stream.write StanzaError.new(iq, 'not-acceptable', :cancel).to_node
|
33
|
+
end
|
34
|
+
else
|
35
|
+
@stream.write StanzaError.new(iq, 'unexpected-request', :wait).to_node
|
36
|
+
end
|
37
|
+
true
|
38
|
+
end
|
39
|
+
|
40
|
+
@stream.register_handler :ibb_close, :from => @iq.from, :sid => @iq.sid do |iq|
|
41
|
+
@stream.write iq.reply
|
42
|
+
@stream.clear_handlers :ibb_data, :from => @iq.from, :sid => @iq.sid
|
43
|
+
@stream.clear_handlers :ibb_close, :from => @iq.from, :sid => @iq.sid
|
44
|
+
|
45
|
+
@io_write.close
|
46
|
+
true
|
47
|
+
end
|
48
|
+
|
49
|
+
@stream.clear_handlers :ibb_open, :from => @iq.from
|
50
|
+
@stream.clear_handlers :ibb_open, :from => @iq.from, :sid => @iq.sid
|
51
|
+
@stream.write @iq.reply
|
52
|
+
end
|
53
|
+
|
54
|
+
# Decline an incoming file-transfer
|
55
|
+
def decline
|
56
|
+
@stream.clear_handlers :ibb_open, :from => @iq.from
|
57
|
+
@stream.clear_handlers :ibb_data, :from => @iq.from, :sid => @iq.sid
|
58
|
+
@stream.clear_handlers :ibb_close, :from => @iq.from, :sid => @iq.sid
|
59
|
+
@stream.write StanzaError.new(@iq, 'not-acceptable', :cancel).to_node
|
60
|
+
end
|
61
|
+
|
62
|
+
# Offer a file to somebody, not implemented yet
|
63
|
+
def offer
|
64
|
+
# TODO: implement
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
@@ -0,0 +1,104 @@
|
|
1
|
+
module Blather
|
2
|
+
class FileTransfer
|
3
|
+
# SOCKS5 Bytestreams Transfer helper
|
4
|
+
# Takes care of accepting, declining and offering file transfers through the stream
|
5
|
+
class S5b
|
6
|
+
|
7
|
+
# Set this to false if you don't want to fallback to In-Band Bytestreams
|
8
|
+
attr_accessor :allow_ibb_fallback
|
9
|
+
|
10
|
+
def initialize(stream, iq)
|
11
|
+
@stream = stream
|
12
|
+
@iq = iq
|
13
|
+
@allow_ibb_fallback = true
|
14
|
+
end
|
15
|
+
|
16
|
+
# Accept an incoming file-transfer
|
17
|
+
#
|
18
|
+
# @param [module] handler the handler for incoming data, see Blather::FileTransfer::SimpleFileReceiver for an example
|
19
|
+
# @param [Array] params the params to be passed into the handler
|
20
|
+
def accept(handler, *params)
|
21
|
+
@streamhosts = @iq.streamhosts
|
22
|
+
@socket_address = Digest::SHA1.hexdigest("#{@iq.sid}#{@iq.from}#{@iq.to}")
|
23
|
+
|
24
|
+
@handler = handler
|
25
|
+
@params = params
|
26
|
+
|
27
|
+
connect_next_streamhost
|
28
|
+
@stream.clear_handlers :s5b_open, :from => @iq.from
|
29
|
+
end
|
30
|
+
|
31
|
+
# Decline an incoming file-transfer
|
32
|
+
def decline
|
33
|
+
@stream.clear_handlers :s5b_open, :from => @iq.from
|
34
|
+
@stream.write StanzaError.new(@iq, 'not-acceptable', :auth).to_node
|
35
|
+
end
|
36
|
+
|
37
|
+
# Offer a file to somebody, not implemented yet
|
38
|
+
def offer
|
39
|
+
# TODO: implement
|
40
|
+
end
|
41
|
+
|
42
|
+
private
|
43
|
+
|
44
|
+
def connect_next_streamhost
|
45
|
+
if streamhost = @streamhosts.shift
|
46
|
+
connect(streamhost)
|
47
|
+
else
|
48
|
+
if @allow_ibb_fallback
|
49
|
+
@stream.register_handler :ibb_open, :from => @iq.from, :sid => @iq.sid do |iq|
|
50
|
+
transfer = Blather::FileTransfer::Ibb.new(@stream, iq)
|
51
|
+
transfer.accept(@handler, *@params)
|
52
|
+
true
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
@stream.write StanzaError.new(@iq, 'item-not-found', :cancel).to_node
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def connect(streamhost)
|
61
|
+
begin
|
62
|
+
socket = EM.connect streamhost.host, streamhost.port, SocketConnection, @socket_address, 0, @handler, *@params
|
63
|
+
|
64
|
+
socket.callback do
|
65
|
+
answer = @iq.reply
|
66
|
+
answer.streamhosts = nil
|
67
|
+
answer.streamhost_used = streamhost.jid
|
68
|
+
|
69
|
+
@stream.write answer
|
70
|
+
end
|
71
|
+
|
72
|
+
socket.errback do
|
73
|
+
connect_next_streamhost
|
74
|
+
end
|
75
|
+
rescue EventMachine::ConnectionError => e
|
76
|
+
connect_next_streamhost
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
class SocketConnection < EM::P::Socks5
|
81
|
+
include EM::Deferrable
|
82
|
+
|
83
|
+
def initialize(host, port, handler, *params)
|
84
|
+
super(host, port)
|
85
|
+
@@handler = handler
|
86
|
+
@params = params
|
87
|
+
end
|
88
|
+
|
89
|
+
def post_init
|
90
|
+
self.succeed
|
91
|
+
class << self
|
92
|
+
include @@handler
|
93
|
+
end
|
94
|
+
send(:initialize, *@params)
|
95
|
+
post_init
|
96
|
+
end
|
97
|
+
|
98
|
+
def unbind
|
99
|
+
self.fail if @socks_state != :connected
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|