You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@apr.apache.org by st...@apache.org on 2001/01/10 23:28:04 UTC
cvs commit: apr/network_io/win32 sendrecv.c
stoddard 01/01/10 14:28:04
Modified: network_io/win32 sendrecv.c
Log:
Win32: Fix loop in APR when attempting to send a 0 byte file. Yea, this is a goofy case but it
works in Apache 1.3. Now it works in Apache 2.0.
Revision Changes Path
1.31 +24 -27 apr/network_io/win32/sendrecv.c
Index: sendrecv.c
===================================================================
RCS file: /home/cvs/apr/network_io/win32/sendrecv.c,v
retrieving revision 1.30
retrieving revision 1.31
diff -u -r1.30 -r1.31
--- sendrecv.c 2000/12/01 18:30:20 1.30
+++ sendrecv.c 2001/01/10 22:28:03 1.31
@@ -66,8 +66,7 @@
* The same problem can exist with apr_send(). In that case, we rely on the
* application to adjust socket timeouts and max send segment sizes appropriately.
* For example, Apache will in most cases call apr_send() with less than 8193
- * bytes
- * of data.
+ * bytes.
*/
#define MAX_SEGMENT_SIZE 65536
apr_status_t apr_send(apr_socket_t *sock, const char *buf, apr_size_t *len)
@@ -122,6 +121,7 @@
int lasterror;
DWORD dwBytes = 0;
+ /* Todo: Put the WSABUF array on the stack. */
LPWSABUF pWsaData = (LPWSABUF) malloc(sizeof(WSABUF) * nvec);
if (!pWsaData)
@@ -199,14 +199,10 @@
DWORD nbytes;
OVERLAPPED overlapped;
TRANSMIT_FILE_BUFFERS tfb, *ptfb = NULL;
- int bytes_to_send;
int ptr = 0;
+ int bytes_to_send = *len; /* Bytes to send out of the file (not including headers) */
- /* Must pass in a valid length */
- if (len == 0) {
- return APR_EINVAL;
- }
- bytes_to_send = *len;
+ /* Use len to keep track of number of total bytes sent (including headers) */
*len = 0;
/* Initialize the overlapped structure */
@@ -217,27 +213,30 @@
#ifdef WAIT_FOR_EVENT
overlapped.hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
#endif
-
- /* TransmitFile can only send one header and one footer */
- memset(&tfb, '\0', sizeof (tfb));
- if (hdtr && hdtr->numheaders) {
- ptfb = &tfb;
- collapse_iovec((char **)&ptfb->Head, &ptfb->HeadLength, hdtr->headers, hdtr->numheaders, sock->cntxt);
- }
- /* If we have more than MAX_SEGMENT_SIZE headers to send, send them
- * in segments.
- */
- if (ptfb && ptfb->HeadLength) {
- while (ptfb->HeadLength >= MAX_SEGMENT_SIZE) {
- nbytes = MAX_SEGMENT_SIZE;
- rv = apr_send(sock, ptfb->Head, &nbytes);
+ /* Handle the goofy case of sending headers/trailers and a zero byte file */
+ if (!bytes_to_send && hdtr) {
+ if (hdtr->numheaders) {
+ rv = apr_sendv(sock, hdtr->headers, hdtr->numheaders, &nbytes);
+ if (rv != APR_SUCCESS)
+ return rv;
+ *len += nbytes;
+ }
+ if (hdtr->numtrailers) {
+ rv = apr_sendv(sock, hdtr->trailers, hdtr->numtrailers, &nbytes);
if (rv != APR_SUCCESS)
return rv;
- (char*) ptfb->Head += nbytes;
- ptfb->HeadLength -= nbytes;
*len += nbytes;
}
+ return APR_SUCCESS;
+ }
+
+ /* Collapse the headers into a single buffer */
+ memset(&tfb, '\0', sizeof (tfb));
+ if (hdtr && hdtr->numheaders) {
+ ptfb = &tfb;
+ collapse_iovec((char **)&ptfb->Head, &ptfb->HeadLength, hdtr->headers,
+ hdtr->numheaders, sock->cntxt);
}
while (bytes_to_send) {
@@ -247,9 +246,7 @@
else {
/* Last call to TransmitFile() */
nbytes = bytes_to_send;
- /* Send trailers on the last packet, even if the total size
- * exceeds MAX_SEGMENT_SIZE...
- */
+ /* Collapse the trailers into a single buffer */
if (hdtr && hdtr->numtrailers) {
ptfb = &tfb;
collapse_iovec((char**) &ptfb->Tail, &ptfb->TailLength,