From: Vlad S. <ser...@us...> - 2005-06-30 01:14:13
|
Update of /cvsroot/naviserver/naviserver/nsd In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv4535/nsd Modified Files: fastpath.c Log Message: see ChangeLog Index: fastpath.c =================================================================== RCS file: /cvsroot/naviserver/naviserver/nsd/fastpath.c,v retrieving revision 1.9 retrieving revision 1.10 diff -C2 -d -r1.9 -r1.10 *** fastpath.c 29 Jun 2005 23:27:50 -0000 1.9 --- fastpath.c 30 Jun 2005 01:14:02 -0000 1.10 *************** *** 39,42 **** --- 39,44 ---- NS_RCSID("@(#) $Header$"); + #define MAX_RANGES 10 + /* * The following structure defines the contents of a file *************** *** 61,66 **** static int FastReturn(NsServer *servPtr, Ns_Conn *conn, int status, char *type, char *file, struct stat *stPtr); ! static int ParseRange(Ns_Conn *conn, unsigned long size, ! unsigned long *offset1, unsigned long *offset2); /* --- 63,68 ---- static int FastReturn(NsServer *servPtr, Ns_Conn *conn, int status, char *type, char *file, struct stat *stPtr); ! static int ParseRange(Ns_Conn *conn, unsigned long size, unsigned long *offsets, ! int offsets_size); /* *************** *** 474,479 **** { int fd, new, nread; ! unsigned long size, offset1, offset2; ! int result = NS_ERROR, range = NS_ERROR; char *key; Ns_Entry *entPtr; --- 476,481 ---- { int fd, new, nread; ! unsigned long size, offsets[MAX_RANGES*2]; ! int result = NS_ERROR, ranges = 0; char *key; Ns_Entry *entPtr; *************** *** 520,537 **** size = stPtr->st_size; if (status == 200) { ! range = ParseRange(conn, stPtr->st_size, &offset1, &offset2); } ! if (range != NS_ERROR) { ! if (offset1 > offset2) { ! /* 416 Requested Range Not Satisfiable */ ! Ns_ConnPrintfHeaders(conn, "Content-Range", "bytes */%lu", ! stPtr->st_size); ! Ns_ConnSetRequiredHeaders(conn, type, (int) stPtr->st_size); ! return Ns_ConnFlushHeaders(conn, 416); ! } /* Continue with returning a portion of the file */ Ns_ConnPrintfHeaders(conn, "Content-Range", "bytes %lu-%lu/%lu", ! offset1, offset2, stPtr->st_size); ! size = (offset2 - offset1) + 1; /* 206 Partial Content */ status = 206; --- 522,539 ---- size = stPtr->st_size; if (status == 200) { ! ranges = ParseRange(conn, stPtr->st_size, offsets, MAX_RANGES*2); } ! if (ranges == -1) { ! /* 416 Requested Range Not Satisfiable */ ! Ns_ConnPrintfHeaders(conn, "Content-Range", "bytes */%lu", ! stPtr->st_size); ! Ns_ConnSetRequiredHeaders(conn, type, (int) stPtr->st_size); ! return Ns_ConnFlushHeaders(conn, 416); ! } ! if (ranges == 1) { /* Continue with returning a portion of the file */ Ns_ConnPrintfHeaders(conn, "Content-Range", "bytes %lu-%lu/%lu", ! offsets[0], offsets[1], stPtr->st_size); ! size = (offsets[1] - offsets[0]) + 1; /* 206 Partial Content */ status = 206; *************** *** 540,544 **** if (servPtr->fastpath.cache == NULL || stPtr->st_size > servPtr->fastpath.cachemaxentry ! || range == NS_OK) { /* --- 542,546 ---- if (servPtr->fastpath.cache == NULL || stPtr->st_size > servPtr->fastpath.cachemaxentry ! || ranges == 1) { /* *************** *** 552,557 **** && NsMemMap(file, stPtr->st_size, NS_MMAP_READ, &fmap) == NS_OK) { char *maddr = fmap.addr; ! if (range == NS_OK) { ! maddr += offset1; } result = Ns_ConnReturnData(conn,status, maddr, size, type); --- 554,559 ---- && NsMemMap(file, stPtr->st_size, NS_MMAP_READ, &fmap) == NS_OK) { char *maddr = fmap.addr; ! if (ranges > 0) { ! maddr += offsets[0]; } result = Ns_ConnReturnData(conn,status, maddr, size, type); *************** *** 564,569 **** goto notfound; } ! if (range == NS_OK) { ! lseek(fd, offset1, SEEK_SET); } result = Ns_ConnReturnOpenFd(conn, status, type, fd, size); --- 566,571 ---- goto notfound; } ! if (ranges > 0) { ! lseek(fd, offsets[0], SEEK_SET); } result = Ns_ConnReturnOpenFd(conn, status, type, fd, size); *************** *** 690,694 **** * * Results: ! * NS_OK or NS_ERROR * * Side effects: --- 692,696 ---- * * Results: ! * -1 on error, number of byte ranges parsed * * Side effects: *************** *** 699,755 **** static int ! ParseRange(Ns_Conn *conn, unsigned long size, ! unsigned long *offset1, unsigned long *offset2) { char *range; ! *offset1 = *offset2 = 0; ! if ((range = Ns_SetIGet(conn->headers, "Range")) != NULL ! && (range = strstr(range,"bytes=")) != NULL) { ! range += 6; ! /* Multiple ranges are not supported yet */ ! if (strchr(range,',') != NULL) { ! return NS_ERROR; ! } if (isdigit(*range)) { ! *offset1 = atol(range); while (isdigit(*range)) range++; if (*range == '-') { range++; if (!isdigit(*range)) { ! if (*range != '\0') { ! return NS_ERROR; ! } ! *offset2 = size - 1; } else { ! *offset2 = atol(range); ! if (*offset1 > *offset2) { ! return NS_ERROR; } ! if (*offset2 >= size) { ! *offset2 = size - 1; } } ! return NS_OK; ! } else { ! return NS_ERROR; } } else if (*range == '-') { range++; if (!isdigit(*range)) { ! return NS_ERROR; } ! *offset2 = atol(range); ! if (*offset2 > size) { ! *offset2 = size; } /* Size from the end requested, convert into offset */ ! *offset1 = size - *offset2; ! *offset2 = *offset1 + *offset2 - 1; ! return NS_OK; } } ! return NS_ERROR; } --- 701,780 ---- static int ! ParseRange(Ns_Conn *conn, unsigned long size, unsigned long *offsets, ! int offsets_size) { + int count = 0; char *range; ! if ((range = Ns_SetIGet(conn->headers, "Range")) == NULL ! || (range = strstr(range,"bytes=")) == NULL) { ! return 0; ! } ! range += 6; ! memset(offsets,0,sizeof(unsigned long)*offsets_size); ! while(*range && count < offsets_size-1) { if (isdigit(*range)) { ! offsets[count] = atol(range); while (isdigit(*range)) range++; if (*range == '-') { range++; if (!isdigit(*range)) { ! offsets[count+1] = size - 1; } else { ! offsets[count+1] = atol(range); ! if (offsets[count] > offsets[count+1]) { ! return 0; } ! if (offsets[count+1] >= size) { ! offsets[count+1] = size - 1; } + while (isdigit(*range)) range++; } ! switch (*range) { ! case ',': ! range++; ! case '\0': ! break; ! default: ! return 0; ! } ! if (offsets[count] > offsets[count+1]) { ! return -1; ! } ! count += 2; ! continue; } } else if (*range == '-') { range++; if (!isdigit(*range)) { ! return 0; } ! offsets[count+1] = atol(range); ! if (offsets[count+1] > size) { ! offsets[count+1] = size; } /* Size from the end requested, convert into offset */ ! offsets[count] = size - offsets[count+1]; ! offsets[count+1] = offsets[count] + offsets[count+1] - 1; ! while (isdigit(*range)) range++; ! switch (*range) { ! case ',': ! range++; ! case '\0': ! break; ! default: ! return 0; ! } ! if (offsets[count] > offsets[count+1]) { ! return -1; ! } ! count += 2; ! continue; } + /* Invalid syntax */ + return 0; } ! return count/2; } |