Mercurial > hg > nginx
diff src/http/ngx_http_parse.c @ 200:abeaebe0a33c
nginx-0.0.1-2003-11-28-20:41:47 import
author | Igor Sysoev <igor@sysoev.ru> |
---|---|
date | Fri, 28 Nov 2003 17:41:47 +0000 |
parents | 2357fa41738a |
children | 267ea1d98683 |
line wrap: on
line diff
--- a/src/http/ngx_http_parse.c Fri Nov 28 08:40:40 2003 +0000 +++ b/src/http/ngx_http_parse.c Fri Nov 28 17:41:47 2003 +0000 @@ -5,8 +5,7 @@ int ngx_http_parse_request_line(ngx_http_request_t *r) { - char ch; - char *p; + char ch, *p; enum { sw_start = 0, sw_G, @@ -198,9 +197,7 @@ state = sw_uri; break; case '/': -#if (WIN32) r->complex_uri = 1; -#endif break; case '?': r->args_start = p; @@ -421,11 +418,11 @@ } } + int ngx_http_parse_header_line(ngx_http_request_t *r, ngx_hunk_t *h) { - char c, ch; - char *p; - enum { + char c, ch, *p; + enum { sw_start = 0, sw_name, sw_space_before_value, @@ -622,3 +619,197 @@ return NGX_AGAIN; } } + + +int ngx_http_parse_complex_uri(ngx_http_request_t *r) +{ + char c, ch, decoded, *p, *u; + enum { + sw_usual = 0, + sw_slash, + sw_dot, + sw_dot_dot, +#if (WIN32) + sw_dot_dot_dot, +#endif + sw_quoted, + sw_quoted_second + } state, quoted_state; + + decoded = '\0'; + quoted_state = sw_usual; + + state = sw_usual; + p = r->uri_start; + u = r->uri.data; + + ch = *p++; + + while (p < r->uri_start + r->uri.len + 1) { + +ngx_log_debug(r->connection->log, "S: %d UN: '%x:%c', URI: '%c'" _ + state _ ch _ ch _ *u); + + switch (state) { + case sw_usual: + switch(ch) { + case '/': + state = sw_slash; + *u++ = ch; + break; + case '%': + quoted_state = state; + state = sw_quoted; + break; + default: + *u++ = ch; + break; + } + ch = *p++; + break; + + case sw_slash: + switch(ch) { + case '/': + break; + case '.': + state = sw_dot; + *u++ = ch; + break; + case '%': + quoted_state = state; + state = sw_quoted; + break; + default: + state = sw_usual; + *u++ = ch; + break; + } + ch = *p++; + break; + + case sw_dot: + switch(ch) { + case '/': + state = sw_slash; + u--; + break; + case '.': + state = sw_dot_dot; + *u++ = ch; + break; + case '%': + quoted_state = state; + state = sw_quoted; + break; + default: + state = sw_usual; + *u++ = ch; + break; + } + ch = *p++; + break; + + case sw_dot_dot: + switch(ch) { + case '/': + state = sw_slash; + u -= 4; + if (u < r->uri.data) { + return NGX_HTTP_PARSE_INVALID_REQUEST; + } + while (*(u - 1) != '/') { + u--; + } + break; + case '%': + quoted_state = state; + state = sw_quoted; + break; +#if (WIN32) + case '.': + state = sw_dot_dot_dot; + *u++ = ch; + break; +#endif + default: + state = sw_usual; + *u++ = ch; + break; + } + ch = *p++; + break; + +#if (WIN32) + case sw_dot_dot_dot: + switch(ch) { + case '/': + state = sw_slash; + u -= 5; + if (u < r->uri.data) { + return NGX_HTTP_PARSE_INVALID_REQUEST; + } + while (*u != '/') { + u--; + } + if (u < r->uri.data) { + return NGX_HTTP_PARSE_INVALID_REQUEST; + } + while (*(u - 1) != '/') { + u--; + } + break; + case '%': + quoted_state = state; + state = sw_quoted; + break; + default: + state = sw_usual; + *u++ = ch; + break; + } + ch = *p++; + break; +#endif + + case sw_quoted: + if (ch >= '0' && ch <= '9') { + decoded = ch - '0'; + state = sw_quoted_second; + ch = *p++; + break; + } + + c = ch | 0x20; + if (c >= 'a' && c <= 'f') { + decoded = c - 'a' + 10; + state = sw_quoted_second; + ch = *p++; + break; + } + + return NGX_HTTP_PARSE_INVALID_REQUEST; + + case sw_quoted_second: + if (ch >= '0' && ch <= '9') { + ch = (decoded << 4) + ch - '0'; + state = quoted_state; + break; + } + + c = ch | 0x20; + if (c >= 'a' && c <= 'f') { + ch = (decoded << 4) + c - 'a' + 10; + state = quoted_state; + break; + } + + return NGX_HTTP_PARSE_INVALID_REQUEST; + } + } + + r->uri.len = u - r->uri.data; + r->uri.data[r->uri.len] = '\0'; + + return NGX_OK; +}