fielding 97/05/14 12:22:57
Modified: src CHANGES httpd.h alloc.h http_request.c
http_protocol.c
Log:
Restore the semantics of
headers_out headers sent only with 200..299 and 304 responses
err_headers_out headers sent with all responses
Moved the prior changes from the die() function to send_error_response()
where they belong, and supplemented those with the other values that need
to be reset. It also avoids the overhead of copying tables if
err_headers_out is empty (the usual case), fixes a bug with assbackwards
and 204/304, and removes a bit of code that should not be generating a
Cache-Control header field even if r->no_cache is set.
Reviewed by: Dean Gaudet
Revision Changes Path
1.275 +6 -1 apache/src/CHANGES
Index: CHANGES
===================================================================
RCS file: /export/home/cvs/apache/src/CHANGES,v
retrieving revision 1.274
retrieving revision 1.275
diff -C3 -r1.274 -r1.275
*** CHANGES 1997/05/13 04:01:49 1.274
--- CHANGES 1997/05/14 19:22:50 1.275
***************
*** 2,8 ****
*) If the lookup for a DirectoryIndex name with content negotiation
has found matching variants, but none are acceptable, return the
! negotiation result if there are no more DirectoryIndex names lookup.
[Petr Lampa and Roy Fielding]
*) If a soft_timeout occurs after keepalive is set, then the main child
--- 2,8 ----
*) If the lookup for a DirectoryIndex name with content negotiation
has found matching variants, but none are acceptable, return the
! negotiation result if there are no more DirectoryIndex names to lookup.
[Petr Lampa and Roy Fielding]
*) If a soft_timeout occurs after keepalive is set, then the main child
***************
*** 22,27 ****
--- 22,32 ----
reset the content_language(s) and content_encoding of the response
before generating or redirecting to an error message, since the new
message will have its own Content-* definitions. [Dean Gaudet]
+
+ *) Restored the semantics of headers_out (headers sent only with 200..299
+ and 304 responses) and err_headers_out (headers sent with all
responses).
+ Avoid the overhead of copying tables if err_headers_out is empty
+ (the usual case). [Roy Fielding]
*) Fixed a couple places where a check for the default Content-Type was
not properly checking both the value configured by the DefaultType
1.104 +1 -1 apache/src/httpd.h
Index: httpd.h
===================================================================
RCS file: /export/home/cvs/apache/src/httpd.h,v
retrieving revision 1.103
retrieving revision 1.104
diff -C3 -r1.103 -r1.104
*** httpd.h 1997/05/08 11:27:28 1.103
--- httpd.h 1997/05/14 19:22:51 1.104
***************
*** 474,480 ****
* write modules to add to that environment.
*
* The difference between headers_out and err_headers_out is that the
! * latter persist across internal redirects
* (so the headers printed for ErrorDocument handlers will have them).
*
* The 'notes' table is for notes from one module to another, with no
--- 474,480 ----
* write modules to add to that environment.
*
* The difference between headers_out and err_headers_out is that the
! * latter are printed even on error, and persist across internal redirects
* (so the headers printed for ErrorDocument handlers will have them).
*
* The 'notes' table is for notes from one module to another, with no
1.20 +2 -0 apache/src/alloc.h
Index: alloc.h
===================================================================
RCS file: /export/home/cvs/apache/src/alloc.h,v
retrieving revision 1.19
retrieving revision 1.20
diff -C3 -r1.19 -r1.20
*** alloc.h 1997/04/24 23:35:19 1.19
--- alloc.h 1997/05/14 19:22:52 1.20
***************
*** 156,161 ****
--- 156,163 ----
array_header *table_elts (table *);
+ #define is_empty_table(t) (((t) == NULL)||((t)->nelts == 0))
+
/* routines to remember allocation of other sorts of things...
* generic interface first. Note that we want to have two separate
* cleanup functions in the general case, one for exec() preparation,
1.50 +0 -10 apache/src/http_request.c
Index: http_request.c
===================================================================
RCS file: /export/home/cvs/apache/src/http_request.c,v
retrieving revision 1.49
retrieving revision 1.50
diff -C3 -r1.49 -r1.50
*** http_request.c 1997/05/11 22:30:37 1.49
--- http_request.c 1997/05/14 19:22:52 1.50
***************
*** 764,779 ****
r->status = type;
- /* XXX: this is an awful thing to have to do here, in fact there are
- * probably other cases that need this attention. Essentially we're
- * about to report an error, and if we don't do an internal_redirect
- * below then we'll report the error with the wrong headers -- we'll
- * use headers belonging to the original request.
- */
- r->content_language = NULL;
- r->content_languages = NULL;
- r->content_encoding = NULL;
-
/* Two types of custom redirects --- plain text, and URLs.
* Plain text has a leading '"', so the URL code, here, is triggered
* on its absence
--- 764,769 ----
1.121 +62 -45 apache/src/http_protocol.c
Index: http_protocol.c
===================================================================
RCS file: /export/home/cvs/apache/src/http_protocol.c,v
retrieving revision 1.120
retrieving revision 1.121
diff -C3 -r1.120 -r1.121
*** http_protocol.c 1997/05/11 22:30:37 1.120
--- http_protocol.c 1997/05/14 19:22:53 1.121
***************
*** 1186,1192 ****
* header field tables into a single table. If we don't do this, our
* later attempts to set or unset a given fieldname might be bypassed.
*/
! r->headers_out=overlay_tables(r->pool, r->err_headers_out,
r->headers_out);
hard_timeout("send headers", r);
--- 1186,1194 ----
* header field tables into a single table. If we don't do this, our
* later attempts to set or unset a given fieldname might be bypassed.
*/
! if (!is_empty_table(r->err_headers_out))
! r->headers_out = overlay_tables(r->pool, r->err_headers_out,
! r->headers_out);
hard_timeout("send headers", r);
***************
*** 1223,1237 ****
/* Control cachability for non-cachable responses if not already set
* by some other part of the server configuration.
*/
! if (r->no_cache) {
! if ((r->proto_num >= 1001) &&
! !table_get(r->headers_out, "Cache-Control"))
! table_add(r->headers_out, "Cache-Control", "private");
!
! if (!table_get(r->headers_out, "Expires"))
! table_add(r->headers_out, "Expires",
! gm_timestr_822(r->pool, r->request_time));
! }
/* Send the entire table of header fields, terminated by an empty line.
*/
--- 1225,1233 ----
/* Control cachability for non-cachable responses if not already set
* by some other part of the server configuration.
*/
! if (r->no_cache && !table_get(r->headers_out, "Expires"))
! table_add(r->headers_out, "Expires",
! gm_timestr_822(r->pool, r->request_time));
/* Send the entire table of header fields, terminated by an empty line.
*/
***************
*** 1643,1648 ****
--- 1639,1650 ----
return bflush(r->connection->client);
}
+ /* We should have named this send_canned_response, since it is used for any
+ * response that can be generated by the server from the request record.
+ * This includes all 204 (no content), 3xx (redirect), 4xx (client error),
+ * and 5xx (server error) messages that have not been redirected to another
+ * handler via the ErrorDocument feature.
+ */
void send_error_response (request_rec *r, int recursive_error)
{
BUFF *fd = r->connection->client;
***************
*** 1651,1700 ****
char *custom_response;
char *location = pstrdup(r->pool, table_get(r->headers_out,
"Location"));
! if (!r->assbackwards) {
!
! /* For non-error statuses (2xx and 3xx), send out all the normal
! * headers unless it is a 304. Don't send a Location unless its
! * a redirect status (3xx).
! */
! if (status == HTTP_NOT_MODIFIED) {
! r->headers_out = overlay_tables(r->pool, r->err_headers_out,
! r->headers_out);
! hard_timeout("send 304", r);
!
! basic_http_header(r);
! set_keepalive(r);
!
! table_do((int (*)(void *, const char *, const char
*))send_header_field,
! (void *)r, r->headers_out,
! "Connection",
! "Keep-Alive",
! "ETag",
! "Content-Location",
! "Expires",
! "Cache-Control",
! "Vary",
! "Warning",
! "WWW-Authenticate",
! NULL);
! terminate_header(r->connection->client);
! kill_timeout(r);
! return;
! }
if ((status == METHOD_NOT_ALLOWED) || (status == NOT_IMPLEMENTED))
table_set(r->headers_out, "Allow", make_allow(r));
- if (!is_HTTP_REDIRECT(status))
- table_unset(r->headers_out, "Location");
-
- r->content_type = "text/html";
send_http_header(r);
! if (r->header_only || (status == HTTP_NO_CONTENT)) {
finalize_request_protocol(r);
return;
}
--- 1653,1717 ----
char *custom_response;
char *location = pstrdup(r->pool, table_get(r->headers_out,
"Location"));
! /* We need to special-case the handling of 204 and 304 responses,
! * since they have specific HTTP requirements and do not include a
! * message body. Note that being assbackwards here is not an option.
! */
! if (status == HTTP_NOT_MODIFIED) {
! if (!is_empty_table(r->err_headers_out))
! r->headers_out = overlay_tables(r->pool, r->err_headers_out,
! r->headers_out);
! hard_timeout("send 304", r);
!
! basic_http_header(r);
! set_keepalive(r);
!
! table_do((int (*)(void *, const char *, const char
*))send_header_field,
! (void *)r, r->headers_out,
! "Connection",
! "Keep-Alive",
! "ETag",
! "Content-Location",
! "Expires",
! "Cache-Control",
! "Vary",
! "Warning",
! "WWW-Authenticate",
! NULL);
! terminate_header(r->connection->client);
! kill_timeout(r);
! return;
! }
! if (status == HTTP_NO_CONTENT) {
! send_http_header(r);
! finalize_request_protocol(r);
! return;
! }
!
! if (!r->assbackwards) {
!
! /* For all HTTP/1.x responses for which we generate the message,
! * we need to avoid inheriting the "normal status" header fields
! * that may have been set by the request handler before the
! * error or redirect.
! */
! r->headers_out = r->err_headers_out;
! r->err_headers_out = NULL;
! r->content_language = NULL;
! r->content_languages = NULL;
! r->content_encoding = NULL;
! r->clength = 0;
! r->content_type = "text/html";
if ((status == METHOD_NOT_ALLOWED) || (status == NOT_IMPLEMENTED))
table_set(r->headers_out, "Allow", make_allow(r));
send_http_header(r);
! if (r->header_only) {
finalize_request_protocol(r);
return;
}