Ticket #287: xcache_vhost.patch

File xcache_vhost.patch, 11.2 KB (added by mzhg, 3 years ago)

version 4 (good file .. really time to go to bed)

  • mod_cacher/xc_cacher.c

     
    2828#endif
    2929#include "ext/standard/php_math.h"
    3030#include "SAPI.h"
     31#include <pwd.h>
    3132
    3233#define ECALLOC_N(x, n) ((x) = ecalloc(n, sizeof((x)[0])))
    3334#define ECALLOC_ONE(x) ECALLOC_N(x, 1)
     
    144145
    145146static zend_bool xc_readonly_protection = 0;
    146147
     148static zend_ulong xc_var_prefix_mode = 0;
     149static char *xc_var_prefix_value = NULL;
     150static zval *xc_var_prefix_computed = NULL;
     151
     152
    147153zend_bool xc_have_op_array_ctor = 0;
    148154/* }}} */
    149155
     
    151157
    152158/* any function in *_unlocked is only safe be called within locked (single thread access) area */
    153159
     160
     161static int hg_internal_var_prefix_startwith(zval** name)
     162{
     163    char* from = NULL;
     164    char* prefix = NULL;
     165
     166#ifdef IS_UNICODE
     167    switch (xc_var_prefix_computed->type) {
     168                case IS_UNICODE:
     169                        prefix = Z_UNIVAL_P(xc_var_prefix_computed);
     170                        break;
     171                case IS_STRING:
     172                        prefix = Z_STRVAL_P(xc_var_prefix_computed);
     173                        break;
     174                default:
     175                        assert(0);
     176        }
     177    switch (name->type) {
     178        case IS_UNICODE:
     179            from = Z_UNIVAL_PP(name);
     180            break;
     181        case IS_STRING:
     182            from = Z_STRVAL_PP(name);
     183            break;
     184        default:
     185            assert(0);
     186    }
     187#else
     188    prefix = Z_STRVAL_P(xc_var_prefix_computed);
     189    from = Z_STRVAL_PP(name);
     190#endif
     191    if (strncmp(from, prefix, strlen(prefix)) == 0)
     192    {
     193        return 1;
     194    } else {
     195        return 0;
     196    }   
     197}
     198
     199static void hg_internal_var_prefix_remove(zval** name)
     200{
     201    char* from = NULL;
     202    char* prefix = NULL;
     203    int index = 0;
     204
     205#ifdef IS_UNICODE
     206        switch (xc_var_prefix_computed->type) {
     207                case IS_UNICODE:
     208                        prefix = Z_UNIVAL_P(xc_var_prefix_computed);
     209                        break;
     210                case IS_STRING:
     211                        prefix = Z_STRVAL_P(xc_var_prefix_computed);
     212                        break;
     213                default:
     214                        assert(0);
     215        }
     216        switch (name->type) {
     217                case IS_UNICODE:
     218                        from = Z_UNIVAL_PP(name);
     219                        break;
     220                case IS_STRING:
     221                        from = Z_STRVAL_PP(name);
     222                        break;
     223                default:
     224                        assert(0);
     225        }
     226#else
     227        prefix = Z_STRVAL_P(xc_var_prefix_computed);
     228        from = Z_STRVAL_PP(name);
     229#endif
     230    index = strlen(prefix);
     231
     232#ifdef IS_UNICODE
     233        switch (name->type) {
     234                case IS_UNICODE:
     235            ZVAL_UNICODEL(*name, from + index, strlen(from) - index, 1);
     236                        break;
     237                case IS_STRING:
     238            ZVAL_STRINGL(*name, from + index, strlen(from) - index, 1);
     239                        break;
     240                default:
     241                        assert(0);
     242        }
     243#else
     244    ZVAL_STRINGL(*name, from + index, strlen(from) - index, 1);
     245#endif
     246/* *
     247#ifdef IS_UNICODE
     248    php_printf("unicode prefix remove, name=%s<br>", Z_UNIVAL_PP(name));
     249#else
     250    php_printf("string prefix remove, name=%s<br>", Z_STRVAL_PP(name));
     251#endif
     252// */
     253}
     254
     255static char* hg_internal_var_prefix_global_server_array(char* key)
     256{
     257    // This code makes sure $_SERVER has been initialized
     258    if (!zend_hash_exists(&EG(symbol_table), "_SERVER", 8)) {
     259        zend_auto_global* auto_global;
     260        if (zend_hash_find(CG(auto_globals), "_SERVER", 8, (void **)&auto_global) != FAILURE) {
     261            auto_global->armed = auto_global->auto_global_callback(auto_global->name, auto_global->name_len TSRMLS_CC);
     262        }
     263    }
     264    // This fetches $_SERVER['key']
     265    zval** arr;
     266    if (zend_hash_find(&EG(symbol_table), "_SERVER", 8, (void**)&arr) != FAILURE) {
     267        HashTable* ht = Z_ARRVAL_P(*arr);
     268        zval** val;
     269        if (zend_hash_find(ht, key, strlen(key)+1, (void**)&val) != FAILURE) {
     270            return Z_STRVAL_PP(val);
     271        }
     272    }
     273    return "";
     274}
     275
     276static void hg_internal_var_prefix_compute()
     277{
     278    xc_var_prefix_computed = NULL;
     279    int id = -1;
     280
     281    MAKE_STD_ZVAL(xc_var_prefix_computed);
     282
     283    switch(xc_var_prefix_mode) {
     284        case 1:
     285            if (strncmp(xc_var_prefix_value, "uid", 3) == 0) {
     286                id = getuid();
     287            } else if (strncmp(xc_var_prefix_value, "gid", 3) == 0) {
     288                                id = getgid();
     289                        }
     290            if (id == -1){
     291                ZVAL_EMPTY_STRING(xc_var_prefix_computed);
     292                // assert bad configuration ?
     293            } else {
     294                Z_TYPE_P(xc_var_prefix_computed) = IS_LONG;
     295                Z_LVAL_P(xc_var_prefix_computed) = id;
     296#ifdef IS_UNICODE
     297                           convert_to_unicode(xc_var_prefix_computed);
     298#else
     299                           convert_to_string(xc_var_prefix_computed);
     300#endif
     301            }
     302            break;
     303        case 2:
     304#ifdef IS_UNICODE
     305            ZVAL_UNICODE(xc_var_prefix_computed, hg_internal_var_prefix_global_server_array(xc_var_prefix_value), 1);
     306#else
     307            ZVAL_STRING(xc_var_prefix_computed, hg_internal_var_prefix_global_server_array(xc_var_prefix_value), 1);
     308#endif
     309            break;
     310        case 3:
     311#ifdef IS_UNICODE
     312                        ZVAL_UNICODE(xc_var_prefix_computed, xc_var_prefix_value, 1);
     313#else
     314                        ZVAL_STRING(xc_var_prefix_computed, xc_var_prefix_value, 1);
     315#endif         
     316                        break;
     317        case 0:
     318        default:
     319            ZVAL_EMPTY_STRING(xc_var_prefix_computed);
     320    }
     321}
     322
    154323static void xc_php_add_unlocked(xc_cached_t *cached, xc_entry_data_php_t *php) /* {{{ */
    155324{
    156325    xc_entry_data_php_t **head = &(cached->phps[php->hvalue]);
     
    272441static inline int xc_entry_has_prefix_unlocked(xc_entry_type_t type, xc_entry_t *entry, zval *prefix) /* {{{ */
    273442{
    274443    /* this function isn't required but can be in unlocked */
     444    zval* prefixprefix = NULL;
     445    MAKE_STD_VAL(prefixprefix);
    275446
    276447#ifdef IS_UNICODE
    277448    if (entry->name_type != prefix->type) {
    278449        return 0;
    279450    }
    280451
     452    concat_function(prefixprefix, xc_var_prefix_computed, prefix);
     453
    281454    if (entry->name_type == IS_UNICODE) {
    282         if (entry->name.ustr.len < Z_USTRLEN_P(prefix)) {
     455        if (entry->name.ustr.len < Z_USTRLEN_P(prefixprefix)) {
    283456            return 0;
    284457        }
    285         return memcmp(entry->name.ustr.val, Z_USTRVAL_P(prefix), Z_USTRLEN_P(prefix) * sizeof(UChar)) == 0;
     458        return memcmp(entry->name.ustr.val, Z_USTRVAL_P(prefixprefix), Z_USTRLEN_P(prefixprefix) * sizeof(UChar)) == 0;
    286459    }
    287 #endif
     460#else
    288461    if (prefix->type != IS_STRING) {
    289462        return 0;
    290463    }
    291464
    292     if (entry->name.str.len < Z_STRLEN_P(prefix)) {
     465    concat_function(prefixprefix, xc_var_prefix_computed, prefix);
     466
     467    if (entry->name.str.len < Z_STRLEN_P(prefixprefix)) {
    293468        return 0;
    294469    }
    295470
    296     return memcmp(entry->name.str.val, Z_STRVAL_P(prefix), Z_STRLEN_P(prefix)) == 0;
     471    return memcmp(entry->name.str.val, Z_STRVAL_P(prefixprefix), Z_STRLEN_P(prefixprefix)) == 0;
     472#endif
    297473}
    298474/* }}} */
    299475static void xc_entry_add_unlocked(xc_cached_t *cached, xc_hash_value_t entryslotid, xc_entry_t *entry) /* {{{ */
     
    697873    if (del) {
    698874        add_assoc_long_ex(ei, ZEND_STRS("dtime"), entry->dtime);
    699875    }
     876
     877    zval *zv;
     878    ALLOC_INIT_ZVAL(zv);
    700879#ifdef IS_UNICODE
    701880    do {
    702         zval *zv;
    703         ALLOC_INIT_ZVAL(zv);
    704881        switch (entry->name_type) {
    705882            case IS_UNICODE:
    706883                ZVAL_UNICODEL(zv, entry->name.ustr.val, entry->name.ustr.len, 1);
     
    715892        add_assoc_zval_ex(ei, ZEND_STRS("name"), zv);
    716893    } while (0);
    717894#else
    718     add_assoc_stringl_ex(ei, ZEND_STRS("name"), entry->name.str.val, entry->name.str.len, 1);
     895    ZVAL_STRINGL(zv, entry->name.str.val, entry->name.str.len, 1);
     896//  add_assoc_stringl_ex(ei, ZEND_STRS("name"), entry->name.str.val, entry->name.str.len, 1);
    719897#endif
     898    if (xc_var_prefix_mode > 0) {
     899        if (hg_internal_var_prefix_startwith(&zv) == 0) return;
     900        hg_internal_var_prefix_remove(&zv);
     901    }
     902    add_assoc_zval_ex(ei, ZEND_STRS("name"), zv);
     903
    720904    switch (type) {
    721905        case XC_TYPE_PHP: {
    722906            xc_entry_php_t *entry_php = (xc_entry_php_t *) entry;
     
    25012685            xc_stack_init(&XG(var_holds[i]));
    25022686        }
    25032687    }
    2504 
     2688    hg_internal_var_prefix_compute();
    25052689#ifdef ZEND_ENGINE_2
    25062690    zend_llist_init(&XG(gc_op_arrays), sizeof(xc_gc_op_array_t), xc_gc_op_array, 0);
    25072691#endif
     
    25192703    xc_gc_expires_php(TSRMLS_C);
    25202704    xc_gc_expires_var(TSRMLS_C);
    25212705    xc_gc_deletes(TSRMLS_C);
     2706    ZVAL_EMPTY_STRING(xc_var_prefix_computed);
    25222707#ifdef ZEND_ENGINE_2
    25232708    zend_llist_destroy(&XG(gc_op_arrays));
    25242709#endif
     
    28062991static int xc_entry_var_init_key(xc_entry_var_t *entry_var, xc_entry_hash_t *entry_hash, zval *name TSRMLS_DC) /* {{{ */
    28072992{
    28082993    xc_hash_value_t hv;
     2994    zval *new_name = NULL;
    28092995
    28102996    switch (name->type) {
    28112997#ifdef IS_UNICODE
     
    28233009#ifdef IS_UNICODE
    28243010    entry_var->name_type = name->type;
    28253011#endif
    2826     entry_var->entry.name = name->value;
     3012    if (xc_var_prefix_mode>0) {
     3013        MAKE_STD_ZVAL(new_name);
     3014#ifdef IS_UNICODE
     3015                switch (name->type) {
     3016                        case IS_UNICODE:
     3017                                if (name->type != xc_var_prefix_computed->type) convert_to_unicode(xc_var_prefix_computed);
     3018                        case IS_STRING:
     3019                                if (name->type != xc_var_prefix_computed->type) convert_to_string(xc_var_prefix_computed);
     3020                }
     3021#endif
     3022        // do not concat into name directly, it update the variable php side too, the prefix goes back up to the client
     3023        concat_function(new_name, xc_var_prefix_computed, name);
     3024        // we change the entry name with the prefix, but let the real name zval untouch
     3025        entry_var->entry.name = new_name->value;
     3026    } else {
     3027        entry_var->entry.name = name->value;
     3028    }
    28273029
    28283030    hv = xc_entry_hash_var((xc_entry_t *) entry_var TSRMLS_CC);
    28293031
     
    32203422    PHP_INI_ENTRY1     ("xcache.var_gc_interval",      "120", PHP_INI_SYSTEM, xcache_OnUpdateULong,    &xc_var_gc_interval)
    32213423    PHP_INI_ENTRY1     ("xcache.var_allocator",    "bestfit", PHP_INI_SYSTEM, xcache_OnUpdateString,   &xc_var_allocator)
    32223424    STD_PHP_INI_ENTRY  ("xcache.var_ttl",                "0", PHP_INI_ALL,    OnUpdateLong, var_ttl,   zend_xcache_globals, xcache_globals)
     3425    PHP_INI_ENTRY1     ("xcache.var_prefix_mode",        "0", PHP_INI_SYSTEM, xcache_OnUpdateULong,    &xc_var_prefix_mode)
     3426    PHP_INI_ENTRY1     ("xcache.var_prefix_value",        "", PHP_INI_SYSTEM, xcache_OnUpdateString,   &xc_var_prefix_value)
    32233427PHP_INI_END()
    32243428/* }}} */
    32253429static PHP_MINFO_FUNCTION(xcache_cacher) /* {{{ */
     
    33943598        pefree(xc_var_allocator, 1);
    33953599        xc_var_allocator = NULL;
    33963600    }
     3601    if (xc_var_prefix_value) {
     3602                pefree(xc_var_prefix_value, 1);
     3603                xc_var_prefix_value = NULL;
     3604        }
    33973605
    33983606    return SUCCESS;
    33993607}
  • htdocs/cacher/sub/entrylist.tpl.php

     
    140140}
    141141?>
    142142    </table>
    143 <?php if (!$isphp && $listName == 'Deleted') { ?>
     143<?php if (!$isphp) { ?>
    144144    <input type="submit" value="<?php echo _T("Remove Selected"); ?>">
    145145<?php } ?>
    146146</form>
  • htdocs/cacher/edit.php

     
    2222    exit;
    2323}
    2424$value = xcache_get($name);
    25 if (!empty($enable['enable_eval'])) {
     25if (!empty($config['enable_eval'])) {
    2626    $value = var_export($value, true);
    2727    $editable = true;
    2828}