+ {
+ // we did not find CRLF.. See if buffer is too large..
+ if (sz >= MAX_HTTP_HEADER-1)
+ return MAX_HTTP_HEADER-1; // yes. Return that (will fail later)
+ break;
+ }
+ len += (b - buf);
+ if (skipped == 0)
+ {
+ // CRLF CRLF , i.e. end of header
+ if (len + content_len <= sz)
+ return len + content_len;
+ break;
+ }
+ buf = b;
+ // following first skip of \r\n so that we don't consider Method
+ if (!strncasecmp(buf, "Content-Length:", 15))
+ {
+ const char *cp = buf+15;
+ while (*cp == ' ')
+ cp++;
+ content_len = 0;
+ while (*cp && isdigit(*cp))
+ content_len = content_len*10 + (*cp++ - '0');
+ if (content_len < 0) /* prevent negative offsets */
+ content_len = 0;
+ }
+ }
+ return 0; // incomplete request
+}
+
+// Check if we have a request. Return 0 or length
+static int request_check(struct http_buf *queue)
+{
+ char tmp[MAX_HTTP_HEADER];
+
+ // only peek at the header..
+ http_buf_peek(queue, tmp, MAX_HTTP_HEADER-1);
+ // still we only return non-zero if the complete request is received..
+ return package_check(tmp, http_buf_size(queue));
+}
+
+struct http_response *http_parse_response_buf(struct http_channel *c, const char *buf, int len)
+{
+ char tmp[MAX_HTTP_HEADER];
+ struct http_response *r = http_create_response(c);
+ char *p, *p2;
+ struct http_header **hp = &r->headers;
+
+ if (len >= MAX_HTTP_HEADER)
+ return 0;
+ memcpy(tmp, buf, len);
+ for (p = tmp; *p && *p != ' '; p++) // Skip HTTP version
+ ;
+ p++;
+ // Response code
+ for (p2 = p; *p2 && *p2 != ' ' && p2 - p < 3; p2++)
+ r->code[p2 - p] = *p2;
+ if (!(p = strstr(tmp, "\r\n")))
+ return 0;
+ p += 2;
+ while (*p)
+ {
+ if (!(p2 = strstr(p, "\r\n")))