]> xenbits.xensource.com Git - libvirt.git/commitdiff
* src/xend_internal.c: applied patch from Daniel P. Berrange,
authorDaniel Veillard <veillard@redhat.com>
Thu, 30 Mar 2006 16:37:15 +0000 (16:37 +0000)
committerDaniel Veillard <veillard@redhat.com>
Thu, 30 Mar 2006 16:37:15 +0000 (16:37 +0000)
  plus a bit of code cleanup
Daniel

ChangeLog
src/xend_internal.c

index 6eb81fc4ba5834e9e917459e7ea7101264c0480b..9f56346dba04de387aa712dca7ce041410be5114 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+Thu Mar 30 16:38:18 EST 2006 Daniel Veillard <veillard@redhat.com>
+
+       * src/xend_internal.c: applied patch from Daniel P. Berrange,
+         plus a bit of code cleanup
+
 Thu Mar 30 16:04:47 EST 2006 Daniel Veillard <veillard@redhat.com>
 
        * src/virsh.c: allocation check (Jim Meyering) and adding a
index 42335058e03868a5622317318f5dfeb9e68d9009..f1771c9dcc048e6b04930beafec94b1bd62e56c3 100644 (file)
@@ -287,42 +287,6 @@ swrites(int fd, const char *string)
     return swrite(fd, string, strlen(string));
 }
 
-/**
- * sreads:
- * @fd:  the file descriptor
- * @buffer: the I/O buffer
- * @n_buffer: the size of the I/O buffer
- *
- * Internal routine to do a synchronous read of a line
- *
- * Returns the number of bytes read, or -1 in case of error
- */
-static ssize_t
-sreads(int fd, char *buffer, size_t n_buffer)
-{
-    size_t offset;
-
-    if (n_buffer < 1)
-        return (-1);
-
-    for (offset = 0; offset < (n_buffer - 1); offset++) {
-        ssize_t ret;
-
-        ret = sread(fd, buffer + offset, 1);
-        if (ret == 0)
-            break;
-        else if (ret == -1)
-            return ret;
-
-        if (buffer[offset] == '\n') {
-            offset++;
-            break;
-        }
-    }
-    buffer[offset] = 0;
-
-    return offset;
-}
 
 static int
 istartswith(const char *haystack, const char *needle)
@@ -330,6 +294,7 @@ istartswith(const char *haystack, const char *needle)
     return (strncasecmp(haystack, needle, strlen(needle)) == 0);
 }
 
+
 /**
  * xend_req:
  * @fd: the file descriptor
@@ -344,32 +309,95 @@ static int
 xend_req(int fd, char *content, size_t n_content)
 {
     char buffer[4096];
+    int nbuf = -1;
     int content_length = -1;
     int retcode = 0;
 
+    /*
+     * Fill buffer with as much as possible to get 
+     * process going
+     */
+    nbuf = sread(fd, buffer, sizeof(buffer));
+
+    /*
+     * Extract lines from the buffer, until the 
+     * end of header is found
+     */
+    while (nbuf > -1) {
+        /* Seach for offset of first \r\n pair */
+        int i, offset = -1;
+
+        for (i = 0; i < (nbuf - 1); i++) {
+            if (buffer[i] == '\r' && buffer[i + 1] == '\n') {
+                offset = i;
+                break;
+            }
+        }
 
-    while (sreads(fd, buffer, sizeof(buffer)) > 0) {
-        if (strcmp(buffer, "\r\n") == 0)
-            break;
+        if (offset == -1) { /* No newline found, so try to fill more data */
 
-        if (istartswith(buffer, "Content-Length: "))
-            content_length = atoi(buffer + 16);
-        else if (istartswith(buffer, "HTTP/1.1 "))
-            retcode = atoi(buffer + 9);
-    }
+            if (nbuf == sizeof(buffer)) {
+                /* Already have 4096 bytes of data & no newline, 
+                 * get the hell out of this game */
+                break;
+            }
 
-    if (content_length > -1) {
-        ssize_t ret;
+            /* Fill remainder of buffer with more data */
+            int extra = sread(fd, buffer + nbuf, sizeof(buffer) - nbuf);
 
+            if (extra < 1) {
+                /* Couldn't get more, so quit trying */
+                break;
+            }
+            nbuf += extra;
+        } else if (!offset) { /* Immediate newline, indicates end of header */
+            /* Overwrite the \r\n pair */
+            offset += 2;
+            nbuf -= offset;
+            memmove(buffer, buffer + offset, nbuf);
+            break;
+        } else { /* We have a single line */
+            buffer[offset] = '\0';
+
+            if (istartswith(buffer, "Content-Length: "))
+                content_length = atoi(buffer + 16);
+            else if (istartswith(buffer, "HTTP/1.1 "))
+                retcode = atoi(buffer + 9);
+
+            /*
+            * Now move buffer, overwriting first line, to make room for
+             * more data on next iteration of loop (if needed)
+            */
+            offset += 2;
+            nbuf -= offset;
+            memmove(buffer, buffer + offset, nbuf);
+        }
+    }
+
+    if (content_length > -1) {  /* Read the header, now get body */
         if ((unsigned int) content_length > (n_content + 1))
             content_length = n_content - 1;
 
-        ret = sread(fd, content, content_length);
-        if (ret < 0)
-            return -1;
+        /*
+        * Copy across any data left in buffer after
+         * reading header
+        */
+        if (nbuf > content_length) {
+            nbuf = content_length;
+        }
+        memmove(content, buffer, nbuf);
+
+        if (nbuf < content_length) { /* Still need more data for body */
+            size_t ret = sread(fd, content + nbuf, content_length - nbuf);
 
-        content[ret] = 0;
-    } else {
+            if (0 > (int) ret)
+                return -1;
+
+            content[nbuf + ret + 1] = '\0';
+        } else {
+            content[nbuf + 1] = '\0';
+        }
+    } else { /* Unable to complete reading header */
         content[0] = 0;
     }