httpd-cvs mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From grega...@locus.apache.org
Subject cvs commit: apache-2.0/src/main http_core.c
Date Mon, 20 Nov 2000 22:39:17 GMT
gregames    00/11/20 14:39:17

  Modified:    src      CHANGES
               src/main http_core.c
  Log:
  Add partial write support for apr_sendfile to core_output_filter.
  
  Big .jpg's ( >70K or so) were being truncated on Linux.
  
  Revision  Changes    Path
  1.344     +3 -0      apache-2.0/src/CHANGES
  
  Index: CHANGES
  ===================================================================
  RCS file: /home/cvs/apache-2.0/src/CHANGES,v
  retrieving revision 1.343
  retrieving revision 1.344
  diff -u -r1.343 -r1.344
  --- CHANGES	2000/11/19 16:55:10	1.343
  +++ CHANGES	2000/11/20 22:39:15	1.344
  @@ -1,3 +1,6 @@
  +Changes with Apache 2.0a9
  +  *) Add support for partial writes with apr_sendfile() to core_output_filter.
  +     [Greg Ames] 
   Changes with Apache 2.0a8
     *) Add a directive to mod_mime so that filters can be associated with
        a given mime-type.
  
  
  
  1.221     +88 -8     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.220
  retrieving revision 1.221
  diff -u -r1.220 -r1.221
  --- http_core.c	2000/11/14 06:11:24	1.220
  +++ http_core.c	2000/11/20 22:39:17	1.221
  @@ -2564,6 +2564,85 @@
   
       return APR_SUCCESS;
   }
  +
  +/* sendfile_it_all()
  + *  send the entire file using sendfile()
  + *  handle partial writes
  + *  return only when all bytes have been sent or an error is encountered.
  + */
  +
  +#if APR_HAS_SENDFILE
  +static apr_status_t sendfile_it_all(conn_rec   *c, 
  +                                    apr_file_t *fd,
  +                                    apr_hdtr_t *hdtr, 
  +                                    apr_off_t   file_offset,
  +                                    apr_size_t  file_bytes_left, 
  +                                    apr_size_t  total_bytes_left,
  +                                    apr_int32_t flags)
  +{
  +    apr_status_t rv;
  +    apr_int32_t timeout = 0;
  +
  +    AP_DEBUG_ASSERT((apr_getsocketopt(c->client_socket, APR_SO_TIMEOUT, 
  +                       &timeout) == APR_SUCCESS) && 
  +                     timeout > 0);  /* socket must be in timeout mode */ 
  +    do {
  +        apr_ssize_t tmplen = file_bytes_left;
  +        
  +        rv = apr_sendfile(c->client_socket, fd, hdtr, &file_offset, &tmplen,

  +                          flags);
  +        total_bytes_left -= tmplen;
  +        if (!total_bytes_left || rv != APR_SUCCESS) {
  +            return rv;        /* normal case & error exit */ 
  +        }
  +
  +        AP_DEBUG_ASSERT(total_bytes_left > 0 && tmplen > 0);
  +        
  +        /* partial write, oooh noooo... 
  +         * Skip over any header data which was written
  +         */
  +        while (tmplen && hdtr->numheaders) {
  +            if (tmplen >= hdtr->headers[0].iov_len) {
  +                tmplen -= hdtr->headers[0].iov_len;
  +                --hdtr->numheaders;
  +                ++hdtr->headers;
  +            }
  +            else {
  +                hdtr->headers[0].iov_len -= tmplen;
  +       (char *) hdtr->headers[0].iov_base += tmplen;
  +                tmplen = 0;
  +            }
  +        }
  +
  +        /* Skip over any file data which was written */
  +
  +        if (tmplen <= file_bytes_left) {
  +            file_offset += tmplen;
  +            file_bytes_left -= tmplen;
  +            continue; 
  +        }
  +        tmplen -= file_bytes_left;
  +        file_bytes_left = 0;
  +        file_offset = 0;
  +        
  +        /* Skip over any trailer data which was written */
  +        
  +        while (tmplen && hdtr->numtrailers) {
  +            if (tmplen >= hdtr->trailers[0].iov_len) {
  +                tmplen -= hdtr->trailers[0].iov_len;
  +                --hdtr->numtrailers;
  +                ++hdtr->trailers;
  +            }
  +            else {
  +                hdtr->trailers[0].iov_len -= tmplen;
  +        (char *)hdtr->trailers[0].iov_base += tmplen;
  +                tmplen = 0;
  +            }
  +        }
  +    } while (1);
  +}
  +#endif
  +        
   /*
    * send_the_file()
    * Sends the contents of file fd along with header/trailer bytes, if any,
  @@ -3341,14 +3420,15 @@
                   /* Prepare the socket to be reused */
                   flags |= APR_SENDFILE_DISCONNECT_SOCKET;
               }
  -            nbytes = flen;
  -            rv = apr_sendfile(c->client_socket, 
  -                              fd,       /* The file to send */
  -                              &hdtr,    /* Header and trailer iovecs */
  -                              &foffset, /* Offset in file to begin sending from */
  -                              &nbytes,
  -                              flags);
  -            bytes_sent = nbytes;
  +            rv = sendfile_it_all(c,             /* the connection            */
  +                                 fd,            /* the file to send          */
  +                                 &hdtr,         /* header and trailer iovecs */
  +                                 foffset,       /* offset in the file to begin
  +                                                   sending from              */
  +                                 flen,          /* length of file            */
  +                                 nbytes + flen, /* total length including 
  +                                                   headers                   */
  +                                 flags);        /* apr_sendfile flags        */
   
               /* If apr_sendfile() returns APR_ENOTIMPL, call send_the_file() to
                * loop on apr_read/apr_send to send the file. Our Windows binary 
  
  
  

Mime
View raw message