From: Vlad S. <ser...@us...> - 2005-07-08 18:09:55
|
Update of /cvsroot/naviserver/naviserver/nsd In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv29913/nsd Modified Files: fastpath.c Log Message: See ChangeLog Index: fastpath.c =================================================================== RCS file: /cvsroot/naviserver/naviserver/nsd/fastpath.c,v retrieving revision 1.14 retrieving revision 1.15 diff -C2 -d -r1.14 -r1.15 *** fastpath.c 8 Jul 2005 16:24:17 -0000 1.14 --- fastpath.c 8 Jul 2005 18:09:38 -0000 1.15 *************** *** 894,919 **** default: sprintf(boundary,"%lu",now); /* Multiple ranges, return as multipart/byterange */ Ns_ConnPrintfHeaders(conn, "Content-type","multipart/byteranges; boundary=%s", boundary); ! Ns_ConnSetRequiredHeaders(conn, type, -1); ! Ns_ConnQueueHeaders(conn, rnPtr->status); ! Ns_DStringInit(&ds); ! /* ! * For mmap mode create 3 iovec structures for each range to ! * contain headers, data and closing boundary and send all ! * iov buffers for all ranges at once ! * ! * For fd mode, re-use the same iov struct and send headers and ! * file contents one after another for all ranges */ for (i = 0;i < rnPtr->count;i++) { ! if (fd == -1) { ! /* Point to first iov struct for the given index */ ! iovPtr = &bufs[i*3]; ! } /* First io vector in the triple will hold the headers */ iovPtr->iov_base = &ds.string[ds.length]; --- 894,916 ---- default: + Ns_DStringInit(&ds); sprintf(boundary,"%lu",now); /* Multiple ranges, return as multipart/byterange */ Ns_ConnPrintfHeaders(conn, "Content-type","multipart/byteranges; boundary=%s", boundary); ! /* ! * Use 3 iovec structures for each range to ! * contain starting boundary and headers, data and closing boundary ! * and send all iov buffers for all ranges at once in mmap mode or ! * in seperate calls for fd mode. */ + /* First pass, produce headers and calculate content length */ + rnPtr->size = 0; + for (i = 0;i < rnPtr->count;i++) { ! /* Point to first iov struct for the given index */ ! iovPtr = &bufs[i*3]; /* First io vector in the triple will hold the headers */ iovPtr->iov_base = &ds.string[ds.length]; *************** *** 923,932 **** rnPtr->offsets[i].start, rnPtr->offsets[i].end, len); iovPtr->iov_len = strlen(iovPtr->iov_base); ! /* In fd mode, we send headers and file contents */ ! if (fd != -1) { result = Ns_ConnSend(conn, iovPtr, 1); if (result == NS_ERROR) { break; } lseek(fd, rnPtr->offsets[i].start, SEEK_SET); result = Ns_ConnSendFd(conn, fd, rnPtr->offsets[i].size); --- 920,961 ---- rnPtr->offsets[i].start, rnPtr->offsets[i].end, len); iovPtr->iov_len = strlen(iovPtr->iov_base); ! rnPtr->size += iovPtr->iov_len; ! ! /* ! * Second io vector will contain actual range buffer offset and ! * size. It will be ignored in fd mode. ! */ ! ! iovPtr++; ! iovPtr->iov_base = data + rnPtr->offsets[i].start; ! iovPtr->iov_len = rnPtr->offsets[i].size; ! rnPtr->size += iovPtr->iov_len; ! ! /* Third io vector will hold closing boundary */ ! iovPtr++; ! iovPtr->iov_base = &ds.string[ds.length]; ! /* Last boundary should have trailing -- */ ! if (i == rnPtr->count - 1) { ! Ns_DStringPrintf(&ds,"\r\n--%s--",boundary); ! } ! Ns_DStringAppend(&ds,"\r\n"); ! iovPtr->iov_len = strlen(iovPtr->iov_base); ! rnPtr->size += iovPtr->iov_len; ! } ! ! /* Second pass, content length is ready, send http headers and data now */ ! Ns_ConnSetRequiredHeaders(conn, type, rnPtr->size); ! Ns_ConnQueueHeaders(conn, rnPtr->status); ! ! /* In fd mode, we send headers and file contents in separate calls */ ! if (fd != -1) { ! for (i = 0;i < rnPtr->count;i++) { ! /* Point iovPtr to headers iov buffer */ ! iovPtr = &bufs[i*3]; result = Ns_ConnSend(conn, iovPtr, 1); if (result == NS_ERROR) { break; } + /* Send file content directly from open fd */ lseek(fd, rnPtr->offsets[i].start, SEEK_SET); result = Ns_ConnSendFd(conn, fd, rnPtr->offsets[i].size); *************** *** 934,962 **** break; } ! } else { ! /* Second io vector will contain actual range buffer offset and size */ ! iovPtr++; ! iovPtr->iov_base = data + rnPtr->offsets[i].start; ! iovPtr->iov_len = rnPtr->offsets[i].size; ! iovPtr++; ! } ! /* Third io vector will hold closing boundary */ ! iovPtr->iov_base = &ds.string[ds.length]; ! /* Last boundary should have trailing -- */ ! if (i == rnPtr->count - 1) { ! Ns_DStringPrintf(&ds,"\r\n--%s--",boundary); ! } ! Ns_DStringAppend(&ds,"\r\n"); ! iovPtr->iov_len = strlen(iovPtr->iov_base); ! /* In fd mode send boundary immediately after the contents */ ! if (fd != -1) { result = Ns_ConnSend(conn, iovPtr, 1); if (result == NS_ERROR) { break; } ! } ! } ! /* In mmap mode we send all iov buffers at once */ ! if (fd == -1) { result = Ns_ConnSend(conn, bufs, rnPtr->count * 3); } --- 963,980 ---- break; } ! ! /* ! * Point iovPtr to the closing boundary iov buffer, ! * second iov buffer is not used in fd mode ! */ ! ! iovPtr += 2; result = Ns_ConnSend(conn, iovPtr, 1); if (result == NS_ERROR) { break; } ! } ! } else { ! /* In mmap mode we send all iov buffers at once */ result = Ns_ConnSend(conn, bufs, rnPtr->count * 3); } |