* rework stringbuffered reading on nonblocking files
authorWilfried Göesgens <willi@citadel.org>
Sat, 3 Oct 2009 16:57:24 +0000 (16:57 +0000)
committerWilfried Göesgens <willi@citadel.org>
Sat, 3 Oct 2009 16:57:24 +0000 (16:57 +0000)
* add tests for these Linebased and Blobbased plus combined tests

libcitadel/lib/stringbuf.c
libcitadel/tests/Makefile.in
libcitadel/tests/stringbuf_IO_test.c

index 00d935896c561591766c769e41b14ccb81122922..463f978b5e8e44e505e7c969dd4379b05e49da54 100644 (file)
@@ -1703,6 +1703,7 @@ int StrBufTCP_read_buffered_line(StrBuf *Line,
        fd_set rfds;
        char *pch = NULL;
         int fdflags;
+       int IsNonBlock;
        struct timeval tv;
 
        if (buf->BufUsed > 0) {
@@ -1722,43 +1723,46 @@ int StrBufTCP_read_buffered_line(StrBuf *Line,
                IncreaseBuf(buf, 1, -1);
 
        fdflags = fcntl(*fd, F_GETFL);
-       if ((fdflags & O_NONBLOCK) == O_NONBLOCK)
-               return -1;
+       IsNonBlock = (fdflags & O_NONBLOCK) == O_NONBLOCK;
 
        while ((nSuccessLess < timeout) && (pch == NULL)) {
-               tv.tv_sec = selectresolution;
-               tv.tv_usec = 0;
-               
-               FD_ZERO(&rfds);
-               FD_SET(*fd, &rfds);
-               if (select(*fd + 1, NULL, &rfds, NULL, &tv) == -1) {
-                       *Error = strerror(errno);
-                       close (*fd);
-                       *fd = -1;
-                       return -1;
-               }               
-               if (FD_ISSET(*fd, &rfds)) {
-                       rlen = read(*fd, 
-                                   &buf->buf[buf->BufUsed], 
-                                   buf->BufSize - buf->BufUsed - 1);
-                       if (rlen < 1) {
+               if (IsNonBlock){
+                       tv.tv_sec = selectresolution;
+                       tv.tv_usec = 0;
+                       
+                       FD_ZERO(&rfds);
+                       FD_SET(*fd, &rfds);
+                       if (select(*fd + 1, NULL, &rfds, NULL, &tv) == -1) {
                                *Error = strerror(errno);
-                               close(*fd);
+                               close (*fd);
                                *fd = -1;
                                return -1;
                        }
-                       else if (rlen > 0) {
-                               nSuccessLess = 0;
-                               buf->BufUsed += rlen;
-                               buf->buf[buf->BufUsed] = '\0';
-                               if (buf->BufUsed + 10 > buf->BufSize) {
-                                       IncreaseBuf(buf, 1, -1);
-                               }
-                               pch = strchr(buf->buf, '\n');
-                               continue;
+               }
+               if (IsNonBlock && !  FD_ISSET(*fd, &rfds)) {
+                       nSuccessLess ++;
+                       continue;
+               }
+               rlen = read(*fd, 
+                           &buf->buf[buf->BufUsed], 
+                           buf->BufSize - buf->BufUsed - 1);
+               if (rlen < 1) {
+                       *Error = strerror(errno);
+                       close(*fd);
+                       *fd = -1;
+                       return -1;
+               }
+               else if (rlen > 0) {
+                       nSuccessLess = 0;
+                       buf->BufUsed += rlen;
+                       buf->buf[buf->BufUsed] = '\0';
+                       if (buf->BufUsed + 10 > buf->BufSize) {
+                               IncreaseBuf(buf, 1, -1);
                        }
+                       pch = strchr(buf->buf, '\n');
+                       continue;
                }
-               nSuccessLess ++;
+               
        }
        if (pch != NULL) {
                rlen = 0;
@@ -1773,7 +1777,6 @@ int StrBufTCP_read_buffered_line(StrBuf *Line,
 
 }
 
-static const char *ErrRBLF_WrongFDFlags="StrBufTCP_read_buffered_line_fast: don't work with fdflags & O_NONBLOCK";
 static const char *ErrRBLF_SelectFailed="StrBufTCP_read_buffered_line_fast: Select failed without reason";
 static const char *ErrRBLF_NotEnoughSentFromServer="StrBufTCP_read_buffered_line_fast: No complete line was sent from peer";
 /**
@@ -1801,6 +1804,7 @@ int StrBufTCP_read_buffered_line_fast(StrBuf *Line,
        fd_set rfds;
        const char *pch = NULL;
         int fdflags;
+       int IsNonBlock;
        struct timeval tv;
        
        pos = *Pos;
@@ -1840,54 +1844,55 @@ int StrBufTCP_read_buffered_line_fast(StrBuf *Line,
        }
 
        fdflags = fcntl(*fd, F_GETFL);
-       if ((fdflags & O_NONBLOCK) == O_NONBLOCK) {
-               *Error = ErrRBLF_WrongFDFlags;
-               return -1;
-       }
+       IsNonBlock = (fdflags & O_NONBLOCK) == O_NONBLOCK;
 
        pch = NULL;
        while ((nSuccessLess < timeout) && (pch == NULL)) {
-               tv.tv_sec = selectresolution;
-               tv.tv_usec = 0;
+               if (IsNonBlock)
+               {
+                       tv.tv_sec = 1;
+                       tv.tv_usec = 0;
                
-               FD_ZERO(&rfds);
-               FD_SET(*fd, &rfds);
-               if (select(*fd + 1, NULL, &rfds, NULL, &tv) == -1) {
-                       *Error = strerror(errno);
-                       close (*fd);
-                       *fd = -1;
-                       if (*Error == NULL)
-                               *Error = ErrRBLF_SelectFailed;
-                       return -1;
-               }               
-               if (FD_ISSET(*fd, &rfds) != 0) {
-                       rlen = read(*fd, 
-                                   &IOBuf->buf[IOBuf->BufUsed], 
-                                   IOBuf->BufSize - IOBuf->BufUsed - 1);
-                       if (rlen < 1) {
+                       FD_ZERO(&rfds);
+                       FD_SET(*fd, &rfds);
+                       if (select((*fd) + 1, &rfds, NULL, NULL, &tv) == -1) {
                                *Error = strerror(errno);
-                               close(*fd);
+                               close (*fd);
                                *fd = -1;
+                               if (*Error == NULL)
+                                       *Error = ErrRBLF_SelectFailed;
                                return -1;
                        }
-                       else if (rlen > 0) {
-                               nSuccessLess = 0;
-                               IOBuf->BufUsed += rlen;
-                               IOBuf->buf[IOBuf->BufUsed] = '\0';
-                               if (IOBuf->BufUsed + 10 > IOBuf->BufSize) {
-                                       IncreaseBuf(IOBuf, 1, -1);
-                               }
-
-                               pche = IOBuf->buf + IOBuf->BufUsed;
-                               pch = IOBuf->buf;
-                               while ((pch < pche) && (*pch != '\n'))
-                                       pch ++;
-                               if ((pch >= pche) || (*pch == '\0'))
-                                       pch = NULL;
+                       if (! FD_ISSET(*fd, &rfds) != 0) {
+                               nSuccessLess ++;
                                continue;
                        }
                }
-               nSuccessLess ++;
+               rlen = read(*fd, 
+                           &IOBuf->buf[IOBuf->BufUsed], 
+                           IOBuf->BufSize - IOBuf->BufUsed - 1);
+               if (rlen < 1) {
+                       *Error = strerror(errno);
+                       close(*fd);
+                       *fd = -1;
+                       return -1;
+               }
+               else if (rlen > 0) {
+                       nSuccessLess = 0;
+                       IOBuf->BufUsed += rlen;
+                       IOBuf->buf[IOBuf->BufUsed] = '\0';
+                       if (IOBuf->BufUsed + 10 > IOBuf->BufSize) {
+                               IncreaseBuf(IOBuf, 1, -1);
+                       }
+                       
+                       pche = IOBuf->buf + IOBuf->BufUsed;
+                       pch = IOBuf->buf;
+                       while ((pch < pche) && (*pch != '\n'))
+                               pch ++;
+                       if ((pch >= pche) || (*pch == '\0'))
+                               pch = NULL;
+                       continue;
+               }
        }
        if (pch != NULL) {
                pos = IOBuf->buf;
@@ -1916,12 +1921,14 @@ int StrBufTCP_read_buffered_line_fast(StrBuf *Line,
  */
 int StrBufReadBLOB(StrBuf *Buf, int *fd, int append, long nBytes, const char **Error)
 {
-        fd_set wset;
-        int fdflags;
+       int fdflags;
        int len, rlen, slen;
+       int nSuccessLess;
        int nRead = 0;
        char *ptr;
-
+       int IsNonBlock;
+       struct timeval tv;
+       fd_set rfds;
        if ((Buf == NULL) || (*fd == -1))
                return -1;
        if (!append)
@@ -1934,16 +1941,29 @@ int StrBufReadBLOB(StrBuf *Buf, int *fd, int append, long nBytes, const char **E
        slen = len = Buf->BufUsed;
 
        fdflags = fcntl(*fd, F_GETFL);
-
+       IsNonBlock = (fdflags & O_NONBLOCK) == O_NONBLOCK;
+       nSuccessLess = 0;
        while (nRead < nBytes) {
-               if ((fdflags & O_NONBLOCK) == O_NONBLOCK) {
-                        FD_ZERO(&wset);
-                        FD_SET(*fd, &wset);
-                        if (select(*fd + 1, NULL, &wset, NULL, NULL) == -1) {
+               if (IsNonBlock)
+               {
+                       tv.tv_sec = 1;
+                       tv.tv_usec = 0;
+               
+                       FD_ZERO(&rfds);
+                       FD_SET(*fd, &rfds);
+                       if (select(*fd + 1, &rfds, NULL, NULL, &tv) == -1) {
                                *Error = strerror(errno);
-                                return -1;
-                        }
-                }
+                               close (*fd);
+                               *fd = -1;
+                               if (*Error == NULL)
+                                       *Error = ErrRBLF_SelectFailed;
+                               return -1;
+                       }
+                       if (! FD_ISSET(*fd, &rfds) != 0) {
+                               nSuccessLess ++;
+                               continue;
+                       }
+               }
 
                 if ((rlen = read(*fd, 
                                 ptr,
@@ -1985,14 +2005,17 @@ int StrBufReadBLOBBuffered(StrBuf *Blob,
        const char *pos;
        int nSelects = 0;
        int SelRes;
-        fd_set wset;
-        int fdflags;
+       int fdflags;
        int len = 0;
        int rlen, slen;
        int nRead = 0;
        int nAlreadyRead = 0;
+       int IsNonBlock;
        char *ptr;
+       fd_set rfds;
        const char *pch;
+       struct timeval tv;
+       int nSuccessLess;
 
        if ((Blob == NULL) || (*fd == -1) || (IOBuf == NULL) || (Pos == NULL))
                return -1;
@@ -2044,34 +2067,44 @@ int StrBufReadBLOBBuffered(StrBuf *Blob,
        slen = len = Blob->BufUsed;
 
        fdflags = fcntl(*fd, F_GETFL);
+       IsNonBlock = (fdflags & O_NONBLOCK) == O_NONBLOCK;
 
        SelRes = 1;
        nBytes -= nRead;
        nRead = 0;
        while (nRead < nBytes) {
-               if ((fdflags & O_NONBLOCK) == O_NONBLOCK) {
-                        FD_ZERO(&wset);
-                        FD_SET(*fd, &wset);
-                       SelRes = select(*fd + 1, NULL, &wset, NULL, NULL);
-               }
-               if (SelRes == -1) {
-                       *Error = strerror(errno);
-                       return -1;
-               }
-               else if (SelRes) {
-                       nSelects = 0;
-                       rlen = read(*fd, 
-                                   ptr,
-                                   nBytes - nRead);
-                       if (rlen == -1) {
-                               close(*fd);
-                               *fd = -1;
+               if (IsNonBlock)
+               {
+                       tv.tv_sec = 1;
+                       tv.tv_usec = 0;
+               
+                       FD_ZERO(&rfds);
+                       FD_SET(*fd, &rfds);
+                       if (select(*fd + 1, &rfds, NULL, NULL, &tv) == -1) {
                                *Error = strerror(errno);
-                               return rlen;
+                               close (*fd);
+                               *fd = -1;
+                               if (*Error == NULL)
+                                       *Error = ErrRBLF_SelectFailed;
+                               return -1;
+                       }
+                       if (! FD_ISSET(*fd, &rfds) != 0) {
+                               nSuccessLess ++;
+                               continue;
                        }
                }
-               else {
-                       nSelects ++;
+               nSuccessLess = 0;
+               rlen = read(*fd, 
+                           ptr,
+                           nBytes - nRead);
+               if (rlen == -1) {
+                       close(*fd);
+                       *fd = -1;
+                       *Error = strerror(errno);
+                       return rlen;
+               }
+               else if (rlen == 0){
+                       nSuccessLess ++;
                        if ((check == NNN_TERM) && 
                            (nRead > 5) &&
                            (strncmp(IOBuf->buf + IOBuf->BufUsed - 5, "\n000\n", 5) == 0)) 
@@ -2086,7 +2119,7 @@ int StrBufReadBLOBBuffered(StrBuf *Blob,
                                return -1;
                        }
                }
-               if (rlen > 0) {
+               else if (rlen > 0) {
                        nRead += rlen;
                        ptr += rlen;
                        IOBuf->BufUsed += rlen;
index 7d24aaa9365c65b382ace78999af1b43ad2f4cb8..32718a0f949a7ecd42e19dc0e9d03e4b39f35c58 100644 (file)
@@ -5,9 +5,9 @@ CC=@CC@
 CFLAGS=@CFLAGS@
 DEFS=@DEFS@
 INSTALL=@INSTALL@
-LIBOBJS=@LIBOBJS@ -lcunit -lcitadel
+LIBOBJS=@LIBOBJS@ -lcunit
 LIBS=@LIBS@
-LDFLAGS=@LDFLAGS@ -L ../.libs
+LDFLAGS=@LDFLAGS@ -dn
 SED=@SED@
 LCUNIT_DEFS=
 srcdir=../
@@ -33,12 +33,14 @@ distclean: clean
 stringbuf_test:        $(LIBOBJS) stringbuf_test.o 
        $(CC) $(LDFLAGS) $(LIBOBJS) $(LIBS) \
        stringbuf_test.o \
+       ../.libs/libcitadel.a \
        -o stringbuf_test \
        $(LIBS)
 
 stringbuf_IO_test:     $(LIBOBJS) stringbuf_IO_test.o 
        $(CC) $(LDFLAGS) $(LIBOBJS) $(LIBS) \
        stringbuf_IO_test.o \
+       ../.libs/libcitadel.a \
        -o stringbuf_io_test \
        $(LIBS)
 
index 1097b960d4fe8cb10c5fc25605f5256649aff5d0..fcaf24ef468e7502205fc5eabe763413ab722998 100644 (file)
@@ -45,6 +45,7 @@
 #include <pthread.h>
 #include <signal.h>
 #include <sys/utsname.h>
+#include <string.h>
 
 
 typedef void testfunc(int Sock);
@@ -180,7 +181,7 @@ static void worker_entry(testfunc F)
 
                if ((msock == -1)||(time_to_die))
                {/* ok, we're going down. */
-                       exit(0);
+                       return;
                }
                if (ssock < 0 ) continue;
 
@@ -218,7 +219,7 @@ static void SimpleLineBufTestFunc(int sock)
        StrBuf *ReadBuffer;
        StrBuf *Line;
        const char *Pos = NULL;
-       const char *err;
+       const char *err = NULL;
        int i;
 
        ReadBuffer = NewStrBuf();
@@ -232,9 +233,10 @@ static void SimpleLineBufTestFunc(int sock)
                                                  timeout,
                                                  selres,
                                                  &err);
+               TestRevalidateStrBuf(Line);
                if (err != NULL)
                        printf("%s", err);
-               CU_ASSERT_PTR_NOT_NULL(err);
+               CU_ASSERT_PTR_NULL(err);
                CU_ASSERT_NOT_EQUAL(sock, -1);
                if (sock == -1)
                        break;
@@ -245,14 +247,133 @@ static void SimpleLineBufTestFunc(int sock)
        time_to_die = 1;
 }
 
-
 static void SimpleLinebufferTest(void)
 {
        msock = ig_tcp_server(ip_addr, listen_port, LISTEN_QUEUE_LENGTH);
 
        worker_entry(SimpleLineBufTestFunc);
+       close (msock);
+}
+
+
+static void SimpleBlobTestFunc(int sock)
+{
+       StrBuf *ReadBuffer;
+       StrBuf *Blob;
+       const char *Pos = NULL;
+       const char *err = NULL;
+       
+       ReadBuffer = NewStrBuf();
+       Blob = NewStrBuf();
+
+       StrBufReadBLOBBuffered(Blob, 
+                              ReadBuffer, 
+                              &Pos,
+                              &sock,
+                              0,
+                              blobsize,
+                              0,
+                              &err);
+       TestRevalidateStrBuf(Blob);
+       if (err != NULL)
+               printf("%s", err);
+       CU_ASSERT(blobsize == StrLength(Blob));
+       CU_ASSERT_PTR_NULL(err);
+       CU_ASSERT_NOT_EQUAL(sock, -1);
+       if (sock == -1)
+       printf("BLOB: >%s<\n", ChrPtr(Blob));
+       
+       FreeStrBuf(&ReadBuffer);
+       FreeStrBuf(&Blob);
+       time_to_die = 1;
 }
 
+
+static void SimpleHttpPostTestFunc(int sock)
+{
+       StrBuf *ReadBuffer;
+       StrBuf *Blob;
+       StrBuf *Line;
+       const char *Pos = NULL;
+       const char *err = NULL;
+       int blobsize = 0;
+       int i;
+       const char *pch;
+       
+       ReadBuffer = NewStrBuf();
+       Blob = NewStrBuf();
+       Line = NewStrBuf();
+
+       for (i = 0; (i == 0) || (StrLength(Line) != 0); i++) {
+               StrBufTCP_read_buffered_line_fast(Line, 
+                                                 ReadBuffer, 
+                                                 &Pos,
+                                                 &sock,
+                                                 timeout,
+                                                 selres,
+                                                 &err);
+               TestRevalidateStrBuf(Line);
+               if (err != NULL)
+                       printf("%s", err);
+               CU_ASSERT_PTR_NULL(err);
+               CU_ASSERT_NOT_EQUAL(sock, -1);
+               if (sock == -1)
+                       break;
+               printf("LINE: >%s<\n", ChrPtr(Line));
+               pch = strstr(ChrPtr(Line), "Content-Length");
+               if (pch != NULL) {
+                       blobsize = atol(ChrPtr(Line) + 
+                                       sizeof("Content-Length:"));
+
+               }
+               FlushStrBuf(Line);
+       }
+
+       StrBufReadBLOBBuffered(Blob, 
+                              ReadBuffer, 
+                              &Pos,
+                              &sock,
+                              0,
+                              blobsize,
+                              0,
+                              &err);
+       TestRevalidateStrBuf(Blob);
+       if (err != NULL)
+               printf("%s", err);
+       CU_ASSERT(blobsize != 0);
+       CU_ASSERT(blobsize == StrLength(Blob));
+       CU_ASSERT_PTR_NULL(err);
+       CU_ASSERT_NOT_EQUAL(sock, -1);
+       if (sock == -1)
+       printf("BLOB: >%s<\n", ChrPtr(Blob));
+       
+       FreeStrBuf(&ReadBuffer);
+       FreeStrBuf(&Blob);
+       FreeStrBuf(&Line);
+       time_to_die = 1;
+}
+
+
+static void SimpleBLOBbufferTest(void)
+{
+       msock = ig_tcp_server(ip_addr, listen_port, LISTEN_QUEUE_LENGTH);
+
+       worker_entry(SimpleBlobTestFunc);
+       close (msock);
+}
+
+static void SimpleMixedLineBlob(void)
+{
+       msock = ig_tcp_server(ip_addr, listen_port, LISTEN_QUEUE_LENGTH);
+
+       worker_entry(SimpleHttpPostTestFunc);
+       close (msock);
+}
+
+
+
+
+
 /*
 Some samples from the original...
        CU_ASSERT_EQUAL(10, 10);
@@ -293,8 +414,12 @@ static void AddStrBufSimlpeTests(void)
        CU_pTest pTest = NULL;
 
        pGroup = CU_add_suite("TestStringBufSimpleAppenders", NULL, NULL);
-       pTest = CU_add_test(pGroup, "testSimpleLinebufferTest", SimpleLinebufferTest);
-
+       if (n_Lines_to_read > 0)
+               pTest = CU_add_test(pGroup, "testSimpleLinebufferTest", SimpleLinebufferTest);
+       else if (blobsize > 0)
+               pTest = CU_add_test(pGroup, "testSimpleBLOBbufferTest", SimpleBLOBbufferTest);
+       else 
+               pTest = CU_add_test(pGroup,"testSimpleMixedLineBlob", SimpleMixedLineBlob);
 
 }
 
@@ -316,10 +441,13 @@ int main(int argc, char* argv[])
                        safestrncpy(ip_addr, optarg, sizeof ip_addr);
                        break;
                case 'n':
+                       // do linetest?
                        n_Lines_to_read = atoi(optarg);
                        break;
                case 'b':
+                       // or blobtest?
                        blobsize = atoi(optarg);
+                       // else run the simple http test
                        break;
                case 't':
                        timeout = atoi(optarg);