Welcome! Log In Create A New Profile

Advanced

[nginx] svn commit: r4314 - trunk/src/http

Anonymous User
November 28, 2011 04:16AM
Author: vbart
Date: 2011-11-28 09:15:33 +0000 (Mon, 28 Nov 2011)
New Revision: 4314

Modified:
trunk/src/http/ngx_http_parse.c
trunk/src/http/ngx_http_request.c
Log:
Added support for IP-literal in host header and request line (ticket #1).

Additional parsing logic added to correctly handle RFC 3986 compliant IPv6 and
IPvFuture characters enclosed in square brackets.

The host validation was completely rewritten. The behavior for non IP literals
was changed in a more proper and safer way:

- Host part is now delimited either by the first colon or by the end of string
if there's no colon. Previously the last colon was used as delimiter which
allowed substitution of a port number in the $host variable.
(e.g. Host: 127.0.0.1:9000:80)

- Fixed stripping off the ending dot in the Host header when the host was also
followed by a port number.
(e.g. Host: nginx.com.:80)

- Fixed upper case characters detection. Previously it was broken which led to
wasting memory and CPU.



Modified: trunk/src/http/ngx_http_parse.c
===================================================================
--- trunk/src/http/ngx_http_parse.c 2011-11-25 16:36:02 UTC (rev 4313)
+++ trunk/src/http/ngx_http_parse.c 2011-11-28 09:15:33 UTC (rev 4314)
@@ -110,7 +110,10 @@
sw_schema,
sw_schema_slash,
sw_schema_slash_slash,
+ sw_host_start,
sw_host,
+ sw_host_end,
+ sw_host_ip_literal,
sw_port,
sw_host_http_09,
sw_after_slash_in_uri,
@@ -323,14 +326,26 @@
case sw_schema_slash_slash:
switch (ch) {
case '/':
- r->host_start = p + 1;
- state = sw_host;
+ state = sw_host_start;
break;
default:
return NGX_HTTP_PARSE_INVALID_REQUEST;
}
break;

+ case sw_host_start:
+
+ r->host_start = p;
+
+ if (ch == '[') {
+ state = sw_host_ip_literal;
+ break;
+ }
+
+ state = sw_host;
+
+ /* fall through */
+
case sw_host:

c = (u_char) (ch | 0x20);
@@ -342,6 +357,10 @@
break;
}

+ /* fall through */
+
+ case sw_host_end:
+
r->host_end = p;

switch (ch) {
@@ -366,6 +385,47 @@
}
break;

+ case sw_host_ip_literal:
+
+ if (ch >= '0' && ch <= '9') {
+ break;
+ }
+
+ c = (u_char) (ch | 0x20);
+ if (c >= 'a' && c <= 'z') {
+ break;
+ }
+
+ switch (ch) {
+ case ':':
+ break;
+ case ']':
+ state = sw_host_end;
+ break;
+ case '-':
+ case '.':
+ case '_':
+ case '~':
+ /* unreserved */
+ break;
+ case '!':
+ case '$':
+ case '&':
+ case '\'':
+ case '(':
+ case ')':
+ case '*':
+ case '+':
+ case ',':
+ case ';':
+ case '=':
+ /* sub-delims */
+ break;
+ default:
+ return NGX_HTTP_PARSE_INVALID_REQUEST;
+ }
+ break;
+
case sw_port:
if (ch >= '0' && ch <= '9') {
break;

Modified: trunk/src/http/ngx_http_request.c
===================================================================
--- trunk/src/http/ngx_http_request.c 2011-11-25 16:36:02 UTC (rev 4313)
+++ trunk/src/http/ngx_http_request.c 2011-11-28 09:15:33 UTC (rev 4314)
@@ -1674,56 +1674,85 @@
ngx_http_validate_host(ngx_http_request_t *r, u_char **host, size_t len,
ngx_uint_t alloc)
{
- u_char *h, ch;
- size_t i, last;
- ngx_uint_t dot;
+ u_char *h, ch;
+ size_t i, dot_pos, host_len;

- last = len;
+ enum {
+ sw_usual = 0,
+ sw_literal,
+ sw_rest
+ } state;
+
+ dot_pos = len;
+ host_len = len;
+
h = *host;
- dot = 0;

+ state = sw_usual;
+
for (i = 0; i < len; i++) {
ch = h[i];

- if (ch == '.') {
- if (dot) {
+ switch (ch) {
+
+ case '.':
+ if (dot_pos == i - 1) {
return 0;
}
+ dot_pos = i;
+ break;

- dot = 1;
- continue;
- }
+ case ':':
+ if (state == sw_usual) {
+ host_len = i;
+ state = sw_rest;
+ }
+ break;

- dot = 0;
+ case '[':
+ if (i == 0) {
+ state = sw_literal;
+ }
+ break;

- if (ch == ':') {
- last = i;
- continue;
- }
+ case ']':
+ if (state == sw_literal) {
+ host_len = i + 1;
+ state = sw_rest;
+ }
+ break;

- if (ngx_path_separator(ch) || ch == '\0') {
+ case '\0':
return 0;
- }

- if (ch >= 'A' || ch < 'Z') {
- alloc = 1;
+ default:
+
+ if (ngx_path_separator(ch)) {
+ return 0;
+ }
+
+ if (ch >= 'A' && ch <= 'Z') {
+ alloc = 1;
+ }
+
+ break;
}
}

- if (dot) {
- last--;
+ if (dot_pos == host_len - 1) {
+ host_len--;
}

if (alloc) {
- *host = ngx_pnalloc(r->pool, last) ;
+ *host = ngx_pnalloc(r->pool, host_len);
if (*host == NULL) {
return -1;
}

- ngx_strlow(*host, h, last);
+ ngx_strlow(*host, h, host_len);
}

- return last;
+ return host_len;
}



_______________________________________________
nginx-devel mailing list
nginx-devel@nginx.org
http://mailman.nginx.org/mailman/listinfo/nginx-devel
Subject Author Views Posted

[nginx] svn commit: r4314 - trunk/src/http

Anonymous User 1037 November 28, 2011 04:16AM



Sorry, you do not have permission to post/reply in this forum.

Online Users

Guests: 75
Record Number of Users: 6 on February 13, 2018
Record Number of Guests: 421 on December 02, 2018
Powered by nginx      Powered by FreeBSD      PHP Powered      Powered by MariaDB      ipv6 ready