Search moodle.org's
Developer Documentation

See Release Notes

  • Bug fixes for general core bugs in 3.11.x will end 14 Nov 2022 (12 months plus 6 months extension).
  • Bug fixes for security issues in 3.11.x will end 13 Nov 2023 (18 months plus 12 months extension).
  • PHP version: minimum PHP 7.3.0 Note: minimum PHP version has increased since Moodle 3.10. PHP 7.4.x is supported too.

Differences Between: [Versions 39 and 311]

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