nginx uri 参数对 .. 的解析

nginx uri 参数对 .. 的解析

在 Web 开发中,URI(Uniform Resource Identifier)是指用于标识某一互联网资源的名称。在 HTTP 协议中,URI 用于表示客户端请求的资源,如网页、图片等。Nginx 是一个高性能的 Web 服务器,能够处理海量的请求,因此对 URI 解析的性能要求也非常高。

Nginx 中的 URI 解析主要分为两个部分:请求行解析和 URI 解析。其中,请求行解析是指解析客户端请求的第一行,包括请求方法、URI 和协议版本;URI 解析则是对请求行中的 URI 进行进一步的解析和处理。
Nginx 中的 URI 解析主要包括 ngx_http_parse_request_line 和 ngx_http_parse_uri 两个函数。其中,ngx_http_parse_request_line 负责解析请求行,而 ngx_http_parse_uri 则负责解析 URI。

在解析 URI 时,需要考虑一些特殊情况,例如相对路径的引用和斜线的压缩等。具体来说,需要对以 “%XX” 形式编码的文本进行解码,解决对相对路径 “. “和”. .”的引用,以及可能将两个或多个相邻的斜线压缩为一个斜线之后,针对规范化的 URI 进行匹配。

需要注意的是,如果出现 http_host/../aaa/bb 的 uri,/../aa/bb 的第一个 “..” 导致了相对路径非法。在这种情况下,Nginx 打印出来的 uri 的值为空字符串。

下面是对一些常见 URI 进行解析的示例:

请求 uri
foo.com /
foo.com/ /
foo.com/aaa/bbb /aaa/bbb
foo.com/aaa/../bbb /bbb
foo.com/../aaa/bbb

nginx 中对 .. 的解析

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
// ngx_http_parse_complex_uri 
case sw_dot_dot:

if (usual[ch >> 5] & (1U << (ch & 0x1f))) {
state = sw_usual;
*u++ = ch;
ch = *p++;
break;
}

switch (ch) {
#if (NGX_WIN32)
case '\\':
#endif
case '/':
state = sw_slash;
u -= 5;
for ( ;; ) {
if (u < r->uri.data) {
return NGX_HTTP_PARSE_INVALID_REQUEST;
}
if (*u == '/') {
u++;
break;
}
u--;
}
break;

当出现 .. 到小于 uri.data(uri 的起地址) 时 (在上面表格中的最后一个例子) , 返回 NGX_HTTP_PARSE_INVALID_REQUEST .

在 ngx_http_process_request_uri 里表现出来返回 NGX_HTTP_BAD_REQUEST

1
2
3
4
5
6
7
8
if (ngx_http_parse_complex_uri(r, cscf->merge_slashes) != NGX_OK) {
r->uri.len = 0;

ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
"client sent invalid request");
ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);//return 400
return NGX_ERROR;
}
作者

张巍

发布于

2023-06-16

更新于

2023-06-16

许可协议

评论