BOSH.php 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189
  1. <?php
  2. /**
  3. * XMPPHP: The PHP XMPP Library
  4. * Copyright (C) 2008 Nathanael C. Fritz
  5. * This file is part of SleekXMPP.
  6. *
  7. * XMPPHP is free software; you can redistribute it and/or modify
  8. * it under the terms of the GNU General Public License as published by
  9. * the Free Software Foundation; either version 2 of the License, or
  10. * (at your option) any later version.
  11. *
  12. * XMPPHP is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public License
  18. * along with XMPPHP; if not, write to the Free Software
  19. * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  20. *
  21. * @category xmpphp
  22. * @package XMPPHP
  23. * @author Nathanael C. Fritz <JID: fritzy@netflint.net>
  24. * @author Stephan Wentz <JID: stephan@jabber.wentz.it>
  25. * @author Michael Garvin <JID: gar@netflint.net>
  26. * @copyright 2008 Nathanael C. Fritz
  27. */
  28. /** XMPPHP_XMLStream */
  29. require_once dirname(__FILE__) . "/XMPP.php";
  30. /**
  31. * XMPPHP Main Class
  32. *
  33. * @category xmpphp
  34. * @package XMPPHP
  35. * @author Nathanael C. Fritz <JID: fritzy@netflint.net>
  36. * @author Stephan Wentz <JID: stephan@jabber.wentz.it>
  37. * @author Michael Garvin <JID: gar@netflint.net>
  38. * @copyright 2008 Nathanael C. Fritz
  39. * @version $Id$
  40. */
  41. class XMPPHP_BOSH extends XMPPHP_XMPP {
  42. protected $rid;
  43. protected $sid;
  44. protected $http_server;
  45. protected $http_buffer = Array();
  46. protected $session = false;
  47. public function connect($server, $wait='1', $session=false) {
  48. $this->http_server = $server;
  49. $this->use_encryption = false;
  50. $this->session = $session;
  51. $this->rid = 3001;
  52. $this->sid = null;
  53. if($session)
  54. {
  55. $this->loadSession();
  56. }
  57. if(!$this->sid) {
  58. $body = $this->__buildBody();
  59. $body->addAttribute('hold','1');
  60. $body->addAttribute('to', $this->host);
  61. $body->addAttribute('route', "xmpp:{$this->host}:{$this->port}");
  62. $body->addAttribute('secure','true');
  63. $body->addAttribute('xmpp:version','1.6', 'urn:xmpp:xbosh');
  64. $body->addAttribute('wait', strval($wait));
  65. $body->addAttribute('ack','1');
  66. $body->addAttribute('xmlns:xmpp','urn:xmpp:xbosh');
  67. $buff = "<stream:stream xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams'>";
  68. xml_parse($this->parser, $buff, false);
  69. $response = $this->__sendBody($body);
  70. $rxml = new SimpleXMLElement($response);
  71. $this->sid = $rxml['sid'];
  72. } else {
  73. $buff = "<stream:stream xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams'>";
  74. xml_parse($this->parser, $buff, false);
  75. }
  76. }
  77. public function __sendBody($body=null, $recv=true) {
  78. if(!$body) {
  79. $body = $this->__buildBody();
  80. }
  81. $ch = curl_init($this->http_server);
  82. curl_setopt($ch, CURLOPT_HEADER, 0);
  83. curl_setopt($ch, CURLOPT_POST, 1);
  84. curl_setopt($ch, CURLOPT_POSTFIELDS, $body->asXML());
  85. curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
  86. $header = array('Accept-Encoding: gzip, deflate','Content-Type: text/xml; charset=utf-8');
  87. curl_setopt($ch, CURLOPT_HTTPHEADER, $header );
  88. curl_setopt($ch, CURLOPT_VERBOSE, 0);
  89. $output = '';
  90. if($recv) {
  91. curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
  92. $output = curl_exec($ch);
  93. $this->http_buffer[] = $output;
  94. }
  95. curl_close($ch);
  96. return $output;
  97. }
  98. public function __buildBody($sub=null) {
  99. $xml = new SimpleXMLElement("<body xmlns='http://jabber.org/protocol/httpbind' xmlns:xmpp='urn:xmpp:xbosh' />");
  100. $xml->addAttribute('content', 'text/xml; charset=utf-8');
  101. $xml->addAttribute('rid', $this->rid);
  102. $this->rid += 1;
  103. if($this->sid) $xml->addAttribute('sid', $this->sid);
  104. #if($this->sid) $xml->addAttribute('xmlns', 'http://jabber.org/protocol/httpbind');
  105. $xml->addAttribute('xml:lang', 'en');
  106. if($sub) { // ok, so simplexml is lame
  107. $p = dom_import_simplexml($xml);
  108. $c = dom_import_simplexml($sub);
  109. $cn = $p->ownerDocument->importNode($c, true);
  110. $p->appendChild($cn);
  111. $xml = simplexml_import_dom($p);
  112. }
  113. return $xml;
  114. }
  115. public function __process() {
  116. if($this->http_buffer) {
  117. $this->__parseBuffer();
  118. } else {
  119. $this->__sendBody();
  120. $this->__parseBuffer();
  121. }
  122. }
  123. public function __parseBuffer() {
  124. while ($this->http_buffer) {
  125. $idx = key($this->http_buffer);
  126. $buffer = $this->http_buffer[$idx];
  127. unset($this->http_buffer[$idx]);
  128. if($buffer) {
  129. $xml = new SimpleXMLElement($buffer);
  130. $children = $xml->xpath('child::node()');
  131. foreach ($children as $child) {
  132. $buff = $child->asXML();
  133. $this->log->log("RECV: $buff", XMPPHP_Log::LEVEL_VERBOSE);
  134. xml_parse($this->parser, $buff, false);
  135. }
  136. }
  137. }
  138. }
  139. public function send($msg) {
  140. $this->log->log("SEND: $msg", XMPPHP_Log::LEVEL_VERBOSE);
  141. $msg = new SimpleXMLElement($msg);
  142. #$msg->addAttribute('xmlns', 'jabber:client');
  143. $this->__sendBody($this->__buildBody($msg), true);
  144. #$this->__parseBuffer();
  145. }
  146. public function reset() {
  147. $this->xml_depth = 0;
  148. unset($this->xmlobj);
  149. $this->xmlobj = array();
  150. $this->setupParser();
  151. #$this->send($this->stream_start);
  152. $body = $this->__buildBody();
  153. $body->addAttribute('to', $this->host);
  154. $body->addAttribute('xmpp:restart', 'true', 'urn:xmpp:xbosh');
  155. $buff = "<stream:stream xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams'>";
  156. $response = $this->__sendBody($body);
  157. $this->been_reset = true;
  158. xml_parse($this->parser, $buff, false);
  159. }
  160. public function loadSession() {
  161. if(isset($_SESSION['XMPPHP_BOSH_RID'])) $this->rid = $_SESSION['XMPPHP_BOSH_RID'];
  162. if(isset($_SESSION['XMPPHP_BOSH_SID'])) $this->sid = $_SESSION['XMPPHP_BOSH_SID'];
  163. if(isset($_SESSION['XMPPHP_BOSH_authed'])) $this->authed = $_SESSION['XMPPHP_BOSH_authed'];
  164. if(isset($_SESSION['XMPPHP_BOSH_jid'])) $this->jid = $_SESSION['XMPPHP_BOSH_jid'];
  165. if(isset($_SESSION['XMPPHP_BOSH_fulljid'])) $this->fulljid = $_SESSION['XMPPHP_BOSH_fulljid'];
  166. }
  167. public function saveSession() {
  168. $_SESSION['XMPPHP_BOSH_RID'] = (string) $this->rid;
  169. $_SESSION['XMPPHP_BOSH_SID'] = (string) $this->sid;
  170. $_SESSION['XMPPHP_BOSH_authed'] = (boolean) $this->authed;
  171. $_SESSION['XMPPHP_BOSH_jid'] = (string) $this->jid;
  172. $_SESSION['XMPPHP_BOSH_fulljid'] = (string) $this->fulljid;
  173. }
  174. }