comparison src/http/ngx_http_parse.c @ 4313:e7db97bfac25

Added support for IP-literal in the 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 of 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.
author Valentin Bartenev <vbart@nginx.com>
date Mon, 28 Nov 2011 09:15:33 +0000
parents e5df04b05e75
children d620f497c50f
comparison
equal deleted inserted replaced
4312:0a8e51a16484 4313:e7db97bfac25
108 sw_method, 108 sw_method,
109 sw_spaces_before_uri, 109 sw_spaces_before_uri,
110 sw_schema, 110 sw_schema,
111 sw_schema_slash, 111 sw_schema_slash,
112 sw_schema_slash_slash, 112 sw_schema_slash_slash,
113 sw_host_start,
113 sw_host, 114 sw_host,
115 sw_host_end,
116 sw_host_ip_literal,
114 sw_port, 117 sw_port,
115 sw_host_http_09, 118 sw_host_http_09,
116 sw_after_slash_in_uri, 119 sw_after_slash_in_uri,
117 sw_check_uri, 120 sw_check_uri,
118 sw_check_uri_http_09, 121 sw_check_uri_http_09,
321 break; 324 break;
322 325
323 case sw_schema_slash_slash: 326 case sw_schema_slash_slash:
324 switch (ch) { 327 switch (ch) {
325 case '/': 328 case '/':
326 r->host_start = p + 1; 329 state = sw_host_start;
327 state = sw_host; 330 break;
328 break; 331 default:
329 default: 332 return NGX_HTTP_PARSE_INVALID_REQUEST;
330 return NGX_HTTP_PARSE_INVALID_REQUEST; 333 }
331 } 334 break;
332 break; 335
336 case sw_host_start:
337
338 r->host_start = p;
339
340 if (ch == '[') {
341 state = sw_host_ip_literal;
342 break;
343 }
344
345 state = sw_host;
346
347 /* fall through */
333 348
334 case sw_host: 349 case sw_host:
335 350
336 c = (u_char) (ch | 0x20); 351 c = (u_char) (ch | 0x20);
337 if (c >= 'a' && c <= 'z') { 352 if (c >= 'a' && c <= 'z') {
339 } 354 }
340 355
341 if ((ch >= '0' && ch <= '9') || ch == '.' || ch == '-') { 356 if ((ch >= '0' && ch <= '9') || ch == '.' || ch == '-') {
342 break; 357 break;
343 } 358 }
359
360 /* fall through */
361
362 case sw_host_end:
344 363
345 r->host_end = p; 364 r->host_end = p;
346 365
347 switch (ch) { 366 switch (ch) {
348 case ':': 367 case ':':
358 * if request line will be copied to large client buffer 377 * if request line will be copied to large client buffer
359 */ 378 */
360 r->uri_start = r->schema_end + 1; 379 r->uri_start = r->schema_end + 1;
361 r->uri_end = r->schema_end + 2; 380 r->uri_end = r->schema_end + 2;
362 state = sw_host_http_09; 381 state = sw_host_http_09;
382 break;
383 default:
384 return NGX_HTTP_PARSE_INVALID_REQUEST;
385 }
386 break;
387
388 case sw_host_ip_literal:
389
390 if (ch >= '0' && ch <= '9') {
391 break;
392 }
393
394 c = (u_char) (ch | 0x20);
395 if (c >= 'a' && c <= 'z') {
396 break;
397 }
398
399 switch (ch) {
400 case ':':
401 break;
402 case ']':
403 state = sw_host_end;
404 break;
405 case '-':
406 case '.':
407 case '_':
408 case '~':
409 /* unreserved */
410 break;
411 case '!':
412 case '$':
413 case '&':
414 case '\'':
415 case '(':
416 case ')':
417 case '*':
418 case '+':
419 case ',':
420 case ';':
421 case '=':
422 /* sub-delims */
363 break; 423 break;
364 default: 424 default:
365 return NGX_HTTP_PARSE_INVALID_REQUEST; 425 return NGX_HTTP_PARSE_INVALID_REQUEST;
366 } 426 }
367 break; 427 break;