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;
        }
  
  
  

Reply via email to