MDL-65743 lib: update moodle library docs
[moodle.git] / lib / jabber / XMPP / BOSH.php
1 <?php
3 namespace BirknerAlex\XMPPHP;
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      */
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;
52     public function connect($server, $wait = '1', $session = false)
53     {
54         $this->http_server = $server;
55         $this->use_encryption = false;
56         $this->session = $session;
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'];
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     }
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     }
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     }
127     public function __process()
128     {
129         if ($this->http_buffer) {
130             $this->__parseBuffer();
131         } else {
132             $this->__sendBody();
133             $this->__parseBuffer();
134         }
135     }
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     }
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     }
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     }
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     }
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     }