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