You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@httpd.apache.org by st...@locus.apache.org on 2000/07/10 23:49:23 UTC

cvs commit: apache-2.0/src/modules/standard mod_asis.c mod_file_cache.c

stoddard    00/07/10 14:49:23

  Modified:    src      ApacheCore.def
               src/include http_protocol.h
               src/main http_core.c http_protocol.c
               src/modules/standard mod_asis.c mod_file_cache.c
  Log:
  Reimplement ap_send_fd. Eliminate ap_send_fd_length. If APR_HAS_SENDFILE is
  defined but ap_sendfile fails with APR_ENOTIMPL, the BUFF implementation
  of ap_send_fd will get a shot at serving the request.  This fix is
  required to get Apache working on 95/98 again and can also be useful on
  Unix systems where sendfile is available via a servicepack/fixpack/PTF
  on a particular level of the OS (e.g., AIX 4.3.2 base does not include
  sendfile but is is available with a PTF).
  
  This fix also reimplements the mod_file_cache sendfile_handler using
  ap_send_fd and sets the connection aborted flag if the sendfile fails.
  
  Future modification... Add code to ap_send_fd to hijack any data in the
  client BUFF structure and send it along with the sendfile.
  
  Revision  Changes    Path
  1.25      +1 -1      apache-2.0/src/ApacheCore.def
  
  Index: ApacheCore.def
  ===================================================================
  RCS file: /home/cvs/apache-2.0/src/ApacheCore.def,v
  retrieving revision 1.24
  retrieving revision 1.25
  diff -u -r1.24 -r1.25
  --- ApacheCore.def	2000/06/28 14:46:01	1.24
  +++ ApacheCore.def	2000/07/10 21:49:18	1.25
  @@ -219,7 +219,7 @@
   	;ap_send_fb   @212
   	;ap_send_fb_length   @213
   	ap_send_fd   @214
  -	ap_send_fd_length   @215
  +;	ap_send_fd_length   @215
   	ap_send_http_header   @216
   	ap_send_http_trace   @217
   ;	ap_send_mmap   @218
  
  
  
  1.18      +2 -2      apache-2.0/src/include/http_protocol.h
  
  Index: http_protocol.h
  ===================================================================
  RCS file: /home/cvs/apache-2.0/src/include/http_protocol.h,v
  retrieving revision 1.17
  retrieving revision 1.18
  diff -u -r1.17 -r1.18
  --- http_protocol.h	2000/07/04 00:28:04	1.17
  +++ http_protocol.h	2000/07/10 21:49:20	1.18
  @@ -136,8 +136,8 @@
    * (Ditto the send_header stuff).
    */
   
  -API_EXPORT(long) ap_send_fd(ap_file_t *fd, request_rec *r);
  -API_EXPORT(long) ap_send_fd_length(ap_file_t *fd, request_rec *r, long length);
  +API_EXPORT(ap_status_t) ap_send_fd(ap_file_t *fd, request_rec *r, ap_off_t offset, 
  +                                   ap_size_t length, ap_size_t *nbytes);
   
   API_EXPORT(long) ap_send_fb(BUFF *f, request_rec *r);
   API_EXPORT(long) ap_send_fb_length(BUFF *f, request_rec *r, long length);
  
  
  
  1.86      +6 -7      apache-2.0/src/main/http_core.c
  
  Index: http_core.c
  ===================================================================
  RCS file: /home/cvs/apache-2.0/src/main/http_core.c,v
  retrieving revision 1.85
  retrieving revision 1.86
  diff -u -r1.85 -r1.86
  --- http_core.c	2000/06/28 14:33:32	1.85
  +++ http_core.c	2000/07/10 21:49:21	1.86
  @@ -2771,21 +2771,20 @@
   	ap_send_http_header(r);
   	
   	if (!r->header_only) {
  +            ap_size_t length = r->finfo.size;
  +            ap_off_t  offset = 0;
  +            ap_size_t nbytes = 0;
  +
   	    if (!rangestatus) {
  -		ap_send_fd(fd, r);
  +		ap_send_fd(fd, r, offset, length, &nbytes);
   	    }
   	    else {
  -		long     length;
  -                ap_off_t offset;
  -
   		while (ap_each_byterange(r, &offset, &length)) {
  -                    if ((status = ap_seek(fd, APR_SET, &offset)) != APR_SUCCESS) {
  +                    if ((status = ap_send_fd(fd, r, offset, length, &nbytes)) != APR_SUCCESS) {
   		        ap_log_error(APLOG_MARK, APLOG_ERR, status, r->server,
   				  "error byteserving file: %s", r->filename);
  -			ap_close(fd);
   			return HTTP_INTERNAL_SERVER_ERROR;
   		    }
  -		    ap_send_fd_length(fd, r, length);
   		}
   	    }
   	}
  
  
  
  1.94      +74 -47    apache-2.0/src/main/http_protocol.c
  
  Index: http_protocol.c
  ===================================================================
  RCS file: /home/cvs/apache-2.0/src/main/http_protocol.c,v
  retrieving revision 1.93
  retrieving revision 1.94
  diff -u -r1.93 -r1.94
  --- http_protocol.c	2000/07/06 21:25:19	1.93
  +++ http_protocol.c	2000/07/10 21:49:21	1.94
  @@ -2243,63 +2243,88 @@
       return OK;
   }
   
  +#if APR_HAS_SENDFILE
  +static ap_status_t static_send_file(ap_file_t *fd, request_rec *r, ap_off_t offset, 
  +                                    ap_size_t length, ap_size_t *nbytes) 
  +{
  +    ap_int32_t flags = 0;
  +    ap_status_t rv;
  +
  +    ap_bsetopt(r->connection->client, BO_TIMEOUT,
  +               r->connection->keptalive
  +               ? &r->server->keep_alive_timeout
  +               : &r->server->timeout);
  +
  +    ap_bflush(r->connection->client);
  +
  +    if (!r->connection->keepalive) {
  +        /* Prepare the socket to be reused */
  +        flags |= APR_SENDFILE_DISCONNECT_SOCKET;
  +    }
  +
  +    rv = iol_sendfile(r->connection->client->iol, 
  +                      fd,      /* The file to send */
  +                      NULL,    /* Header and trailer iovecs */
  +                      &offset, /* Offset in file to begin sending from */
  +                      &length,
  +                      flags);
  +
  +    if (r->connection->keptalive) {
  +        ap_bsetopt(r->connection->client, BO_TIMEOUT, 
  +                   &r->server->timeout);
  +    }
  +
  +    *nbytes = length;
  +
  +    return rv;
  +}
  +#endif
   /*
    * Send the body of a response to the client.
    */
  -API_EXPORT(long) ap_send_fd(ap_file_t *fd, request_rec *r)
  +API_EXPORT(ap_status_t) ap_send_fd(ap_file_t *fd, request_rec *r, ap_off_t offset, 
  +                                   ap_size_t length, ap_size_t *nbytes) 
   {
  -    ap_size_t len = r->finfo.size;
  +    ap_status_t rv = APR_SUCCESS;
  +    ap_size_t total_bytes_sent = 0;
  +    register int o;
  +    ap_ssize_t n;
  +    char buf[IOBUFSIZE];
  +
  +    if ((length == 0) || r->connection->aborted) {
  +        *nbytes = 0;
  +        return APR_SUCCESS;
  +    }
  +
   #if APR_HAS_SENDFILE
  -    ap_int32_t flags = 0;
  +    /* Chunked encoding must be handled in the BUFF */
       if (!r->chunked) {
  -	ap_status_t rv;
  -        ap_bsetopt(r->connection->client, BO_TIMEOUT,
  -                   r->connection->keptalive
  -                   ? &r->server->keep_alive_timeout
  -                   : &r->server->timeout);
  -        ap_bflush(r->connection->client);
  -
  -        if (!r->connection->keepalive) {
  -            /* Prepare the socket to be reused. Ignored on systems
  -             * that do not support reusing the accept socket
  -             */
  -            flags |= APR_SENDFILE_DISCONNECT_SOCKET;
  -        }
  -
  -        rv = iol_sendfile(r->connection->client->iol, 
  -                          fd,     /* The file to send */
  -                          NULL,   /* header and trailer iovecs */
  -                          0,      /* Offset in file to begin sending from */
  -                          &len,
  -                          flags);
  -        if (rv != APR_SUCCESS) {
  -            ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r,
  -                          "ap_send_fd: iol_sendfile failed.");
  +        rv = static_send_file(fd, r, offset, length, &total_bytes_sent);
  +        if (rv == APR_SUCCESS) {
  +            r->bytes_sent += total_bytes_sent;
  +            *nbytes = total_bytes_sent;
  +            return rv;
           }
  -        if (r->connection->keptalive) {
  -            ap_bsetopt(r->connection->client, BO_TIMEOUT, 
  -                       &r->server->timeout);
  +        /* Don't consider APR_ENOTIMPL a failure */
  +        if (rv != APR_ENOTIMPL) {
  +            check_first_conn_error(r, "send_fd", rv);
  +            r->bytes_sent += total_bytes_sent;
  +            *nbytes = total_bytes_sent;
  +            return rv;
           }
       }
  -    else {
  -        len = ap_send_fd_length(fd, r, -1);
  -    }
  -#else
  -    len = ap_send_fd_length(fd, r, -1);
   #endif
  -    return len;
  -}
  -
  -API_EXPORT(long) ap_send_fd_length(ap_file_t *fd, request_rec *r, long length)
  -{
  -    char buf[IOBUFSIZE];
  -    long total_bytes_sent = 0;
  -    register int o;
  -    ap_ssize_t n;
  -    ap_status_t rv;
   
  -    if (length == 0)
  -        return 0;
  +    /* Either sendfile is not defined or it failed with APR_ENOTIMPL */
  +    if (offset) {
  +        /* Seek the file to the offset */
  +        rv = ap_seek(fd, APR_SET, &offset);
  +        if (rv != APR_SUCCESS) {
  +            *nbytes = total_bytes_sent;
  +            /* ap_close(fd); close the file or let the caller handle it? */
  +            return rv;
  +        }
  +    }
   
       while (!r->connection->aborted) {
           if ((length > 0) && (total_bytes_sent + IOBUFSIZE) > length)
  @@ -2311,6 +2336,7 @@
               rv = ap_read(fd, buf, &n);
           } while (rv == APR_EINTR && !r->connection->aborted);
   
  +        /* Is this still the right check? maybe check for n==0 or rv == APR_EOF? */
           if (n < 1) {
               break;
           }
  @@ -2322,7 +2348,8 @@
       }
   
       SET_BYTES_SENT(r);
  -    return total_bytes_sent;
  +    *nbytes = total_bytes_sent;
  +    return rv;
   }
   
   /*
  
  
  
  1.23      +2 -1      apache-2.0/src/modules/standard/mod_asis.c
  
  Index: mod_asis.c
  ===================================================================
  RCS file: /home/cvs/apache-2.0/src/modules/standard/mod_asis.c,v
  retrieving revision 1.22
  retrieving revision 1.23
  diff -u -r1.22 -r1.23
  --- mod_asis.c	2000/06/24 17:34:00	1.22
  +++ mod_asis.c	2000/07/10 21:49:22	1.23
  @@ -72,6 +72,7 @@
       ap_file_t *f = NULL;
       ap_status_t status;
       const char *location;
  +    ap_size_t nbytes;
   
       r->allowed |= (1 << M_GET);
       if (r->method_number != M_GET)
  @@ -112,7 +113,7 @@
   
       ap_send_http_header(r);
       if (!r->header_only) {
  -	ap_send_fd(f, r);
  +	ap_send_fd(f, r, 0, r->finfo.size, &nbytes);
       }
   
       ap_close(f);
  
  
  
  1.17      +26 -1     apache-2.0/src/modules/standard/mod_file_cache.c
  
  Index: mod_file_cache.c
  ===================================================================
  RCS file: /home/cvs/apache-2.0/src/modules/standard/mod_file_cache.c,v
  retrieving revision 1.16
  retrieving revision 1.17
  diff -u -r1.16 -r1.17
  --- mod_file_cache.c	2000/07/07 02:39:00	1.16
  +++ mod_file_cache.c	2000/07/10 21:49:22	1.17
  @@ -398,7 +398,31 @@
       return OK;
   }
   
  +static int sendfile_handler(request_rec *r, a_file *file, int rangestatus)
  +{
  +#if APR_HAS_SENDFILE
  +    ap_size_t length, nbytes;
  +    ap_off_t offset = 0;
  +    ap_status_t rv; 
   
  +    if (!rangestatus) {
  +        rv = ap_send_fd(file->file, r, 0, file->finfo.size, &nbytes);
  +    }
  +    else {
  +        while (ap_each_byterange(r, &offset, &length)) {
  +            if ((rv = ap_send_fd(file->file, r, offset, length, &nbytes)) != APR_SUCCESS)
  +                break;
  +        }
  +    }
  +    if (rv != APR_SUCCESS) {
  +        ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r,
  +                      "mod_file_cache: sendfile_handler error serving file: %s", r->filename);
  +        return HTTP_INTERNAL_SERVER_ERROR;
  +    }
  +#endif
  +    return OK;
  +}
  +#if 0
   static int sendfile_handler(request_rec *r, a_file *file, int rangestatus)
   {
   #if APR_HAS_SENDFILE
  @@ -447,7 +471,7 @@
           if (rv != APR_SUCCESS) { 
               ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, 
                             "mod_file_cache: iol_sendfile failed."); 
  -    }
  +        }
       } 
       else {
           while (ap_each_byterange(r, &offset, &length)) {
  @@ -467,6 +491,7 @@
   #endif
       return OK;
   }
  +#endif
   
   static int file_cache_handler(request_rec *r) 
   {
  
  
  

Re: cvs commit: apache-2.0/src/modules/standard mod_asis.cmod_file_cache.c

Posted by Bill Stoddard <re...@attglobal.net>.
>
> >   Log:
> >   Reimplement ap_send_fd. Eliminate ap_send_fd_length. If APR_HAS_SENDFILE is
> >   defined but ap_sendfile fails with APR_ENOTIMPL, the BUFF implementation
> >   of ap_send_fd will get a shot at serving the request.  This fix is
> >   required to get Apache working on 95/98 again and can also be useful on
> >   Unix systems where sendfile is available via a servicepack/fixpack/PTF
> >   on a particular level of the OS (e.g., AIX 4.3.2 base does not include
> >   sendfile but is is available with a PTF).
>
> I am very confused by this.  If the PTF is applied to the machine, then
> APR will detect sendfile won't it?  If it isn't applied, then the machine
> doesn't have sendfile.  If Apache is compiled, and then the PTF is
> applied, then Apache/APR will need to be re-compiled in order to pick it
> up.  How is this useful on a Unix machine?
>

As in the Windows case, we would do a runtime check.  Say I compile an Apache binary kit on AIX
4.3.2 (with the sendfile PTF applied). The binary kit works for me, but not on a 4.3.2 machine w/o
the PTF applied. So, would need to do a runtime check for the PTF and not call send_file (and return
APR_ENOTIMPL) if the PTF is not available. That's what I'm talking about. Not sure it is worth the
effort, but now it's at least possible to do runtime checks if needed.

Bill


Re: cvs commit: apache-2.0/src/modules/standard mod_asis.c mod_file_cache.c

Posted by rb...@covalent.net.
>   Log:
>   Reimplement ap_send_fd. Eliminate ap_send_fd_length. If APR_HAS_SENDFILE is
>   defined but ap_sendfile fails with APR_ENOTIMPL, the BUFF implementation
>   of ap_send_fd will get a shot at serving the request.  This fix is
>   required to get Apache working on 95/98 again and can also be useful on
>   Unix systems where sendfile is available via a servicepack/fixpack/PTF
>   on a particular level of the OS (e.g., AIX 4.3.2 base does not include
>   sendfile but is is available with a PTF).

I am very confused by this.  If the PTF is applied to the machine, then
APR will detect sendfile won't it?  If it isn't applied, then the machine
doesn't have sendfile.  If Apache is compiled, and then the PTF is
applied, then Apache/APR will need to be re-compiled in order to pick it
up.  How is this useful on a Unix machine?

Ryan

_______________________________________________________________________________
Ryan Bloom                        	rbb@apache.org
406 29th St.
San Francisco, CA 94131
-------------------------------------------------------------------------------


Re: cvs commit: apache-2.0/src/modules/standard mod_asis.c mod_file_cache.c

Posted by rb...@covalent.net.
>   Log:
>   Reimplement ap_send_fd. Eliminate ap_send_fd_length. If APR_HAS_SENDFILE is
>   defined but ap_sendfile fails with APR_ENOTIMPL, the BUFF implementation
>   of ap_send_fd will get a shot at serving the request.  This fix is
>   required to get Apache working on 95/98 again and can also be useful on
>   Unix systems where sendfile is available via a servicepack/fixpack/PTF
>   on a particular level of the OS (e.g., AIX 4.3.2 base does not include
>   sendfile but is is available with a PTF).

I am very confused by this.  If the PTF is applied to the machine, then
APR will detect sendfile won't it?  If it isn't applied, then the machine
doesn't have sendfile.  If Apache is compiled, and then the PTF is
applied, then Apache/APR will need to be re-compiled in order to pick it
up.  How is this useful on a Unix machine?

Ryan

_______________________________________________________________________________
Ryan Bloom                        	rbb@apache.org
406 29th St.
San Francisco, CA 94131
-------------------------------------------------------------------------------