Merge branch 'alagoutte-http_parser'
This commit is contained in:
commit
6a21a6f148
|
@ -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"
|
||||
|
|
Loading…
Reference in New Issue