| 1450 | |
| 1451 | |
| 1452 | AP_DECLARE(int) ap_location_walk(request_rec *r) |
| 1453 | { |
| 1454 | ap_conf_vector_t *now_merged = NULL; |
| 1455 | core_server_config *sconf = |
| 1456 | ap_get_core_module_config(r->server->module_config); |
| 1457 | ap_conf_vector_t **sec_ent = (ap_conf_vector_t **)sconf->sec_url->elts; |
| 1458 | int num_sec = sconf->sec_url->nelts; |
| 1459 | walk_cache_t *cache; |
| 1460 | const char *entry_uri; |
| 1461 | int cached; |
| 1462 | |
| 1463 | /* No tricks here, there are no <Locations > to parse in this vhost. |
| 1464 | * We won't destroy the cache, just in case _this_ redirect is later |
| 1465 | * redirected again to a vhost with <Location > blocks to optimize. |
| 1466 | */ |
| 1467 | if (!num_sec) { |
| 1468 | return OK; |
| 1469 | } |
| 1470 | |
| 1471 | cache = prep_walk_cache(AP_NOTE_LOCATION_WALK, r); |
| 1472 | cached = (cache->cached != NULL); |
| 1473 | |
| 1474 | /* |
| 1475 | * When merge_slashes is set to AP_CORE_CONFIG_OFF the slashes in r->uri |
| 1476 | * have not been merged. But for Location walks we always go with merged |
| 1477 | * slashes no matter what merge_slashes is set to. |
| 1478 | */ |
| 1479 | if (sconf->merge_slashes != AP_CORE_CONFIG_OFF) { |
| 1480 | entry_uri = r->uri; |
| 1481 | } |
| 1482 | else { |
| 1483 | char *uri = apr_pstrdup(r->pool, r->uri); |
| 1484 | ap_no2slash(uri); |
| 1485 | entry_uri = uri; |
| 1486 | } |
| 1487 | |
| 1488 | /* If we have an cache->cached location that matches r->uri, |
| 1489 | * and the vhost's list of locations hasn't changed, we can skip |
| 1490 | * rewalking the location_walk entries. |
| 1491 | */ |
| 1492 | if (cached |
| 1493 | && (cache->dir_conf_tested == sec_ent) |
| 1494 | && (strcmp(entry_uri, cache->cached) == 0)) { |
| 1495 | /* Well this looks really familiar! If our end-result (per_dir_result) |
| 1496 | * didn't change, we have absolutely nothing to do :) |
| 1497 | * Otherwise (as is the case with most dir_merged/file_merged requests) |
| 1498 | * we must merge our dir_conf_merged onto this new r->per_dir_config. |
| 1499 | */ |
| 1500 | if (r->per_dir_config == cache->per_dir_result) { |
| 1501 | return OK; |
| 1502 | } |
| 1503 | |
| 1504 | if (cache->walked->nelts) { |
| 1505 | now_merged = ((walk_walked_t*)cache->walked->elts) |
| 1506 | [cache->walked->nelts - 1].merged; |
| 1507 | } |
| 1508 | } |
| 1509 | else { |
no test coverage detected