Class: Jabber::HTTPBinding::Client
- Inherits:
-
Client
- Object
- Stream
- Connection
- Client
- Jabber::HTTPBinding::Client
- Defined in:
- lib/xmpp4r/httpbinding/client.rb
Overview
This class implements an alternative Client using HTTP Binding (JEP0124).
This class is designed to be a drop-in replacement for Jabber::Client, except for the Jabber::HTTP::Client#connect method which takes an URI as argument.
HTTP requests are buffered to not exceed the negotiated ‘polling’ and ‘requests’ parameters.
Stanzas in HTTP resonses may be delayed to arrive in the order defined by ‘rid’ parameters.
Debugging
Turning Jabber::debug to true will make debug output not only spit out stanzas but HTTP request/response bodies, too.
Constant Summary
Constants inherited from Stream
Stream::CONNECTED, Stream::DISCONNECTED
Instance Attribute Summary collapse
-
#http_content_type ⇒ Object
Content-Type to be used for communication (you can set this to “text/html”).
-
#http_hold ⇒ Object
The server may hold this amount of stanzas to reduce number of HTTP requests.
-
#http_ssl_setup ⇒ Object
Hook to initialize SSL parameters on Net::HTTP.
-
#http_wait ⇒ Object
The server should wait this value seconds if there is no stanza to be received.
Attributes inherited from Client
Attributes inherited from Connection
#allow_tls, #features_timeout, #host, #keepalive_interval, #port, #ssl_capath, #ssl_verifycb, #use_ssl
Attributes inherited from Stream
Instance Method Summary collapse
-
#close ⇒ Object
Close the session by sending <body type=‘terminate’/>.
-
#connect(uri, host = nil, port = 5222) ⇒ Object
Set up the stream using uri as the HTTP Binding URI.
-
#ensure_one_pending_request ⇒ Object
Ensure that there is one pending request.
-
#http_proxy_env ⇒ Object
Set up proxy from the environment variables.
-
#http_proxy_uri=(uri) ⇒ Object
- url
- URI::Generic or String
-
of the form: when without proxy authentication proxy_host:proxy_port/ when with proxy authentication proxy_user:proxy_password@proxy_host:proxy_port/.
-
#initialize(jid) ⇒ Client
constructor
- Initialize jid
-
[JID or String].
Methods inherited from Client
#auth, #auth_anonymous, #auth_anonymous_sasl, #auth_nonsasl, #auth_sasl, #bind, #password=, #register, #register_info, #remove_registration, #start, #supports_anonymous?, #unbind
Methods inherited from Connection
#accept_features, #close!, #is_tls?, #start, #starttls
Methods inherited from Stream
#add_iq_callback, #add_message_callback, #add_presence_callback, #add_stanza_callback, #add_xml_callback, #close!, #delete_iq_callback, #delete_message_callback, #delete_presence_callback, #delete_stanza_callback, #delete_xml_callback, #iq_callbacks, #is_connected?, #is_disconnected?, #message_callbacks, #on_exception, #parse_failure, #parser_end, #presence_callbacks, #receive, #send, #send_with_id, #stanza_callbacks, #start, #stop, #xml_callbacks
Constructor Details
#initialize(jid) ⇒ Client
Initialize
- jid
- JID or String
51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 |
# File 'lib/xmpp4r/httpbinding/client.rb', line 51 def initialize(jid) super @lock = Mutex.new @pending_requests = 0 @last_send = Time.at(0) @send_buffer = '' @http_requests = 1 @http_wait = 20 @http_hold = 1 @http_content_type = 'text/xml; charset=utf-8' @no_proxy = [] @proxy_args = [] end |
Instance Attribute Details
#http_content_type ⇒ Object
Content-Type to be used for communication (you can set this to “text/html”)
38 39 40 |
# File 'lib/xmpp4r/httpbinding/client.rb', line 38 def http_content_type @http_content_type end |
#http_hold ⇒ Object
The server may hold this amount of stanzas to reduce number of HTTP requests
44 45 46 |
# File 'lib/xmpp4r/httpbinding/client.rb', line 44 def http_hold @http_hold end |
#http_ssl_setup ⇒ Object
Hook to initialize SSL parameters on Net::HTTP
46 47 48 |
# File 'lib/xmpp4r/httpbinding/client.rb', line 46 def http_ssl_setup @http_ssl_setup end |
#http_wait ⇒ Object
The server should wait this value seconds if there is no stanza to be received
41 42 43 |
# File 'lib/xmpp4r/httpbinding/client.rb', line 41 def http_wait @http_wait end |
Instance Method Details
#close ⇒ Object
Close the session by sending <body type=‘terminate’/>
178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 |
# File 'lib/xmpp4r/httpbinding/client.rb', line 178 def close @status = DISCONNECTED req_body = nil @lock.synchronize { req_body = "<body" req_body += " rid='#{@http_rid += 1}'" req_body += " sid='#{@http_sid}'" req_body += " type='terminate'" req_body += " xmlns='http://jabber.org/protocol/httpbind'" req_body += ">" req_body += "<presence type='unavailable' xmlns='jabber:client'/>" req_body += "</body>" current_rid = @http_rid @pending_requests += 1 @last_send = Time.now } res_body = post(req_body, "terminate sid=#{@http_sid} rid=#{@http_rid}") sleep(3) Jabber::debuglog("Connection closed") end |
#connect(uri, host = nil, port = 5222) ⇒ Object
Set up the stream using uri as the HTTP Binding URI
You may optionally pass host and port parameters to make use of the JEP0124 ‘route’ feature.
- uri
- URI::Generic or String
- host
- String
-
Optional host to route to
- port
- Fixnum
-
Port for route feature
118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 |
# File 'lib/xmpp4r/httpbinding/client.rb', line 118 def connect(uri, host=nil, port=5222) uri = URI::parse(uri) unless uri.kind_of? URI::Generic @uri = uri @allow_tls = false # Shall be done at HTTP level @stream_mechanisms = [] @stream_features = {} @http_rid = IdGenerator.generate_id.to_i @pending_rid = @http_rid @pending_rid_lock = Mutex.new @pending_rid_cv = [] # [ [rid, cv], [rid, cv], ... ] req_body = REXML::Element.new('body') req_body.attributes['rid'] = @http_rid req_body.attributes['content'] = @http_content_type req_body.attributes['hold'] = @http_hold.to_s req_body.attributes['wait'] = @http_wait.to_s req_body.attributes['to'] = @jid.domain if host req_body.attributes['route'] = "xmpp:#{host}:#{port}" end req_body.attributes['secure'] = 'true' req_body.attributes['xmlns'] = 'http://jabber.org/protocol/httpbind' res_body = post(req_body, "sid=new rid=#{@http_rid}") unless res_body.name == 'body' raise 'Response body is no <body/> element' end @streamid = res_body.attributes['authid'] @status = CONNECTED @http_sid = res_body.attributes['sid'] @http_wait = res_body.attributes['wait'].to_i if res_body.attributes['wait'] @http_hold = res_body.attributes['hold'].to_i if res_body.attributes['hold'] @http_inactivity = res_body.attributes['inactivity'].to_i @http_polling = res_body.attributes['polling'].to_i @http_polling = 5 if @http_polling == 0 @http_requests = res_body.attributes['requests'].to_i @http_requests = 1 if @http_requests == 0 receive_elements_with_rid(@http_rid, res_body.children) @features_sem.run end |
#ensure_one_pending_request ⇒ Object
Ensure that there is one pending request
Will be automatically called if you’ve sent a stanza.
167 168 169 170 171 172 173 |
# File 'lib/xmpp4r/httpbinding/client.rb', line 167 def ensure_one_pending_request return if is_disconnected? if @lock.synchronize { @pending_requests } < 1 send_data('') end end |
#http_proxy_env ⇒ Object
Set up proxy from the environment variables
Following environment variables are considered HTTP_PROXY, http_proxy NO_PROXY, no_proxy HTTP_PROXY_USER, HTTP_PROXY_PASSWORD
93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 |
# File 'lib/xmpp4r/httpbinding/client.rb', line 93 def http_proxy_env @proxy_args = [] env_proxy = ENV['http_proxy'] || ENV['HTTP_PROXY'] return if env_proxy.nil? or env_proxy.empty? uri = URI.parse env_proxy unless uri.user or uri.password then uri.user = CGI.escape (ENV['http_proxy_user'] || ENV['HTTP_PROXY_USER']) rescue nil uri.password = CGI.escape (ENV['http_proxy_pass'] || ENV['HTTP_PROXY_PASS']) rescue nil end self.http_proxy_uri = uri @no_proxy = (ENV['NO_PROXY'] || ENV['no_proxy'] || 'localhost, 127.0.0.1').split(/\s*,\s*/) end |
#http_proxy_uri=(uri) ⇒ Object
- url
- URI::Generic or String
-
of the form:
when without proxy authentication
http://proxy_host:proxy_port/
when with proxy authentication
http://proxy_user:proxy_password@proxy_host:proxy_port/
76 77 78 79 80 81 82 83 84 |
# File 'lib/xmpp4r/httpbinding/client.rb', line 76 def http_proxy_uri=(uri) uri = URI.parse(uri) unless uri.respond_to?(:host) @proxy_args = [ uri.host, uri.port, uri.user, uri.password, ] end |