Merge branch 'master' into test
[GitHub/Stricted/speedport-hybrid-php-api.git] / SpeedportHybrid.class.php
1 <?php
2 require_once('lib/exception/RebootException.class.php');
3 require_once('lib/exception/RouterException.class.php');
4 require_once('lib/exception/NotImplementedException.class.php');
5 require_once('CryptLib/CryptLib.php');
6 require_once('Speedport.class.php');
7 require_once('ISpeedport.class.php');
8 require_once('lib/trait/Connection.class.php');
9 require_once('lib/trait/CryptLib.class.php');
10 require_once('lib/trait/Login.class.php');
11 require_once('lib/trait/Firewall.class.php');
12 require_once('lib/trait/Network.class.php');
13 require_once('lib/trait/Phone.class.php');
14 require_once('lib/trait/System.class.php');
15
16 /**
17 * @author Jan Altensen (Stricted)
18 * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
19 * @copyright 2015-2016 Jan Altensen (Stricted)
20 */
21 class SpeedportHybrid extends Speedport implements ISpeedport {
22 use Connection;
23 use CryptLib;
24 use Firewall;
25 use Login;
26 use Network;
27 use Phone;
28 use System;
29
30 /**
31 * class version
32 * @const string
33 */
34 const VERSION = '1.0.5';
35
36 /**
37 * check php requirements
38 */
39 protected function checkRequirements () {
40 if (!extension_loaded('curl')) {
41 throw new Exception("The PHP Extension 'curl' is missing.");
42 }
43 else if (!extension_loaded('json')) {
44 throw new Exception("The PHP Extension 'json' is missing.");
45 }
46 else if (!extension_loaded('pcre')) {
47 throw new Exception("The PHP Extension 'pcre' is missing.");
48 }
49 else if (!extension_loaded('ctype')) {
50 throw new Exception("The PHP Extension 'ctype' is missing.");
51 }
52 else if (!extension_loaded('hash')) {
53 throw new Exception("The PHP Extension 'hash' is missing.");
54 }
55 else if (!in_array('sha256', hash_algos())) {
56 throw new Exception('SHA-256 algorithm is not Supported.');
57 }
58 }
59
60 /**
61 * sends the encrypted request to router
62 *
63 * @param string $path
64 * @param mixed $fields
65 * @param string $cookie
66 * @return array
67 */
68 protected function sentEncryptedRequest ($path, $fields, $cookie = false) {
69 $count = count($fields);
70 $fields = $this->encrypt(http_build_query($fields));
71 return $this->sentRequest($path, $fields, $cookie, $count);
72 }
73
74 /**
75 * sends the request to router
76 *
77 * @param string $path
78 * @param mixed $fields
79 * @param string $cookie
80 * @param integer $count
81 * @return array
82 */
83 private function sendRequest ($path, $fields, $cookie = false, $count = 0) {
84 $url = $this->url.$path;
85 $ch = curl_init();
86 curl_setopt($ch, CURLOPT_URL, $url);
87
88 if (!empty($fields)) {
89 curl_setopt($ch, CURLOPT_POST, true);
90
91 if (is_array($fields)) {
92 curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($fields));
93 }
94 else {
95 curl_setopt($ch, CURLOPT_POSTFIELDS, $fields);
96 }
97 }
98
99 if ($cookie === true) {
100 curl_setopt($ch, CURLOPT_COOKIE, 'challengev='.$this->challenge.'; '.$this->cookie);
101 }
102
103 curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
104 curl_setopt($ch, CURLOPT_HEADER, true);
105
106 $result = curl_exec($ch);
107
108 $header_size = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
109 $header = substr($result, 0, $header_size);
110 $body = substr($result, $header_size);
111 curl_close($ch);
112
113 // check if response is empty
114 if (empty($body)) {
115 throw new RouterException('empty response');
116 }
117
118 // check if body is encrypted (hex instead of json)
119 if (ctype_xdigit($body)) {
120 $body = $this->decrypt($body);
121 }
122
123 // fix invalid json
124 $body = preg_replace("/(\r\n)|(\r)/", "\n", $body);
125 $body = preg_replace('/\'/i', '"', $body);
126 $body = preg_replace("/\[\s+\]/i", '[ {} ]', $body);
127 $body = preg_replace("/},\s+]/", "}\n]", $body);
128
129 // decode json
130 if (strpos($path, '.json') !== false) {
131 $json = json_decode($body, true);
132
133 if (is_array($json)) {
134 $body = $json;
135 }
136 }
137
138 return array('header' => $header, 'body' => $body);
139 }
140 }