Ticket #287: xcache_vhost.patch

File xcache_vhost.patch, 11.2 KB (added by mzhg, 2 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}