Ignore:
Timestamp:
2012-08-09T16:36:06+02:00 (3 years ago)
Author:
moo
Message:

closes #198: support for caching protocol url

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/mod_cacher/xc_cacher.c

    r1135 r1140  
    243243            }
    244244
    245             assert(IS_ABSOLUTE_PATH(entry1->name.str.val, entry1->name.str.len));
    246             assert(IS_ABSOLUTE_PATH(entry2->name.str.val, entry2->name.str.len));
     245            assert(strstr(entry1->name.str.val, "://") != NULL || IS_ABSOLUTE_PATH(entry1->name.str.val, entry1->name.str.len));
     246            assert(strstr(entry1->name.str.val, "://") != NULL || IS_ABSOLUTE_PATH(entry2->name.str.val, entry2->name.str.len));
    247247
    248248            return entry1->name.str.len == entry2->name.str.len
     
    947947/* }}} */
    948948
    949 #define XC_RESOLVE_PATH_CHECKER(name) zend_bool name(const char *filepath, size_t filepath_len, void *data TSRMLS_DC)
     949#define XC_RESOLVE_PATH_CHECKER(name) int name(const char *filepath, size_t filepath_len, void *data TSRMLS_DC)
    950950typedef XC_RESOLVE_PATH_CHECKER((*xc_resolve_path_checker_func_t));
    951 static zend_bool xc_resolve_path(const char *filepath, char *path_buffer, xc_resolve_path_checker_func_t checker_func, void *data TSRMLS_DC) /* {{{ */
     951static int xc_resolve_path(const char *filepath, char *path_buffer, xc_resolve_path_checker_func_t checker_func, void *data TSRMLS_DC) /* {{{ */
    952952{
    953953    char *paths, *path;
     
    967967        !*path) {
    968968
    969         if (checker_func(path_buffer, path_buffer_len, data TSRMLS_CC)) {
    970             ret = 1;
    971         }
    972         else {
    973             ret = FAILURE;
    974         }
     969        ret = checker_func(path_buffer, path_buffer_len, data TSRMLS_CC);
    975970        goto finish;
    976971    }
     
    984979        path_buffer_len = snprintf(path_buffer, MAXPATHLEN, "%s/%s", path, filepath);
    985980        if (path_buffer_len < MAXPATHLEN - 1) {
    986             if (checker_func(path_buffer, path_buffer_len, data TSRMLS_CC)) {
    987                 ret = 1;
     981            ret = checker_func(path_buffer, path_buffer_len, data TSRMLS_CC);
     982            if (ret == SUCCESS) {
    988983                goto finish;
    989984            }
     
    993988    /* fall back to current directory */
    994989    if (zend_is_executing(TSRMLS_C)) {
    995         const char *executed_filename = zend_get_executed_filename(TSRMLS_C);
    996         if (executed_filename && executed_filename[0] && executed_filename[0] != '[') {
    997             size_t filename_len = strlen(filepath);
    998             size_t dirname_len;
    999 
    1000             for (dirname_len = strlen(executed_filename) - 1; dirname_len > 0; --dirname_len) {
    1001                 if (IS_SLASH(executed_filename[dirname_len])) {
    1002                     if (dirname_len + filename_len < MAXPATHLEN - 1) {
    1003                         ++dirname_len; /* include tailing slash */
    1004                         memcpy(path_buffer, executed_filename, dirname_len);
    1005                         memcpy(path_buffer + dirname_len, filepath, filename_len);
    1006                         path_buffer_len = dirname_len + filename_len;
    1007                         path_buffer[path_buffer_len] = '\0';
    1008                         if (checker_func(path_buffer, path_buffer_len, data TSRMLS_CC)) {
    1009                             ret = 1;
    1010                             goto finish;
    1011                         }
    1012                     }
    1013                     break;
    1014                 }
    1015             }
    1016         }
    1017     }
    1018 
    1019     ret = 0;
     990        const char *executing_filename = zend_get_executed_filename(TSRMLS_C);
     991        int dirname_len = strlen(executing_filename);
     992        size_t filename_len = strlen(filepath);
     993
     994        while ((--dirname_len >= 0) && !IS_SLASH(executing_filename[dirname_len]));
     995        if (executing_filename && dirname_len > 0 && executing_filename[0] && executing_filename[0] != '['
     996         && dirname_len + 1 + filename_len + 1 < MAXPATHLEN) {
     997            memcpy(path_buffer, executing_filename, dirname_len + 1);
     998            memcpy(path_buffer + dirname_len + 1, filepath, filename_len + 1);
     999            path_buffer_len = dirname_len + 1 + filename_len;
     1000            ret = checker_func(path_buffer, path_buffer_len, data TSRMLS_CC);
     1001            if (ret == SUCCESS) {
     1002                goto finish;
     1003            }
     1004        }
     1005    }
     1006
     1007    ret = FAILURE;
    10201008
    10211009finish:
     
    10251013}
    10261014/* }}} */
     1015
     1016static zend_bool xc_is_absolute(const char *filepath, size_t filepath_len) /* {{{ */
     1017{
     1018    const char *p;
     1019
     1020    if (IS_ABSOLUTE_PATH(filepath, filepath_len)) {
     1021        return 1;
     1022    }
     1023
     1024    for (p = filepath; isalnum((int)*p) || *p == '+' || *p == '-' || *p == '.'; p++);
     1025    if ((*p == ':') && (p - filepath > 1) && (p[1] == '/') && (p[2] == '/')) {
     1026        return 1;
     1027    }
     1028
     1029    return 0;
     1030}
     1031/* }}} */
     1032static int xc_stat(const char *filepath, struct stat *statbuf TSRMLS_DC) /* {{{ */
     1033{
     1034    if (strstr(filepath, "://") != NULL) {
     1035        php_stream_statbuf ssb;
     1036        php_stream_wrapper *wrapper = NULL;
     1037        char *path_for_open = NULL;
     1038
     1039        wrapper = php_stream_locate_url_wrapper(filepath, &path_for_open, 0 TSRMLS_CC);
     1040        if (wrapper && wrapper->wops->url_stat
     1041         && wrapper != &php_plain_files_wrapper
     1042         && wrapper->wops->url_stat(wrapper, path_for_open, PHP_STREAM_URL_STAT_QUIET, &ssb, NULL TSRMLS_CC) == SUCCESS) {
     1043            *statbuf = ssb.sb;
     1044            return SUCCESS;
     1045        }
     1046
     1047        return FAILURE;
     1048    }
     1049
     1050    return VCWD_STAT(filepath, statbuf);
     1051}
     1052/* }}} */
     1053static XC_RESOLVE_PATH_CHECKER(xc_resolve_path_stat_checker) /* {{{ */
     1054{
     1055    return xc_stat(filepath, (struct stat *) data TSRMLS_CC);
     1056}
     1057/* }}} */
    10271058#ifndef ZEND_ENGINE_2_3
    1028 static XC_RESOLVE_PATH_CHECKER(xc_stat_file) /* {{{ */
    1029 {
    1030     return VCWD_STAT(filepath, (struct stat *) data) == 0 ? 1 : 0;
    1031 }
    1032 /* }}} */
    10331059static int xc_resolve_path_stat(const char *filepath, char *path_buffer, struct stat *pbuf TSRMLS_DC) /* {{{ */
    10341060{
    1035     return xc_resolve_path(filepath, path_buffer, xc_stat_file, (void *) pbuf TSRMLS_CC)
    1036         ? SUCCESS
    1037         : FAILURE;
     1061    return xc_resolve_path(filepath, path_buffer, xc_resolve_path_stat_checker, (void *) pbuf TSRMLS_CC);
    10381062}
    10391063/* }}} */
     
    10511075} xc_compiler_t;
    10521076/* }}} */
    1053 typedef struct xc_entry_resolve_path_data_t { /* {{{ */
     1077typedef struct xc_resolve_path_entry_checker_t { /* {{{ */
    10541078    xc_compiler_t *compiler;
    10551079    xc_entry_php_t **stored_entry;
    1056 } xc_entry_resolve_path_data_t;
    1057 /* }}} */
    1058 static XC_RESOLVE_PATH_CHECKER(xc_entry_resolve_path_func_unlocked) /* {{{ */
    1059 {
    1060     xc_entry_resolve_path_data_t *entry_resolve_path_data = (xc_entry_resolve_path_data_t *) data;
    1061     xc_compiler_t *compiler = entry_resolve_path_data->compiler;
     1080} xc_resolve_path_entry_checker_data_t;
     1081/* }}} */
     1082static XC_RESOLVE_PATH_CHECKER(xc_resolve_path_entry_checker) /* {{{ */
     1083{
     1084    xc_resolve_path_entry_checker_data_t *entry_checker_data = (xc_resolve_path_entry_checker_data_t *) data;
     1085    xc_compiler_t *compiler = entry_checker_data->compiler;
    10621086
    10631087    compiler->new_entry.entry.name.str.val = xc_expand_url(filepath, compiler->opened_path_buffer TSRMLS_CC);
    10641088    compiler->new_entry.entry.name.str.len = strlen(compiler->new_entry.entry.name.str.val);
    10651089
    1066     *entry_resolve_path_data->stored_entry = (xc_entry_php_t *) xc_entry_find_unlocked(
     1090    *entry_checker_data->stored_entry = (xc_entry_php_t *) xc_entry_find_unlocked(
    10671091            XC_TYPE_PHP
    10681092            , &xc_php_caches[compiler->entry_hash.cacheid]
     
    10711095            TSRMLS_CC);
    10721096
    1073     return *entry_resolve_path_data->stored_entry ? 1 : 0;
    1074 }
    1075 /* }}} */
    1076 static int xc_entry_resolve_path_unlocked(xc_compiler_t *compiler, const char *filepath, xc_entry_php_t **stored_entry TSRMLS_DC) /* {{{ */
     1097    return *entry_checker_data->stored_entry ? SUCCESS : FAILURE;
     1098}
     1099/* }}} */
     1100static int xc_resolve_path_check_entry_unlocked(xc_compiler_t *compiler, const char *filepath, xc_entry_php_t **stored_entry TSRMLS_DC) /* {{{ */
    10771101{
    10781102    char path_buffer[MAXPATHLEN];
    1079     xc_entry_resolve_path_data_t entry_resolve_path_data;
    1080     entry_resolve_path_data.compiler = compiler;
    1081     entry_resolve_path_data.stored_entry = stored_entry;
    1082 
    1083     return xc_resolve_path(filepath, path_buffer, xc_entry_resolve_path_func_unlocked, (void *) &entry_resolve_path_data TSRMLS_CC)
    1084         ? SUCCESS
    1085         : FAILURE;
     1103    xc_resolve_path_entry_checker_data_t entry_checker_data;
     1104    entry_checker_data.compiler = compiler;
     1105    entry_checker_data.stored_entry = stored_entry;
     1106
     1107    return xc_resolve_path(filepath, path_buffer, xc_resolve_path_entry_checker, (void *) &entry_checker_data TSRMLS_CC);
    10861108}
    10871109/* }}} */
     
    11041126
    11051127    /* absolute path */
    1106     if (IS_ABSOLUTE_PATH(compiler->filename, strlen(compiler->filename))) {
    1107         if (statbuf && VCWD_STAT(compiler->filename, statbuf) != 0) {
     1128    if (xc_is_absolute(compiler->filename, strlen(compiler->filename))) {
     1129        if (statbuf && xc_stat(compiler->filename, statbuf TSRMLS_CC) != SUCCESS) {
    11081130            return FAILURE;
    11091131        }
     
    11471169            efree(opened_path);
    11481170            compiler->opened_path = compiler->opened_path_buffer;
    1149             if (!statbuf || VCWD_STAT(compiler->opened_path, statbuf) == 0) {
     1171            if (!statbuf || xc_stat(compiler->opened_path, statbuf TSRMLS_CC) == SUCCESS) {
    11501172                return SUCCESS;
    11511173            }
     
    11691191
    11701192        if (compiler->opened_path) {
    1171             if (VCWD_STAT(compiler->opened_path, &buf) != 0) {
     1193            if (xc_stat(compiler->opened_path, &buf TSRMLS_CC) != SUCCESS) {
    11721194                return FAILURE;
    11731195            }
     
    20752097
    20762098    ENTER_LOCK_EX(cache) {
    2077         if (!compiler->opened_path && xc_entry_resolve_path_unlocked(compiler, compiler->filename, &stored_entry TSRMLS_CC) == SUCCESS) {
     2099        if (!compiler->opened_path && xc_resolve_path_check_entry_unlocked(compiler, compiler->filename, &stored_entry TSRMLS_CC) == SUCCESS) {
    20782100            compiler->opened_path = compiler->new_entry.entry.name.str.val;
    20792101        }
     
    21782200     || !h->filename
    21792201     || !SG(request_info).path_translated
    2180      || strstr(h->filename, "://") != NULL
    2181 #ifdef ZEND_ENGINE_2_3
    2182      /* supported by php_resolve_path */
    2183      || (!XG(stat) && strstr(PG(include_path), "://") != NULL)
    2184 #else
    2185      || strstr(PG(include_path), "://") != NULL
    2186 #endif
    2187      ) {
     2202
     2203    ) {
    21882204        TRACE("%s", "cacher not enabled");
    21892205        return old_compile_file(h, type TSRMLS_CC);
Note: See TracChangeset for help on using the changeset viewer.