comparison src/http/ngx_http_parse.c @ 7881:52338ddf9e2f

Disabled spaces in URIs (ticket #196). From now on, requests with spaces in URIs are immediately rejected rather than allowed. Spaces were allowed in 31e9677b15a1 (0.8.41) to handle bad clients. It is believed that now this behaviour causes more harm than good.
author Maxim Dounin <mdounin@mdounin.ru>
date Mon, 28 Jun 2021 18:01:13 +0300
parents 63c66b7cc07c
children b4073527be81
comparison
equal deleted inserted replaced
7880:dfd8dfb436e5 7881:52338ddf9e2f
114 sw_host_start, 114 sw_host_start,
115 sw_host, 115 sw_host,
116 sw_host_end, 116 sw_host_end,
117 sw_host_ip_literal, 117 sw_host_ip_literal,
118 sw_port, 118 sw_port,
119 sw_host_http_09,
120 sw_after_slash_in_uri, 119 sw_after_slash_in_uri,
121 sw_check_uri, 120 sw_check_uri,
122 sw_check_uri_http_09,
123 sw_uri, 121 sw_uri,
124 sw_http_09, 122 sw_http_09,
125 sw_http_H, 123 sw_http_H,
126 sw_http_HT, 124 sw_http_HT,
127 sw_http_HTT, 125 sw_http_HTT,
396 * use single "/" from request line to preserve pointers, 394 * use single "/" from request line to preserve pointers,
397 * if request line will be copied to large client buffer 395 * if request line will be copied to large client buffer
398 */ 396 */
399 r->uri_start = r->schema_end + 1; 397 r->uri_start = r->schema_end + 1;
400 r->uri_end = r->schema_end + 2; 398 r->uri_end = r->schema_end + 2;
401 state = sw_host_http_09; 399 state = sw_http_09;
402 break; 400 break;
403 default: 401 default:
404 return NGX_HTTP_PARSE_INVALID_REQUEST; 402 return NGX_HTTP_PARSE_INVALID_REQUEST;
405 } 403 }
406 break; 404 break;
470 * use single "/" from request line to preserve pointers, 468 * use single "/" from request line to preserve pointers,
471 * if request line will be copied to large client buffer 469 * if request line will be copied to large client buffer
472 */ 470 */
473 r->uri_start = r->schema_end + 1; 471 r->uri_start = r->schema_end + 1;
474 r->uri_end = r->schema_end + 2; 472 r->uri_end = r->schema_end + 2;
475 state = sw_host_http_09; 473 state = sw_http_09;
476 break; 474 break;
477 default: 475 default:
478 return NGX_HTTP_PARSE_INVALID_REQUEST; 476 return NGX_HTTP_PARSE_INVALID_REQUEST;
479 } 477 }
480 break; 478 break;
481
482 /* space+ after "http://host[:port] " */
483 case sw_host_http_09:
484 switch (ch) {
485 case ' ':
486 break;
487 case CR:
488 r->http_minor = 9;
489 state = sw_almost_done;
490 break;
491 case LF:
492 r->http_minor = 9;
493 goto done;
494 case 'H':
495 r->http_protocol.data = p;
496 state = sw_http_H;
497 break;
498 default:
499 return NGX_HTTP_PARSE_INVALID_REQUEST;
500 }
501 break;
502
503 479
504 /* check "/.", "//", "%", and "\" (Win32) in URI */ 480 /* check "/.", "//", "%", and "\" (Win32) in URI */
505 case sw_after_slash_in_uri: 481 case sw_after_slash_in_uri:
506 482
507 if (usual[ch >> 5] & (1U << (ch & 0x1f))) { 483 if (usual[ch >> 5] & (1U << (ch & 0x1f))) {
510 } 486 }
511 487
512 switch (ch) { 488 switch (ch) {
513 case ' ': 489 case ' ':
514 r->uri_end = p; 490 r->uri_end = p;
515 state = sw_check_uri_http_09; 491 state = sw_http_09;
516 break; 492 break;
517 case CR: 493 case CR:
518 r->uri_end = p; 494 r->uri_end = p;
519 r->http_minor = 9; 495 r->http_minor = 9;
520 state = sw_almost_done; 496 state = sw_almost_done;
582 case '.': 558 case '.':
583 r->uri_ext = p + 1; 559 r->uri_ext = p + 1;
584 break; 560 break;
585 case ' ': 561 case ' ':
586 r->uri_end = p; 562 r->uri_end = p;
587 state = sw_check_uri_http_09; 563 state = sw_http_09;
588 break; 564 break;
589 case CR: 565 case CR:
590 r->uri_end = p; 566 r->uri_end = p;
591 r->http_minor = 9; 567 r->http_minor = 9;
592 state = sw_almost_done; 568 state = sw_almost_done;
619 case '\0': 595 case '\0':
620 return NGX_HTTP_PARSE_INVALID_REQUEST; 596 return NGX_HTTP_PARSE_INVALID_REQUEST;
621 } 597 }
622 break; 598 break;
623 599
600 /* URI */
601 case sw_uri:
602
603 if (usual[ch >> 5] & (1U << (ch & 0x1f))) {
604 break;
605 }
606
607 switch (ch) {
608 case ' ':
609 r->uri_end = p;
610 state = sw_http_09;
611 break;
612 case CR:
613 r->uri_end = p;
614 r->http_minor = 9;
615 state = sw_almost_done;
616 break;
617 case LF:
618 r->uri_end = p;
619 r->http_minor = 9;
620 goto done;
621 case '#':
622 r->complex_uri = 1;
623 break;
624 case '\0':
625 return NGX_HTTP_PARSE_INVALID_REQUEST;
626 }
627 break;
628
624 /* space+ after URI */ 629 /* space+ after URI */
625 case sw_check_uri_http_09: 630 case sw_http_09:
626 switch (ch) { 631 switch (ch) {
627 case ' ': 632 case ' ':
628 break; 633 break;
629 case CR: 634 case CR:
630 r->http_minor = 9; 635 r->http_minor = 9;
636 case 'H': 641 case 'H':
637 r->http_protocol.data = p; 642 r->http_protocol.data = p;
638 state = sw_http_H; 643 state = sw_http_H;
639 break; 644 break;
640 default: 645 default:
641 r->space_in_uri = 1;
642 state = sw_check_uri;
643 p--;
644 break;
645 }
646 break;
647
648
649 /* URI */
650 case sw_uri:
651
652 if (usual[ch >> 5] & (1U << (ch & 0x1f))) {
653 break;
654 }
655
656 switch (ch) {
657 case ' ':
658 r->uri_end = p;
659 state = sw_http_09;
660 break;
661 case CR:
662 r->uri_end = p;
663 r->http_minor = 9;
664 state = sw_almost_done;
665 break;
666 case LF:
667 r->uri_end = p;
668 r->http_minor = 9;
669 goto done;
670 case '#':
671 r->complex_uri = 1;
672 break;
673 case '\0':
674 return NGX_HTTP_PARSE_INVALID_REQUEST; 646 return NGX_HTTP_PARSE_INVALID_REQUEST;
675 }
676 break;
677
678 /* space+ after URI */
679 case sw_http_09:
680 switch (ch) {
681 case ' ':
682 break;
683 case CR:
684 r->http_minor = 9;
685 state = sw_almost_done;
686 break;
687 case LF:
688 r->http_minor = 9;
689 goto done;
690 case 'H':
691 r->http_protocol.data = p;
692 state = sw_http_H;
693 break;
694 default:
695 r->space_in_uri = 1;
696 state = sw_uri;
697 p--;
698 break;
699 } 647 }
700 break; 648 break;
701 649
702 case sw_http_H: 650 case sw_http_H:
703 switch (ch) { 651 switch (ch) {
1169 break; 1117 break;
1170 } 1118 }
1171 1119
1172 switch (ch) { 1120 switch (ch) {
1173 case ' ': 1121 case ' ':
1174 r->space_in_uri = 1; 1122 return NGX_ERROR;
1175 state = sw_check_uri;
1176 break;
1177 case '.': 1123 case '.':
1178 r->complex_uri = 1; 1124 r->complex_uri = 1;
1179 state = sw_uri; 1125 state = sw_uri;
1180 break; 1126 break;
1181 case '%': 1127 case '%':
1230 break; 1176 break;
1231 case '.': 1177 case '.':
1232 r->uri_ext = p + 1; 1178 r->uri_ext = p + 1;
1233 break; 1179 break;
1234 case ' ': 1180 case ' ':
1235 r->space_in_uri = 1; 1181 return NGX_ERROR;
1236 break;
1237 #if (NGX_WIN32) 1182 #if (NGX_WIN32)
1238 case '\\': 1183 case '\\':
1239 r->complex_uri = 1; 1184 r->complex_uri = 1;
1240 state = sw_after_slash_in_uri; 1185 state = sw_after_slash_in_uri;
1241 break; 1186 break;
1265 break; 1210 break;
1266 } 1211 }
1267 1212
1268 switch (ch) { 1213 switch (ch) {
1269 case ' ': 1214 case ' ':
1270 r->space_in_uri = 1; 1215 return NGX_ERROR;
1271 break;
1272 case '#': 1216 case '#':
1273 r->complex_uri = 1; 1217 r->complex_uri = 1;
1274 break; 1218 break;
1275 } 1219 }
1276 break; 1220 break;