mirror of
https://github.com/apache/httpd.git
synced 2025-08-08 15:02:10 +03:00
* If a subrequest has a broken backend also set no_cache for the main request
and ensure that the chunk filter does not sent the last chunk marker in this case. modules/http/chunk_filter.c: Memorize HTTP_BAD_GATEWAY error buckets that had been seen in filter context to ensure that we do not sent the last chunk marker in this case. modules/proxy/proxy_util.c : Set no_cache also for main request if we are a subrequest. Thanks to Joe Orton and André Malo for the "invented unique pointer" trick. git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@366181 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
@@ -39,6 +39,12 @@
|
|||||||
|
|
||||||
#include "mod_core.h"
|
#include "mod_core.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* A pointer to this is used to memorize in the filter context that a bad
|
||||||
|
* gateway error bucket had been seen. It is used as an invented unique pointer.
|
||||||
|
*/
|
||||||
|
static char bad_gateway_seen;
|
||||||
|
|
||||||
apr_status_t ap_http_chunk_filter(ap_filter_t *f, apr_bucket_brigade *b)
|
apr_status_t ap_http_chunk_filter(ap_filter_t *f, apr_bucket_brigade *b)
|
||||||
{
|
{
|
||||||
#define ASCII_CRLF "\015\012"
|
#define ASCII_CRLF "\015\012"
|
||||||
@@ -47,7 +53,6 @@ apr_status_t ap_http_chunk_filter(ap_filter_t *f, apr_bucket_brigade *b)
|
|||||||
apr_bucket_brigade *more;
|
apr_bucket_brigade *more;
|
||||||
apr_bucket *e;
|
apr_bucket *e;
|
||||||
apr_status_t rv;
|
apr_status_t rv;
|
||||||
int bad_gateway_seen = 0;
|
|
||||||
|
|
||||||
for (more = NULL; b; b = more, more = NULL) {
|
for (more = NULL; b; b = more, more = NULL) {
|
||||||
apr_off_t bytes = 0;
|
apr_off_t bytes = 0;
|
||||||
@@ -71,8 +76,11 @@ apr_status_t ap_http_chunk_filter(ap_filter_t *f, apr_bucket_brigade *b)
|
|||||||
if (AP_BUCKET_IS_ERROR(e)
|
if (AP_BUCKET_IS_ERROR(e)
|
||||||
&& (((ap_bucket_error *)(e->data))->status
|
&& (((ap_bucket_error *)(e->data))->status
|
||||||
== HTTP_BAD_GATEWAY)) {
|
== HTTP_BAD_GATEWAY)) {
|
||||||
/* We had a broken backend. Memorize this. */
|
/*
|
||||||
bad_gateway_seen = 1;
|
* We had a broken backend. Memorize this in the filter
|
||||||
|
* context.
|
||||||
|
*/
|
||||||
|
f->ctx = &bad_gateway_seen;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (APR_BUCKET_IS_FLUSH(e)) {
|
if (APR_BUCKET_IS_FLUSH(e)) {
|
||||||
@@ -155,7 +163,8 @@ apr_status_t ap_http_chunk_filter(ap_filter_t *f, apr_bucket_brigade *b)
|
|||||||
* 3) the end-of-chunked body CRLF
|
* 3) the end-of-chunked body CRLF
|
||||||
*
|
*
|
||||||
* If there is no EOS bucket, or if we had seen an error bucket with
|
* If there is no EOS bucket, or if we had seen an error bucket with
|
||||||
* status HTTP_BAD_GATEWAY then do nothing.
|
* status HTTP_BAD_GATEWAY then do nothing. We have memorized an
|
||||||
|
* error bucket that we had seen in the filter context.
|
||||||
* The error bucket with status HTTP_BAD_GATEWAY indicates that the
|
* The error bucket with status HTTP_BAD_GATEWAY indicates that the
|
||||||
* connection to the backend (mod_proxy) broke in the middle of the
|
* connection to the backend (mod_proxy) broke in the middle of the
|
||||||
* response. In order to signal the client that something went wrong
|
* response. In order to signal the client that something went wrong
|
||||||
@@ -166,7 +175,7 @@ apr_status_t ap_http_chunk_filter(ap_filter_t *f, apr_bucket_brigade *b)
|
|||||||
* marker above, but this is a bit more straight-forward for
|
* marker above, but this is a bit more straight-forward for
|
||||||
* now.
|
* now.
|
||||||
*/
|
*/
|
||||||
if (eos && !bad_gateway_seen) {
|
if (eos && !f->ctx) {
|
||||||
/* XXX: (2) trailers ... does not yet exist */
|
/* XXX: (2) trailers ... does not yet exist */
|
||||||
e = apr_bucket_immortal_create(ASCII_ZERO ASCII_CRLF
|
e = apr_bucket_immortal_create(ASCII_ZERO ASCII_CRLF
|
||||||
/* <trailers> */
|
/* <trailers> */
|
||||||
|
@@ -2137,6 +2137,12 @@ PROXY_DECLARE(void) ap_proxy_backend_broke(request_rec *r,
|
|||||||
conn_rec *c = r->connection;
|
conn_rec *c = r->connection;
|
||||||
|
|
||||||
r->no_cache = 1;
|
r->no_cache = 1;
|
||||||
|
/*
|
||||||
|
* If this is a subrequest, then prevent also caching of the main
|
||||||
|
* request.
|
||||||
|
*/
|
||||||
|
if (r->main)
|
||||||
|
r->main->no_cache = 1;
|
||||||
e = ap_bucket_error_create(HTTP_BAD_GATEWAY, NULL, c->pool,
|
e = ap_bucket_error_create(HTTP_BAD_GATEWAY, NULL, c->pool,
|
||||||
c->bucket_alloc);
|
c->bucket_alloc);
|
||||||
APR_BRIGADE_INSERT_TAIL(brigade, e);
|
APR_BRIGADE_INSERT_TAIL(brigade, e);
|
||||||
|
Reference in New Issue
Block a user