📄 http_request.c
字号:
} else { r->status = HTTP_OK; ap_die(access_status, r); } /* * We want to flush the last packet if this isn't a pipelining connection * *before* we start into logging. Suppose that the logging causes a DNS * lookup to occur, which may have a high latency. If we hold off on * this packet, then it'll appear like the link is stalled when really * it's the application that's stalled. */ check_pipeline_flush(r); ap_update_child_status(r->connection->sbh, SERVER_BUSY_LOG, r); ap_run_log_transaction(r); if (ap_extended_status) ap_time_process_request(r->connection->sbh, STOP_PREQUEST);}static apr_table_t *rename_original_env(apr_pool_t *p, apr_table_t *t){ const apr_array_header_t *env_arr = apr_table_elts(t); const apr_table_entry_t *elts = (const apr_table_entry_t *) env_arr->elts; apr_table_t *new = apr_table_make(p, env_arr->nalloc); int i; for (i = 0; i < env_arr->nelts; ++i) { if (!elts[i].key) continue; apr_table_setn(new, apr_pstrcat(p, "REDIRECT_", elts[i].key, NULL), elts[i].val); } return new;}static request_rec *internal_internal_redirect(const char *new_uri, request_rec *r) { int access_status; request_rec *new; if (ap_is_recursion_limit_exceeded(r)) { ap_die(HTTP_INTERNAL_SERVER_ERROR, r); return NULL; } new = (request_rec *) apr_pcalloc(r->pool, sizeof(request_rec)); new->connection = r->connection; new->server = r->server; new->pool = r->pool; /* * A whole lot of this really ought to be shared with http_protocol.c... * another missing cleanup. It's particularly inappropriate to be * setting header_only, etc., here. */ new->method = r->method; new->method_number = r->method_number; new->allowed_methods = ap_make_method_list(new->pool, 2); ap_parse_uri(new, new_uri); new->request_config = ap_create_request_config(r->pool); new->per_dir_config = r->server->lookup_defaults; new->prev = r; r->next = new; /* Must have prev and next pointers set before calling create_request * hook. */ ap_run_create_request(new); /* Inherit the rest of the protocol info... */ new->the_request = r->the_request; new->allowed = r->allowed; new->status = r->status; new->assbackwards = r->assbackwards; new->header_only = r->header_only; new->protocol = r->protocol; new->proto_num = r->proto_num; new->hostname = r->hostname; new->request_time = r->request_time; new->main = r->main; new->headers_in = r->headers_in; new->headers_out = apr_table_make(r->pool, 12); new->err_headers_out = r->err_headers_out; new->subprocess_env = rename_original_env(r->pool, r->subprocess_env); new->notes = apr_table_make(r->pool, 5); new->allowed_methods = ap_make_method_list(new->pool, 2); new->htaccess = r->htaccess; new->no_cache = r->no_cache; new->expecting_100 = r->expecting_100; new->no_local_copy = r->no_local_copy; new->read_length = r->read_length; /* We can only read it once */ new->vlist_validator = r->vlist_validator; new->proto_output_filters = r->proto_output_filters; new->proto_input_filters = r->proto_input_filters; new->output_filters = new->proto_output_filters; new->input_filters = new->proto_input_filters; if (new->main) { /* Add back the subrequest filter, which we lost when * we set output_filters to include only the protocol * output filters from the original request. */ ap_add_output_filter_handle(ap_subreq_core_filter_handle, NULL, new, new->connection); } update_r_in_filters(new->input_filters, r, new); update_r_in_filters(new->output_filters, r, new); apr_table_setn(new->subprocess_env, "REDIRECT_STATUS", apr_itoa(r->pool, r->status)); /* * XXX: hmm. This is because mod_setenvif and mod_unique_id really need * to do their thing on internal redirects as well. Perhaps this is a * misnamed function. */ if ((access_status = ap_run_post_read_request(new))) { ap_die(access_status, new); return NULL; } return new;}/* XXX: Is this function is so bogus and fragile that we deep-6 it? */AP_DECLARE(void) ap_internal_fast_redirect(request_rec *rr, request_rec *r){ /* We need to tell POOL_DEBUG that we're guaranteeing that rr->pool * will exist as long as r->pool. Otherwise we run into troubles because * some values in this request will be allocated in r->pool, and others in * rr->pool. */ apr_pool_join(r->pool, rr->pool); r->proxyreq = rr->proxyreq; r->no_cache = (r->no_cache && rr->no_cache); r->no_local_copy = (r->no_local_copy && rr->no_local_copy); r->mtime = rr->mtime; r->uri = rr->uri; r->filename = rr->filename; r->canonical_filename = rr->canonical_filename; r->path_info = rr->path_info; r->args = rr->args; r->finfo = rr->finfo; r->handler = rr->handler; ap_set_content_type(r, rr->content_type); r->content_encoding = rr->content_encoding; r->content_languages = rr->content_languages; r->per_dir_config = rr->per_dir_config; /* copy output headers from subrequest, but leave negotiation headers */ r->notes = apr_table_overlay(r->pool, rr->notes, r->notes); r->headers_out = apr_table_overlay(r->pool, rr->headers_out, r->headers_out); r->err_headers_out = apr_table_overlay(r->pool, rr->err_headers_out, r->err_headers_out); r->subprocess_env = apr_table_overlay(r->pool, rr->subprocess_env, r->subprocess_env); r->output_filters = rr->output_filters; r->input_filters = rr->input_filters; if (r->main) { ap_add_output_filter_handle(ap_subreq_core_filter_handle, NULL, r, r->connection); } else if (r->output_filters->frec == ap_subreq_core_filter_handle) { ap_remove_output_filter(r->output_filters); r->output_filters = r->output_filters->next; } /* If any filters pointed at the now-defunct rr, we must point them * at our "new" instance of r. In particular, some of rr's structures * will now be bogus (say rr->headers_out). If a filter tried to modify * their f->r structure when it is pointing to rr, the real request_rec * will not get updated. Fix that here. */ update_r_in_filters(r->input_filters, rr, r); update_r_in_filters(r->output_filters, rr, r);}AP_DECLARE(void) ap_internal_redirect(const char *new_uri, request_rec *r){ request_rec *new = internal_internal_redirect(new_uri, r); int access_status; /* ap_die was already called, if an error occured */ if (!new) { return; } access_status = ap_run_quick_handler(new, 0); /* Not a look-up request */ if (access_status == DECLINED) { access_status = ap_process_request_internal(new); if (access_status == OK) { access_status = ap_invoke_handler(new); } } if (access_status == OK) { ap_finalize_request_protocol(new); } else { ap_die(access_status, new); }}/* This function is designed for things like actions or CGI scripts, when * using AddHandler, and you want to preserve the content type across * an internal redirect. */AP_DECLARE(void) ap_internal_redirect_handler(const char *new_uri, request_rec *r){ int access_status; request_rec *new = internal_internal_redirect(new_uri, r); /* ap_die was already called, if an error occured */ if (!new) { return; } if (r->handler) ap_set_content_type(new, r->content_type); access_status = ap_process_request_internal(new); if (access_status == OK) { if ((access_status = ap_invoke_handler(new)) != 0) { ap_die(access_status, new); return; } ap_finalize_request_protocol(new); } else { ap_die(access_status, new); }}AP_DECLARE(void) ap_allow_methods(request_rec *r, int reset, ...){ const char *method; va_list methods; /* * Get rid of any current settings if requested; not just the * well-known methods but any extensions as well. */ if (reset) { ap_clear_method_list(r->allowed_methods); } va_start(methods, reset); while ((method = va_arg(methods, const char *)) != NULL) { ap_method_list_add(r->allowed_methods, method); } va_end(methods);}AP_DECLARE(void) ap_allow_standard_methods(request_rec *r, int reset, ...){ int method; va_list methods; apr_int64_t mask; /* * Get rid of any current settings if requested; not just the * well-known methods but any extensions as well. */ if (reset) { ap_clear_method_list(r->allowed_methods); } mask = 0; va_start(methods, reset); while ((method = va_arg(methods, int)) != -1) { mask |= (AP_METHOD_BIT << method); } va_end(methods); r->allowed_methods->method_mask |= mask;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -