add local XMLRPC cache

This commit is contained in:
Christian Dickmann 2002-07-06 14:44:05 +00:00
parent 7cdd6a6bb5
commit d04c8495d3
2 changed files with 91 additions and 9 deletions

View File

@ -19,6 +19,7 @@
// $Id$
require_once 'PEAR.php';
require_once 'System.php';
/**
* Last created PEAR_Config instance.
@ -49,6 +50,9 @@ define('PEAR_CONFIG_DEFAULT_DATADIR',
PEAR_INSTALL_DIR.DIRECTORY_SEPARATOR.'data');
define('PEAR_CONFIG_DEFAULT_TESTDIR',
PEAR_INSTALL_DIR.DIRECTORY_SEPARATOR.'tests');
define('PEAR_CONFIG_DEFAULT_CACHEDIR', (System::tmpdir()).'/pear/cache');
if (@is_dir(PHP_SYSCONFDIR)) {
define('PEAR_CONFIG_SYSCONFDIR', PHP_SYSCONFDIR);
} else {
@ -172,6 +176,13 @@ class PEAR_Config extends PEAR
'prompt' => 'PEAR test directory',
'group' => 'File Locations (Advanced)',
),
'cache_dir' => array(
'type' => 'directory',
'default' => PEAR_CONFIG_DEFAULT_CACHEDIR,
'doc' => 'directory which is used for XMLRPC cache',
'prompt' => 'PEAR Installer cache directory',
'group' => 'File Locations (Advanced)',
),
// Maintainers
'username' => array(
'type' => 'string',
@ -215,6 +226,13 @@ class PEAR_Config extends PEAR
'prompt' => 'Unix file mask',
'group' => 'Advanced',
),
'cache_ttl' => array(
'type' => 'integer',
'default' => 0,
'doc' => 'amount of secs where the local cache is used and not updated',
'prompt' => 'Cache TimeToLive',
'group' => 'Advanced',
),
/*
'testset1' => array(
'type' => 'set',

View File

@ -34,6 +34,7 @@ class PEAR_Remote extends PEAR
// {{{ properties
var $config = null;
var $cache = null;
// }}}
@ -46,19 +47,63 @@ class PEAR_Remote extends PEAR
}
// }}}
function getCache($args)
{
$id = md5(serialize($args));
$cachedir = $this->config->get('cache_dir');
if (!file_exists($cachedir)) {
System::mkdir('-p '.$cachedir);
}
$filename = $cachedir.'/xmlrpc_cache_'.$id;
if (!file_exists($filename)) {
return null;
};
$result = array(
'age' => time() - filemtime($filename),
'lastChange' => filemtime($filename),
'content' => unserialize(implode('', file($filename))),
);
return $result;
}
function saveCache($args, $data)
{
$id = md5(serialize($args));
$cachedir = $this->config->get('cache_dir');
if (!file_exists($cachedir)) {
System::mkdir('-p '.$cachedir);
}
$filename = $cachedir.'/xmlrpc_cache_'.$id;
$fp = @fopen($filename, "w");
if ($fp !== null) {
fwrite($fp, serialize($data));
fclose($fp);
};
}
// {{{ call(method, [args...])
function call($method)
{
$_args = $args = func_get_args();
$this->cache = $this->getCache($args);
$cachettl = $this->config->get('cache_ttl');
// If cache is newer than $cachettl seconds, we use the cache!
if ($this->cache !== null && $this->cache['age'] < $cachettl) {
return $this->cache['content'];
};
if (extension_loaded("xmlrpc")) {
$args = func_get_args();
return call_user_func_array(array(&$this, 'call_epi'), $args);
$result = call_user_func_array(array(&$this, 'call_epi'), $args);
$this->saveCache($_args, $result);
return $result;
}
if (!@include_once("XML/RPC.php")) {
return $this->raiseError("For this remote PEAR operation you need to install the XML_RPC package");
}
$args = func_get_args();
array_shift($args);
$server_host = $this->config->get('master_server');
$username = $this->config->get('username');
@ -66,7 +111,12 @@ class PEAR_Remote extends PEAR
$eargs = array();
foreach($args as $arg) $eargs[] = $this->_encode($arg);
$f = new XML_RPC_Message($method, $eargs);
$c = new XML_RPC_Client('/xmlrpc.php', $server_host, 80);
if ($this->cache !== null) {
$maxAge = '?maxAge='.$this->cache['lastChange'];
} else {
$maxAge = '';
};
$c = new XML_RPC_Client('/xmlrpc.php'.$maxAge, $server_host, 80);
if ($username && $password) {
$c->setCredentials($username, $password);
}
@ -79,10 +129,15 @@ class PEAR_Remote extends PEAR
}
$v = $r->value();
if ($e = $r->faultCode()) {
if ($e == $GLOBALS['XML_RPC_err']['http_error'] && strstr($r->faultString(), '304 Not Modified') !== false) {
return $this->cache['content'];
}
return $this->raiseError($r->faultString(), $e);
}
return XML_RPC_decode($v);
$result = XML_RPC_decode($v);
$this->saveCache($_args, $result);
return $result;
}
// }}}
@ -139,22 +194,31 @@ class PEAR_Remote extends PEAR
$tmp = base64_encode("$username:$password");
$req_headers .= "Authorization: Basic $tmp\r\n";
}
if ($this->cache !== null) {
$maxAge = '?maxAge='.$this->cache['lastChange'];
} else {
$maxAge = '';
};
if ($this->config->get('verbose') > 3) {
print "XMLRPC REQUEST HEADERS:\n";
var_dump($req_headers);
print "XMLRPC REQUEST BODY:\n";
var_dump($request);
}
fwrite($fp, ("POST /xmlrpc.php HTTP/1.0\r\n$req_headers\r\n$request"));
fwrite($fp, ("POST /xmlrpc.php$maxAge HTTP/1.0\r\n$req_headers\r\n$request"));
$response = '';
$line1 = fgets($fp, 2048);
if (!preg_match('!^HTTP/[0-9\.]+ (\d+) (.*)!', $line1, $matches)) {
return $this->raiseError("PEAR_Remote: invalid HTTP response from XML-RPC server");
}
switch ($matches[1]) {
case "200":
case "200": // OK
break;
case "401":
case "304": // Not Modified
return $this->cache['content'];
case "401": // Unauthorized
if ($username && $password) {
return $this->raiseError("PEAR_Remote: authorization failed", 401);
} else {