XCache Administration web frontend
git-svn-id: svn://svn.lighttpd.net/xcache/trunk@34 c26eb9a1-5813-0410-bd6c-c2e55f420ca71.1
parent
791ec85409
commit
127b9b1d72
|
@ -0,0 +1,47 @@
|
|||
<?php
|
||||
|
||||
// this is an example only
|
||||
// write your own config and name it as config.php
|
||||
|
||||
$charset = "UTF-8";
|
||||
|
||||
// this function is detected by xcache.tpl.php, and enabled if function_exists
|
||||
// this ob filter is applied for the cache list, not the whole page
|
||||
function ob_filter_path_nicer($o)
|
||||
{
|
||||
$o = str_replace("/home/", "{H}/", $o);
|
||||
return $o;
|
||||
}
|
||||
|
||||
// you can simply let xcache to do the http auth
|
||||
// but if you have your home made login/permission system, you can implement the following
|
||||
// {{{ home made login example
|
||||
// this is an example only, it's won't work for you without your implemention.
|
||||
function check_admin_and_by_pass_xcache_http_auth()
|
||||
{
|
||||
require("/path/to/user-login-and-permission-lib.php");
|
||||
session_start();
|
||||
|
||||
if (!user_logined()) {
|
||||
if (!ask_the_user_to_login()) {
|
||||
exit;
|
||||
}
|
||||
}
|
||||
|
||||
user_load_permissions();
|
||||
if (!user_is_admin()) {
|
||||
die("Permission denied");
|
||||
}
|
||||
|
||||
// user is trusted after permission checks above.
|
||||
// tell XCache about it (the only way to by pass XCache http auth)
|
||||
$_SERVER["PHP_AUTH_USER"] = "moo";
|
||||
$_SERVER["PHP_AUTH_PW"] = "your-xcache-password";
|
||||
return true;
|
||||
}
|
||||
|
||||
// uncomment:
|
||||
// check_admin_and_by_pass_xcache_http_auth();
|
||||
// }}}
|
||||
|
||||
?>
|
|
@ -0,0 +1,3 @@
|
|||
<?php
|
||||
|
||||
include("xcache.php");
|
|
@ -0,0 +1,58 @@
|
|||
var sort_column;
|
||||
var prev_span = null;
|
||||
function get_inner_text(el) {
|
||||
if((typeof el == 'string')||(typeof el == 'undefined'))
|
||||
return el;
|
||||
if(el.innerText)
|
||||
return el.innerText;
|
||||
else {
|
||||
var str = "";
|
||||
var cs = el.childNodes;
|
||||
var l = cs.length;
|
||||
for (i=0;i<l;i++) {
|
||||
if (cs[i].nodeType==1) str += get_inner_text(cs[i]);
|
||||
else if (cs[i].nodeType==3) str += cs[i].nodeValue;
|
||||
}
|
||||
}
|
||||
return str;
|
||||
}
|
||||
function sortfn(a,b) {
|
||||
var i = a.cells[sort_column].getAttribute('int');
|
||||
if (i != null) {
|
||||
return parseInt(i)-parseInt(b.cells[sort_column].getAttribute('int'));
|
||||
} else {
|
||||
var at = get_inner_text(a.cells[sort_column]);
|
||||
var bt = get_inner_text(b.cells[sort_column]);
|
||||
aa = at.toLowerCase();
|
||||
bb = bt.toLowerCase();
|
||||
if (aa==bb) return 0;
|
||||
else if (aa<bb) return -1;
|
||||
else return 1;
|
||||
}
|
||||
}
|
||||
function resort(lnk) {
|
||||
var span = lnk.childNodes[1];
|
||||
if (!span) {
|
||||
var span = document.createElement("span")
|
||||
span.className = "sortarrow";
|
||||
lnk.appendChild(span);
|
||||
}
|
||||
var table = lnk.parentNode.parentNode.parentNode.parentNode;
|
||||
var rows = new Array();
|
||||
for (j=1;j<table.rows.length;j++)
|
||||
rows[j-1] = table.rows[j];
|
||||
sort_column = lnk.parentNode.cellIndex;
|
||||
rows.sort(sortfn);
|
||||
if (prev_span != null) prev_span.innerHTML = '';
|
||||
if (span.getAttribute('sortdir')=='down') {
|
||||
span.innerHTML = '↑';
|
||||
span.setAttribute('sortdir','up');
|
||||
rows.reverse();
|
||||
} else {
|
||||
span.innerHTML = '↓';
|
||||
span.setAttribute('sortdir','down');
|
||||
}
|
||||
for (i=0;i<rows.length;i++)
|
||||
table.tBodies[0].appendChild(rows[i]);
|
||||
prev_span = span;
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
input, table { font-family: monospace; font-size: 11px; }
|
||||
table.cycles { border: 1px solid black; background: white; margin-top: 5px; margin-bottom: 5px; }
|
||||
table.cycles .col1 { background-color: #f5f5f5; }
|
||||
table.cycles .col2 { background-color: #e0e0e0; }
|
||||
table.cycles th { background-color: #707090; color: white; font-weight: bold; height: 20px; line-height: 16px; font-family: serif; }
|
||||
th a { color: white; font-weight: bold; display: block; width: 100%; height: 100%; }
|
||||
.button { }
|
||||
span.sortarrow { color: white; text-decoration: none; }
|
||||
.freeblocks { float: left; margin-right: 4px;}
|
||||
form {margin: 0; padding: 0}
|
||||
.percent { border: 1px solid gray; width: 100%; }
|
||||
.percent .v { background: black; font-size: 1px; line-height: 11px;}
|
||||
.switcher, h1 { text-align: center; display: block; }
|
||||
.switcher * { color: blue; }
|
||||
.switcher a.active { font-weight: bold; font-size: 130%; color: black; }
|
|
@ -0,0 +1,189 @@
|
|||
<?php
|
||||
|
||||
error_reporting(E_ALL);
|
||||
define('REQUEST_TIME', time());
|
||||
|
||||
class Cycle
|
||||
{
|
||||
var $values;
|
||||
var $i;
|
||||
var $count;
|
||||
|
||||
function Cycle($v)
|
||||
{
|
||||
$this->values = func_get_args();
|
||||
$this->i = -1;
|
||||
$this->count = count($this->values);
|
||||
}
|
||||
|
||||
function next()
|
||||
{
|
||||
$this->i = ($this->i + 1) % $this->count;
|
||||
return $this->values[$this->i];
|
||||
}
|
||||
|
||||
function cur()
|
||||
{
|
||||
return $this->values[$this->i];
|
||||
}
|
||||
|
||||
function reset()
|
||||
{
|
||||
$this->i = -1;
|
||||
}
|
||||
}
|
||||
|
||||
function number_formats($a, $keys)
|
||||
{
|
||||
foreach ($keys as $k) {
|
||||
$a[$k] = number_format($a[$k]);
|
||||
}
|
||||
return $a;
|
||||
}
|
||||
|
||||
function size($size, $suffix = '', $precision = 2)
|
||||
{
|
||||
$size = (int) $size;
|
||||
if ($size < 1024)
|
||||
return number_format($size, $precision) . ' ' . $suffix;
|
||||
|
||||
if ($size < 1048576)
|
||||
return number_format($size / 1024, $precision) . ' K' . $suffix;
|
||||
|
||||
return number_format($size / 1048576, $precision) . ' M' . $suffix;
|
||||
}
|
||||
|
||||
function age($time)
|
||||
{
|
||||
if (!$time) return '';
|
||||
$delta = REQUEST_TIME - $time;
|
||||
|
||||
if ($delta < 0) {
|
||||
$delta = -$delta;
|
||||
}
|
||||
|
||||
static $seconds = array(1, 60, 3600, 86400, 604800, 2678400, 31536000);
|
||||
static $name = array('sec', 'min', 'hr', 'day', 'week', 'month', 'year');
|
||||
|
||||
for ($i = 6; $i >= 0; $i --) {
|
||||
if ($delta >= $seconds[$i]) {
|
||||
$ret = (int) ($delta / $seconds[$i]);
|
||||
return $ret . ' ' . $name[$i] . ($ret > 1 ? 's' : '');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function switcher($name, $options)
|
||||
{
|
||||
$n = isset($_GET[$name]) ? $_GET[$name] : null;
|
||||
$html = array();
|
||||
foreach ($options as $k => $v) {
|
||||
$html[] = sprintf('<a href="?%s=%s"%s>%s</a>', $name, $k, $k == $n ? 'class="active"' : '', $v);
|
||||
}
|
||||
return implode(' ', $html);
|
||||
}
|
||||
|
||||
$charset = "UTF-8";
|
||||
|
||||
if (file_exists("config.php")) {
|
||||
include("config.php");
|
||||
}
|
||||
|
||||
$pcnt = xcache_count(XC_TYPE_PHP);
|
||||
$vcnt = xcache_count(XC_TYPE_VAR);
|
||||
|
||||
$type_none = -1;
|
||||
if (!isset($_GET['type'])) {
|
||||
$_GET['type'] = $type_none;
|
||||
}
|
||||
$_GET['type'] = $type = (int) $_GET['type'];
|
||||
|
||||
// {{{ process clear
|
||||
function processClear()
|
||||
{
|
||||
$type = isset($_POST['type']) ? $_POST['type'] : null;
|
||||
if ($type != XC_TYPE_PHP && $type != XC_TYPE_VAR) {
|
||||
$type = null;
|
||||
}
|
||||
if (isset($type)) {
|
||||
$cacheid = (int) (isset($_POST['cacheid']) ? $_POST['cacheid'] : 0);
|
||||
if (isset($_POST['clearcache'])) {
|
||||
xcache_clear_cache($type, $cacheid);
|
||||
}
|
||||
}
|
||||
}
|
||||
processClear();
|
||||
// }}}
|
||||
// {{{ load info/list
|
||||
$cacheinfos = array();
|
||||
for ($i = 0; $i < $pcnt; $i ++) {
|
||||
$data = xcache_info(XC_TYPE_PHP, $i);
|
||||
if ($type === XC_TYPE_PHP) {
|
||||
$data += xcache_list(XC_TYPE_PHP, $i);
|
||||
}
|
||||
$data['type'] = XC_TYPE_PHP;
|
||||
$data['cache_name'] = "php#$i";
|
||||
$data['cacheid'] = $i;
|
||||
$cacheinfos[] = $data;
|
||||
}
|
||||
for ($i = 0; $i < $vcnt; $i ++) {
|
||||
$data = xcache_info(XC_TYPE_VAR, $i);
|
||||
if ($type === XC_TYPE_VAR) {
|
||||
$data += xcache_list(XC_TYPE_VAR, $i);
|
||||
}
|
||||
$data['type'] = XC_TYPE_VAR;
|
||||
$data['cache_name'] = "var#$i";
|
||||
$data['cacheid'] = $i;
|
||||
$cacheinfos[] = $data;
|
||||
}
|
||||
// }}}
|
||||
// {{{ merge the list
|
||||
switch ($type) {
|
||||
case XC_TYPE_PHP:
|
||||
case XC_TYPE_VAR:
|
||||
$cachelist = array('type' => $type, 'cache_list' => array(), 'deleted_list' => array());
|
||||
if ($type == XC_TYPE_VAR) {
|
||||
$cachelist['type_name'] = 'var';
|
||||
}
|
||||
else {
|
||||
$cachelist['type_name'] = 'php';
|
||||
}
|
||||
foreach ($cacheinfos as $i => $c) {
|
||||
if ($c['type'] == $type && isset($c['cache_list'])) {
|
||||
foreach ($c['cache_list'] as $e) {
|
||||
$e['cache_name'] = $c['cache_name'];
|
||||
$cachelist['cache_list'][] = $e;
|
||||
}
|
||||
foreach ($c['deleted_list'] as $e) {
|
||||
$e['cache_name'] = $c['cache_name'];
|
||||
$cachelist['deleted_list'][] = $e;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($type == XC_TYPE_PHP) {
|
||||
$inodes = array();
|
||||
foreach ($cachelist['cache_list'] as $e) {
|
||||
$i = &$inodes[$e['inode']];
|
||||
if (isset($i) && $i == 1) {
|
||||
set_error("duplicate inode $e[inode]");
|
||||
}
|
||||
$i ++;
|
||||
}
|
||||
}
|
||||
unset($data);
|
||||
break;
|
||||
|
||||
default:
|
||||
$_GET['type'] = $type_none;
|
||||
$cachelist = array();
|
||||
break;
|
||||
}
|
||||
// }}}
|
||||
|
||||
$type_php = XC_TYPE_PHP;
|
||||
$type_var = XC_TYPE_VAR;
|
||||
$types = array($type_none => 'Statistics', $type_php =>'List PHP', $type_var =>'List Var Data');
|
||||
|
||||
include("xcache.tpl.php");
|
||||
|
||||
?>
|
|
@ -0,0 +1,233 @@
|
|||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<meta http-equiv="Content-Language" content="en-us" />
|
||||
<?php
|
||||
echo <<<HEAD
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=$charset" />
|
||||
<script type="text/javascript" src="tablesort.js" charset="$charset"></script>
|
||||
HEAD;
|
||||
?>
|
||||
|
||||
<link rel="stylesheet" type="text/css" href="xcache.css" />
|
||||
<title>XCache Administration</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<h1>XCache Administration</h1>
|
||||
<span class="switcher"><?php echo switcher("type", $types); ?></span>
|
||||
<?php
|
||||
$a = new Cycle('class="col1"', 'class="col2"');
|
||||
$b = new Cycle('class="col1"', 'class="col2"');
|
||||
?>
|
||||
<table cellspacing="1" cellpadding="4" class="cycles">
|
||||
<col />
|
||||
<col align="right" />
|
||||
<col align="right" />
|
||||
<col align="right" />
|
||||
<col />
|
||||
<col />
|
||||
<col align="right" />
|
||||
<col align="right" />
|
||||
<col align="right" />
|
||||
<col align="right" />
|
||||
<col align="right" />
|
||||
<col align="right" />
|
||||
<col align="right" />
|
||||
<col align="right" />
|
||||
<col />
|
||||
<tr <?php echo $a->next(); ?>>
|
||||
<th></th>
|
||||
<th>Slots</th>
|
||||
<th>Size</th>
|
||||
<th>Avail</th>
|
||||
<th>Used</th>
|
||||
<th>Clear</th>
|
||||
<th>Compiling</th>
|
||||
<th>Hits</th>
|
||||
<th>Misses</th>
|
||||
<th>CLogs</th>
|
||||
<th>OOMs</th>
|
||||
<th>Protected</th>
|
||||
<th>Cached</th>
|
||||
<th>Deleted</th>
|
||||
<th>Blocks</th>
|
||||
</tr>
|
||||
<?php
|
||||
$numkeys = explode(',', 'slots,size,avail,hits,misses,clogs,ooms,cached,deleted');
|
||||
foreach ($cacheinfos as $i => $ci) {
|
||||
echo "
|
||||
<tr ", $a->next(), ">";
|
||||
$ci = number_formats($ci, $numkeys);
|
||||
$ci['compiling'] = $ci['type'] == $type_php ? ($ci['compiling'] ? 'yes' : 'no') : '-';
|
||||
$ci['can_readonly'] = $ci['can_readonly'] ? 'yes' : 'no';
|
||||
|
||||
$percent = (int) (($ci['size'] - $ci['avail']) / $ci['size'] * 100);
|
||||
echo <<<EOS
|
||||
<th>{$ci['cache_name']}</th>
|
||||
<td>{$ci['slots']}</td>
|
||||
<td>{$ci['size']}</td>
|
||||
<td>{$ci['avail']}</td>
|
||||
<td><div class="percent"><div style="width: $percent%" class="v"> </div></div></td>
|
||||
<td>
|
||||
<form method="post">
|
||||
<div>
|
||||
<input type="hidden" name="type" value="{$ci['type']}">
|
||||
<input type="hidden" name="cacheid" value="{$ci['cacheid']}">
|
||||
<input type="submit" name="clearcache" value="Clear" class="submit" onclick="return confirm('Sure to clear?');" />
|
||||
</div>
|
||||
</form>
|
||||
</td>
|
||||
<td>{$ci['compiling']}</td>
|
||||
<td>{$ci['hits']}</td>
|
||||
<td>{$ci['misses']}</td>
|
||||
<td>{$ci['clogs']}</td>
|
||||
<td>{$ci['ooms']}</td>
|
||||
<td>{$ci['can_readonly']}</td>
|
||||
<td>{$ci['cached']}</td>
|
||||
<td>{$ci['deleted']}</td>
|
||||
<td>
|
||||
EOS;
|
||||
|
||||
$b->reset();
|
||||
?>
|
||||
</td>
|
||||
</tr>
|
||||
<?php } ?>
|
||||
</table>
|
||||
<?php
|
||||
foreach ($cacheinfos as $i => $ci) {
|
||||
?>
|
||||
<table cellspacing="1" cellpadding="4" class="cycles freeblocks">
|
||||
<tr>
|
||||
<th><?php echo $ci['cache_name']; ?> size<br>offset</th>
|
||||
<?php
|
||||
foreach ($ci['free_blocks'] as $block) {
|
||||
$size = number_format($block['size']);
|
||||
$offset = number_format($block['offset']);
|
||||
|
||||
$c = $b->next();
|
||||
echo "
|
||||
<td $c><nobr>$size<br>$offset</nobr></td>";
|
||||
}
|
||||
?>
|
||||
|
||||
</tr>
|
||||
</table>
|
||||
<?php
|
||||
}
|
||||
?>
|
||||
<div style="clear: both"> </div>
|
||||
<?php
|
||||
|
||||
if ($cachelist) {
|
||||
$isphp = $cachelist['type'] == $type_php;
|
||||
if (function_exists("ob_filter_path_nicer")) {
|
||||
ob_start("ob_filter_path_nicer");
|
||||
}
|
||||
foreach (array('Cached' => $cachelist['cache_list'], 'Deleted' => $cachelist['deleted_list']) as $listname => $entries) {
|
||||
$a->reset();
|
||||
echo "
|
||||
<caption>{$cachelist['type_name']} $listname</caption>";
|
||||
?>
|
||||
|
||||
<table cellspacing="1" cellpadding="4" class="cycles entrys" width="100%">
|
||||
<col />
|
||||
<col />
|
||||
<col align="right" />
|
||||
<col align="right" />
|
||||
<col align="right" />
|
||||
<col align="right" />
|
||||
<col align="right" />
|
||||
<col align="right" />
|
||||
<?php
|
||||
if ($listname == 'Deleted') {
|
||||
echo '<col align="right" />';
|
||||
}
|
||||
if ($isphp) {
|
||||
echo '<col align="right" />';
|
||||
echo '<col align="right" />';
|
||||
echo '<col align="right" />';
|
||||
}
|
||||
|
||||
echo "
|
||||
<tr ", $a->next(), ">";
|
||||
?>
|
||||
|
||||
<th><a href="javascript:" onclick="resort(this); return false">Cache</a></th>
|
||||
<th><a href="javascript:" onclick="resort(this); return false">entry</a></th>
|
||||
<th><a href="javascript:" onclick="resort(this); return false">Hits</a></th>
|
||||
<th><a href="javascript:" onclick="resort(this); return false">Ref count</a></th>
|
||||
<th><a href="javascript:" onclick="resort(this); return false">Size</a></th>
|
||||
<?php if ($isphp) { ?>
|
||||
<th><a href="javascript:" onclick="resort(this); return false">SrcSize</a></th>
|
||||
<th><a href="javascript:" onclick="resort(this); return false">Modify</a></th>
|
||||
<th><a href="javascript:" onclick="resort(this); return false">device</a></th>
|
||||
<th><a href="javascript:" onclick="resort(this); return false">inode</a></th>
|
||||
<?php } ?>
|
||||
<th><a href="javascript:" onclick="resort(this); return false">Access</a></th>
|
||||
<th><a href="javascript:" onclick="resort(this); return false">Create</a></th>
|
||||
<?php if ($listname == 'Deleted') { ?>
|
||||
<th><a href="javascript:" onclick="resort(this); return false">Delete</a></th>
|
||||
<?php } ?>
|
||||
</tr>
|
||||
<?php
|
||||
foreach ($entries as $i => $entry) {
|
||||
echo "
|
||||
<tr ", $a->next(), ">";
|
||||
$name = htmlspecialchars($entry['name']);
|
||||
$hits = number_format($entry['hits']);
|
||||
$refcount = number_format($entry['refcount']);
|
||||
$size = size($entry['size']);
|
||||
if ($isphp) {
|
||||
$sourcesize = size($entry['sourcesize']);
|
||||
}
|
||||
|
||||
if ($isphp) {
|
||||
$mtime = age($entry['mtime']);
|
||||
}
|
||||
$ctime = age($entry['ctime']);
|
||||
$atime = age($entry['atime']);
|
||||
$dtime = age($entry['dtime']);
|
||||
|
||||
echo <<<ENTRY
|
||||
<td>{$entry['cache_name']} {$i}</td>
|
||||
<td>{$name}</td>
|
||||
<td int="{$entry['hits']}">{$entry['hits']}</td>
|
||||
<td int="{$entry['refcount']}">{$entry['refcount']}</td>
|
||||
<td int="{$entry['size']}">{$size}</td>
|
||||
ENTRY;
|
||||
if ($isphp) {
|
||||
echo <<<ENTRY
|
||||
<td int="{$entry['sourcesize']}">{$sourcesize}</td>
|
||||
<td int="{$entry['mtime']}">{$mtime}</td>
|
||||
<td int="{$entry['device']}">{$entry['device']}</td>
|
||||
<td int="{$entry['inode']}">{$entry['inode']}</td>
|
||||
ENTRY;
|
||||
}
|
||||
echo <<<ENTRY
|
||||
<td int="{$entry['atime']}">{$atime}</td>
|
||||
<td int="{$entry['ctime']}">{$ctime}</td>
|
||||
ENTRY;
|
||||
if ($listname == 'Deleted') {
|
||||
echo <<<ENTRY
|
||||
<td int="{$entry['dtime']}">{$dtime}</td>
|
||||
ENTRY;
|
||||
}
|
||||
|
||||
echo "
|
||||
</tr>
|
||||
";
|
||||
}
|
||||
?>
|
||||
|
||||
</table>
|
||||
<?php
|
||||
}
|
||||
if (function_exists("ob_filter_path_nicer")) {
|
||||
ob_end_flush();
|
||||
}
|
||||
}
|
||||
?>
|
||||
</body>
|
||||
</html>
|
88
xcache.c
88
xcache.c
|
@ -11,6 +11,7 @@
|
|||
|
||||
#include "php.h"
|
||||
#include "ext/standard/info.h"
|
||||
#include "ext/standard/md5.h"
|
||||
#include "zend_extensions.h"
|
||||
#include "SAPI.h"
|
||||
|
||||
|
@ -1047,9 +1048,82 @@ static void xc_shutdown_globals(zend_xcache_globals* xc_globals TSRMLS_DC) /* {{
|
|||
/* }}} */
|
||||
|
||||
/* user functions */
|
||||
/* {{{ xcache_op */
|
||||
static int xcache_admin_auth_check(TSRMLS_C) /* {{{ */
|
||||
{
|
||||
zval **server = NULL;
|
||||
zval **user = NULL;
|
||||
zval **pass = NULL;
|
||||
char *admin_user = NULL;
|
||||
char *admin_pass = NULL;
|
||||
HashTable *ht;
|
||||
|
||||
if (cfg_get_string("xcache.admin.user", &admin_user) == FAILURE || !admin_user[0]) {
|
||||
admin_user = NULL;
|
||||
}
|
||||
if (cfg_get_string("xcache.admin.pass", &admin_pass) == FAILURE || !admin_pass[0]) {
|
||||
admin_pass = NULL;
|
||||
}
|
||||
|
||||
if (admin_user == NULL || admin_pass == NULL) {
|
||||
php_error_docref(NULL TSRMLS_CC, E_ERROR, "xcache.admin.user and xcache.admin.pass is required");
|
||||
zend_bailout();
|
||||
}
|
||||
if (strlen(admin_pass) != 32) {
|
||||
php_error_docref(NULL TSRMLS_CC, E_ERROR, "unexpect %d bytes of xcache.admin.pass, expected 32 bytes, the password after md5()", strlen(admin_pass));
|
||||
zend_bailout();
|
||||
}
|
||||
|
||||
if (zend_hash_find(&EG(symbol_table), "_SERVER", sizeof("_SERVER"), (void **) &server) != SUCCESS || Z_TYPE_PP(server) != IS_ARRAY) {
|
||||
php_error_docref(NULL TSRMLS_CC, E_ERROR, "_SERVER is corrupted");
|
||||
zend_bailout();
|
||||
}
|
||||
ht = HASH_OF((*server));
|
||||
|
||||
if (zend_hash_find(ht, "PHP_AUTH_USER", sizeof("PHP_AUTH_USER"), (void **) &user) == FAILURE) {
|
||||
user = NULL;
|
||||
}
|
||||
else if (Z_TYPE_PP(user) != IS_STRING) {
|
||||
user = NULL;
|
||||
}
|
||||
|
||||
if (zend_hash_find(ht, "PHP_AUTH_PW", sizeof("PHP_AUTH_PW"), (void **) &pass) == FAILURE) {
|
||||
pass = NULL;
|
||||
}
|
||||
else if (Z_TYPE_PP(pass) != IS_STRING) {
|
||||
pass = NULL;
|
||||
}
|
||||
|
||||
if (user != NULL && pass != NULL && strcmp(admin_user, Z_STRVAL_PP(user)) == 0) {
|
||||
PHP_MD5_CTX context;
|
||||
char md5str[33];
|
||||
unsigned char digest[16];
|
||||
|
||||
PHP_MD5Init(&context);
|
||||
PHP_MD5Update(&context, Z_STRVAL_PP(pass), Z_STRLEN_PP(pass));
|
||||
PHP_MD5Final(digest, &context);
|
||||
|
||||
md5str[0] = '\0';
|
||||
make_digest(md5str, digest);
|
||||
if (strcmp(admin_pass, md5str) == 0) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
#define STR "WWW-authenticate: basic realm='XCache Administration'"
|
||||
sapi_add_header_ex(STR, sizeof(STR) - 1, 1, 1 TSRMLS_CC);
|
||||
#undef STR
|
||||
#define STR "HTTP/1.0 401 Unauthorized"
|
||||
sapi_add_header_ex(STR, sizeof(STR) - 1, 1, 1 TSRMLS_CC);
|
||||
#undef STR
|
||||
ZEND_PUTS("XCache Auth Failed. User and Password is case sense\n");
|
||||
|
||||
zend_bailout();
|
||||
return 0;
|
||||
}
|
||||
/* }}} */
|
||||
/* {{{ xcache_admin_operate */
|
||||
typedef enum { XC_OP_COUNT, XC_OP_INFO, XC_OP_LIST, XC_OP_CLEAR } xcache_op_type;
|
||||
static void xcache_op(xcache_op_type optype, INTERNAL_FUNCTION_PARAMETERS)
|
||||
static void xcache_admin_operate(xcache_op_type optype, INTERNAL_FUNCTION_PARAMETERS)
|
||||
{
|
||||
long type;
|
||||
int size;
|
||||
|
@ -1061,6 +1135,8 @@ static void xcache_op(xcache_op_type optype, INTERNAL_FUNCTION_PARAMETERS)
|
|||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
xcache_admin_auth_check(TSRMLS_C);
|
||||
|
||||
if (optype == XC_OP_COUNT) {
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &type) == FAILURE) {
|
||||
return;
|
||||
|
@ -1142,28 +1218,28 @@ static void xcache_op(xcache_op_type optype, INTERNAL_FUNCTION_PARAMETERS)
|
|||
Return count of cache on specified cache type */
|
||||
PHP_FUNCTION(xcache_count)
|
||||
{
|
||||
xcache_op(XC_OP_COUNT, INTERNAL_FUNCTION_PARAM_PASSTHRU);
|
||||
xcache_admin_operate(XC_OP_COUNT, INTERNAL_FUNCTION_PARAM_PASSTHRU);
|
||||
}
|
||||
/* }}} */
|
||||
/* {{{ proto array xcache_info(int type, int id)
|
||||
Get cache info by id on specified cache type */
|
||||
PHP_FUNCTION(xcache_info)
|
||||
{
|
||||
xcache_op(XC_OP_INFO, INTERNAL_FUNCTION_PARAM_PASSTHRU);
|
||||
xcache_admin_operate(XC_OP_INFO, INTERNAL_FUNCTION_PARAM_PASSTHRU);
|
||||
}
|
||||
/* }}} */
|
||||
/* {{{ proto array xcache_list(int type, int id)
|
||||
Get cache entries list by id on specified cache type */
|
||||
PHP_FUNCTION(xcache_list)
|
||||
{
|
||||
xcache_op(XC_OP_LIST, INTERNAL_FUNCTION_PARAM_PASSTHRU);
|
||||
xcache_admin_operate(XC_OP_LIST, INTERNAL_FUNCTION_PARAM_PASSTHRU);
|
||||
}
|
||||
/* }}} */
|
||||
/* {{{ proto array xcache_clear_cache(int type, int id)
|
||||
Clear cache by id on specified cache type */
|
||||
PHP_FUNCTION(xcache_clear_cache)
|
||||
{
|
||||
xcache_op(XC_OP_CLEAR, INTERNAL_FUNCTION_PARAM_PASSTHRU);
|
||||
xcache_admin_operate(XC_OP_CLEAR, INTERNAL_FUNCTION_PARAM_PASSTHRU);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
|
|
|
@ -7,6 +7,11 @@ extension = xcache.so
|
|||
; required for >=php5.1 if you turn xcache on
|
||||
auto_globals_jit = Off
|
||||
|
||||
[xcache.admin]
|
||||
xcache.admin.user = "mOo"
|
||||
; xcache.admin.pass = md5($your_password)
|
||||
xcache.admin.pass = ""
|
||||
|
||||
[xcache]
|
||||
; ini only settings, all the values here is default
|
||||
; to disable: xcache.size=0
|
||||
|
|
Loading…
Reference in New Issue