aboutsummaryrefslogtreecommitdiff
path: root/src/http/ngx_http_parse.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/http/ngx_http_parse.c')
-rw-r--r--src/http/ngx_http_parse.c167
1 files changed, 91 insertions, 76 deletions
diff --git a/src/http/ngx_http_parse.c b/src/http/ngx_http_parse.c
index e1304e80f..33bc23759 100644
--- a/src/http/ngx_http_parse.c
+++ b/src/http/ngx_http_parse.c
@@ -5,19 +5,17 @@
ngx_int_t ngx_http_parse_request_line(ngx_http_request_t *r)
{
- u_char ch, *p;
+ u_char ch, *p, *m;
enum {
sw_start = 0,
- sw_G,
- sw_GE,
- sw_H,
- sw_HE,
- sw_HEA,
- sw_P,
- sw_PO,
- sw_POS,
+ sw_method,
sw_space_after_method,
sw_spaces_before_uri,
+ sw_schema,
+ sw_schema_slash,
+ sw_schema_slash_slash,
+ sw_host,
+ sw_port,
sw_after_slash_in_uri,
sw_check_uri,
sw_uri,
@@ -48,128 +46,145 @@ ngx_int_t ngx_http_parse_request_line(ngx_http_request_t *r)
case sw_start:
r->request_start = p - 1;
- switch (ch) {
- case 'G':
- state = sw_G;
- break;
- case 'H':
- state = sw_H;
- break;
- case 'P':
- state = sw_P;
- break;
- default:
+ if (ch < 'A' || ch > 'Z') {
return NGX_HTTP_PARSE_INVALID_METHOD;
}
- break;
- case sw_G:
- switch (ch) {
- case 'E':
- state = sw_GE;
- break;
- default:
- return NGX_HTTP_PARSE_INVALID_METHOD;
- }
+ state = sw_method;
break;
- case sw_GE:
- switch (ch) {
- case 'T':
- r->method = NGX_HTTP_GET;
- state = sw_space_after_method;
+ case sw_method:
+ if (ch == ' ') {
+ r->method_end = p - 1;
+ m = r->request_start;
+
+ if (r->method_end - m == 3) {
+
+ if (*m == 'G' && *(m + 1) == 'E' && *(m + 2) == 'T') {
+ r->method = NGX_HTTP_GET;
+ }
+
+ } else if (r->method_end - m == 4) {
+
+ if (*m == 'P' && *(m + 1) == 'O'
+ && *(m + 2) == 'T' && *(m + 3) == 'T')
+ {
+ r->method = NGX_HTTP_POST;
+
+ } else if (*m == 'H' && *(m + 1) == 'E'
+ && *(m + 2) == 'A' && *(m + 3) == 'D')
+ {
+ r->method = NGX_HTTP_HEAD;
+ }
+ }
+
+ state = sw_spaces_before_uri;
break;
- default:
- return NGX_HTTP_PARSE_INVALID_METHOD;
}
- break;
- case sw_H:
- switch (ch) {
- case 'E':
- state = sw_HE;
- break;
- default:
+ if (ch < 'A' || ch > 'Z') {
return NGX_HTTP_PARSE_INVALID_METHOD;
}
+
break;
- case sw_HE:
+ /* single space after method */
+ case sw_space_after_method:
switch (ch) {
- case 'A':
- state = sw_HEA;
+ case ' ':
+ state = sw_spaces_before_uri;
break;
default:
return NGX_HTTP_PARSE_INVALID_METHOD;
}
break;
- case sw_HEA:
+ /* space* before URI */
+ case sw_spaces_before_uri:
switch (ch) {
- case 'D':
- r->method = NGX_HTTP_HEAD;
- state = sw_space_after_method;
+ case '/':
+ r->uri_start = p - 1;
+ state = sw_after_slash_in_uri;
+ break;
+ case ' ':
break;
default:
- return NGX_HTTP_PARSE_INVALID_METHOD;
+ if ((ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z')) {
+ r->schema_start = p - 1;
+ state = sw_schema;
+ break;
+ }
+ return NGX_HTTP_PARSE_INVALID_REQUEST;
}
break;
- case sw_P:
+ case sw_schema:
switch (ch) {
- case 'O':
- state = sw_PO;
+ case ':':
+ r->schema_end = p - 1;
+ state = sw_schema_slash;
break;
default:
- return NGX_HTTP_PARSE_INVALID_METHOD;
+ if ((ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z')) {
+ break;
+ }
+ return NGX_HTTP_PARSE_INVALID_REQUEST;
}
break;
- case sw_PO:
+ case sw_schema_slash:
switch (ch) {
- case 'S':
- state = sw_POS;
+ case '/':
+ state = sw_schema_slash_slash;
break;
default:
- return NGX_HTTP_PARSE_INVALID_METHOD;
+ return NGX_HTTP_PARSE_INVALID_REQUEST;
}
break;
- case sw_POS:
+ case sw_schema_slash_slash:
switch (ch) {
- case 'T':
- r->method = NGX_HTTP_POST;
- state = sw_space_after_method;
+ case '/':
+ r->host_start = p - 1;
+ state = sw_host;
break;
default:
- return NGX_HTTP_PARSE_INVALID_METHOD;
+ return NGX_HTTP_PARSE_INVALID_REQUEST;
}
break;
- /* single space after method */
- case sw_space_after_method:
+ case sw_host:
switch (ch) {
- case ' ':
- state = sw_spaces_before_uri;
+ case ':':
+ r->host_end = p - 1;
+ state = sw_port;
+ break;
+ case '/':
+ r->host_end = p - 1;
+ r->uri_start = p - 1;
+ state = sw_after_slash_in_uri;
break;
default:
- return NGX_HTTP_PARSE_INVALID_METHOD;
+ if ((ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z')
+ || (ch >= '0' && ch <= '9') || ch == '.' || ch == '-')
+ {
+ break;
+ }
+ return NGX_HTTP_PARSE_INVALID_REQUEST;
}
break;
- /* space* before URI */
- case sw_spaces_before_uri:
+ case sw_port:
switch (ch) {
case '/':
+ r->port_end = p - 1;
r->uri_start = p - 1;
state = sw_after_slash_in_uri;
break;
- case ' ':
- break;
default:
- r->unusual_uri = 1;
- r->uri_start = p - 1;
- state = sw_uri;
+ if (ch < '0' && ch > '9') {
+ return NGX_HTTP_PARSE_INVALID_REQUEST;
+ }
break;
}
break;