Date: 2005-02-08 15:44
Sender: Nobody
Logged In: NO
Forgot to attach the file :-(.
require 'xmlparser'
require 'jabber4r/jabber4r'
module Jabber
##
# The Jabber ID class is used to hold a parsed jabber identifier
(account+host+resource)
#
class JID
#If not node then don't add the @ sign since components do not
use node
def to_s
if (@node!=nil and @node!='')
result = (@node.to_s+"@"+@host.to_s)
else
result = @host.to_s
end
result += ("/"+@resource) if @resource
return result
end
end
module Protocol
class Iq
#PATCH: Component iq stanzas *must* be sent with from
attribute
def to_xml
elem = XMLElement.new("iq",
{ "type"=>@type})
elem.add_attribute("to" ,@to) if @to
elem.add_attribute("from" ,@from) if @from
elem.add_attribute("id", @id) if @id
elem.add_child("query").add_attribute("xmlns&q
uot;,@xmlns).add_data(@data.to_s)
if @type=="error" then
e=elem.add_child("error");
e.add_attribute("code",@errorcode) if @errorcode
e.add_data(@error) if @error
end
return elem.to_s
end
end
#PATCH: Component message stanzas *must* be sent with from
attribute
class Message
def to_xml
@thread = Jabber.gen_random_thread if @thread.nil? and (not
@is_reply)
elem = XMLElement.new("message",
{"to"=>@to, "type"=>@type,
"from"=>@from})
elem.add_attribute("id", @id) if @id
elem.add_child("thread").add_data(@thread)
if @thread
elem.add_child("subject").add_data(@subject) if
@subject
elem.add_child("body").add_data(@body) if @body
if @xhtml then
t=elem.add_child("xhtml").add_attribute("xml
ns","http://www.w3.org/1999/xhtml")
t.add_child("body").add_data(@xhtml)
end
if @type=="error" then
e=elem.add_child("error");
e.add_attribute("code",@errorcode) if @errorcode
e.add_data(@error) if @error
end
elem.add_child("x").add_attribute("xmlns",
"jabber:x:oob").add_data(@oobData) if @oobData
elem.add_xml(@x.to_s) if @x
return elem.to_s
end
end
end
#PATCH: New class represents a component
class SessionComponent < Session
def SessionComponent.bind_component(component_name, password,
host, port=5347)
session = SessionComponent.new(component_name, host, port)
raise "Authentication failed" unless
session.authenticate_component(component_name, password)
session.register_presence_filter
session.register_iq_filter
session.register_message_filter
return session
end
#Standard component greeting according to JEP 0114
def gen_component_stream(host)
return ('<?xml version="1.0"
encoding="UTF-8" ?><stream:stream
to="'+host+'" xmlns="jabber:component:accept"
xmlns:stream="http://etherx.jabber.org/streams">')
end
#Start XMPP stream with router
def initialize(component, host, port)
@id = 1
@host = host
@port = port
@roster = Roster.new(self)
@messageListeners = Hash.new
@iqHandlers=Hash.new
@subscriptionHandler = nil
@connection = Jabber::Protocol::Connection.new(host, port)
@connection.connect
unless @connection.is_connected?
raise "Session Error: Could not connected
to #{host}:#{port}"
else
@connection.send(gen_component_stream(host)) do |element|
if element.element_tag=="stream:stream"
element.consume_element
@session_id = element.attr_id
end
end
@connection.on_connection_exception do
if @session_failure_block
self.release
@session_failure_block.call
end
end
Thread.stop
end
end
# Implement JEP 0114 authentication
def authenticate_component(component_name, password)
@username = component_name
@password = password
authHandler = Proc.new do |element|
element.consume_element
if element.element_tag=="handshake"
@authenticated = true
elsif element.attr_type=="error"
@authenticated = false
end
end
authdigest=Digest::SHA1.new(@session_id + password)
authdigest="<handshake>"+authdigest.to_s+"
;</handshake>"
@connection.send(authdigest) do |element|
if element.element_tag=="handshake"
element.consume_element
@authenticated = true
elsif element.attr_type=="error"
@authenticated = false
end
end
Thread.stop
return @authenticated
end
end
end
|