static void _watch_parse(AccountFolder * folder, char const buf[], size_t read) { size_t i = 0; while(i < read) switch(folder->context) { case PC_FROM: _parse_from(folder, buf, read, &i); break; case PC_GARBAGE: _parse_garbage(folder, buf, read, &i); break; case PC_HEADER: _parse_header(folder, buf, read, &i); break; case PC_BODY: _parse_body(folder, buf, read, &i); break; } folder->offset += read; }
struct http_pack *http_parse(char *http_buf) { struct http_pack *http; struct fmap *header_map = NULL; http = http_pack_create(); if (http == NULL) return NULL; /* 1.parse start line */ if ((http_buf = _parse_request_line(http_buf, &http->start_line)) == NULL) goto reject; /* 2.parse headers */ if ((header_map = fmap_create_dupkey()) == NULL) return NULL; header_map->type = &http_header_hash_type; if ((http_buf = _parse_header(http_buf, header_map)) == NULL) goto reject; http->headers = header_map; /* 3.parse body with Content-Length * TODO..to implement Transfer-Encoding may allow not Content-Length */ struct http_header_item *item = fmap_getvalue(http->headers, "Content-Length"); if (item == NULL) { http->start_line.status = *_defined_status_get(411); goto reject; } if (_parse_body(http_buf, (int) item->val_parse_func(item->val), http) == -1) goto reject; return http; reject: http->headers = NULL; http->body = NULL; fmap_free(header_map); fstr_freestr(http->body); return http; }