jabber4r-revive 0.9.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +4 -0
- data/.rspec +3 -0
- data/.travis.yml +8 -0
- data/CHANGELOG +45 -0
- data/Gemfile +3 -0
- data/Gemfile.lock +45 -0
- data/LICENSE +12 -0
- data/README.md +29 -0
- data/Rakefile +71 -0
- data/jabber4r-revive.gemspec +25 -0
- data/lib/jabber4r/bosh_session.rb +224 -0
- data/lib/jabber4r/connection.rb +258 -0
- data/lib/jabber4r/debugger.rb +61 -0
- data/lib/jabber4r/jid.rb +125 -0
- data/lib/jabber4r/protocol/iq.rb +260 -0
- data/lib/jabber4r/protocol/message.rb +246 -0
- data/lib/jabber4r/protocol/parsed_xml_element.rb +208 -0
- data/lib/jabber4r/protocol/presence.rb +160 -0
- data/lib/jabber4r/protocol/xml_element.rb +144 -0
- data/lib/jabber4r/protocol.rb +257 -0
- data/lib/jabber4r/rexml_1.8_patch.rb +16 -0
- data/lib/jabber4r/roster.rb +322 -0
- data/lib/jabber4r/session.rb +615 -0
- data/lib/jabber4r/vcard.rb +42 -0
- data/lib/jabber4r/version.rb +3 -0
- data/lib/jabber4r.rb +33 -0
- data/spec/lib/jabber4r/bosh_session_spec.rb +150 -0
- data/spec/lib/jabber4r/connection_spec.rb +174 -0
- data/spec/lib/jabber4r/debugger_spec.rb +36 -0
- data/spec/lib/jabber4r/jid_spec.rb +198 -0
- data/spec/spec_helper.rb +11 -0
- data/spec/support/mocks/tcp_socket_mock.rb +8 -0
- metadata +151 -0
data/.gitignore
ADDED
data/.rspec
ADDED
data/.travis.yml
ADDED
data/CHANGELOG
ADDED
@@ -0,0 +1,45 @@
|
|
1
|
+
|
2
|
+
v0.9.0
|
3
|
+
- 2013/06/26: feature(changelog) added changelog file (Strech (aka Sergey Fedorov))
|
4
|
+
- 2013/06/26: Jabber::BoshSession : Modified to_json method (Strech (aka Sergey Fedorov))
|
5
|
+
- 2013/06/25: Jabber::BoshSession : XMPP over BOSH (XEP-0206) (Strech (aka Sergey Fedorov))
|
6
|
+
- 2013/06/20: Jabber::Connection : Change method parse_failure (Strech (aka Sergey Fedorov))
|
7
|
+
- 2013/06/20: Jabber::Connection : Refactoring (Strech (aka Sergey Fedorov))
|
8
|
+
- 2013/06/20: Rspec : Socket mock changed. Jabber::Connection : Specs for #send (Strech (aka Sergey Fedorov))
|
9
|
+
- 2013/06/20: Rspec : Change rspec dummy text (Strech (aka Sergey Fedorov))
|
10
|
+
- 2013/06/20: Jabber::Debugger : Added (Strech (aka Sergey Fedorov))
|
11
|
+
- 2013/06/20: Jabber : Moved up on one level (Strech (aka Sergey Fedorov))
|
12
|
+
- 2013/06/20: Jabber::Connection : add_filter and remove_filter refactoring (Strech (aka Sergey Fedorov))
|
13
|
+
- 2013/06/20: F (Strech (aka Sergey Fedorov))
|
14
|
+
- 2013/06/20: F (Strech (aka Sergey Fedorov))
|
15
|
+
- 2013/06/19: Jabber::Connection : New method force_close! added (Strech (aka Sergey Fedorov))
|
16
|
+
- 2013/06/19: Jabber::Connection : Added :end_document listener (Strech (aka Sergey Fedorov))
|
17
|
+
- 2013/06/07: Jabber::Protocol::Connection : Fix misstype (Strech (aka Sergey Fedorov))
|
18
|
+
- 2013/06/07: Jabber : Added missing requires (Strech (aka Sergey Fedorov))
|
19
|
+
- 2013/06/07: Jabber::JID : Specs for same?, ::to_jid methods (Strech (aka Sergey Fedorov))
|
20
|
+
- 2013/06/07: Jabber::JID : Specs for hash, ==, strip! methods (Strech (aka Sergey Fedorov))
|
21
|
+
- 2013/06/07: Jabber::JID : Specs for to_s method. Jid regexp (Strech (aka Sergey Fedorov))
|
22
|
+
- 2013/06/07: CI : TravisCI config updated (Strech (aka Sergey Fedorov))
|
23
|
+
- 2013/06/07: CI : TravisCI config updated (Strech (aka Sergey Fedorov))
|
24
|
+
- 2013/06/07: CI : TravisCI config updated (Strech (aka Sergey Fedorov))
|
25
|
+
- 2013/06/07: CI : TravisCI config added (Strech (aka Sergey Fedorov))
|
26
|
+
- 2013/06/07: Update README.md (Sergey Fedorov)
|
27
|
+
- 2013/06/07: Jabber::Protocol : Methods send and receive sync by mutex. Some part of refactoring (Strech (aka Sergey Fedorov))
|
28
|
+
- 2013/06/07: Jabber::Protocol : Class methods refactoring. Split subclasses (Strech (aka Sergey Fedorov))
|
29
|
+
- 2013/06/06: Jabber::Protocol : Class refactoring (Strech (aka Sergey Fedorov))
|
30
|
+
- 2013/06/04: Jabber::JID : Strip method added (Strech (aka Sergey Fedorov))
|
31
|
+
- 2013/06/04: Jabber::Protocol::Iq : Class method from_element refactoring (Strech (aka Sergey Fedorov))
|
32
|
+
- 2013/06/04: Jabber::Protocol::Iq : Replace class name to self (Strech (aka Sergey Fedorov))
|
33
|
+
- 2013/06/04: Update README.md (Sergey Fedorov)
|
34
|
+
- 2013/06/04: Update README.md (Sergey Fedorov)
|
35
|
+
- 2013/06/04: Jabber::Protocol::Iq : Send method refactoring (Strech (aka Sergey Fedorov))
|
36
|
+
- 2013/06/04: Jabber::JID : Tomdoc (Strech (aka Sergey Fedorov))
|
37
|
+
- 2013/06/04: Jabber::JID : Rspec specs added. Refactoring (Strech (aka Sergey Fedorov))
|
38
|
+
- 2013/06/04: Gem: Rspec gem dependency added (Strech (aka Sergey Fedorov))
|
39
|
+
- 2013/06/03: Update .gitignore (Strech (aka Sergey Fedorov))
|
40
|
+
- 2013/06/03: Jabber::Protocol::Iq : Misstype fixed. Trailing spaces removed (Strech (aka Sergey Fedorov))
|
41
|
+
- 2013/06/03: Rename LICENSE.txt to LICENSE (Sergey Fedorov)
|
42
|
+
- 2013/06/03: Update README.md (Sergey Fedorov)
|
43
|
+
|
44
|
+
v0.8.0
|
45
|
+
- 2013/06/03: Initial commit (Strech (aka Sergey Fedorov))
|
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,45 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
jabber4r-revive (0.9.0)
|
5
|
+
ox
|
6
|
+
|
7
|
+
GEM
|
8
|
+
remote: https://rubygems.org/
|
9
|
+
specs:
|
10
|
+
addressable (2.3.4)
|
11
|
+
changelogger (0.0.3)
|
12
|
+
grit (~> 2.5.0)
|
13
|
+
thor (~> 0.16.0)
|
14
|
+
crack (0.4.0)
|
15
|
+
safe_yaml (~> 0.9.0)
|
16
|
+
diff-lcs (1.2.4)
|
17
|
+
grit (2.5.0)
|
18
|
+
diff-lcs (~> 1.1)
|
19
|
+
mime-types (~> 1.15)
|
20
|
+
posix-spawn (~> 0.3.6)
|
21
|
+
mime-types (1.23)
|
22
|
+
ox (2.0.4)
|
23
|
+
posix-spawn (0.3.6)
|
24
|
+
rspec (2.13.0)
|
25
|
+
rspec-core (~> 2.13.0)
|
26
|
+
rspec-expectations (~> 2.13.0)
|
27
|
+
rspec-mocks (~> 2.13.0)
|
28
|
+
rspec-core (2.13.1)
|
29
|
+
rspec-expectations (2.13.0)
|
30
|
+
diff-lcs (>= 1.1.3, < 2.0)
|
31
|
+
rspec-mocks (2.13.1)
|
32
|
+
safe_yaml (0.9.3)
|
33
|
+
thor (0.16.0)
|
34
|
+
webmock (1.11.0)
|
35
|
+
addressable (>= 2.2.7)
|
36
|
+
crack (>= 0.3.2)
|
37
|
+
|
38
|
+
PLATFORMS
|
39
|
+
ruby
|
40
|
+
|
41
|
+
DEPENDENCIES
|
42
|
+
changelogger
|
43
|
+
jabber4r-revive!
|
44
|
+
rspec
|
45
|
+
webmock
|
data/LICENSE
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
Copyright (c) 2002, Rich Kilmer (rich@infoether.com)
|
2
|
+
All rights reserved.
|
3
|
+
|
4
|
+
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
5
|
+
|
6
|
+
Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
7
|
+
|
8
|
+
Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
|
9
|
+
|
10
|
+
The name Rich Kilmer may not be used to endorse or promote products derived from this software without specific prior written permission.
|
11
|
+
|
12
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
data/README.md
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
# Jabber4r (revive)
|
2
|
+
|
3
|
+
Original [README](http://rubydoc.info/gems/jabber4r/file/README) and original [jabber4r web-site](http://jabber4r.rubyforge.org/)
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add this line to your application's Gemfile:
|
8
|
+
|
9
|
+
gem 'jabber4r-revive'
|
10
|
+
|
11
|
+
And then execute:
|
12
|
+
|
13
|
+
$ bundle
|
14
|
+
|
15
|
+
Or install it yourself as:
|
16
|
+
|
17
|
+
$ gem install jabber4r-revive
|
18
|
+
|
19
|
+
## Usage
|
20
|
+
|
21
|
+
TODO: Write usage instructions here
|
22
|
+
|
23
|
+
## Contributing
|
24
|
+
|
25
|
+
1. Fork it
|
26
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
27
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
28
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
29
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1,71 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
require "bundler/gem_tasks"
|
4
|
+
require "pty"
|
5
|
+
|
6
|
+
# ============================== Support =======================================
|
7
|
+
|
8
|
+
ROOT_PATH = File.expand_path("..", __FILE__)
|
9
|
+
VERSION_PATH = File.join(ROOT_PATH, "lib", "jabber4r", "version.rb")
|
10
|
+
CHANGELOG_PATH = File.join(ROOT_PATH, "CHANGELOG")
|
11
|
+
|
12
|
+
# get current version from version.rb file
|
13
|
+
def current_version
|
14
|
+
version = File.read(VERSION_PATH).gsub(/[^\d\.]+/, "").strip.chomp
|
15
|
+
end
|
16
|
+
|
17
|
+
# get released version from git
|
18
|
+
def released_version
|
19
|
+
/\Av([\d\.]+)\z/ === `git describe --tags --abbrev=0 2>/dev/null || echo 'v0.0.0'`.chomp.strip
|
20
|
+
|
21
|
+
$1
|
22
|
+
end
|
23
|
+
|
24
|
+
# run +cmd+ in subprocess, redirect its stdout to parent's stdout
|
25
|
+
def spawn(cmd, stdout = STDOUT)
|
26
|
+
puts ">> #{cmd}"
|
27
|
+
|
28
|
+
cmd += ' 2>&1'
|
29
|
+
PTY.spawn cmd do |r, w, pid|
|
30
|
+
begin
|
31
|
+
r.sync
|
32
|
+
r.each_char { |chr| stdout.write(chr) }
|
33
|
+
rescue Errno::EIO => e
|
34
|
+
# simply ignoring this
|
35
|
+
ensure
|
36
|
+
::Process.wait pid
|
37
|
+
end
|
38
|
+
end
|
39
|
+
abort "#{cmd} failed" unless $? && $?.exitstatus == 0
|
40
|
+
end
|
41
|
+
|
42
|
+
# =============================== Tasks ========================================
|
43
|
+
|
44
|
+
namespace :version do
|
45
|
+
task :current do
|
46
|
+
puts current_version
|
47
|
+
end
|
48
|
+
|
49
|
+
desc "Release new version"
|
50
|
+
task release: [:changelog, :commit, :tag]
|
51
|
+
|
52
|
+
desc "Add new version to git repo"
|
53
|
+
task :commit do
|
54
|
+
spawn "git add '#{VERSION_PATH}'"
|
55
|
+
spawn "git diff --cached --exit-code > /dev/null || git commit -m \"Release #{current_version}\" || echo -n"
|
56
|
+
end
|
57
|
+
|
58
|
+
desc "Add git tag for new version"
|
59
|
+
task :tag do
|
60
|
+
spawn "git tag v#{current_version}"
|
61
|
+
end
|
62
|
+
|
63
|
+
desc "Generate file CHANGELOG"
|
64
|
+
task :changelog do
|
65
|
+
spawn "changelogger changelog '#{ROOT_PATH}' --top_version='v#{current_version}' > '#{CHANGELOG_PATH}'"
|
66
|
+
spawn "git add '#{CHANGELOG_PATH}'"
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
desc "Show current version"
|
71
|
+
task version: "version:current"
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path("../lib", __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require "jabber4r/version"
|
5
|
+
|
6
|
+
Gem::Specification.new do |gem|
|
7
|
+
gem.name = "jabber4r-revive"
|
8
|
+
gem.version = Jabber::VERSION
|
9
|
+
gem.authors = ["Richard Kilmer", "Sergey Fedorov"]
|
10
|
+
gem.email = ["rich@infoether.com", "strech_ftf@mail.ru"]
|
11
|
+
gem.description = "The purpose of this library is to allow Ruby applications to talk to a Jabber IM system. Jabber is an open-source instant messaging service, which can be learned about at http://www.jabber.org"
|
12
|
+
gem.summary = "Read more http://jabber4r.rubyforge.org"
|
13
|
+
gem.homepage = "https://github.com/Strech/jabber4r-revive"
|
14
|
+
|
15
|
+
gem.files = `git ls-files`.split($/)
|
16
|
+
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
17
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
18
|
+
gem.require_paths = ["lib"]
|
19
|
+
|
20
|
+
gem.add_dependency "ox"
|
21
|
+
|
22
|
+
gem.add_development_dependency "rspec"
|
23
|
+
gem.add_development_dependency "webmock"
|
24
|
+
gem.add_development_dependency "changelogger"
|
25
|
+
end
|
@@ -0,0 +1,224 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
# License: see LICENSE
|
4
|
+
# Jabber4R - Jabber Instant Messaging Library for Ruby
|
5
|
+
# Copyright (C) 2002 Rich Kilmer <rich@infoether.com>
|
6
|
+
# Copyright (C) 2013 Sergey Fedorov <strech_ftf@mail.ru>
|
7
|
+
|
8
|
+
require "ox"
|
9
|
+
require "json"
|
10
|
+
require "net/http"
|
11
|
+
require "digest/sha1"
|
12
|
+
|
13
|
+
module Jabber
|
14
|
+
# XMPP Over BOSH class
|
15
|
+
# NOTE: http://xmpp.org/extensions/xep-0206.html
|
16
|
+
class BoshSession
|
17
|
+
# Public: Default connection options
|
18
|
+
DEFAULTS = {
|
19
|
+
host: "localhost",
|
20
|
+
port: 5280,
|
21
|
+
bind_uri: "/http-bind"
|
22
|
+
}.freeze
|
23
|
+
|
24
|
+
attr_reader :stream_id
|
25
|
+
attr_reader :jid, :rid, :sid
|
26
|
+
attr_reader :host, :port, :bind_uri
|
27
|
+
|
28
|
+
# Public: Create new BOSH-session and bind it to jabber http-bind service
|
29
|
+
#
|
30
|
+
# username - String the login of jabber server user
|
31
|
+
# password - String the password of jabber server user
|
32
|
+
# options - Hash the options for jabber http-bind service (default: Empty hash)
|
33
|
+
# :host - String the jabber server host
|
34
|
+
# :port - [String|Fixnum] the port of http-bind endpoint of jabber server
|
35
|
+
# :bind_uri - String the http-bind uri
|
36
|
+
#
|
37
|
+
#
|
38
|
+
# Examples
|
39
|
+
#
|
40
|
+
# Jabber::BoshSession.bind("strech@localhost/res-1", "secret-pass")
|
41
|
+
# Jabber::BoshSession.bind("strech@localhost/res-1", "secret-pass", )
|
42
|
+
#
|
43
|
+
# Raises Jabber::AuthenticationError
|
44
|
+
# Returns Jabber::BoshSession
|
45
|
+
def self.bind(username, password, options = {})
|
46
|
+
host, port, bind_uri = DEFAULTS.dup.merge!(options).values
|
47
|
+
|
48
|
+
session = new(host, port, bind_uri)
|
49
|
+
raise AuthenticationError, "Failed to login" unless session.authenticate(username, password)
|
50
|
+
|
51
|
+
session
|
52
|
+
end
|
53
|
+
|
54
|
+
# Public: Create new BOSH-session (not binded to http-bind service)
|
55
|
+
#
|
56
|
+
# host - String the jabber server host
|
57
|
+
# port - [String|Fixnum] the port of http-bind endpoint of jabber server
|
58
|
+
# bind_uri - String the http-bind uri
|
59
|
+
#
|
60
|
+
# Examples
|
61
|
+
#
|
62
|
+
# Jabber::BoshSession.new("localhost", 5280, "/http-bind")
|
63
|
+
#
|
64
|
+
# Returns Jabber::BoshSession
|
65
|
+
def initialize(host, port, bind_uri)
|
66
|
+
@host, @port, @bind_uri = host, port, bind_uri
|
67
|
+
@alive = false
|
68
|
+
end
|
69
|
+
|
70
|
+
# Public: Authenticate user in jabber server by his username and password
|
71
|
+
# NOTE: This authentication is Non-SASL http://xmpp.org/extensions/xep-0078.html
|
72
|
+
#
|
73
|
+
# Examples
|
74
|
+
#
|
75
|
+
# bosh = Jabber::BoshSession.new ...
|
76
|
+
# bosh.authenticate("strech@localhost/my-resource", "super-secret-password") # => true
|
77
|
+
# bosh.alive? # => true
|
78
|
+
#
|
79
|
+
# Returns boolean
|
80
|
+
def authenticate(username, password)
|
81
|
+
open_new_stream
|
82
|
+
|
83
|
+
@jid = username.is_a?(JID) ? username : JID.new(username)
|
84
|
+
@alive = login(jid, password)
|
85
|
+
end
|
86
|
+
|
87
|
+
# Public: Is BOSH-session active? (no polling consider)
|
88
|
+
#
|
89
|
+
# Returns boolean
|
90
|
+
def alive?
|
91
|
+
@alive
|
92
|
+
end
|
93
|
+
|
94
|
+
# Public: Represent BOSH-session as json object
|
95
|
+
#
|
96
|
+
# Returns String
|
97
|
+
def to_json
|
98
|
+
{jid: jid.to_s, rid: rid, sid: sid}.to_json
|
99
|
+
end
|
100
|
+
|
101
|
+
private
|
102
|
+
# Internal: Send open stream command to jabber server
|
103
|
+
#
|
104
|
+
# Raises XMLMalformedError
|
105
|
+
# Returns boolean
|
106
|
+
def open_new_stream
|
107
|
+
Jabber.debug("Open stream for bosh session")
|
108
|
+
|
109
|
+
body = Ox::Element.new("body").tap do |element|
|
110
|
+
element[:xmlns] = "http://jabber.org/protocol/httpbind"
|
111
|
+
element[:content] = "text/xml; charset=utf-8"
|
112
|
+
element[:rid] = generate_next_rid
|
113
|
+
element[:to] = host
|
114
|
+
element[:secure] = true
|
115
|
+
element[:wait] = 60
|
116
|
+
element[:hold] = 1
|
117
|
+
end
|
118
|
+
|
119
|
+
response = post(Ox.dump body)
|
120
|
+
xml = Ox.parse(response.body.tr("'", '"'))
|
121
|
+
|
122
|
+
[:sid, :authid].each do |m|
|
123
|
+
raise XMLMalformedError,
|
124
|
+
"Couldn't find <body /> attribute [#{m}]" if xml[m].nil?
|
125
|
+
end
|
126
|
+
|
127
|
+
@sid, @stream_id = xml.sid, xml.authid
|
128
|
+
|
129
|
+
true
|
130
|
+
end
|
131
|
+
|
132
|
+
# Internal: Send login request to jabber server
|
133
|
+
#
|
134
|
+
# jid - Jabber::JID the jid of jabber user
|
135
|
+
# password - String the password of jabber user
|
136
|
+
#
|
137
|
+
# Raises ArgumentError
|
138
|
+
# Raises XMLMalformedError
|
139
|
+
# Returns boolean
|
140
|
+
def login(jid, password)
|
141
|
+
raise ArgumentError,
|
142
|
+
"Jabber::JID expected, but #{jid.class} was given" unless jid.is_a?(JID)
|
143
|
+
|
144
|
+
query = Ox::Element.new("query").tap do |element|
|
145
|
+
element[:xmlns] = "jabber:iq:auth"
|
146
|
+
|
147
|
+
element << (Ox::Element.new("username") << jid.node)
|
148
|
+
element << (Ox::Element.new("digest") << generate_digest_for(stream_id, password))
|
149
|
+
element << (Ox::Element.new("resource") << jid.resource)
|
150
|
+
end
|
151
|
+
|
152
|
+
iq = Ox::Element.new("iq").tap do |element|
|
153
|
+
element[:xmlns] = "jabber:client"
|
154
|
+
element[:type] = "set"
|
155
|
+
element[:id] = Jabber.gen_random_id
|
156
|
+
|
157
|
+
element << query
|
158
|
+
end
|
159
|
+
|
160
|
+
body = Ox::Element.new("body").tap do |element|
|
161
|
+
element[:xmlns] = 'http://jabber.org/protocol/httpbind'
|
162
|
+
element[:content] = "text/xml; charset=utf-8"
|
163
|
+
element[:rid] = generate_next_rid
|
164
|
+
element[:sid] = sid
|
165
|
+
|
166
|
+
element << iq
|
167
|
+
end
|
168
|
+
|
169
|
+
response = post(Ox.dump body)
|
170
|
+
xml = Ox.parse(response.body.tr("'", '"'))
|
171
|
+
|
172
|
+
raise XMLMalformedError, "Couldn't find xml tag <iq/>" if xml.locate("iq").empty?
|
173
|
+
return false unless xml.iq[:type] == "result"
|
174
|
+
|
175
|
+
@rid = body.rid
|
176
|
+
|
177
|
+
true
|
178
|
+
end
|
179
|
+
|
180
|
+
# Internal: Send HTTP-post request on HTTP-bind uri
|
181
|
+
#
|
182
|
+
# body - String data, which will be sended
|
183
|
+
#
|
184
|
+
# Examples
|
185
|
+
#
|
186
|
+
# post(%Q[<body><iq id="1"/></body>]) # => Net::HTTPSuccess
|
187
|
+
#
|
188
|
+
# Raises Net::HTTPBadResponse
|
189
|
+
# Returns Net:HttpResponse
|
190
|
+
def post(body)
|
191
|
+
request = Net::HTTP::Post.new(bind_uri)
|
192
|
+
request.body = body
|
193
|
+
request.content_length = request.body.size
|
194
|
+
request["Content-Type"] = "text/xml; charset=utf-8"
|
195
|
+
|
196
|
+
Jabber.debug("Sending POST request - #{body.strip}")
|
197
|
+
|
198
|
+
response = Net::HTTP.new(host, port).start { |http| http.request(request) }
|
199
|
+
|
200
|
+
Jabber.debug("Receiving - #{response.code}: #{response.body.inspect}")
|
201
|
+
|
202
|
+
unless response.is_a?(Net::HTTPSuccess)
|
203
|
+
raise Net::HTTPBadResponse, "Net::HTTPSuccess expected, but #{response.class} was received"
|
204
|
+
end
|
205
|
+
|
206
|
+
response
|
207
|
+
end
|
208
|
+
|
209
|
+
# Internal: Generate hex string consist of concatination of all arguments
|
210
|
+
#
|
211
|
+
# Returns String
|
212
|
+
def generate_digest_for(*args)
|
213
|
+
Digest::SHA1.hexdigest(args.join)
|
214
|
+
end
|
215
|
+
|
216
|
+
# Internal: Generate next request id for http post request
|
217
|
+
#
|
218
|
+
# Returns Fixnum
|
219
|
+
def generate_next_rid
|
220
|
+
@rid ||= rand(1_000_000_000)
|
221
|
+
@rid += 1
|
222
|
+
end
|
223
|
+
end
|
224
|
+
end
|