You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@httpd.apache.org by Roy Fielding <fi...@hyperreal.org> on 1997/07/19 22:27:57 UTC

cvs commit: apache/src CHANGES http_core.c http_protocol.c http_protocol.h http_request.c http_config.h

fielding    97/07/19 13:27:56

  Modified:    src       CHANGES http_core.c http_protocol.c
                        http_protocol.h  http_request.c http_config.h
  Log:
  In HTTP/1.1, whether or not a request message contains a body
  is independent of the request method and based solely on the presence
  of a Content-Length or Transfer-Encoding.  Therefore, our default
  handlers need to be prepared to read a body even if they don't know
  what to do with it; otherwise, the body would be mistaken for the
  next request on a persistent connection.  discard_request_body()
  has been added to the API to make this easier for modules.
  
  PR: 378
  Reviewed by: Dean Gaudet
  
  Revision  Changes    Path
  1.352     +8 -0      apache/src/CHANGES
  
  Index: CHANGES
  ===================================================================
  RCS file: /export/home/cvs/apache/src/CHANGES,v
  retrieving revision 1.351
  retrieving revision 1.352
  diff -C3 -r1.351 -r1.352
  *** CHANGES	1997/07/19 19:42:17	1.351
  --- CHANGES	1997/07/19 20:27:50	1.352
  ***************
  *** 177,182 ****
  --- 177,190 ----
    
    Changes with Apache 1.2.2
    
  +   *) API: In HTTP/1.1, whether or not a request message contains a body
  +      is independent of the request method and based solely on the presence
  +      of a Content-Length or Transfer-Encoding.  Therefore, our default
  +      handlers need to be prepared to read a body even if they don't know
  +      what to do with it; otherwise, the body would be mistaken for the
  +      next request on a persistent connection.  discard_request_body()
  +      has been added to take care of that.  [Roy Fielding] PR#378
  + 
      *) API: Symbol APACHE_RELEASE provides a numeric form of the Apache
         release version number, such that it always increases along the
         same lines as our source code branching.  [Roy Fielding]
  
  
  
  1.98      +7 -2      apache/src/http_core.c
  
  Index: http_core.c
  ===================================================================
  RCS file: /export/home/cvs/apache/src/http_core.c,v
  retrieving revision 1.97
  retrieving revision 1.98
  diff -C3 -r1.97 -r1.98
  *** http_core.c	1997/07/17 22:27:29	1.97
  --- http_core.c	1997/07/19 20:27:51	1.98
  ***************
  *** 1368,1376 ****
          (core_dir_config *)get_module_config(r->per_dir_config, &core_module);
        int rangestatus, errstatus;
        FILE *f;
  !     
        r->allowed |= (1 << M_GET);
  -     r->allowed |= (1 << M_TRACE);
        r->allowed |= (1 << M_OPTIONS);
    
        if (r->method_number == M_INVALID) {
  --- 1368,1381 ----
          (core_dir_config *)get_module_config(r->per_dir_config, &core_module);
        int rangestatus, errstatus;
        FILE *f;
  ! 
  !     /* This handler has no use for a request body (yet), but we still
  !      * need to read and discard it if the client sent one.
  !      */
  !     if ((errstatus = discard_request_body(r)) != OK)
  !         return errstatus;
  ! 
        r->allowed |= (1 << M_GET);
        r->allowed |= (1 << M_OPTIONS);
    
        if (r->method_number == M_INVALID) {
  
  
  
  1.143     +53 -19    apache/src/http_protocol.c
  
  Index: http_protocol.c
  ===================================================================
  RCS file: /export/home/cvs/apache/src/http_protocol.c,v
  retrieving revision 1.142
  retrieving revision 1.143
  diff -C3 -r1.142 -r1.143
  *** http_protocol.c	1997/07/19 10:20:50	1.142
  --- http_protocol.c	1997/07/19 20:27:52	1.143
  ***************
  *** 1094,1127 ****
        bputs("\015\012", client);    /* Send the terminating empty line */
    }
    
    static char *make_allow(request_rec *r)
    {
  !     int allowed = r->allowed;
  ! 
  !     if( allowed == 0 ) {
  ! 	/* RFC2068 #14.7, Allow must contain at least one method.  So rather
  ! 	 * than deal with the possibility of trying not to emit an Allow:
  ! 	 * header, i.e. #10.4.6 says 405 Method Not Allowed MUST include
  ! 	 * an Allow header, we'll just say TRACE is valid.
  ! 	 */
  ! 	return( "TRACE" );
  !     }
  ! 
  !     return 2 + pstrcat(r->pool, (allowed & (1 << M_GET)) ? ", GET, HEAD" : "",
  ! 		       (allowed & (1 << M_POST)) ? ", POST" : "",
  ! 		       (allowed & (1 << M_PUT)) ? ", PUT" : "",
  ! 		       (allowed & (1 << M_DELETE)) ? ", DELETE" : "",
  ! 		       (allowed & (1 << M_OPTIONS)) ? ", OPTIONS" : "",
  ! 		       (allowed & (1 << M_TRACE)) ? ", TRACE" : "",
  ! 		       NULL);
  !     
    }
    
    int send_http_trace (request_rec *r)
    {
        /* Get the original request */
        while (r->prev) r = r->prev;
    
        hard_timeout("send TRACE", r);
    
        r->content_type = "message/http";
  --- 1094,1124 ----
        bputs("\015\012", client);    /* Send the terminating empty line */
    }
    
  + /* Build the Allow field-value from the request handler method mask.
  +  * Note that we always allow TRACE, since it is handled below.
  +  */
    static char *make_allow(request_rec *r)
    {
  !     return 2 + pstrcat(r->pool,
  !                        (r->allowed & (1 << M_GET)) ? ", GET, HEAD" : "",
  !                        (r->allowed & (1 << M_POST)) ? ", POST" : "",
  !                        (r->allowed & (1 << M_PUT)) ? ", PUT" : "",
  !                        (r->allowed & (1 << M_DELETE)) ? ", DELETE" : "",
  !                        (r->allowed & (1 << M_OPTIONS)) ? ", OPTIONS" : "",
  !                        ", TRACE",
  !                        NULL);
    }
    
    int send_http_trace (request_rec *r)
    {
  +     int rv;
  + 
        /* Get the original request */
        while (r->prev) r = r->prev;
    
  +     if ((rv = setup_client_block(r, REQUEST_NO_BODY)))
  +         return rv;
  + 
        hard_timeout("send TRACE", r);
    
        r->content_type = "message/http";
  ***************
  *** 1533,1538 ****
  --- 1530,1572 ----
        return (chunk_start + len_read);
    }
    
  + /* In HTTP/1.1, any method can have a body.  However, most GET handlers
  +  * wouldn't know what to do with a request body if they received one.
  +  * This helper routine tests for and reads any message body in the request,
  +  * simply discarding whatever it receives.  We need to do this because
  +  * failing to read the request body would cause it to be interpreted
  +  * as the next request on a persistent connection.  
  +  *
  +  * Since we return an error status if the request is malformed, this
  +  * routine should be called at the beginning of a no-body handler, e.g.,
  +  *
  +  *    if ((retval = discard_request_body(r)) != OK)
  +  *        return retval;
  +  */
  + API_EXPORT(int) discard_request_body(request_rec *r)
  + {
  +     int rv;
  + 
  +     if ((rv = setup_client_block(r, REQUEST_CHUNKED_PASS)))
  +         return rv;
  + 
  +     if (should_client_block(r)) {
  +         char dumpbuf[HUGE_STRING_LEN];
  + 
  +         hard_timeout("reading request body", r);
  +         while ((rv = get_client_block(r, dumpbuf, HUGE_STRING_LEN)) > 0)
  +             continue;
  +         kill_timeout(r);
  + 
  +         if (rv < 0)
  +             return HTTP_BAD_REQUEST;
  +     }
  +     return OK;
  + }
  + 
  + /*
  +  * Send the body of a response to the client.
  +  */
    API_EXPORT(long) send_fd(FILE *f, request_rec *r) {
        return send_fd_length(f, r, -1);
    }
  
  
  
  1.24      +1 -0      apache/src/http_protocol.h
  
  Index: http_protocol.h
  ===================================================================
  RCS file: /export/home/cvs/apache/src/http_protocol.h,v
  retrieving revision 1.23
  retrieving revision 1.24
  diff -C3 -r1.23 -r1.24
  *** http_protocol.h	1997/07/15 21:39:56	1.23
  --- http_protocol.h	1997/07/19 20:27:52	1.24
  ***************
  *** 134,139 ****
  --- 134,140 ----
    API_EXPORT(int) setup_client_block (request_rec *r, int read_policy);
    API_EXPORT(int) should_client_block (request_rec *r);
    API_EXPORT(long) get_client_block (request_rec *r, char *buffer, int bufsiz);
  + API_EXPORT(int) discard_request_body (request_rec *r);
    
    /* Sending a byterange */
    
  
  
  
  1.65      +4 -2      apache/src/http_request.c
  
  Index: http_request.c
  ===================================================================
  RCS file: /export/home/cvs/apache/src/http_request.c,v
  retrieving revision 1.64
  retrieving revision 1.65
  diff -C3 -r1.64 -r1.65
  *** http_request.c	1997/07/19 08:03:53	1.64
  --- http_request.c	1997/07/19 20:27:53	1.65
  ***************
  *** 930,937 ****
             * we handle it specially.
             */
            if (r->method_number == M_TRACE) {
  !             send_http_trace(r);
  !             finalize_request_protocol(r);
                return;
            }
    
  --- 930,939 ----
             * we handle it specially.
             */
            if (r->method_number == M_TRACE) {
  !             if ((access_status = send_http_trace(r)))
  ! 	        die(access_status, r);
  !             else
  !                 finalize_request_protocol(r);
                return;
            }
    
  
  
  
  1.38      +1 -1      apache/src/http_config.h
  
  Index: http_config.h
  ===================================================================
  RCS file: /export/home/cvs/apache/src/http_config.h,v
  retrieving revision 1.37
  retrieving revision 1.38
  diff -C3 -r1.37 -r1.38
  *** http_config.h	1997/07/17 23:30:07	1.37
  --- http_config.h	1997/07/19 20:27:53	1.38
  ***************
  *** 238,244 ****
     * handle it back-compatibly, or at least signal an error).
     */
    
  ! #define MODULE_MAGIC_NUMBER 19970717
    #define STANDARD_MODULE_STUFF MODULE_MAGIC_NUMBER, -1, __FILE__, NULL
    
    /* Generic accessors for other modules to get at their own module-specific
  --- 238,244 ----
     * handle it back-compatibly, or at least signal an error).
     */
    
  ! #define MODULE_MAGIC_NUMBER 19970719
    #define STANDARD_MODULE_STUFF MODULE_MAGIC_NUMBER, -1, __FILE__, NULL
    
    /* Generic accessors for other modules to get at their own module-specific