httpd-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "David Reid" <dr...@jetnet.co.uk>
Subject ab Pt 2
Date Sun, 15 Oct 2000 14:32:38 GMT
There's a note in ab that strstr is a performance drain.  The diff 
attached tries to remove strstr from a few places and changes the way 
that we check things.  It works and is as fast, if not slightly faster, 
that the current code but I'm sure it can be improved on.  anyway, it's 
here should it be of interest.  I won't commit it unless I get some 
positive agreement.

I've tried at avoid using str* functions where possible.

david

Index: ab.c
===================================================================
RCS file: /home/cvs/apache-2.0/src/support/ab.c,v
retrieving revision 1.29
diff -u -u -r1.29 ab.c
--- ab.c	2000/10/15 11:46:22	1.29
+++ ab.c	2000/10/15 13:35:14
@@ -566,6 +566,7 @@
 /* --------------------------------------------------------- */
 
 /* read data from connection */
+#define ASCII_LF '\012'
 
 static void read_connection(struct connection *c)
 {
@@ -590,7 +591,9 @@
     totalread += r;
 
     if (!c->gotheader) {
-        char *s;
+        char *s, *pos, *temppos;
+        apr_size_t len;
+        int loops = 0;
         int l = 4;
         int space = CBUFFSIZE - c->cbx - 1;  /* -1 to allow for 0 
terminator */
         int tocopy = (space < r) ? space : r;
@@ -613,15 +616,46 @@
         if (verbosity >= 4) {
             printf("LOG: header received:\n%s\n", c->cbuff);
         }
-        s = strstr(c->cbuff, "\r\n\r\n");
-            /* this next line is so that we talk to NCSA 1.5 which 
blatantly 
-             * breaks the http specifaction 
-             */
-        if (!s) {
-            s = strstr(c->cbuff, "\n\n");
-            l = 2;
-        }
+        
+        temppos = c->cbuff;
+        len = c->cbx;
+        while (pos = memchr(temppos, ASCII_LF, len)){           
+            /* Get the response code... */
+            if (*temppos == 'H' && *(temppos+1) == 'T' && *(temppos+2) 
== 'T'
+              && *(temppos+3) == 'P'){
+                respcode[0] = *(temppos + 9);
+                respcode[1] = *(temppos + 10);
+                respcode[2] = *(temppos + 11);
+                respcode[3] = '\0';
+            }
+            /* Do we need the servername ? */
+            if (!good && *temppos == 'S' && *(temppos+1) == 'e' 
+              && *(temppos+2) == 'r' && *(temppos+3) == 'v'){
+                char *q;
+                q = servername;
+                temppos += 8;
+                   
+                while (*temppos > 32)
+                   *q++ = *temppos++;
 
+                *q = 0;
+            }
+            
+            /* Have we reached the end of the headers? */
+            if ((*(pos + 1)) == '\r' && (*(pos + 2)) == '\n'){
+                s = pos;
+                break;
+            } else if ((*(pos + 1)) == '\n'){
+                s=pos;
+                l = 2;
+                break;
+            }
+            len -= (pos - temppos);
+            if (len <= 0)
+                break;
+            temppos = ++pos;
+        }
+        
         if (!s) {
             /* read rest next time */
             if (space) {
@@ -640,28 +674,6 @@
         }
         else {
             /* have full header */
-            if (!good) {
-               /* this is first time, extract some interesting info */
-               char *p, *q;
-               p = strstr(c->cbuff, "Server:");
-               q = servername;
-               if (p) {
-                   p += 8;
-                   while (*p > 32)
-                       *q++ = *p++;
-               }
-               *q = 0;
-            }
-
-            /* XXX: this parsing isn't even remotely HTTP compliant...
-             * but in the interest of speed it doesn't totally have to 
be,
-             * it just needs to be extended to handle whatever servers
-             * folks want to test against. -djg */
-
-            /* check response code */
-            part = strstr(c->cbuff, "HTTP");   /* really HTTP/1.x_ */
-            strncpy(respcode, (part + strlen("HTTP/1.x_")), 3);
-            respcode[3] = '\0';
             if (respcode[0] != '2') {
                err_response++;
                if (verbosity >= 2)
@@ -711,10 +723,10 @@
         }
         if (done < requests) {
             struct data s;
-           c->done = apr_now();
+            c->done = apr_now();
             s.read = c->read;
-           s.ctime = (c->connect - c->start) / 1000;
-           s.time = (c->done - c->start) / 1000;
+            s.ctime = (c->connect - c->start) / 1000;
+            s.time = (c->done - c->start) / 1000;
             stats[done++] = s;
         }
         c->keepalive = 0;

Mime
View raw message