+// Check if we have a request. Return 0 or length
+// (including trailing CRNL) FIXME: Does not deal gracefully with requests
+// carrying payload but this is kind of OK since we will reject anything
+// other than an empty GET
+static int request_check(struct http_buf *queue)
+{
+ char tmp[4096];
+
+ http_buf_peek(queue, tmp, 4096);
+ return package_check(tmp);
+}
+
+struct http_response *http_parse_response_buf(struct http_channel *c, const char *buf, int len)
+{
+ char tmp[4096];
+ struct http_response *r = http_create_response(c);
+ char *p, *p2;
+ struct http_header **hp = &r->headers;
+
+ if (len >= 4096)
+ 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")))
+ return 0;
+ if (p == p2) // End of headers
+ break;
+ else
+ {
+ struct http_header *h = *hp = nmem_malloc(c->nmem, sizeof(*h));
+ char *value = strchr(p, ':');
+ if (!value)
+ return 0;
+ *(value++) = '\0';
+ h->name = nmem_strdup(c->nmem, p);
+ while (isspace(*value))
+ value++;
+ if (value >= p2) // Empty header;
+ {
+ h->value = "";
+ p = p2 + 2;
+ continue;
+ }
+ *p2 = '\0';
+ h->value = nmem_strdup(c->nmem, value);
+ h->next = 0;
+ hp = &h->next;
+ p = p2 + 2;
+ }
+ }
+ return r;
+}
+