-
Notifications
You must be signed in to change notification settings - Fork 29.7k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
7 changed files
with
137 additions
and
118 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,4 @@ | ||
Copyright 2009 Ryan Dahl <[email protected]> | ||
Copyright 2009,2010 Ryan Dahl <[email protected]> | ||
|
||
Permission is hereby granted, free of charge, to any person obtaining a copy | ||
of this software and associated documentation files (the "Software"), to | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,4 @@ | ||
/* Copyright 2009 Ryan Dahl <[email protected]> | ||
/* Copyright 2009,2010 Ryan Dahl <[email protected]> | ||
* | ||
* Some parts of this source file were taken from NGINX | ||
* (src/http/ngx_http_parser.c) copyright (C) 2002-2009 Igor Sysoev. | ||
|
@@ -97,6 +97,7 @@ static inline int message_complete_callback (http_parser *parser) | |
return parser->on_message_complete(parser); | ||
} | ||
|
||
#define PROXY_CONNECTION "proxy-connection" | ||
#define CONNECTION "connection" | ||
#define CONTENT_LENGTH "content-length" | ||
#define TRANSFER_ENCODING "transfer-encoding" | ||
|
@@ -218,6 +219,7 @@ enum header_states | |
, h_CON | ||
|
||
, h_matching_connection | ||
, h_matching_proxy_connection | ||
, h_matching_content_length | ||
, h_matching_transfer_encoding | ||
|
||
|
@@ -245,6 +247,8 @@ enum flags | |
#define LF '\n' | ||
#define LOWER(c) (unsigned char)(c | 0x20) | ||
|
||
#define start_state (parser->type == HTTP_REQUEST ? s_start_req : s_start_res) | ||
|
||
#if HTTP_PARSER_STRICT | ||
# define STRICT_CHECK(cond) if (cond) goto error | ||
# define NEW_MESSAGE() (http_should_keep_alive(parser) ? start_state : s_dead) | ||
|
@@ -253,8 +257,9 @@ enum flags | |
# define NEW_MESSAGE() start_state | ||
#endif | ||
|
||
static inline | ||
size_t parse (http_parser *parser, const char *data, size_t len, int start_state) | ||
size_t http_parser_execute (http_parser *parser, | ||
const char *data, | ||
size_t len) | ||
{ | ||
char c, ch; | ||
const char *p, *pe; | ||
|
@@ -950,6 +955,10 @@ size_t parse (http_parser *parser, const char *data, size_t len, int start_state | |
header_state = h_C; | ||
break; | ||
|
||
case 'p': | ||
header_state = h_matching_proxy_connection; | ||
break; | ||
|
||
case 't': | ||
header_state = h_matching_transfer_encoding; | ||
break; | ||
|
@@ -1007,6 +1016,18 @@ size_t parse (http_parser *parser, const char *data, size_t len, int start_state | |
} | ||
break; | ||
|
||
/* proxy-connection */ | ||
|
||
case h_matching_proxy_connection: | ||
index++; | ||
if (index > sizeof(PROXY_CONNECTION)-1 | ||
|| c != PROXY_CONNECTION[index]) { | ||
header_state = h_general; | ||
} else if (index == sizeof(PROXY_CONNECTION)-2) { | ||
header_state = h_connection; | ||
} | ||
break; | ||
|
||
/* content-length */ | ||
|
||
case h_matching_content_length: | ||
|
@@ -1256,7 +1277,7 @@ size_t parse (http_parser *parser, const char *data, size_t len, int start_state | |
/* Content-Length header given and non-zero */ | ||
state = s_body_identity; | ||
} else { | ||
if (start_state == s_start_req || http_should_keep_alive(parser)) { | ||
if (parser->type == HTTP_REQUEST || http_should_keep_alive(parser)) { | ||
/* Assume content-length 0 - read the next */ | ||
CALLBACK2(message_complete); | ||
state = NEW_MESSAGE(); | ||
|
@@ -1408,22 +1429,6 @@ size_t parse (http_parser *parser, const char *data, size_t len, int start_state | |
} | ||
|
||
|
||
size_t | ||
http_parse_requests (http_parser *parser, const char *data, size_t len) | ||
{ | ||
if (!parser->state) parser->state = s_start_req; | ||
return parse(parser, data, len, s_start_req); | ||
} | ||
|
||
|
||
size_t | ||
http_parse_responses (http_parser *parser, const char *data, size_t len) | ||
{ | ||
if (!parser->state) parser->state = s_start_res; | ||
return parse(parser, data, len, s_start_res); | ||
} | ||
|
||
|
||
int | ||
http_should_keep_alive (http_parser *parser) | ||
{ | ||
|
@@ -1446,9 +1451,10 @@ http_should_keep_alive (http_parser *parser) | |
|
||
|
||
void | ||
http_parser_init (http_parser *parser) | ||
http_parser_init (http_parser *parser, enum http_parser_type t) | ||
{ | ||
parser->state = 0; | ||
parser->type = t; | ||
parser->state = (t == HTTP_REQUEST ? s_start_req : s_start_res); | ||
parser->on_message_begin = NULL; | ||
parser->on_path = NULL; | ||
parser->on_query_string = NULL; | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,4 @@ | ||
/* Copyright 2009 Ryan Dahl <[email protected]> | ||
/* Copyright 2009,2010 Ryan Dahl <[email protected]> | ||
* | ||
* Permission is hereby granted, free of charge, to any person obtaining a copy | ||
* of this software and associated documentation files (the "Software"), to | ||
|
@@ -74,8 +74,11 @@ enum http_method | |
, HTTP_UNLOCK = 0x4000 | ||
}; | ||
|
||
enum http_parser_type { HTTP_REQUEST, HTTP_RESPONSE }; | ||
|
||
struct http_parser { | ||
/** PRIVATE **/ | ||
enum http_parser_type type; | ||
unsigned short state; | ||
unsigned short header_state; | ||
size_t index; | ||
|
@@ -125,9 +128,8 @@ struct http_parser { | |
http_cb on_message_complete; | ||
}; | ||
|
||
void http_parser_init(http_parser *parser); | ||
size_t http_parse_requests(http_parser *parser, const char *data, size_t len); | ||
size_t http_parse_responses(http_parser *parser, const char *data, size_t len); | ||
void http_parser_init(http_parser *parser, enum http_parser_type type); | ||
size_t http_parser_execute(http_parser *parser, const char *data, size_t len); | ||
/* Call this in the on_headers_complete or on_message_complete callback to | ||
* determine if this will be the last message on the connection. | ||
* If you are the server, respond with the "Connection: close" header | ||
|
Oops, something went wrong.