Bearsampp 2026.9.23
Loading...
Searching...
No Matches
PEAR_REST Class Reference

Public Member Functions

 __construct (&$config, $options=array())
 downloadHttp ($url, $lastmodified=null, $accept=false, $channel=false)
 getCache ($url)
 getCacheId ($url)
 retrieveCacheFirst ($url, $accept=false, $forcestring=false, $channel=false)
 retrieveData ($url, $accept=false, $forcestring=false, $channel=false)
 saveCache ($url, $contents, $lastmodified, $nochange=false, $cacheid=null)
 saveCacheFile ($file, $contents)
 useLocalCache ($url, $cacheid=null)

Data Fields

 $_options
 $config

Detailed Description

Definition at line 35 of file REST.php.

Constructor & Destructor Documentation

◆ __construct()

__construct ( & $config,
$options = array() )

Definition at line 40 of file REST.php.

41 {
42 $this->config = &$config;
43 $this->_options = $options;
44 }
$options
Definition pearcmd.php:145

References $config, and $options.

Member Function Documentation

◆ downloadHttp()

downloadHttp ( $url,
$lastmodified = null,
$accept = false,
$channel = false )

Efficiently Download a file through HTTP. Returns downloaded file as a string in-memory This is best used for small files

If an HTTP proxy has been configured (http_proxy PEAR_Config setting), the proxy will be used.

Parameters
string$urlthe URL to download
string$save_dirdirectory to save file in
false | string | array$lastmodifiedheader values to check against for caching use false to return the header values from this download
false | array$acceptAccept headers to send
Returns
string|array Returns the contents of the downloaded file or a PEAR error on failure. If the error is caused by socket-related errors, the error object will have the fsockopen error code available through getCode(). If caching is requested, then return the header values.

@access public

Definition at line 338 of file REST.php.

339 {
340 static $redirect = 0;
341 // always reset , so we are clean case of error
342 $wasredirect = $redirect;
343 $redirect = 0;
344
345 $info = parse_url($url);
346 if (!isset($info['scheme']) || !in_array($info['scheme'], array('http', 'https'))) {
347 return PEAR::raiseError('Cannot download non-http URL "' . $url . '"');
348 }
349
350 if (!isset($info['host'])) {
351 return PEAR::raiseError('Cannot download from non-URL "' . $url . '"');
352 }
353
354 $host = isset($info['host']) ? $info['host'] : null;
355 $port = isset($info['port']) ? $info['port'] : null;
356 $path = isset($info['path']) ? $info['path'] : null;
357 $schema = (isset($info['scheme']) && $info['scheme'] == 'https') ? 'https' : 'http';
358
359 $proxy = new PEAR_Proxy($this->config);
360
361 if (empty($port)) {
362 $port = (isset($info['scheme']) && $info['scheme'] == 'https') ? 443 : 80;
363 }
364
365 if ($proxy->isProxyConfigured() && $schema === 'http') {
366 $request = "GET $url HTTP/1.1\r\n";
367 } else {
368 $request = "GET $path HTTP/1.1\r\n";
369 }
370
371 $request .= "Host: $host\r\n";
372 $ifmodifiedsince = '';
373 if (is_array($lastmodified)) {
374 if (isset($lastmodified['Last-Modified'])) {
375 $ifmodifiedsince = 'If-Modified-Since: ' . $lastmodified['Last-Modified'] . "\r\n";
376 }
377
378 if (isset($lastmodified['ETag'])) {
379 $ifmodifiedsince .= "If-None-Match: $lastmodified[ETag]\r\n";
380 }
381 } else {
382 $ifmodifiedsince = ($lastmodified ? "If-Modified-Since: $lastmodified\r\n" : '');
383 }
384
385 $request .= $ifmodifiedsince .
386 "User-Agent: PEAR/1.10.18/PHP/" . PHP_VERSION . "\r\n";
387
388 $username = $this->config->get('username', null, $channel);
389 $password = $this->config->get('password', null, $channel);
390
391 if ($username && $password) {
392 $tmp = base64_encode("$username:$password");
393 $request .= "Authorization: Basic $tmp\r\n";
394 }
395
396 $proxyAuth = $proxy->getProxyAuth();
397 if ($proxyAuth) {
398 $request .= 'Proxy-Authorization: Basic ' .
399 $proxyAuth . "\r\n";
400 }
401
402 if ($accept) {
403 $request .= 'Accept: ' . implode(', ', $accept) . "\r\n";
404 }
405
406 $request .= "Accept-Encoding:\r\n";
407 $request .= "Connection: close\r\n";
408 $request .= "\r\n";
409
410 $secure = ($schema == 'https');
411 $fp = $proxy->openSocket($host, $port, $secure);
412 if (PEAR::isError($fp)) {
413 return $fp;
414 }
415
416 fwrite($fp, $request);
417
418 $headers = array();
419 $reply = 0;
420 while ($line = trim(fgets($fp, 1024))) {
421 if (preg_match('/^([^:]+):\s+(.*)\s*\\z/', $line, $matches)) {
422 $headers[strtolower($matches[1])] = trim($matches[2]);
423 } elseif (preg_match('|^HTTP/1.[01] ([0-9]{3}) |', $line, $matches)) {
424 $reply = (int)$matches[1];
425 if ($reply == 304 && ($lastmodified || ($lastmodified === false))) {
426 return false;
427 }
428
429 if (!in_array($reply, array(200, 301, 302, 303, 305, 307))) {
430 return PEAR::raiseError("File $schema://$host:$port$path not valid (received: $line)");
431 }
432 }
433 }
434
435 if ($reply != 200) {
436 if (!isset($headers['location'])) {
437 return PEAR::raiseError("File $schema://$host:$port$path not valid (redirected but no location)");
438 }
439
440 if ($wasredirect > 4) {
441 return PEAR::raiseError("File $schema://$host:$port$path not valid (redirection looped more than 5 times)");
442 }
443
444 $redirect = $wasredirect + 1;
445 return $this->downloadHttp($headers['location'], $lastmodified, $accept, $channel);
446 }
447
448 $length = isset($headers['content-length']) ? $headers['content-length'] : -1;
449
450 $data = '';
451 if (isset($headers['transfer-encoding']) && strtolower($headers['transfer-encoding']) === 'chunked') {
452 while (!feof($fp)) {
453 $chunk_size = hexdec(fgets($fp));
454 if ($chunk_size === 0) {
455 break;
456 }
457 $data .= fread($fp, $chunk_size);
458 fgets($fp); // Skip the trailing CRLF
459 }
460 } else {
461 while ($chunk = @fread($fp, 8192)) {
462 $data .= $chunk;
463 }
464 }
465 fclose($fp);
466
467 if ($lastmodified === false || $lastmodified) {
468 if (isset($headers['etag'])) {
469 $lastmodified = array('ETag' => $headers['etag']);
470 }
471
472 if (isset($headers['last-modified'])) {
473 if (is_array($lastmodified)) {
474 $lastmodified['Last-Modified'] = $headers['last-modified'];
475 } else {
476 $lastmodified = $headers['last-modified'];
477 }
478 }
479
480 return array($data, $lastmodified, $headers);
481 }
482
483 return $data;
484 }
$port
downloadHttp($url, $lastmodified=null, $accept=false, $channel=false)
Definition REST.php:338

References $port, and downloadHttp().

Referenced by downloadHttp(), and retrieveData().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ getCache()

getCache ( $url)

Definition at line 206 of file REST.php.

207 {
208 $cachefile = $this->config->get('cache_dir') . DIRECTORY_SEPARATOR .
209 md5($url) . 'rest.cachefile';
210
211 if (!file_exists($cachefile)) {
212 return PEAR::raiseError('No cached content available for "' . $url . '"');
213 }
214
215 return unserialize(implode('', file($cachefile)));
216 }

Referenced by retrieveData(), and useLocalCache().

Here is the caller graph for this function:

◆ getCacheId()

getCacheId ( $url)
Parameters
string$url
Returns
bool|mixed

Definition at line 193 of file REST.php.

194 {
195 $cacheidfile = $this->config->get('cache_dir') . DIRECTORY_SEPARATOR .
196 md5($url) . 'rest.cacheid';
197
198 if (!file_exists($cacheidfile)) {
199 return false;
200 }
201
202 $ret = unserialize(implode('', file($cacheidfile)));
203 return $ret;
204 }

Referenced by retrieveData(), and useLocalCache().

Here is the caller graph for this function:

◆ retrieveCacheFirst()

retrieveCacheFirst ( $url,
$accept = false,
$forcestring = false,
$channel = false )

Retrieve REST data, but always retrieve the local cache if it is available.

This is useful for elements that should never change, such as information on a particular release

Parameters
stringfull URL to this resource
array|falsecontents of the accept-encoding header
booleanif true, xml will be returned as a string, otherwise, xml will be parsed using PEAR_XMLParser
Returns
string|array

Definition at line 57 of file REST.php.

