skyfallsin-ruby_bosh 0.0.0
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/ruby_bosh.rb +145 -0
- data/test/ruby_bosh_test.rb +7 -0
- data/test/test_helper.rb +10 -0
- metadata +57 -0
data/lib/ruby_bosh.rb
ADDED
@@ -0,0 +1,145 @@
|
|
1
|
+
require 'rest_client'
|
2
|
+
require 'builder'
|
3
|
+
require 'rexml/document'
|
4
|
+
require 'base64'
|
5
|
+
require 'hpricot'
|
6
|
+
|
7
|
+
# based on
|
8
|
+
# http://code.stanziq.com/svn/strophe/trunk/strophejs/examples/attach/boshclient.py
|
9
|
+
class RubyBOSHClient
|
10
|
+
BOSH_XMLNS = 'http://jabber.org/protocol/httpbind'
|
11
|
+
TLS_XMLNS = 'urn:ietf:params:xml:ns:xmpp-tls'
|
12
|
+
SASL_XMLNS = 'urn:ietf:params:xml:ns:xmpp-sasl'
|
13
|
+
BIND_XMLNS = 'urn:ietf:params:xml:ns:xmpp-bind'
|
14
|
+
SESSION_XMLNS = 'urn:ietf:params:xml:ns:xmpp-session'
|
15
|
+
|
16
|
+
attr_accessor :jid, :rid, :sid, :success
|
17
|
+
def initialize(jid, pw, service_url)
|
18
|
+
@service_url = service_url
|
19
|
+
@jid, @pw = jid, pw
|
20
|
+
@host = jid.split("@").last
|
21
|
+
@success = false
|
22
|
+
@headers = {"Content-Type" => "text/xml; charset=utf-8",
|
23
|
+
"Accept" => "text/xml"}
|
24
|
+
connect
|
25
|
+
end
|
26
|
+
|
27
|
+
def connect
|
28
|
+
initialize_bosh_session
|
29
|
+
if send_auth_request
|
30
|
+
send_restart_request
|
31
|
+
request_resource_binding
|
32
|
+
@success = send_session_request
|
33
|
+
end
|
34
|
+
|
35
|
+
if @success
|
36
|
+
@rid+=1 #send this directly to the browser
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def initialize_bosh_session
|
41
|
+
response = deliver(construct_body(:wait => 5, :to => @host,
|
42
|
+
:hold => 3, :window => 5,
|
43
|
+
"xmpp:version" => '1.0'))
|
44
|
+
parse(response)
|
45
|
+
end
|
46
|
+
|
47
|
+
def construct_body(params={}, &block)
|
48
|
+
@rid ? @rid+=1 : @rid=rand(100000)
|
49
|
+
|
50
|
+
builder = Builder::XmlMarkup.new
|
51
|
+
parameters = {:rid => @rid, :xmlns => BOSH_XMLNS}.merge(params)
|
52
|
+
|
53
|
+
if block_given?
|
54
|
+
builder.body(parameters) {|body| yield(body)}
|
55
|
+
else
|
56
|
+
builder.body(parameters)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def send_auth_request
|
61
|
+
request = construct_body(:sid => @sid) do |body|
|
62
|
+
auth_string = "#{@jid}\x00#{@jid.split("@").first.strip}\x00#{@pw}"
|
63
|
+
body.auth(Base64.encode64(auth_string).gsub(/\s/,''),
|
64
|
+
:xmlns => SASL_XMLNS, :mechanism => 'PLAIN')
|
65
|
+
end
|
66
|
+
|
67
|
+
response = deliver(request)
|
68
|
+
# TODO: make the following more robust
|
69
|
+
response.include?("success")
|
70
|
+
end
|
71
|
+
|
72
|
+
def send_restart_request
|
73
|
+
request = construct_body(:sid => @sid, "xmpp:restart" => true, "xmlns:xmpp" => 'urn:xmpp:xbosh')
|
74
|
+
deliver(request).include?("stream:features")
|
75
|
+
end
|
76
|
+
|
77
|
+
def request_resource_binding
|
78
|
+
request = construct_body(:sid => @sid) do |body|
|
79
|
+
body.iq(:id => "bind_#{rand(100000)}", :type => "set",
|
80
|
+
:xmlns => "jabber:client") do |iq|
|
81
|
+
iq.bind(:xmlns => BIND_XMLNS) do |bind|
|
82
|
+
bind.resource('presently')
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
response = deliver(request)
|
88
|
+
response.include?("<jid>")
|
89
|
+
end
|
90
|
+
|
91
|
+
def send_session_request
|
92
|
+
request = construct_body(:sid => @sid) do |body|
|
93
|
+
body.iq(:xmlns => "jabber:client", :type => "set",
|
94
|
+
:id => "sess_#{rand(100000)}") do |iq|
|
95
|
+
iq.session(:xmlns => SESSION_XMLNS)
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
response = deliver(request)
|
100
|
+
response.include?("body")
|
101
|
+
end
|
102
|
+
|
103
|
+
def parse(_response)
|
104
|
+
doc = Hpricot(_response)
|
105
|
+
doc.search("//body").each do |body|
|
106
|
+
@sid = body.attributes["sid"].to_s
|
107
|
+
end
|
108
|
+
_response
|
109
|
+
end
|
110
|
+
|
111
|
+
def success?
|
112
|
+
success == true
|
113
|
+
end
|
114
|
+
|
115
|
+
private
|
116
|
+
def deliver(xml)
|
117
|
+
send(xml)
|
118
|
+
recv(RestClient.post(@service_url, xml, @headers))
|
119
|
+
end
|
120
|
+
|
121
|
+
def send(msg)
|
122
|
+
puts "Ruby-BOSH - SEND\n#{msg}"; msg
|
123
|
+
end
|
124
|
+
|
125
|
+
def recv(msg)
|
126
|
+
puts "Ruby-BOSH - RECV\n#{msg}"; msg
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
|
131
|
+
class RubyBOSH
|
132
|
+
def self.initialize_session(jid, pw, service_url)
|
133
|
+
conn = RubyBOSHClient.new(jid, pw, service_url)
|
134
|
+
if conn.success?
|
135
|
+
[conn.jid, conn.sid, conn.rid]
|
136
|
+
else
|
137
|
+
[nil, nil, nil]
|
138
|
+
end
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
if __FILE__ == $0
|
143
|
+
p RubyBOSH.initialize_session("skyfallsin@localhost", "skyfallsin",
|
144
|
+
"http://localhost:5280/http-bind")
|
145
|
+
end
|
data/test/test_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,57 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: skyfallsin-ruby_bosh
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Pradeep Elankumaran
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2009-02-18 00:00:00 -08:00
|
13
|
+
default_executable:
|
14
|
+
dependencies: []
|
15
|
+
|
16
|
+
description: TODO
|
17
|
+
email: pradeep@intridea.com
|
18
|
+
executables: []
|
19
|
+
|
20
|
+
extensions: []
|
21
|
+
|
22
|
+
extra_rdoc_files: []
|
23
|
+
|
24
|
+
files:
|
25
|
+
- VERSION.yml
|
26
|
+
- lib/ruby_bosh.rb
|
27
|
+
- test/ruby_bosh_test.rb
|
28
|
+
- test/test_helper.rb
|
29
|
+
has_rdoc: true
|
30
|
+
homepage: http://github.com/skyfallsin/ruby_bosh
|
31
|
+
post_install_message:
|
32
|
+
rdoc_options:
|
33
|
+
- --inline-source
|
34
|
+
- --charset=UTF-8
|
35
|
+
require_paths:
|
36
|
+
- lib
|
37
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
38
|
+
requirements:
|
39
|
+
- - ">="
|
40
|
+
- !ruby/object:Gem::Version
|
41
|
+
version: "0"
|
42
|
+
version:
|
43
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: "0"
|
48
|
+
version:
|
49
|
+
requirements: []
|
50
|
+
|
51
|
+
rubyforge_project:
|
52
|
+
rubygems_version: 1.2.0
|
53
|
+
signing_key:
|
54
|
+
specification_version: 2
|
55
|
+
summary: A BOSH session pre-initializer for Ruby web applications
|
56
|
+
test_files: []
|
57
|
+
|