httpd-cvs mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From stodd...@locus.apache.org
Subject cvs commit: apache-2.0/src/modules/standard mod_asis.c mod_file_cache.c
Date Mon, 10 Jul 2000 21:49:23 GMT
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) 
   {
  
  
  

Mime
View raw message