diff --git a/ChangeLog b/ChangeLog index 6eb81fc4ba5834e9e917459e7ea7101264c0480b..9f56346dba04de387aa712dca7ce041410be5114 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +Thu Mar 30 16:38:18 EST 2006 Daniel Veillard + + * 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 * src/virsh.c: allocation check (Jim Meyering) and adding a diff --git a/src/xend_internal.c b/src/xend_internal.c index 42335058e03868a5622317318f5dfeb9e68d9009..f1771c9dcc048e6b04930beafec94b1bd62e56c3 100644 --- a/src/xend_internal.c +++ b/src/xend_internal.c @@ -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; }