/* Licensed to the Apache Software Foundation (ASF) under one or more *contributorlicenseagreements.SeetheNOTICEfiledistributedwith *thisworkforadditionalinformationregardingcopyrightownership. *TheASFlicensesthisfiletoYouundertheApacheLicense,Version2.0 *(the"License");youmaynotusethisfileexceptincompliancewith *theLicense.YoumayobtainacopyoftheLicenseat * *http://www.apache.org/licenses/LICENSE-2.0 * *Unlessrequiredbyapplicablelaworagreedtoinwriting,software *distributedundertheLicenseisdistributedonan"ASIS"BASIS, *WITHOUTWARRANTIESORCONDITIONSOFANYKIND,eitherexpressorimplied. *SeetheLicenseforthespecificlanguagegoverningpermissionsand *limitationsundertheLicense.
*/
/* XXX A cleaner and faster way to do this might be to pass the request_rec *downthefilterchainasaparameter.Itwouldneedtochangefor *subrequestvs.mainrequestfilters;perhapsthesubrequestfiltercould *maketheswitch.
*/ staticvoid update_r_in_filters(ap_filter_t *f,
request_rec *from,
request_rec *to)
{ while (f) { if (f->r == from) {
f->r = to;
}
f = f->next;
}
}
if (type == OK || type == DONE) {
ap_finalize_request_protocol(r); return;
}
if (!ap_is_HTTP_VALID_RESPONSE(type)) {
ap_filter_t *next;
/* *Checkifwestillhavetheap_http_header_filterinplace.If *thisisthecaseweshouldnotignoretheerrorherebecause *itmeansthatwehavenotsentanyresponseatallandnever *will.Thisisbad.Sentaninternalservererrorinstead.
*/
next = r->output_filters; while (next && (next->frec != ap_http_header_filter_handle)) {
next = next->next;
}
/* *Ifnext!=NULLthenweleftthewhileabovebecauseof *next->frec==ap_http_header_filter
*/ if (next) { if (type != AP_FILTER_ERROR) {
ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01579) "Invalid response status %i", type);
} else {
ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(02831) "Response from AP_FILTER_ERROR");
}
type = HTTP_INTERNAL_SERVER_ERROR;
} else { return;
}
}
/* *ThefollowingtakescareofApacheredirectstocustomresponseURLs *Notethatifwearealreadydealingwiththeresponsetosomeother *errorcondition,wejustreportontheoriginalerror,andgiveupon *anyattempttohandletheotherthing"intelligently"...
*/ if (recursive_error != HTTP_OK) { while (r_1st_err->prev && (r_1st_err->prev->status != HTTP_OK))
r_1st_err = r_1st_err->prev; /* Get back to original error */
if (r_1st_err != r) { /* The recursive error was caused by an ErrorDocument specifying *aninternalredirecttoabadURI.ap_internal_redirecthas *changedthefilterchainstopointtotheErrorDocument's *request_rec.Backoutthosechangessowecansafelyusethe *originalfailingrequest_rectosendthecannederrormessage. * *ap_send_error_responsegetsridofexistingresourcefilters *ontheoutputside,sowecanskipthose.
*/
update_r_in_filters(r_1st_err->proto_output_filters, r, r_1st_err);
update_r_in_filters(r_1st_err->input_filters, r, r_1st_err);
}
custom_response = NULL; /* Do NOT retry the custom thing! */
} else { int error_index = ap_index_of_response(type);
custom_response = ap_response_code_string(r, error_index);
recursive_error = 0;
}
/* If we don't want to keep the connection, make sure we mark that the *connectionisnoteligibleforkeepalive.Ifwewanttokeepthe *connection,besurethattherequestbody(ifany)hasbeenread.
*/ if (ap_status_drops_connection(r->status)) {
r->connection->keepalive = AP_CONN_CLOSE;
}
/* Send an EOR bucket through the output filter chain. When *thisbucketisdestroyed,therequestwillbeloggedand *itspoolwillbefreed
*/
RETRIEVE_BRIGADE_FROM_POOL(bb, "ap_process_request_after_handler_brigade",
c->pool, c->bucket_alloc);
b = ap_bucket_eor_create(c->bucket_alloc, r);
APR_BRIGADE_INSERT_HEAD(bb, b);
ap_pass_brigade(c->output_filters, bb);
/* The EOR bucket has either been handled by an output filter (eg. *deletedormovedtoabuffered_bb=>nomoreinbb),oranerror *occuredbeforethat(eg.c->aborted=>stillinbb)andweought *todestroyitnow.Socleanupanyremainingbucketalongwith *theorphanrequest(ifany).
*/
apr_brigade_cleanup(bb);
/* From here onward, it is no longer safe to reference r *orr->pool,becauser->poolmayhavebeendestroyed *alreadybytheEORbucket'scleanupfunction.
*/
/* Check pipeline consuming blank lines, they must not be interpreted as *thenextpipelinedrequest,otherwisewewouldblockonthenextread *withoutflushingdata,andhencepossiblydelaypendingresponse(s) *untilthenext/realrequestcomesinorthekeepalivetimeoutexpires.
*/
rv = ap_check_pipeline(c, bb, DEFAULT_LIMIT_BLANK_LINES);
c->data_in_input_filters = (rv == APR_SUCCESS);
apr_brigade_cleanup(bb);
if (c->cs)
c->cs->state = (c->aborted) ? CONN_STATE_LINGER
: CONN_STATE_WRITE_COMPLETION;
AP_PROCESS_REQUEST_RETURN((uintptr_t)r, r->uri, r->status); if (ap_extended_status) {
ap_time_process_request(c->sbh, STOP_PREQUEST);
}
}
void ap_process_async_request(request_rec *r)
{
conn_rec *c = r->connection; int access_status;
/* Give quick handlers a shot at serving the request on the fast *path,bypassingalloftheotherApachehooks. * *ThishookwasaddedtoenableservingfilesoutofaURIkeyed *contentcache(e.g.,MikeAbbott'sQuickShortcutCache, *describedhere:http://oss.sgi.com/projects/apache/mod_qsc.html ) * *Itmayhaveotherusesaswell,suchasroutingrequestsdirectlyto *contenthandlersthathavetheabilitytogrokHTTPanddotheir *ownaccesschecking,etc(e.g.servletengines). * *Usethishookwithextremecareandonlyifyouknowwhatyouare *doing.
*/
AP_PROCESS_REQUEST_ENTRY((uintptr_t)r, r->uri); if (ap_extended_status) {
ap_time_process_request(r->connection->sbh, START_PREQUEST);
}
if (APLOGrtrace4(r)) { int i; const apr_array_header_t *t_h = apr_table_elts(r->headers_in); const apr_table_entry_t *t_elt = (apr_table_entry_t *)t_h->elts;
ap_log_rerror(APLOG_MARK, APLOG_TRACE4, 0, r, "Headers received from client:"); for (i = 0; i < t_h->nelts; i++, t_elt++) {
ap_log_rerror(APLOG_MARK, APLOG_TRACE4, 0, r, " %s: %s",
ap_escape_logitem(r->pool, t_elt->key),
ap_escape_logitem(r->pool, t_elt->val));
}
}
#if APR_HAS_THREADS
apr_thread_mutex_create(&r->invoke_mtx, APR_THREAD_MUTEX_DEFAULT, r->pool);
apr_thread_mutex_lock(r->invoke_mtx); #endif
access_status = ap_run_quick_handler(r, 0); /* Not a look-up request */ if (access_status == DECLINED) {
access_status = ap_process_request_internal(r); if (access_status == OK) {
access_status = ap_invoke_handler(r);
}
}
if (access_status == SUSPENDED) { /* TODO: Should move these steps into a generic function, so modules *workingonasuspendedrequestcanalsocall_ENTRYagain.
*/
AP_PROCESS_REQUEST_RETURN((uintptr_t)r, r->uri, access_status); if (ap_extended_status) {
ap_time_process_request(c->sbh, STOP_PREQUEST);
} if (c->cs)
c->cs->state = CONN_STATE_SUSPENDED; #if APR_HAS_THREADS
apr_thread_mutex_unlock(r->invoke_mtx); #endif return;
} #if APR_HAS_THREADS
apr_thread_mutex_unlock(r->invoke_mtx); #endif
/* If this is a subrequest, the filter chain may contain a *mixtureoffiltersspecifictotheoldrequest(r),and *someinheritedfromr->main.Here,inheritthatfilter *chain,andremoveallthosewhicharespecifictotheold
* request; ensuring the subreq filter is left in place. */ new->output_filters = r->output_filters;
f = new->output_filters; do {
nextf = f->next;
if (f->r == r && f->frec != ap_subreq_core_filter_handle) {
ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01582) "dropping filter '%s' in internal redirect from %s to %s",
f->frec->name, r->unparsed_uri, new_uri);
/* To remove the filter, first set f->r to the *new* *request_rec,sothat->output_filterson'new'is
* changed (if necessary) when removing the filter. */
f->r = new;
ap_remove_output_filter(f);
}
f = nextf;
/* Stop at the protocol filters. If a protocol filter has *beennewlyinstalledforthisresource,betterleaveit *inplace,thoughit'sprobablyamisconfigurationor
* filter bug to get into this state. */
} while (f && f != new->proto_output_filters);
} else { /* If this is not a subrequest, clear out all
* resource-specific filters. */ new->output_filters = new->proto_output_filters;
}
/* Begin by presuming any module can make its own path_info assumptions, *untilsomemoduleinterjectsandchangesthevalue.
*/ new->used_path_info = AP_REQ_DEFAULT_PATH_INFO;
/* If any filters pointed at the now-defunct rr, we must point them *atour"new"instanceofr.Inparticular,someofrr'sstructures *willnowbebogus(sayrr->headers_out).Ifafiltertriedtomodify *theirf->rstructurewhenitispointingtorr,therealrequest_rec *willnotgetupdated.Fixthathere.
*/
update_r_in_filters(r->input_filters, rr, r);
update_r_in_filters(r->output_filters, rr, r);
if (r->main) {
ap_filter_t *next = r->output_filters; while (next && (next != r->proto_output_filters)) { if (next->frec == ap_subreq_core_filter_handle) { break;
}
next = next->next;
} if (!next || next == r->proto_output_filters) {
ap_add_output_filter_handle(ap_subreq_core_filter_handle,
NULL, r, r->connection);
}
} else { /* *WeneedtocheckifwenowhavetheSUBREQ_COREfilterinourfilter *chain.IfthisisthecaseweneedtoremoveitsinceweareNO *subrequest.ButweneedtokeepinmindthattheSUBREQ_COREfilter *doesnotnecessarilyneedtobethefirstfilterinourchain.Sowe *needtogothroughthechain.Butweonlyneedtowalkupthechain *untiltheproto_output_filtersastheSUBREQ_COREfilterisbelowthe *protocolfilters.
*/
ap_filter_t *next;
next = r->output_filters; while (next && (next->frec != ap_subreq_core_filter_handle)
&& (next != r->proto_output_filters)) {
next = next->next;
} if (next && (next->frec == ap_subreq_core_filter_handle)) {
ap_remove_output_filter(next);
}
}
}
/* 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);
}
}
ap_die(access_status, new);
}
/* This function is designed for things like actions or CGI scripts, when *usingAddHandler,andyouwanttopreservethecontenttypeacross *aninternalredirect.
*/
AP_DECLARE(void) ap_internal_redirect_handler(constchar *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_ex(new, r->content_type, AP_REQUEST_IS_TRUSTED_CT(r));
access_status = ap_process_request_internal(new); if (access_status == OK) {
access_status = ap_invoke_handler(new);
}
ap_die(access_status, new);
}
¤ Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.0.16Bemerkung:
(vorverarbeitet am 2026-09-29)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.