Commit 6a21a6f1 authored by Tatsuhiro Tsujikawa's avatar Tatsuhiro Tsujikawa

Merge branch 'alagoutte-http_parser'

parents ecd143fc 661b99ec
......@@ -75,7 +75,7 @@ if (parser->upgrade) {
HTTP needs to know where the end of the stream is. For example, sometimes
servers send responses without Content-Length and expect the client to
consume input (for the body) until EOF. To tell http_parser about EOF, give
`0` as the forth parameter to `http_parser_execute()`. Callbacks and errors
`0` as the fourth parameter to `http_parser_execute()`. Callbacks and errors
can still be encountered during an EOF, so one must still be prepared
to receive them.
......@@ -110,7 +110,7 @@ followed by non-HTTP data.
information the Web Socket protocol.)
To support this, the parser will treat this as a normal HTTP message without a
body. Issuing both on_headers_complete and on_message_complete callbacks. However
body, issuing both on_headers_complete and on_message_complete callbacks. However
http_parser_execute() will stop parsing at the end of the headers and return.
The user is expected to check if `parser->upgrade` has been set to 1 after
......@@ -145,7 +145,7 @@ buffer to avoid copying memory around if this fits your application.
Reading headers may be a tricky task if you read/parse headers partially.
Basically, you need to remember whether last header callback was field or value
and apply following logic:
and apply the following logic:
(on_header_field and on_header_value shortened to on_h_*)
------------------------ ------------ --------------------------------------------
......
......@@ -925,7 +925,7 @@ size_t http_parser_execute (http_parser *parser,
case 'G': parser->method = HTTP_GET; break;
case 'H': parser->method = HTTP_HEAD; break;
case 'L': parser->method = HTTP_LOCK; break;
case 'M': parser->method = HTTP_MKCOL; /* or MOVE, MKACTIVITY, MERGE, M-SEARCH */ break;
case 'M': parser->method = HTTP_MKCOL; /* or MOVE, MKACTIVITY, MERGE, M-SEARCH, MKCALENDAR */ break;
case 'N': parser->method = HTTP_NOTIFY; break;
case 'O': parser->method = HTTP_OPTIONS; break;
case 'P': parser->method = HTTP_POST;
......@@ -977,6 +977,8 @@ size_t http_parser_execute (http_parser *parser,
parser->method = HTTP_MSEARCH;
} else if (parser->index == 2 && ch == 'A') {
parser->method = HTTP_MKACTIVITY;
} else if (parser->index == 3 && ch == 'A') {
parser->method = HTTP_MKCALENDAR;
} else {
SET_ERRNO(HPE_INVALID_METHOD);
goto error;
......@@ -1388,18 +1390,6 @@ size_t http_parser_execute (http_parser *parser,
break;
}
if (ch == CR) {
parser->state = s_header_almost_done;
CALLBACK_DATA(header_field);
break;
}
if (ch == LF) {
parser->state = s_header_field_start;
CALLBACK_DATA(header_field);
break;
}
SET_ERRNO(HPE_INVALID_HEADER_TOKEN);
goto error;
}
......@@ -2142,7 +2132,7 @@ http_parser_parse_url(const char *buf, size_t buflen, int is_connect,
u->port = u->field_set = 0;
s = is_connect ? s_req_server_start : s_req_spaces_before_url;
uf = old_uf = UF_MAX;
old_uf = UF_MAX;
for (p = buf; p < buf + buflen; p++) {
s = parse_url_char(s, *p);
......
......@@ -76,7 +76,7 @@ typedef struct http_parser_settings http_parser_settings;
* HEAD request which may contain 'Content-Length' or 'Transfer-Encoding:
* chunked' headers that indicate the presence of a body.
*
* http_data_cb does not return data chunks. It will be call arbitrarally
* http_data_cb does not return data chunks. It will be called arbitrarily
* many times for each string. E.G. you might get 10 callbacks for "on_url"
* each providing just a few characters more data.
*/
......@@ -117,6 +117,8 @@ typedef int (*http_cb) (http_parser*);
/* RFC-5789 */ \
XX(24, PATCH, PATCH) \
XX(25, PURGE, PURGE) \
/* CalDAV */ \
XX(26, MKCALENDAR, MKCALENDAR) \
enum http_method
{
......@@ -278,13 +280,15 @@ struct http_parser_url {
* unsigned major = (version >> 16) & 255;
* unsigned minor = (version >> 8) & 255;
* unsigned patch = version & 255;
* printf("http_parser v%u.%u.%u\n", major, minor, version);
* printf("http_parser v%u.%u.%u\n", major, minor, patch);
*/
unsigned long http_parser_version(void);
void http_parser_init(http_parser *parser, enum http_parser_type type);
/* Executes the parser. Returns number of parsed bytes. Sets
* `parser->http_errno` on error. */
size_t http_parser_execute(http_parser *parser,
const http_parser_settings *settings,
const char *data,
......
......@@ -2207,7 +2207,6 @@ print_error (const char *raw, size_t error_location)
break;
case '\n':
char_len = 2;
fprintf(stderr, "\\n\n");
if (this_line) goto print;
......@@ -2910,15 +2909,11 @@ test_simple (const char *buf, enum http_errno err_expected)
{
parser_init(HTTP_REQUEST);
size_t parsed;
int pass;
enum http_errno err;
parsed = parse(buf, strlen(buf));
pass = (parsed == strlen(buf));
parse(buf, strlen(buf));
err = HTTP_PARSER_ERRNO(parser);
parsed = parse(NULL, 0);
pass &= (parsed == 0);
parse(NULL, 0);
parser_free();
......@@ -3476,6 +3471,13 @@ main (void)
test_simple(buf, HPE_INVALID_METHOD);
}
// illegal header field name line folding
test_simple("GET / HTTP/1.1\r\n"
"name\r\n"
" : value\r\n"
"\r\n",
HPE_INVALID_HEADER_TOKEN);
const char *dumbfuck2 =
"GET / HTTP/1.1\r\n"
"X-SSL-Bullshit: -----BEGIN CERTIFICATE-----\r\n"
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment