You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@httpd.apache.org by gr...@apache.org on 2002/08/13 16:27:39 UTC
cvs commit: httpd-2.0/server protocol.c
gregames 2002/08/13 07:27:39
Modified: modules/http http_protocol.c http_request.c
server protocol.c
Log:
fix weird things that happen with canned error messages due to using two
different request_recs after an ErrorDocument internal redirect failure.
examples: wrong Content-Type, garbled output from ebcdic servers due to
double charset translation
Revision Changes Path
1.454 +5 -15 httpd-2.0/modules/http/http_protocol.c
Index: http_protocol.c
===================================================================
RCS file: /home/cvs/httpd-2.0/modules/http/http_protocol.c,v
retrieving revision 1.453
retrieving revision 1.454
diff -u -r1.453 -r1.454
--- http_protocol.c 8 Aug 2002 20:39:15 -0000 1.453
+++ http_protocol.c 13 Aug 2002 14:27:39 -0000 1.454
@@ -2301,16 +2301,6 @@
const char *title = status_lines[idx];
const char *h1;
- /* XXX This is a major hack that should be fixed cleanly. The
- * problem is that we have the information we need in a previous
- * request, but the text of the page must be sent down the last
- * request_rec's filter stack. rbb
- */
- request_rec *rlast = r;
- while (rlast->next) {
- rlast = rlast->next;
- }
-
/* Accept a status_line set by a module, but only if it begins
* with the 3 digit status code
*/
@@ -2331,24 +2321,24 @@
* so do ebcdic->ascii translation explicitly (if needed)
*/
- ap_rvputs_proto_in_ascii(rlast,
+ ap_rvputs_proto_in_ascii(r,
DOCTYPE_HTML_2_0
"<html><head>\n<title>", title,
"</title>\n</head><body>\n<h1>", h1, "</h1>\n",
NULL);
- ap_rvputs_proto_in_ascii(rlast,
+ ap_rvputs_proto_in_ascii(r,
get_canned_error_string(status, r, location),
NULL);
if (recursive_error) {
- ap_rvputs_proto_in_ascii(rlast, "<p>Additionally, a ",
+ ap_rvputs_proto_in_ascii(r, "<p>Additionally, a ",
status_lines[ap_index_of_response(recursive_error)],
"\nerror was encountered while trying to use an "
"ErrorDocument to handle the request.</p>\n", NULL);
}
- ap_rvputs_proto_in_ascii(rlast, ap_psignature("<hr />\n", r), NULL);
- ap_rvputs_proto_in_ascii(rlast, "</body></html>\n", NULL);
+ ap_rvputs_proto_in_ascii(r, ap_psignature("<hr />\n", r), NULL);
+ ap_rvputs_proto_in_ascii(r, "</body></html>\n", NULL);
}
ap_finalize_request_protocol(r);
}
1.152 +35 -32 httpd-2.0/modules/http/http_request.c
Index: http_request.c
===================================================================
RCS file: /home/cvs/httpd-2.0/modules/http/http_request.c,v
retrieving revision 1.151
retrieving revision 1.152
diff -u -r1.151 -r1.152
--- http_request.c 27 Jun 2002 04:40:47 -0000 1.151
+++ http_request.c 13 Aug 2002 14:27:39 -0000 1.152
@@ -96,6 +96,23 @@
* Mainline request processing...
*/
+/* XXX A cleaner and faster way to do this might be to pass the request_rec
+ * down the filter chain as a parameter. It would need to change for
+ * subrequest vs. main request filters; perhaps the subrequest filter could
+ * make the switch.
+ */
+static void 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;
+ }
+}
+
AP_DECLARE(void) ap_die(int type, request_rec *r)
{
int error_index = ap_index_of_response(type);
@@ -124,6 +141,20 @@
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
+ * an internal redirect to a bad URI. ap_internal_redirect has
+ * changed the filter chains to point to the ErrorDocument's
+ * request_rec. Back out those changes so we can safely use the
+ * original failing request_rec to send the canned error message.
+ *
+ * ap_send_error_response gets rid of existing resource filters
+ * on the output side, so we can skip those.
+ */
+ 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! */
}
@@ -301,7 +332,6 @@
static request_rec *internal_internal_redirect(const char *new_uri,
request_rec *r) {
int access_status;
- ap_filter_t *f;
request_rec *new = (request_rec *) apr_pcalloc(r->pool,
sizeof(request_rec));
@@ -367,21 +397,8 @@
new->output_filters = new->proto_output_filters;
new->input_filters = new->proto_input_filters;
- f = new->input_filters;
- while (f) {
- if (f->r == r) {
- f->r = new;
- }
- f = f->next;
- }
-
- f = new->output_filters;
- while (f) {
- if (f->r == r) {
- f->r = new;
- }
- f = f->next;
- }
+ 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));
@@ -402,8 +419,6 @@
/* 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)
{
- ap_filter_t *filters;
-
/* 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
@@ -449,20 +464,8 @@
* their f->r structure when it is pointing to rr, the real request_rec
* will not get updated. Fix that here.
*/
- filters = r->input_filters;
- while (filters) {
- if (filters->r == rr) {
- filters->r = r;
- }
- filters = filters->next;
- }
- filters = r->output_filters;
- while (filters) {
- if (filters->r == rr) {
- filters->r = r;
- }
- filters = filters->next;
- }
+ 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)
1.115 +0 -4 httpd-2.0/server/protocol.c
Index: protocol.c
===================================================================
RCS file: /home/cvs/httpd-2.0/server/protocol.c,v
retrieving revision 1.114
retrieving revision 1.115
diff -u -r1.114 -r1.115
--- protocol.c 17 Jul 2002 13:50:26 -0000 1.114
+++ protocol.c 13 Aug 2002 14:27:39 -0000 1.115
@@ -1101,10 +1101,6 @@
{
(void) ap_discard_request_body(r);
- while (r->next) {
- r = r->next;
- }
-
/* tell the filter chain there is no more content coming */
if (!r->eos_sent) {
end_output_stream(r);