You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@httpd.apache.org by ji...@apache.org on 2011/04/01 21:25:26 UTC
svn commit: r1087864 - in /httpd/httpd/trunk: CHANGES
modules/proxy/mod_proxy_ajp.c
Author: jim
Date: Fri Apr 1 19:25:26 2011
New Revision: 1087864
URL: http://svn.apache.org/viewvc?rev=1087864&view=rev
Log:
*) mod_proxy_ajp: Add support for 'ProxyErrorOverride on'. PR 50945.
[Peter Pramberger <peter pramberger.at>, Jim Jagielski]
Modified:
httpd/httpd/trunk/CHANGES
httpd/httpd/trunk/modules/proxy/mod_proxy_ajp.c
Modified: httpd/httpd/trunk/CHANGES
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/CHANGES?rev=1087864&r1=1087863&r2=1087864&view=diff
==============================================================================
--- httpd/httpd/trunk/CHANGES [utf-8] (original)
+++ httpd/httpd/trunk/CHANGES [utf-8] Fri Apr 1 19:25:26 2011
@@ -2,7 +2,10 @@
Changes with Apache 2.3.12
- *) mod_proxy_fcgi: Add support for 'ProxyErrorOverride on' PR 50913.
+ *) mod_proxy_ajp: Add support for 'ProxyErrorOverride on'. PR 50945.
+ [Peter Pramberger <peter pramberger.at>, Jim Jagielski]
+
+ *) mod_proxy_fcgi: Add support for 'ProxyErrorOverride on'. PR 50913.
[Mark Montague <mark catseye.org>, Jim Jagielski]
*) core: Change the APIs of ap_cfg_getline() and ap_cfg_getc() to return an
Modified: httpd/httpd/trunk/modules/proxy/mod_proxy_ajp.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/proxy/mod_proxy_ajp.c?rev=1087864&r1=1087863&r2=1087864&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/proxy/mod_proxy_ajp.c (original)
+++ httpd/httpd/trunk/modules/proxy/mod_proxy_ajp.c Fri Apr 1 19:25:26 2011
@@ -190,6 +190,8 @@ static int ap_proxy_ajp_request(apr_pool
apr_size_t maxsize = AJP_MSG_BUFFER_SZ;
int send_body = 0;
apr_off_t content_length = 0;
+ int original_status = r->status;
+ const char *original_status_line = r->status_line;
if (psf->io_buffer_size_set)
maxsize = psf->io_buffer_size;
@@ -430,71 +432,104 @@ static int ap_proxy_ajp_request(apr_pool
if (status != APR_SUCCESS) {
backend_failed = 1;
}
+ else if ((r->status == 401) && conf->error_override) {
+ const char *buf;
+ const char *wa = "WWW-Authenticate";
+ if ((buf = apr_table_get(r->headers_out, wa))) {
+ apr_table_set(r->err_headers_out, wa, buf);
+ } else {
+ ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server,
+ "ap_proxy_ajp_request: origin server "
+ "sent 401 without WWW-Authenticate header");
+ }
+ }
headers_sent = 1;
break;
case CMD_AJP13_SEND_BODY_CHUNK:
/* AJP13_SEND_BODY_CHUNK: piece of data */
status = ajp_parse_data(r, conn->data, &size, &send_body_chunk_buff);
if (status == APR_SUCCESS) {
- /* AJP13_SEND_BODY_CHUNK with zero length
- * is explicit flush message
+ /* If we are overriding the errors, we can't put the content
+ * of the page into the brigade.
*/
- if (size == 0) {
- if (headers_sent) {
- e = apr_bucket_flush_create(r->connection->bucket_alloc);
- APR_BRIGADE_INSERT_TAIL(output_brigade, e);
+ if (!conf->error_override || !ap_is_HTTP_ERROR(r->status)) {
+ /* AJP13_SEND_BODY_CHUNK with zero length
+ * is explicit flush message
+ */
+ if (size == 0) {
+ if (headers_sent) {
+ e = apr_bucket_flush_create(r->connection->bucket_alloc);
+ APR_BRIGADE_INSERT_TAIL(output_brigade, e);
+ }
+ else {
+ ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server,
+ "Ignoring flush message received before headers");
+ }
}
else {
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server,
- "Ignoring flush message received before headers");
- }
- }
- else {
- apr_status_t rv;
-
- e = apr_bucket_transient_create(send_body_chunk_buff, size,
- r->connection->bucket_alloc);
- APR_BRIGADE_INSERT_TAIL(output_brigade, e);
-
- if ((conn->worker->s->flush_packets == flush_on) ||
- ((conn->worker->s->flush_packets == flush_auto) &&
- ((rv = apr_poll(conn_poll, 1, &conn_poll_fd,
- conn->worker->s->flush_wait))
- != APR_SUCCESS) &&
- APR_STATUS_IS_TIMEUP(rv))) {
- e = apr_bucket_flush_create(r->connection->bucket_alloc);
+ apr_status_t rv;
+
+ /* Handle the case where the error document is itself reverse
+ * proxied and was successful. We must maintain any previous
+ * error status so that an underlying error (eg HTTP_NOT_FOUND)
+ * doesn't become an HTTP_OK.
+ */
+ if (conf->error_override && !ap_is_HTTP_ERROR(r->status)
+ && ap_is_HTTP_ERROR(original_status)) {
+ r->status = original_status;
+ r->status_line = original_status_line;
+ }
+
+ e = apr_bucket_transient_create(send_body_chunk_buff, size,
+ r->connection->bucket_alloc);
APR_BRIGADE_INSERT_TAIL(output_brigade, e);
+
+ if ((conn->worker->s->flush_packets == flush_on) ||
+ ((conn->worker->s->flush_packets == flush_auto) &&
+ ((rv = apr_poll(conn_poll, 1, &conn_poll_fd,
+ conn->worker->s->flush_wait))
+ != APR_SUCCESS) &&
+ APR_STATUS_IS_TIMEUP(rv))) {
+ e = apr_bucket_flush_create(r->connection->bucket_alloc);
+ APR_BRIGADE_INSERT_TAIL(output_brigade, e);
+ }
+ apr_brigade_length(output_brigade, 0, &bb_len);
+ if (bb_len != -1)
+ conn->worker->s->read += bb_len;
}
- apr_brigade_length(output_brigade, 0, &bb_len);
- if (bb_len != -1)
- conn->worker->s->read += bb_len;
- }
- if (ap_pass_brigade(r->output_filters,
- output_brigade) != APR_SUCCESS) {
- ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,
- "proxy: error processing body.%s",
- r->connection->aborted ?
- " Client aborted connection." : "");
- output_failed = 1;
+ if (ap_pass_brigade(r->output_filters,
+ output_brigade) != APR_SUCCESS) {
+ ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,
+ "proxy: error processing body.%s",
+ r->connection->aborted ?
+ " Client aborted connection." : "");
+ output_failed = 1;
+ }
+ data_sent = 1;
+ apr_brigade_cleanup(output_brigade);
}
- data_sent = 1;
- apr_brigade_cleanup(output_brigade);
}
else {
backend_failed = 1;
}
break;
case CMD_AJP13_END_RESPONSE:
- e = apr_bucket_eos_create(r->connection->bucket_alloc);
- APR_BRIGADE_INSERT_TAIL(output_brigade, e);
- if (ap_pass_brigade(r->output_filters,
- output_brigade) != APR_SUCCESS) {
- ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,
- "proxy: error processing end");
- output_failed = 1;
+ /* If we are overriding the errors, we must not send anything to
+ * the client, especially as the brigade already contains headers.
+ * So do nothing here, and it will be cleaned up below.
+ */
+ if (!conf->error_override || !ap_is_HTTP_ERROR(r->status)) {
+ e = apr_bucket_eos_create(r->connection->bucket_alloc);
+ APR_BRIGADE_INSERT_TAIL(output_brigade, e);
+ if (ap_pass_brigade(r->output_filters,
+ output_brigade) != APR_SUCCESS) {
+ ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,
+ "proxy: error processing end");
+ output_failed = 1;
+ }
+ /* XXX: what about flush here? See mod_jk */
+ data_sent = 1;
}
- /* XXX: what about flush here? See mod_jk */
- data_sent = 1;
request_ended = 1;
break;
default:
@@ -569,7 +604,18 @@ static int ap_proxy_ajp_request(apr_pool
"proxy: got response from %pI (%s)",
conn->worker->cp->addr,
conn->worker->s->hostname);
- rv = OK;
+
+ if (conf->error_override && ap_is_HTTP_ERROR(r->status)) {
+ /* clear r->status for override error, otherwise ErrorDocument
+ * thinks that this is a recursive error, and doesn't find the
+ * custom error page
+ */
+ rv = r->status;
+ r->status = HTTP_OK;
+ }
+ else {
+ rv = OK;
+ }
}
if (backend_failed) {