cancer 0.1.0.a1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (89) hide show
  1. data/.autotest +3 -0
  2. data/.gitignore +5 -0
  3. data/LICENSE.txt +22 -0
  4. data/Rakefile +46 -0
  5. data/VERSION +1 -0
  6. data/cancer.gemspec +156 -0
  7. data/documentation/STREAM_INITIATION.markdown +18 -0
  8. data/examples/example.rb +80 -0
  9. data/examples/example_2.rb +20 -0
  10. data/examples/example_em.rb +11 -0
  11. data/examples/example_em_helper.rb +23 -0
  12. data/examples/example_im_roster.rb +26 -0
  13. data/examples/example_xep_0004.rb +124 -0
  14. data/examples/example_xep_0047.rb +35 -0
  15. data/examples/example_xep_0050.rb +78 -0
  16. data/examples/example_xep_0065.rb +66 -0
  17. data/examples/example_xep_0096.dup.rb +40 -0
  18. data/examples/example_xep_0096_xep_0047.rb +42 -0
  19. data/examples/example_xep_0096_xep_0065.rb +40 -0
  20. data/lib/cancer.rb +122 -0
  21. data/lib/cancer/adapter.rb +33 -0
  22. data/lib/cancer/adapters/em.rb +88 -0
  23. data/lib/cancer/adapters/socket.rb +122 -0
  24. data/lib/cancer/builder.rb +28 -0
  25. data/lib/cancer/controller.rb +32 -0
  26. data/lib/cancer/dependencies.rb +187 -0
  27. data/lib/cancer/events/abstract_event.rb +10 -0
  28. data/lib/cancer/events/base_matchers.rb +63 -0
  29. data/lib/cancer/events/binary_matchers.rb +30 -0
  30. data/lib/cancer/events/eventable.rb +92 -0
  31. data/lib/cancer/events/exception_events.rb +28 -0
  32. data/lib/cancer/events/handler.rb +33 -0
  33. data/lib/cancer/events/manager.rb +130 -0
  34. data/lib/cancer/events/named_events.rb +25 -0
  35. data/lib/cancer/events/proc_matcher.rb +16 -0
  36. data/lib/cancer/events/xml_events.rb +44 -0
  37. data/lib/cancer/exceptions.rb +53 -0
  38. data/lib/cancer/jid.rb +215 -0
  39. data/lib/cancer/lock.rb +32 -0
  40. data/lib/cancer/spec.rb +35 -0
  41. data/lib/cancer/spec/error.rb +18 -0
  42. data/lib/cancer/spec/extentions.rb +79 -0
  43. data/lib/cancer/spec/matcher.rb +30 -0
  44. data/lib/cancer/spec/mock_adapter.rb +139 -0
  45. data/lib/cancer/spec/mock_stream.rb +15 -0
  46. data/lib/cancer/spec/transcript.rb +107 -0
  47. data/lib/cancer/stream.rb +182 -0
  48. data/lib/cancer/stream/builder.rb +20 -0
  49. data/lib/cancer/stream/controller.rb +36 -0
  50. data/lib/cancer/stream/event_helper.rb +12 -0
  51. data/lib/cancer/stream/xep.rb +52 -0
  52. data/lib/cancer/stream_parser.rb +144 -0
  53. data/lib/cancer/support.rb +27 -0
  54. data/lib/cancer/support/hash.rb +32 -0
  55. data/lib/cancer/support/string.rb +22 -0
  56. data/lib/cancer/synchronized_stanza.rb +79 -0
  57. data/lib/cancer/thread_pool.rb +118 -0
  58. data/lib/cancer/xep.rb +43 -0
  59. data/lib/cancer/xeps/core.rb +109 -0
  60. data/lib/cancer/xeps/core/bind.rb +33 -0
  61. data/lib/cancer/xeps/core/sasl.rb +113 -0
  62. data/lib/cancer/xeps/core/session.rb +22 -0
  63. data/lib/cancer/xeps/core/stream.rb +18 -0
  64. data/lib/cancer/xeps/core/terminator.rb +21 -0
  65. data/lib/cancer/xeps/core/tls.rb +34 -0
  66. data/lib/cancer/xeps/im.rb +323 -0
  67. data/lib/cancer/xeps/xep_0004_x_data.rb +692 -0
  68. data/lib/cancer/xeps/xep_0020_feature_neg.rb +35 -0
  69. data/lib/cancer/xeps/xep_0030_disco.rb +167 -0
  70. data/lib/cancer/xeps/xep_0047_ibb.rb +322 -0
  71. data/lib/cancer/xeps/xep_0050_commands.rb +256 -0
  72. data/lib/cancer/xeps/xep_0065_bytestreams.rb +306 -0
  73. data/lib/cancer/xeps/xep_0066_oob.rb +69 -0
  74. data/lib/cancer/xeps/xep_0095_si.rb +211 -0
  75. data/lib/cancer/xeps/xep_0096_si_filetransfer.rb +173 -0
  76. data/lib/cancer/xeps/xep_0114_component.rb +73 -0
  77. data/lib/cancer/xeps/xep_0115_caps.rb +180 -0
  78. data/lib/cancer/xeps/xep_0138_compress.rb +134 -0
  79. data/lib/cancer/xeps/xep_0144_rosterx.rb +250 -0
  80. data/lib/cancer/xeps/xep_0184_receipts.rb +40 -0
  81. data/lib/cancer/xeps/xep_0199_ping.rb +41 -0
  82. data/spec/spec.opts +2 -0
  83. data/spec/spec_helper.rb +14 -0
  84. data/spec/stream/stanza_errors_spec.rb +47 -0
  85. data/spec/stream/stream_errors_spec.rb +38 -0
  86. data/spec/stream/stream_initialization_spec.rb +160 -0
  87. data/spec/xep_0050/local_spec.rb +165 -0
  88. data/spec/xep_0050/remote_spec.rb +44 -0
  89. metadata +200 -0
@@ -0,0 +1,35 @@
1
+ require '../lib/cancer'
2
+
3
+ Cancer.logger.level = Logger::WARN
4
+
5
+ # a client
6
+ Cancer::Stream.open(:jid => 'alice@xmpp.dev/bbb', :password => 'ihatethequeen', :xeps => %w( xep-0047 ), :server => 'xmpp.dev') do |other|
7
+ other.controller do
8
+
9
+ on { |e| e.ibb }
10
+ def ibb(e)
11
+ e.accept! do |f|
12
+ print f.readpartial(4096) until f.eof?
13
+ end
14
+ end
15
+
16
+ end
17
+ other.send {|x| x.presence(:priority => 10) }
18
+
19
+ Cancer::Stream.open(:jid => 'alice@xmpp.dev/aaa', :password => 'ihatethequeen', :xeps => %w( xep-0047 ), :server => 'xmpp.dev') do |stream|
20
+
21
+ stream.send {|x| x.presence(:priority => 5) }
22
+
23
+ stream.open_ibb('alice@xmpp.dev/bbb') do |f|
24
+ f.puts "hello"
25
+ f.puts "hello hans"
26
+ f.puts "hello bram"
27
+ f.puts "hello hans 2"
28
+ end
29
+
30
+ stream.send {|x| x.presence(:type => :unavailable) }
31
+
32
+ end
33
+
34
+ other.send {|x| x.presence(:type => :unavailable) }
35
+ end
@@ -0,0 +1,78 @@
1
+ require 'pp'
2
+ require '../lib/cancer'
3
+
4
+ Cancer.logger.level = Logger::WARN
5
+
6
+ Cancer::Stream.open(:jid => 'alice@xmpp.dev/aaa', :password => 'ihatethequeen', :xeps => %w( xep-0050 ), :server => 'xmpp.dev') do |stream|
7
+
8
+ stream.send {|x| x.presence(:priority => 5) }
9
+
10
+ # stream.commands_provided_by('xmpp.dev').each do |k,v|
11
+ # puts "#{v}: #{k}"
12
+ # end
13
+
14
+ cmd = 'http://jabber.org/protocol/admin#add-user'
15
+ stream.command('xmpp.dev', cmd) do |session|
16
+
17
+ puts "EXECUTING: #{cmd}"
18
+ form = session.execute!
19
+ puts "STATUS: #{session.status}"
20
+ form['given_name'] = ''
21
+ form['surname'] = ''
22
+ form['email'] = ''
23
+ form['accountjid'] = 'hans@xmpp.dev'
24
+ form['password-verify'] = 'hanz'
25
+ form['password'] = 'hanz'
26
+ session.complete!(form)
27
+ puts "STATUS: #{session.status}"
28
+ puts
29
+
30
+ end
31
+
32
+ cmd = 'http://jabber.org/protocol/admin#add-group'
33
+ stream.command('xmpp.dev', cmd) do |session|
34
+
35
+ puts "EXECUTING: #{cmd}"
36
+ form = session.execute!
37
+ puts "STATUS: #{session.status}"
38
+ form['group'] = 'My-Cool-Group'
39
+ form['displayName'] = 'My Cool Group'
40
+ form['members'] = ['simon@xmpp.dev', 'alice@xmpp.dev']
41
+ form['showInRoster'] = 'onlyGroup'
42
+ session.complete!(form)
43
+ puts "STATUS: #{session.status}"
44
+ puts
45
+
46
+ end
47
+
48
+ cmd = 'http://jabber.org/protocol/admin#get-groups'
49
+ stream.command('xmpp.dev', cmd) do |session|
50
+
51
+ puts "EXECUTING: #{cmd}"
52
+ form = session.execute!
53
+ puts "STATUS: #{session.status}"
54
+ form = session.complete!(form)
55
+ puts "STATUS: #{session.status}"
56
+ form.items.each do |item|
57
+ puts "#{item['name'].inspect} members:#{item['count']} shared:#{item['shared'].inspect}"
58
+ end
59
+ puts
60
+
61
+ end
62
+
63
+ cmd = 'http://jabber.org/protocol/admin#delete-group'
64
+ stream.command('xmpp.dev', cmd) do |session|
65
+
66
+ puts "EXECUTING: #{cmd}"
67
+ form = session.execute!
68
+ puts "STATUS: #{session.status}"
69
+ form['group'] = 'My-Cool-Group'
70
+ session.complete!(form)
71
+ puts "STATUS: #{session.status}"
72
+ puts
73
+
74
+ end
75
+
76
+ stream.send {|x| x.presence(:type => :unavailable) }
77
+
78
+ end
@@ -0,0 +1,66 @@
1
+ require '../lib/cancer'
2
+
3
+ # Cancer.logger.level = Logger::WARN
4
+
5
+ # a client
6
+ Cancer::Stream.open(:jid => 'alice@xmpp.dev/bbb', :password => 'ihatethequeen', :xeps => %w( xep-0065 ), :server => 'xmpp.dev') do |other|
7
+ other.controller do
8
+
9
+ on { |e| e.socks5_bytestream }
10
+ def socks5_bytestream(e)
11
+ e.accept! do |f|
12
+ until f.closed?
13
+ begin
14
+ puts "ok"
15
+ if (s = f.recv_nonblock(100))
16
+ puts s
17
+ end
18
+ rescue Errno::EAGAIN
19
+ IO.select([f], nil, nil, 3)
20
+ rescue Exception => e
21
+ Cancer.logger.info e
22
+ end
23
+ end
24
+ begin
25
+ sleep 3
26
+ f.write "hello"
27
+ f.write "hello hans"
28
+ f.write "hello bram"
29
+ f.write "hello hans 2"
30
+ f.close
31
+ puts "ok"
32
+ rescue Exception => e
33
+ Cancer.logger.info e
34
+ end
35
+ end
36
+ end
37
+
38
+ end
39
+ other.send {|x| x.presence(:priority => 10) }
40
+
41
+ Cancer::Stream.open(:jid => 'alice@xmpp.dev/aaa', :password => 'ihatethequeen', :xeps => %w( xep-0065 ), :server => 'xmpp.dev') do |stream|
42
+
43
+ stream.send {|x| x.presence(:priority => 5) }
44
+
45
+ stream.open_socks5_bytestream('alice@xmpp.dev/bbb') do |f|
46
+ f.write "cool"
47
+ until f.closed?
48
+ begin
49
+ puts "ok"
50
+ if (s = f.recv_nonblock(100))
51
+ puts s
52
+ end
53
+ rescue Errno::EAGAIN
54
+ IO.select([f], nil, nil, 3)
55
+ rescue Exception => e
56
+ Cancer.logger.info e
57
+ end
58
+ end
59
+ end
60
+
61
+ stream.send {|x| x.presence(:type => :unavailable) }
62
+
63
+ end
64
+
65
+ other.send {|x| x.presence(:type => :unavailable) }
66
+ end
@@ -0,0 +1,40 @@
1
+ require '../lib/cancer'
2
+
3
+ # Cancer.logger.level = Logger::WARN
4
+
5
+ # a client
6
+ Cancer::Stream.open(:jid => 'alice@xmpp.dev/bbb', :password => 'ihatethequeen', :xeps => %w( xep-0096 xep-0065 ), :server => 'xmpp.dev') do |other|
7
+ other.controller do
8
+
9
+ on { |e| e.si_file(:filename => /\.rb$/) }
10
+ def transfer_gem(e)
11
+ e.accept! :path => File.join(File.dirname(__FILE__), 'example_xep_0096.dup.rb')
12
+ end
13
+
14
+ on { |e| e.exception(Exception) }
15
+ def err(e)
16
+ Cancer.logger.error e.exception
17
+ end
18
+
19
+ end
20
+ other.send {|x| x.presence(:priority => 10) }
21
+
22
+ Cancer::Stream.open(:jid => 'alice@xmpp.dev/aaa', :password => 'ihatethequeen', :xeps => %w( xep-0096 xep-0065 ), :server => 'xmpp.dev') do |stream|
23
+
24
+ stream.controller do
25
+ on { |e| e.exception(Exception) }
26
+ def err(e)
27
+ Cancer.logger.error e.exception
28
+ end
29
+ end
30
+
31
+ stream.send {|x| x.presence(:priority => 5) }
32
+
33
+ stream.si_file_offer('alice@xmpp.dev/bbb', __FILE__)
34
+
35
+ stream.send {|x| x.presence(:type => :unavailable) }
36
+
37
+ end
38
+
39
+ other.send {|x| x.presence(:type => :unavailable) }
40
+ end
@@ -0,0 +1,42 @@
1
+ require '../lib/cancer'
2
+
3
+ Cancer.logger.level = Logger::WARN
4
+
5
+ #hello cool
6
+
7
+ # a client
8
+ Cancer::Stream.open(:jid => 'alice@xmpp.dev/bbb', :password => 'ihatethequeen', :xeps => %w( xep-0096 xep-0047 ), :server => 'xmpp.dev') do |other|
9
+ other.controller do
10
+
11
+ on { |e| e.si_file(:filename => /\.rb$/) }
12
+ def transfer_gem(e)
13
+ e.accept! :path => File.join(File.dirname(__FILE__), 'example_xep_0096.dup.rb')
14
+ end
15
+
16
+ on { |e| e.exception(Exception) }
17
+ def err(e)
18
+ Cancer.logger.error e.exception
19
+ end
20
+
21
+ end
22
+ other.send {|x| x.presence(:priority => 10) }
23
+
24
+ Cancer::Stream.open(:jid => 'alice@xmpp.dev/aaa', :password => 'ihatethequeen', :xeps => %w( xep-0096 xep-0047 ), :server => 'xmpp.dev') do |stream|
25
+
26
+ stream.controller do
27
+ on { |e| e.exception(Exception) }
28
+ def err(e)
29
+ Cancer.logger.error e.exception
30
+ end
31
+ end
32
+
33
+ stream.send {|x| x.presence(:priority => 5) }
34
+
35
+ stream.si_file_offer('alice@xmpp.dev/bbb', __FILE__)
36
+
37
+ stream.send {|x| x.presence(:type => :unavailable) }
38
+
39
+ end
40
+
41
+ other.send {|x| x.presence(:type => :unavailable) }
42
+ end
@@ -0,0 +1,40 @@
1
+ require '../lib/cancer'
2
+
3
+ # Cancer.logger.level = Logger::WARN
4
+
5
+ # a client
6
+ Cancer::Stream.open(:jid => 'alice@xmpp.dev/bbb', :password => 'ihatethequeen', :xeps => %w( xep-0096 xep-0065 ), :server => 'xmpp.dev') do |other|
7
+ other.controller do
8
+
9
+ on { |e| e.si_file(:filename => /\.rb$/) }
10
+ def transfer_gem(e)
11
+ e.accept! :path => File.join(File.dirname(__FILE__), 'example_xep_0096.dup.rb')
12
+ end
13
+
14
+ on { |e| e.exception(Exception) }
15
+ def err(e)
16
+ Cancer.logger.error e.exception
17
+ end
18
+
19
+ end
20
+ other.send {|x| x.presence(:priority => 10) }
21
+
22
+ Cancer::Stream.open(:jid => 'alice@xmpp.dev/aaa', :password => 'ihatethequeen', :xeps => %w( xep-0096 xep-0065 ), :server => 'xmpp.dev') do |stream|
23
+
24
+ stream.controller do
25
+ on { |e| e.exception(Exception) }
26
+ def err(e)
27
+ Cancer.logger.error e.exception
28
+ end
29
+ end
30
+
31
+ stream.send {|x| x.presence(:priority => 5) }
32
+
33
+ stream.si_file_offer('alice@xmpp.dev/bbb', __FILE__)
34
+
35
+ stream.send {|x| x.presence(:type => :unavailable) }
36
+
37
+ end
38
+
39
+ other.send {|x| x.presence(:type => :unavailable) }
40
+ end
@@ -0,0 +1,122 @@
1
+
2
+ $:.unshift(File.expand_path(File.dirname(__FILE__))) unless $:.include?(File.expand_path(File.dirname(__FILE__)))
3
+
4
+ require 'rubygems'
5
+ require 'nokogiri'
6
+ require 'logger'
7
+
8
+ module Cancer
9
+
10
+ autoload :XEP, 'cancer/xep'
11
+ autoload :JID, 'cancer/jid'
12
+ autoload :Lock, 'cancer/lock'
13
+ autoload :Spec, 'cancer/spec'
14
+ autoload :Stream, 'cancer/stream'
15
+ autoload :Support, 'cancer/support'
16
+ autoload :Builder, 'cancer/builder'
17
+ autoload :Controller, 'cancer/controller'
18
+ autoload :ThreadPool, 'cancer/thread_pool'
19
+ autoload :Dependencies, 'cancer/dependencies'
20
+ autoload :StreamParser, 'cancer/stream_parser'
21
+ autoload :SynchronizedStanza, 'cancer/synchronized_stanza'
22
+
23
+ autoload :CancerError, 'cancer/exceptions'
24
+ autoload :XMPPError, 'cancer/exceptions'
25
+ autoload :StreamError, 'cancer/exceptions'
26
+ autoload :StanzaError, 'cancer/exceptions'
27
+
28
+ autoload :StanzaCancelError, 'cancer/exceptions'
29
+ autoload :StanzaContinueError,'cancer/exceptions'
30
+ autoload :StanzaModifyError, 'cancer/exceptions'
31
+ autoload :StanzaAuthError, 'cancer/exceptions'
32
+ autoload :StanzaWaitError, 'cancer/exceptions'
33
+
34
+ autoload :Adapter, 'cancer/adapter'
35
+ module Adapters
36
+ autoload :Socket, 'cancer/adapters/socket'
37
+ autoload :EM, 'cancer/adapters/em'
38
+ end
39
+
40
+ module Support
41
+ autoload :Hash, 'cancer/support/hash'
42
+ autoload :String, 'cancer/support/string'
43
+ end
44
+
45
+ module Events
46
+ autoload :AbstractEvent, 'cancer/events/abstract_event'
47
+ autoload :Eventable, 'cancer/events/eventable'
48
+ autoload :Handler, 'cancer/events/handler'
49
+ autoload :Manager, 'cancer/events/manager'
50
+ autoload :Matcher, 'cancer/events/base_matchers'
51
+ autoload :UnaryMatcher, 'cancer/events/base_matchers'
52
+ autoload :BinaryMatcher, 'cancer/events/base_matchers'
53
+ autoload :AnyMatcher, 'cancer/events/base_matchers'
54
+ autoload :OrMatcher, 'cancer/events/binary_matchers'
55
+ autoload :AndMatcher, 'cancer/events/binary_matchers'
56
+ autoload :XorMatcher, 'cancer/events/binary_matchers'
57
+ autoload :NotMatcher, 'cancer/events/binary_matchers'
58
+ autoload :NamedMatcher, 'cancer/events/named_events'
59
+ autoload :NamedEvent, 'cancer/events/named_events'
60
+ autoload :XPathMatcher, 'cancer/events/xml_events'
61
+ autoload :XMLEvent, 'cancer/events/xml_events'
62
+ autoload :StanzaEvent, 'cancer/events/xml_events'
63
+ autoload :ProcMatcher, 'cancer/events/proc_matcher'
64
+ autoload :ExceptionMatcher, 'cancer/events/exception_events'
65
+ autoload :ExceptionEvent, 'cancer/events/exception_events'
66
+ end
67
+
68
+ autoload :Core, 'cancer/xeps/core'
69
+ autoload :IM, 'cancer/xeps/im'
70
+ autoload :XEP_0004, 'cancer/xeps/xep_0004_x_data'
71
+ autoload :XEP_0020, 'cancer/xeps/xep_0020_feature_neg'
72
+ autoload :XEP_0030, 'cancer/xeps/xep_0030_disco'
73
+ autoload :XEP_0047, 'cancer/xeps/xep_0047_ibb'
74
+ autoload :XEP_0050, 'cancer/xeps/xep_0050_commands'
75
+ autoload :XEP_0065, 'cancer/xeps/xep_0065_bytestreams'
76
+ autoload :XEP_0066, 'cancer/xeps/xep_0066_oob'
77
+ autoload :XEP_0095, 'cancer/xeps/xep_0095_si'
78
+ autoload :XEP_0096, 'cancer/xeps/xep_0096_si_filetransfer'
79
+ autoload :XEP_0114, 'cancer/xeps/xep_0114_component'
80
+ autoload :XEP_0115, 'cancer/xeps/xep_0115_caps'
81
+ autoload :XEP_0138, 'cancer/xeps/xep_0138_compress'
82
+ autoload :XEP_0144, 'cancer/xeps/xep_0144_rosterx'
83
+ autoload :XEP_0184, 'cancer/xeps/xep_0184_receipts'
84
+ autoload :XEP_0199, 'cancer/xeps/xep_0199_ping'
85
+
86
+ Cancer::XEP.register('core', 'Cancer::Core')
87
+ Cancer::XEP.register('im', 'Cancer::IM')
88
+ Cancer::XEP.register('xep-0004', 'Cancer::XEP_0004')
89
+ Cancer::XEP.register('xep-0020', 'Cancer::XEP_0020')
90
+ Cancer::XEP.register('xep-0030', 'Cancer::XEP_0030')
91
+ Cancer::XEP.register('xep-0047', 'Cancer::XEP_0047')
92
+ Cancer::XEP.register('xep-0050', 'Cancer::XEP_0050')
93
+ Cancer::XEP.register('xep-0065', 'Cancer::XEP_0065')
94
+ Cancer::XEP.register('xep-0066', 'Cancer::XEP_0066')
95
+ Cancer::XEP.register('xep-0095', 'Cancer::XEP_0095')
96
+ Cancer::XEP.register('xep-0096', 'Cancer::XEP_0096')
97
+ Cancer::XEP.register('xep-0114', 'Cancer::XEP_0114')
98
+ Cancer::XEP.register('xep-0115', 'Cancer::XEP_0115')
99
+ Cancer::XEP.register('xep-0138', 'Cancer::XEP_0138')
100
+ Cancer::XEP.register('xep-0144', 'Cancer::XEP_0144')
101
+ Cancer::XEP.register('xep-0184', 'Cancer::XEP_0184')
102
+ Cancer::XEP.register('xep-0199', 'Cancer::XEP_0199')
103
+
104
+ CLIENT_NS = "jabber:client"
105
+ STREAM_NS = "http://etherx.jabber.org/streams"
106
+
107
+ CLIENT = 'http://github.com/simonmenke/cancer'
108
+
109
+ begin # preload
110
+ JID
111
+ Support::Hash
112
+ Support::String
113
+ end
114
+
115
+ class << self
116
+ attr_accessor :debug
117
+ attr_accessor :logger
118
+ end
119
+
120
+ self.logger = Logger.new(STDOUT)
121
+
122
+ end
@@ -0,0 +1,33 @@
1
+
2
+ module Cancer
3
+ class Adapter
4
+
5
+ attr_reader :stream
6
+
7
+ def initialize(stream, options={})
8
+ @stream = stream
9
+ @options = options
10
+ end
11
+
12
+ def connect
13
+
14
+ end
15
+
16
+ def disconnect
17
+
18
+ end
19
+
20
+ def send(xml)
21
+
22
+ end
23
+
24
+ def start_tls?
25
+ false
26
+ end
27
+
28
+ def start_tls
29
+
30
+ end
31
+
32
+ end
33
+ end