58 {
59 $cachefile = $this->config->get('cache_dir') . DIRECTORY_SEPARATOR .
60 md5($url) . 'rest.cachefile';
61
62 if (file_exists($cachefile)) {
63 return unserialize(implode('', file($cachefile)));
64 }
65
66 return $this->retrieveData($url, $accept, $forcestring, $channel);
67 }
retrieveData($url, $accept=false, $forcestring=false, $channel=false)
Definition REST.php:77

References retrieveData().

Here is the call graph for this function:

◆ retrieveData()

retrieveData ( $url,
$accept = false,
$forcestring = false,
$channel = false )

Retrieve a remote REST resource

Parameters
stringfull URL to this resource
array|falsecontents of the accept-encoding header
booleanif true, xml will be returned as a string, otherwise, xml will be parsed using PEAR_XMLParser
Returns
string|array

Definition at line 77 of file REST.php.

78 {
79 $cacheId = $this->getCacheId($url);
80 if ($ret = $this->useLocalCache($url, $cacheId)) {
81 return $ret;
82 }
83
84 $file = $trieddownload = false;
85 if (!isset($this->_options['offline'])) {
86 $trieddownload = true;
87 $file = $this->downloadHttp($url, $cacheId ? $cacheId['lastChange'] : false, $accept, $channel);
88 }
89
90 if (PEAR::isError($file)) {
91 if ($file->getCode() !== -9276) {
92 return $file;
93 }
94
95 $trieddownload = false;
96 $file = false; // use local copy if available on socket connect error
97 }
98
99 if (!$file) {
100 $ret = $this->getCache($url);
101 if (!PEAR::isError($ret) && $trieddownload) {
102 // reset the age of the cache if the server says it was unmodified
103 $result = $this->saveCache($url, $ret, null, true, $cacheId);
104 if (PEAR::isError($result)) {
105 return PEAR::raiseError($result->getMessage());
106 }
107 }
108
109 return $ret;
110 }
111
112 if (is_array($file)) {
113 $headers = $file[2];
114 $lastmodified = $file[1];
115 $content = $file[0];
116 } else {
117 $headers = array();
118 $lastmodified = false;
119 $content = $file;
120 }
121
122 if ($forcestring) {
123 $result = $this->saveCache($url, $content, $lastmodified, false, $cacheId);
124 if (PEAR::isError($result)) {
125 return PEAR::raiseError($result->getMessage());
126 }
127
128 return $content;
129 }
130
131 if (isset($headers['content-type'])) {
132 $content_type = explode(";", $headers['content-type']);
133 $content_type = $content_type[0];
134 switch ($content_type) {
135 case 'text/xml' :
136 case 'application/xml' :
137 case 'text/plain' :
138 if ($content_type === 'text/plain') {
139 $check = substr($content, 0, 5);
140 if ($check !== '<?xml') {
141 break;
142 }
143 }
144
145 $parser = new PEAR_XMLParser;
146 PEAR::pushErrorHandling(PEAR_ERROR_RETURN);
147 $err = $parser->parse($content);
148 PEAR::popErrorHandling();
149 if (PEAR::isError($err)) {
150 return PEAR::raiseError('Invalid xml downloaded from "' . $url . '": ' .
151 $err->getMessage());
152 }
153 $content = $parser->getData();
154 case 'text/html' :
155 default :
156 // use it as a string
157 }
158 } else {
159 // assume XML
160 $parser = new PEAR_XMLParser;
161 $parser->parse($content);
162 $content = $parser->getData();
163 }
164
165 $result = $this->saveCache($url, $content, $lastmodified, false, $cacheId);
166 if (PEAR::isError($result)) {
167 return PEAR::raiseError($result->getMessage());
168 }
169
170 return $content;
171 }
const PEAR_ERROR_RETURN
Definition PEAR.php:24
$result
getCache($url)
Definition REST.php:206
getCacheId($url)
Definition REST.php:193
saveCache($url, $contents, $lastmodified, $nochange=false, $cacheid=null)
Definition REST.php:225
useLocalCache($url, $cacheid=null)
Definition REST.php:173

References $result, downloadHttp(), getCache(), getCacheId(), PEAR_XMLParser\parse(), PEAR_ERROR_RETURN, saveCache(), and useLocalCache().

Referenced by retrieveCacheFirst().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ saveCache()

saveCache ( $url,
$contents,
$lastmodified,
$nochange = false,
$cacheid = null )
Parameters
stringfull URL to REST resource
stringoriginal contents of the REST resource
arrayHTTP Last-Modified and ETag headers
boolif true, then the cache id file should be regenerated to trigger a new time-to-live value

Definition at line 225 of file REST.php.

226 {
227 $cache_dir = $this->config->get('cache_dir');
228 $d = $cache_dir . DIRECTORY_SEPARATOR . md5($url);
229 $cacheidfile = $d . 'rest.cacheid';
230 $cachefile = $d . 'rest.cachefile';
231
232 if (!is_dir($cache_dir)) {
233 if (System::mkdir(array('-p', $cache_dir)) === false) {
234 return PEAR::raiseError("The value of config option cache_dir ($cache_dir) is not a directory and attempts to create the directory failed.");
235 }
236 }
237
238 if (!is_writeable($cache_dir)) {
239 // If writing to the cache dir is not going to work, silently do nothing.
240 // An ugly hack, but retains compat with PEAR 1.9.1 where many commands
241 // work fine as non-root user (w/out write access to default cache dir).
242 return true;
243 }
244
245 if ($cacheid === null && $nochange) {
246 $cacheid = unserialize(implode('', file($cacheidfile)));
247 }
248
249 $idData = serialize(array(
250 'age' => time(),
251 'lastChange' => ($nochange ? $cacheid['lastChange'] : $lastmodified),
252 ));
253
254 $result = $this->saveCacheFile($cacheidfile, $idData);
255 if (PEAR::isError($result)) {
256 return $result;
257 } elseif ($nochange) {
258 return true;
259 }
260
261 $result = $this->saveCacheFile($cachefile, serialize($contents));
262 if (PEAR::isError($result)) {
263 if (file_exists($cacheidfile)) {
264 @unlink($cacheidfile);
265 }
266
267 return $result;
268 }
269
270 return true;
271 }
saveCacheFile($file, $contents)
Definition REST.php:273

References $result, and saveCacheFile().

Referenced by retrieveData().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ saveCacheFile()

saveCacheFile ( $file,
$contents )

Definition at line 273 of file REST.php.

274 {
275 $len = strlen($contents);
276
277 $cachefile_fp = @fopen($file, 'xb'); // x is the O_CREAT|O_EXCL mode
278 if ($cachefile_fp !== false) { // create file
279 if (fwrite($cachefile_fp, $contents, $len) < $len) {
280 fclose($cachefile_fp);
281 return PEAR::raiseError("Could not write $file.");
282 }
283 } else { // update file
284 $cachefile_fp = @fopen($file, 'r+b'); // do not truncate file
285 if (!$cachefile_fp) {
286 return PEAR::raiseError("Could not open $file for writing.");
287 }
288
289 if (OS_WINDOWS) {
290 $not_symlink = !is_link($file); // see bug #18834
291 } else {
292 $cachefile_lstat = lstat($file);
293 $cachefile_fstat = fstat($cachefile_fp);
294 $not_symlink = $cachefile_lstat['mode'] == $cachefile_fstat['mode']
295 && $cachefile_lstat['ino'] == $cachefile_fstat['ino']
296 && $cachefile_lstat['dev'] == $cachefile_fstat['dev']
297 && $cachefile_fstat['nlink'] === 1;
298 }
299
300 if ($not_symlink) {
301 ftruncate($cachefile_fp, 0); // NOW truncate
302 if (fwrite($cachefile_fp, $contents, $len) < $len) {
303 fclose($cachefile_fp);
304 return PEAR::raiseError("Could not write $file.");
305 }
306 } else {
307 fclose($cachefile_fp);
308 $link = function_exists('readlink') ? readlink($file) : $file;
309 return PEAR::raiseError('SECURITY ERROR: Will not write to ' . $file . ' as it is symlinked to ' . $link . ' - Possible symlink attack');
310 }
311 }
312
313 fclose($cachefile_fp);
314 return true;
315 }

Referenced by saveCache().

Here is the caller graph for this function:

◆ useLocalCache()

useLocalCache ( $url,
$cacheid = null )

Definition at line 173 of file REST.php.

174 {
175 if (!is_array($cacheid)) {
176 $cacheid = $this->getCacheId($url);
177 }
178
179 $cachettl = $this->config->get('cache_ttl');
180 // If cache is newer than $cachettl seconds, we use the cache!
181 if (is_array($cacheid) && time() - $cacheid['age'] < $cachettl) {
182 return $this->getCache($url);
183 }
184
185 return false;
186 }

References getCache(), and getCacheId().

Referenced by retrieveData().

Here is the call graph for this function:
Here is the caller graph for this function:

Field Documentation

◆ $_options

$_options

Definition at line 38 of file REST.php.

◆ $config

$config

Definition at line 37 of file REST.php.

Referenced by __construct().


The documentation for this class was generated from the following file:
  • E:/Bearsampp-development/sandbox/core/libs/php/pear/pear/PEAR/REST.php