adhearsion/blather

Unable to use raw Blather::Stream

Opened this issue · 9 comments

brbrr commented

Blather::Stream can be used to build your own handler system if Blather's

doesn't suit your needs.

https://github.com/adhearsion/blather/blob/develop/lib/blather/stream.rb#L5

example in code is not work. even if it started in EM block I got:

NameError: undefined local variable or method `start' for #<Blather::Stream:0x007fdcb2694010>
from /Users/brbrr/.rbenv/versions/2.2.0/lib/ruby/gems/2.2.0/gems/blather-1.1.4/lib/blather/stream.rb:160:in `connection_completed'

I came to raw Stream, because I need to init new session in custom way, sending some custom stanza's

Please provide the code you used.

Additionally, try using Blather::Stream::Client.

brbrr commented
  # @example Create a new stream and handle it with our own class
  #     class MyClient
  #       attr :jid
  #
  #       def post_init(stream, jid = nil)
  #         @stream = stream
  #         self.jid = jid
  #         p "Stream Started"
  #       end
  #
  #       # Pretty print the stream
  #       def receive_data(stanza)
  #         pp stanza
  #       end
  #
  #       def unbind
  #         p "Stream Ended"
  #       end
  #
  #       def write(what)
  #         @stream.write what
  #       end
  #     end
  #
  #     client = Blather::Stream.start MyClient.new, "jid@domain/res", "pass"
  #     client.write "[pure xml over the wire]"

I cant use it, since it tries to register when I don't need it. Also I need to send some specific stanzas before actual login.

I cant use it, since it tries to register when I don't need it.

Actually, it doesn't. You're thinking of Blather::Client. Might you perhaps contribute a fix to #151 to resolve that problem, though? We're always in need of contributors.

brbrr commented

actually it is.

class HandlingClient
  attr_accessor :jid

  def post_init
    #stream started
    puts 'init'
  end

  def unbind
    #stream closed
    puts 'unbind'
  end

  def receive_data(stanza_or_error)
    #handle incoming stanza or error
    puts stanza_or_error
  end
end
handler = HandlingClient.new

EM.run { Blather::Stream::Client.start handler, jid, password }

And I got:

D, [2016-01-06T23:11:57.696894 #33273] DEBUG -- : USING JID: user_name@host_name
D, [2016-01-06T23:11:57.736473 #33273] DEBUG -- : SENDING: (/stream/client.rb:12:in `start') <stream:stream to='host_name' xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams' version='1.0' xml:lang='en'>
D, [2016-01-06T23:11:57.777742 #33273] DEBUG -- : RECEIVING (stream) <stream:stream xmlns:stream="http://etherx.jabber.org/streams" id="1558387797" from="host_name" version="1.0" lang="en"/>
D, [2016-01-06T23:11:57.778394 #33273] DEBUG -- : RECEIVING (features) <stream:features xmlns:stream="http://etherx.jabber.org/streams">
  <mechanisms xmlns="urn:ietf:params:xml:ns:xmpp-sasl">
    <mechanism>PLAIN</mechanism>
    <mechanism>DIGEST-MD5</mechanism>
    <mechanism>SCRAM-SHA-1</mechanism>
  </mechanisms>
  <register xmlns="http://jabber.org/features/iq-register"/>
  <sm xmlns="urn:xmpp:sm:3"/>
</stream:features>
D, [2016-01-06T23:11:57.778996 #33273] DEBUG -- : SENDING: (/stream/features/sasl.rb:102:in `authenticate') <auth xmlns="urn:ietf:params:xml:ns:xmpp-sasl" mechanism="DIGEST-MD5"/>
D, [2016-01-06T23:11:57.818931 #33273] DEBUG -- : RECEIVING (challenge) <challenge xmlns="urn:ietf:params:xml:ns:xmpp-sasl">bm9uY2U9IjMxMDQ3NTIwMCIscW9wPSJhdXRoIixjaGFyc2V0PXV0Zi04LGFsZ29yaXRobT1tZDUtc2Vzcw==</challenge>
D, [2016-01-06T23:11:57.819953 #33273] DEBUG -- : SENDING: (/stream/features/sasl.rb:168:in `respond') <response xmlns="urn:ietf:params:xml:ns:xmpp-sasl">bm9uY2U9IjMxMDQ3NTIwMCIsY2hhcnNldD11dGYtOCx1c2VybmFtZT0iKzM4MDYzNDg5NDgzNSIscmVhbG09InZlZ2EuYWNjZWxpb3IuY29tIixjbm9uY2U9ImUyOGE0ZmM3MGJkYzI0MTQ5MWU5OTg3M2U5ZmU1MjY0IixuYz0wMDAwMDAwMSxxb3A9YXV0aCxkaWdlc3QtdXJpPSJ4bXBwL3ZlZ2EuYWNjZWxpb3IuY29tIixyZXNwb25zZT1iYzE1NjA1M2UwM2ZmZjc5M2IzMjAwYmYzNDcxOWNlNw==</response>
D, [2016-01-06T23:11:57.861320 #33273] DEBUG -- : RECEIVING (challenge) <challenge xmlns="urn:ietf:params:xml:ns:xmpp-sasl">cnNwYXV0aD03YWMxZmMxZTdjYjg1MjFiMzgzOGI3NWRkOGVjNTk0OQ==</challenge>
D, [2016-01-06T23:11:57.861820 #33273] DEBUG -- : SENDING: (/stream/features/sasl.rb:168:in `respond') <response xmlns="urn:ietf:params:xml:ns:xmpp-sasl"/>
D, [2016-01-06T23:11:57.902055 #33273] DEBUG -- : RECEIVING (success) <success xmlns="urn:ietf:params:xml:ns:xmpp-sasl"/>
D, [2016-01-06T23:11:57.902875 #33273] DEBUG -- : SENDING: (/stream/client.rb:12:in `start') <stream:stream to='host_name' xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams' version='1.0' xml:lang='en'>
D, [2016-01-06T23:11:57.943719 #33273] DEBUG -- : RECEIVING (stream) <stream:stream xmlns:stream="http://etherx.jabber.org/streams" id="2058319209" from="host_name" version="1.0" lang="en"/>
D, [2016-01-06T23:11:57.944176 #33273] DEBUG -- : RECEIVING (features) <stream:features xmlns:stream="http://etherx.jabber.org/streams">
  <bind xmlns="urn:ietf:params:xml:ns:xmpp-bind"/>
  <session xmlns="urn:ietf:params:xml:ns:xmpp-session"/>
  <register xmlns="http://jabber.org/features/iq-register"/>
  <sm xmlns="urn:xmpp:sm:3"/>
</stream:features>
D, [2016-01-06T23:11:57.944975 #33273] DEBUG -- : SENDING: (/stream/features/resource.rb:39:in `bind') <iq type="set" id="blather0001">
  <bind xmlns="urn:ietf:params:xml:ns:xmpp-bind"/>
</iq>
D, [2016-01-06T23:11:57.985178 #33273] DEBUG -- : RECEIVING (iq) <iq id="blather0001" type="result">
  <bind xmlns="urn:ietf:params:xml:ns:xmpp-bind">
    <jid>user_name@host_name/11660279821452114717961106</jid>
  </bind>
</iq>
D, [2016-01-06T23:11:57.985481 #33273] DEBUG -- : USING JID: user_name@host_name/11660279821452114717961106
D, [2016-01-06T23:11:57.985944 #33273] DEBUG -- : SENDING: (/stream/features/session.rb:40:in `session') <iq type="set" id="blather0003" to="host_name">
  <session xmlns="urn:ietf:params:xml:ns:xmpp-session"/>
</iq>
D, [2016-01-06T23:11:58.026644 #33273] DEBUG -- : RECEIVING (iq) <iq type="result" from="host_name" id="blather0003">
  <session xmlns="urn:ietf:params:xml:ns:xmpp-session"/>
</iq>
D, [2016-01-06T23:11:58.028329 #33273] DEBUG -- : SENDING: (/stream/features/register.rb:22:in `receive_data') <iq type="set" id="blather0005">
  <query xmlns="jabber:iq:register">
    <username>user_name</username>
    <password>15b9680c-cee0-5c35-bc99-dc80e711be38</password>
  </query>
</iq>
D, [2016-01-06T23:11:58.069108 #33273] DEBUG -- : RECEIVING (iq) <iq from="user_name@host_name" to="user_name@host_name/11660279821452114717961106" type="error" lang="en" id="blather0005">
  <query xmlns="jabber:iq:register">
    <username>user_name</username>
    <password>15b9680c-cee0-5c35-bc99-dc80e711be38</password>
  </query>
  <error code="503" type="cancel">
    <service-unavailable xmlns="urn:ietf:params:xml:ns:xmpp-stanzas"/>
  </error>
</iq>
D, [2016-01-06T23:11:58.069647 #33273] DEBUG -- : SENDING: (/stream.rb:248:in `stop') </stream:stream>
D, [2016-01-06T23:11:58.110034 #33273] DEBUG -- : RECEIVING (end) <stream:end xmlns:stream="http://etherx.jabber.org/streams"/>
user_name15b9680c-cee0-5c35-bc99-dc80e711be38

same use-case with xmpp4r works perfectly fine

actually it is.

You are indeed correct - we do not have a Stream which does not respond to features before establishing a session.

Is it indeed permitted to send stanzas before session establishment? Could you tell us more about your use-case?

same use-case with xmpp4r works perfectly fine

What does xmpp4r do? Do you have wire logs to demonstrate what it is you expect? Maybe a code sample so we can see how you do it?

brbrr commented

This is mobile messenger like WhatsUp, of Viber.
I need to send few iq stanzas for authorization process. It's should be similar to WhatsUp:

  1. iq:authorization with phone number to request sms with OTP;
  2. iq:confirm_authorization with received OTP to get password.

btw, my debug log is not about sending custom stanzas, but for next step - actually login with recieved password.

Unfortunately you didn't fully answer my questions. The best I can do is say you'll need to understand how Stream's statemachine works and hook into that.

brbrr commented

Sorry, I missed last part regarding xmpp4r

with it I can split connection and auth phases like so:

require 'xmpp4r/client'
require 'xmpp4r/roster'
include Jabber

#just to see whats going on
Jabber.debug = true

cli = Client.new jid
cli.connect
if(password.empty?)
  // sending some custom stanza's to get password
end
cl.auth(password)

And here is log for connect method. it just sending initial stanza, and parsing responses

D, [2016-01-07T15:31:23.663583 #16684] DEBUG -- : RESOLVING:
    _xmpp-client._tcp.example.com (SRV)
D, [2016-01-07T15:31:23.798183 #16684] DEBUG -- : CONNECTING:
    example.com:5222
D, [2016-01-07T15:31:23.840103 #16684] DEBUG -- : SENDING:
    <stream:stream xmlns:stream='http://etherx.jabber.org/streams'
    xmlns='jabber:client' to='example.com' xml:lang='en' version='1.0' >
D, [2016-01-07T15:31:23.881185 #16684] DEBUG -- : RECEIVED:
    <stream:stream from='example.com' id='3940058200'
      xml:lang='en' xmlns:stream='http://etherx.jabber.org/streams'
      version='1.0' xmlns='jabber:client'/>
D, [2016-01-07T15:31:23.883814 #16684] DEBUG -- : RECEIVED:
    <stream:features>
      <mechanisms xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>
        <mechanism>PLAIN</mechanism><mechanism>DIGEST-MD5</mechanism>
        <mechanism>SCRAM-SHA-1</mechanism></mechanisms>
      <register xmlns='http://jabber.org/features/iq-register'/><sm xmlns='urn:xmpp:sm:3'/>
    </stream:features>
D, [2016-01-07T15:31:23.884107 #16684] DEBUG -- : FEATURES: waiting...
D, [2016-01-07T15:31:23.885272 #16684] DEBUG -- : FEATURES: received
D, [2016-01-07T15:31:23.885957 #16684] DEBUG -- : PROCESSING:
    <stream:features xmlns='jabber:client'>
      <mechanisms xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>
        <mechanism>PLAIN</mechanism><mechanism>DIGEST-MD5</mechanism>
        <mechanism>SCRAM-SHA-1</mechanism></mechanisms>
      <register xmlns='http://jabber.org/features/iq-register'/>
    <sm xmlns='urn:xmpp:sm:3'/></stream:features> (REXML::Element)
D, [2016-01-07T15:31:23.886045 #16684] DEBUG -- : FEATURES: waiting finished
D, [2016-01-07T15:31:23.886105 #16684] DEBUG -- : TRYING stanzacbs...
D, [2016-01-07T15:31:23.886237 #16684] DEBUG -- : TRYING message/iq/presence/cbs...