comparison src/http/ngx_http_parse.c @ 7752:8989fbd2f89a

Fixed parsing of absolute URIs with empty path (ticket #2079). When the request line contains request-target in the absolute-URI form, it can contain path-empty instead of a single slash (see RFC 7230, RFC 3986). Previously, the ngx_http_parse_request_line() function only accepted empty path when there was no query string. With this change, non-empty query is also correctly handled. That is, request line "GET http://example.com?foo HTTP/1.1" is accepted and results in $uri "/" and $args "foo". Note that $request_uri remains "?foo", similarly to how spaces in URIs are handled. Providing "/?foo", similarly to how "/" is provided for "GET http://example.com HTTP/1.1", requires allocation.
author Maxim Dounin <mdounin@mdounin.ru>
date Thu, 10 Dec 2020 20:09:30 +0300
parents 8f55cb5c7e79
children 63c66b7cc07c f61d347158d0
comparison
equal deleted inserted replaced
7751:7efae6b4cfb0 7752:8989fbd2f89a
378 break; 378 break;
379 case '/': 379 case '/':
380 r->uri_start = p; 380 r->uri_start = p;
381 state = sw_after_slash_in_uri; 381 state = sw_after_slash_in_uri;
382 break; 382 break;
383 case '?':
384 r->uri_start = p;
385 r->args_start = p + 1;
386 r->empty_path_in_uri = 1;
387 state = sw_uri;
388 break;
383 case ' ': 389 case ' ':
384 /* 390 /*
385 * use single "/" from request line to preserve pointers, 391 * use single "/" from request line to preserve pointers,
386 * if request line will be copied to large client buffer 392 * if request line will be copied to large client buffer
387 */ 393 */
443 switch (ch) { 449 switch (ch) {
444 case '/': 450 case '/':
445 r->port_end = p; 451 r->port_end = p;
446 r->uri_start = p; 452 r->uri_start = p;
447 state = sw_after_slash_in_uri; 453 state = sw_after_slash_in_uri;
454 break;
455 case '?':
456 r->port_end = p;
457 r->uri_start = p;
458 r->args_start = p + 1;
459 r->empty_path_in_uri = 1;
460 state = sw_uri;
448 break; 461 break;
449 case ' ': 462 case ' ':
450 r->port_end = p; 463 r->port_end = p;
451 /* 464 /*
452 * use single "/" from request line to preserve pointers, 465 * use single "/" from request line to preserve pointers,
1284 state = sw_usual; 1297 state = sw_usual;
1285 p = r->uri_start; 1298 p = r->uri_start;
1286 u = r->uri.data; 1299 u = r->uri.data;
1287 r->uri_ext = NULL; 1300 r->uri_ext = NULL;
1288 r->args_start = NULL; 1301 r->args_start = NULL;
1302
1303 if (r->empty_path_in_uri) {
1304 *u++ = '/';
1305 }
1289 1306
1290 ch = *p++; 1307 ch = *p++;
1291 1308
1292 while (p <= r->uri_end) { 1309 while (p <= r->uri_end) {
1293 1310