"Fossies" - the Fresh Open Source Software Archive 
Member "fogproject-1.5.9/packages/web/lib/fog/fogurlrequests.class.php" (13 Sep 2020, 17722 Bytes) of package /linux/misc/fogproject-1.5.9.tar.gz:
As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) PHP source code syntax highlighting (style:
standard) with prefixed line numbers and
code folding option.
Alternatively you can here
view or
download the uninterpreted source code file.
See also the latest
Fossies "Diffs" side-by-side code changes report for "fogurlrequests.class.php":
1.5.8_vs_1.5.9.
1 <?php
2 /**
3 * Processes URL requests for our needs.
4 *
5 * PHP version 5
6 *
7 * @category FOGURLRequests
8 * @package FOGProject
9 * @author Tom Elliott <tommygunsster@gmail.com>
10 * @license http://opensource.org/licenses/gpl-3.0 GPLv3
11 * @link https://fogproject.org
12 */
13 /**
14 * Processes URL requests for our needs.
15 *
16 * @category FOGURLRequests
17 * @package FOGProject
18 * @author Tom Elliott <tommygunsster@gmail.com>
19 * @license http://opensource.org/licenses/gpl-3.0 GPLv3
20 * @link https://fogproject.org
21 */
22 class FOGURLRequests extends FOGBase
23 {
24 /**
25 * The maximum urls to process at one time.
26 *
27 * @var int
28 */
29 private $_windowSize = 20;
30 /**
31 * The available connection timeout.
32 *
33 * Default to 2000 milliseconds.
34 *
35 * @var int
36 */
37 private $_aconntimeout = 2000;
38 /**
39 * The base connection timeout.
40 *
41 * Defaults to 15 seconds.
42 *
43 * @var int
44 */
45 private $_conntimeout = 15;
46 /**
47 * The timeout value to process each url.
48 *
49 * Defaults to 86400 seconds or 1 day.
50 *
51 * @var int
52 */
53 private $_timeout = 86400;
54 /**
55 * Defines a specific call back request.
56 *
57 * TODO: Fixup more appropriately to get data
58 * from a callback rather than from an execution
59 * instance.
60 *
61 * @var string
62 */
63 private $_callback = '';
64 /**
65 * Contains the response of our url requests.
66 *
67 * @var array
68 */
69 private $_response = array();
70 /**
71 * Curl options to all url requests.
72 *
73 * @var array
74 */
75 public $options = array(
76 CURLOPT_SSL_VERIFYPEER => false,
77 CURLOPT_SSL_VERIFYHOST => false,
78 CURLOPT_RETURNTRANSFER => true,
79 );
80 /**
81 * Curl headers to send/request.
82 *
83 * @var array
84 */
85 private $_headers = array();
86 /**
87 * The requests themselves.
88 *
89 * @var array
90 */
91 private $_requests = array();
92 /**
93 * The mapping of requests so we can receive
94 * information in the proper order as requested.
95 *
96 * @var array
97 */
98 private $_requestMap = array();
99 /**
100 * Initializes our url requests object.
101 *
102 * @param string $callback Optional callback
103 */
104 public function __construct($callback = null)
105 {
106 parent::__construct();
107 list(
108 $aconntimeout,
109 $conntimeout,
110 $timeout
111 ) = self::getSubObjectIDs(
112 'Service',
113 array(
114 'name' => array(
115 'FOG_URL_AVAILABLE_TIMEOUT',
116 'FOG_URL_BASE_CONNECT_TIMEOUT',
117 'FOG_URL_BASE_TIMEOUT'
118 )
119 ),
120 'value',
121 false,
122 'AND',
123 'name',
124 false,
125 ''
126 );
127 if ($aconntimeout
128 && is_numeric($aconntimeout)
129 && $aconntimeout > 0
130 && $aconntimeout > $this->_aconntimeout
131 ) {
132 $this->_aconntimeout = (int)$aconntimeout;
133 }
134 if ($conntimeout
135 && is_numeric($conntimeout)
136 && $conntimeout > 0
137 ) {
138 $this->_conntimeout = (int)$conntimeout;
139 }
140 if ($timeout
141 && is_numeric($timeout)
142 && $timeout > 0
143 ) {
144 $this->_timeout = (int)$timeout;
145 }
146 $this->options[CURLOPT_CONNECTTIMEOUT] = $this->_conntimeout;
147 $this->options[CURLOPT_TIMEOUT] = $this->_timeout;
148 $this->_callback = $callback;
149 }
150 /**
151 * Cleans up when no longer needed.
152 */
153 public function __destruct()
154 {
155 $this->_windowSize = 20;
156 $this->_callback = '';
157 $this->options = array(
158 CURLOPT_SSL_VERIFYPEER => false,
159 CURLOPT_SSL_VERIFYHOST => false,
160 CURLOPT_RETURNTRANSFER => true,
161 );
162 $this->_response = array();
163 $this->_requests = array();
164 $this->_requestMap = array();
165 }
166 /**
167 * Magic caller to get specialized methods
168 * in a common method.
169 *
170 * @param string $name The method to get
171 *
172 * @return mixed
173 */
174 public function __get($name)
175 {
176 if (in_array($name, array('headers'))) {
177 $name = sprintf(
178 '_%s',
179 $name
180 );
181 }
182 return (isset($this->{$name})) ? $this->{$name} : null;
183 }
184 /**
185 * Magic caller to set specialized methods
186 * in a common method.
187 *
188 * @param string $name The method to set
189 * @param mixed $value The value to set
190 *
191 * @return object
192 */
193 public function __set($name, $value)
194 {
195 $addMethods = array(
196 'options',
197 'headers',
198 );
199 if (in_array($name, array('headers'))) {
200 $name = sprintf(
201 '_%s',
202 $name
203 );
204 }
205 if (in_array($name, $addMethods)) {
206 $this->{$name} = $value + $this->{$name};
207 } else {
208 $this->{$name} = $value;
209 }
210
211 return $this;
212 }
213 /**
214 * Add a request to the requests variable.
215 *
216 * @param FOGRollingURL $request the request to add
217 *
218 * @return object
219 */
220 public function add($request)
221 {
222 $this->_requests[] = $request;
223
224 return $this;
225 }
226 /**
227 * Generates the request and stores to our requests variable.
228 *
229 * @param string $url The url to request
230 * @param string $method The method to call
231 * @param mixed $postData The data to pass
232 * @param mixed $headers Any additional request headers to send
233 * @param mixed $options Any additional request options to use
234 *
235 * @return object
236 */
237 public function request(
238 $url,
239 $method = 'GET',
240 $postData = array(),
241 $headers = array(),
242 $options = array()
243 ) {
244 $this->_requests[] = new FOGRollingURL(
245 $url,
246 $method,
247 $postData,
248 $headers,
249 $options
250 );
251
252 return $this;
253 }
254 /**
255 * Get method url request definition.
256 *
257 * @param string $url The url to request to
258 * @param mixed $headers The custom headers to send with this
259 * @param mixed $options The custom options to send with this
260 *
261 * @return object
262 */
263 public function get(
264 $url,
265 $headers = null,
266 $options = null
267 ) {
268 return $this->request(
269 $url,
270 'GET',
271 null,
272 $headers,
273 $options
274 );
275 }
276 /**
277 * Post method url request definition.
278 *
279 * @param string $url The url to request to
280 * @param mixed $post_data The post data to send
281 * @param mixed $headers The custom headers to send with this
282 * @param mixed $options The custom options to send with this
283 *
284 * @return object
285 */
286 public function post(
287 $url,
288 $post_data = null,
289 $headers = null,
290 $options = null
291 ) {
292 return $this->request(
293 $url,
294 'POST',
295 $post_data,
296 $headers,
297 $options
298 );
299 }
300 /**
301 * Actually executes the requests.
302 * If only one request, perform a _singleCurl.
303 * If multiple perform _rollingCurl.
304 *
305 * @param mixed $window_size The window size to allow at run time
306 *
307 * @return object
308 */
309 public function execute($window_size = null)
310 {
311 $window_count = count($this->_requests);
312 if (empty($window_size)
313 || !is_numeric($window_size)
314 || $window_size > $window_count
315 ) {
316 $window_size = $window_count;
317 }
318 if ($window_count < 1) {
319 return (array) false;
320 }
321 if ($window_count === 1) {
322 return $this->_singleCurl();
323 }
324
325 return $this->_rollingCurl($window_size);
326 }
327 /**
328 * Run a single url request.
329 *
330 * @return mixed
331 */
332 private function _singleCurl()
333 {
334 $ch = curl_init();
335 $request = array_shift($this->_requests);
336 $options = $this->_getOptions($request);
337 curl_setopt_array($ch, $options);
338 $output = curl_exec($ch);
339 $info = curl_getinfo($ch, CURLINFO_HTTP_CODE);
340 curl_close($ch);
341 if ($this->_callback && is_callable($this->_callback)) {
342 $this->_callback($output, $info, $request);
343 }
344
345 return (array)$output;
346 }
347 /**
348 * Perform multiple url requests.
349 *
350 * @param mixed $window_size The customized window size to use
351 *
352 * @return mixed
353 */
354 private function _rollingCurl($window_size = null)
355 {
356 if ($window_size) {
357 $this->_windowSize = $window_size;
358 }
359 if (sizeof($this->_requests) < $this->_windowSize) {
360 $this->_windowSize = sizeof($this->_requests);
361 }
362 if ($this->_windowSize < 2) {
363 throw new Exception(_('Window size must be greater than 1'));
364 }
365 $timeout = $this->_timeout;
366 $master = curl_multi_init();
367 for ($i = 0; $i < $this->_windowSize; ++$i) {
368 $ch = curl_init();
369 $options = $this->_getOptions($this->_requests[$i]);
370 curl_setopt_array($ch, $options);
371 curl_multi_add_handle($master, $ch);
372 $key = (string) $ch;
373 $this->_requestMap[$key] = $i;
374 }
375 do {
376 while ((
377 $execrun = curl_multi_exec(
378 $master,
379 $running
380 )
381 ) == CURLM_CALL_MULTI_PERFORM) {
382 }
383 if ($execrun != CURLM_OK) {
384 break;
385 }
386 while ($done = curl_multi_info_read($master)) {
387 $info = curl_getinfo($done['handle'], CURLINFO_HTTP_CODE);
388 $key = (string)$done['handle'];
389 $output = curl_multi_getcontent($done['handle']);
390 $this->_response[$this->_requestMap[$key]] = $output;
391 if ($this->_callback && is_callable($this->_callback)) {
392 $request = $this->_requests[$this->_requestMap[$key]];
393 $this->_callback($output, $info, $request);
394 }
395 $sizeof = sizeof($this->_requests);
396 if ($i < $sizeof
397 && isset($this->_requests[$i])
398 ) {
399 $ch = curl_init();
400 $options = $this->_getOptions($this->_requests[$i]);
401 curl_setopt_array($ch, $options);
402 curl_multi_add_handle($master, $ch);
403 $key = (string) $ch;
404 $this->_requestMap[$key] = $i;
405 ++$i;
406 } else {
407 unset(
408 $this->_requests[$this->_requestMap[$key]],
409 $this->_requestMap[$key]
410 );
411 }
412 curl_multi_remove_handle($master, $done['handle']);
413 }
414 if ($running) {
415 curl_multi_select($master, $timeout);
416 }
417 } while ($running);
418 ksort($this->_response);
419 curl_multi_close($master);
420
421 return $this->_response;
422 }
423 /**
424 * Get options of the request and whole.
425 *
426 * @param FOGRollingURL $request the request to get options from
427 *
428 * @return array
429 */
430 private function _getOptions($request)
431 {
432 $options = $this->__get('options');
433 if (ini_get('safe_mode') == 'Off' || !ini_get('safe_mode')) {
434 $options[CURLOPT_FOLLOWLOCATION] = 1;
435 $options[CURLOPT_MAXREDIRS] = 5;
436 }
437 $url = $this->_validUrl($request->url);
438 $headers = $this->__get('headers');
439 if ($request->options) {
440 $options = $request->options + $options;
441 }
442 $options[CURLOPT_URL] = $url;
443 if ($request->postData) {
444 $options[CURLOPT_POST] = 1;
445 $options[CURLOPT_POSTFIELDS] = $request->postData;
446 }
447 if ($headers) {
448 $options[CURLOPT_HEADER] = 0;
449 $options[CURLOPT_HTTPHEADER] = (array)$headers;
450 }
451 list($ip, $password, $port, $username) = self::getSubObjectIDs(
452 'Service',
453 array(
454 'name' => array(
455 'FOG_PROXY_IP',
456 'FOG_PROXY_PASSWORD',
457 'FOG_PROXY_PORT',
458 'FOG_PROXY_USERNAME',
459 ),
460 ),
461 'value',
462 false,
463 'AND',
464 'name',
465 false,
466 false
467 );
468 $IPs = self::getSubObjectIDs('StorageNode', array('isEnabled' => 1));
469 $pat = sprintf(
470 '#%s#i',
471 implode('|', $IPs)
472 );
473 if (!preg_match($pat, $url)) {
474 if ($ip) {
475 $options[CURLOPT_PROXYAUTH] = CURLAUTH_BASIC;
476 $options[CURLOPT_PROXYPORT] = $port;
477 $options[CURLOPT_PROXY] = $ip;
478 if ($username) {
479 $options[CURLOPT_PROXYUSERPWD] = sprintf(
480 '%s:%s',
481 $username,
482 $password
483 );
484 }
485 }
486 }
487
488 return $options;
489 }
490 /**
491 * Function simply ensures the url is valid.
492 *
493 * @param string $url The url test check
494 *
495 * @return string
496 */
497 private function _validUrl(&$url)
498 {
499 $url = filter_var($url, FILTER_SANITIZE_URL);
500 if (false === filter_var($url, FILTER_VALIDATE_URL)) {
501 unset($url);
502 }
503
504 return $url;
505 }
506 /**
507 * Processes the requests as needed.
508 *
509 * @param mixed $urls the urls to process
510 * @param string $method the method to use for all urls
511 * @param mixed $data post/get data possibly
512 * @param bool $sendAsJSON Send data as json if needed
513 * @param mixed $auth Any authorization data needed
514 * @param string $callback A callback to use if needed
515 * @param string $file A filename to use to download a file
516 * @param mixed $timeout allow updating timeout values
517 *
518 * @return array
519 */
520 public function process(
521 $urls,
522 $method = 'GET',
523 $data = null,
524 $sendAsJSON = false,
525 $auth = false,
526 $callback = false,
527 $file = false,
528 $timeout = false
529 ) {
530 $this->__destruct();
531 if (false !== $timeout) {
532 $this->_timeout = (int)$timeout;
533 $this->options[CURLOPT_TIMEOUT] = (int)$timeout;
534 }
535 if ($callback && is_callable($callback)) {
536 $this->_callback = $callback;
537 }
538 if ($auth) {
539 $this->options[CURLOPT_USERPWD] = $auth;
540 }
541 if ($sendAsJSON) {
542 $data2 = json_encode($data);
543 $datalen = strlen($data2);
544 $this->options[CURLOPT_HEADER] = true;
545 $this->options[CURLOPT_HTTPHEADER] = array(
546 'Content-Type: application/json',
547 "Content-Length: $datalen",
548 'Expect:',
549 );
550 }
551 if ($file) {
552 $this->options[CURLOPT_FILE] = $file;
553 }
554 $this->options[CURLOPT_USERAGENT] = 'Mozilla/5.0 (Linux x86_64; rv:80.0) Gecko/20100101 Firefox/80.0';
555 foreach ((array) $urls as &$url) {
556 if ($method === 'GET') {
557 $this->get($url);
558 } else {
559 $this->post($url, $data);
560 }
561 unset($url);
562 }
563
564 return $this->execute();
565 }
566 /**
567 * Quick test if url is available.
568 *
569 * @param string $urls the url to check.
570 * @param int $timeout the timeout value.
571 * @param int $port the port to test on.
572 *
573 * @return void
574 */
575 public function isAvailable($urls, $timeout = 30, $port = -1)
576 {
577 $this->__destruct();
578 $output = array();
579 if (empty($timeout) || !$timeout || $timeout < 1) {
580 $timeout = 30;
581 }
582 foreach ((array) $urls as &$url) {
583 $url = parse_url($url);
584 if (!isset($url['host']) && isset($url['path'])) {
585 $url['host'] = $url['path'];
586 }
587 if ($port == -1 || empty($port) || !$port) {
588 if (!isset($url['port']) && isset($url['scheme'])) {
589 switch ($url['scheme']) {
590 case "http":
591 $port = 80;
592 break;
593 case "https":
594 $port = 443;
595 break;
596 case "ftp":
597 $port = 21;
598 break;
599 default:
600 $port = self::$FOGFTP->get('port');
601 }
602 } else {
603 $port = self::$FOGFTP->get('port');
604 }
605 }
606 $socket = @fsockopen(
607 $url['host'],
608 $port,
609 $errno,
610 $errstr,
611 $timeout
612 );
613 if (!$socket) {
614 $output[] = false;
615 continue;
616 }
617 $output[] = true;
618 fclose($socket);
619 unset($url);
620 }
621
622 return $output;
623 }
624 }