📄 ngx_http_parse.c
字号:
#if (NGX_WIN32) case '\\': r->uri_ext = NULL; if (p == r->uri_start + r->uri.len) { /* * we omit the last "\" to cause redirect because * the browsers do not treat "\" as "/" in relative URL path */ break; } state = sw_slash; *u++ = '/'; break;#endif case '/': r->uri_ext = NULL; state = sw_slash; *u++ = ch; break; case '%': quoted_state = state; state = sw_quoted; break; case '?': r->args_start = p; goto args; case '#': goto done; case '.': r->uri_ext = u + 1; *u++ = ch; break; case '+': r->plus_in_uri = 1; default: *u++ = ch; break; } ch = *p++; break; case sw_slash: if (usual[ch >> 5] & (1 << (ch & 0x1f))) { state = sw_usual; *u++ = ch; ch = *p++; break; } switch(ch) {#if (NGX_WIN32) case '\\': break;#endif case '/': if (!merge_slashes) { *u++ = ch; } break; case '.': state = sw_dot; *u++ = ch; break; case '%': quoted_state = state; state = sw_quoted; break; case '?': r->args_start = p; goto args; case '#': goto done; case '+': r->plus_in_uri = 1; default: state = sw_usual; *u++ = ch; break; } ch = *p++; break; case sw_dot: if (usual[ch >> 5] & (1 << (ch & 0x1f))) { state = sw_usual; *u++ = ch; ch = *p++; break; } switch(ch) {#if (NGX_WIN32) case '\\':#endif case '/': state = sw_slash; u--; break; case '.': state = sw_dot_dot; *u++ = ch; break; case '%': quoted_state = state; state = sw_quoted; break; case '?': r->args_start = p; goto args; case '#': goto done; case '+': r->plus_in_uri = 1; default: state = sw_usual; *u++ = ch; break; } ch = *p++; break; case sw_dot_dot: if (usual[ch >> 5] & (1 << (ch & 0x1f))) { state = sw_usual; *u++ = ch; ch = *p++; break; } switch(ch) {#if (NGX_WIN32) case '\\':#endif case '/': state = sw_slash; u -= 4; if (u < r->uri.data) { return NGX_HTTP_PARSE_INVALID_REQUEST; } while (*(u - 1) != '/') { u--; } break; case '%': quoted_state = state; state = sw_quoted; break; case '?': r->args_start = p; goto args; case '#': goto done;#if (NGX_WIN32) case '.': state = sw_dot_dot_dot; *u++ = ch; break;#endif case '+': r->plus_in_uri = 1; default: state = sw_usual; *u++ = ch; break; } ch = *p++; break;#if (NGX_WIN32) case sw_dot_dot_dot: if (usual[ch >> 5] & (1 << (ch & 0x1f))) { state = sw_usual; *u++ = ch; ch = *p++; break; } switch(ch) { case '\\': case '/': state = sw_slash; u -= 5; if (u < r->uri.data) { return NGX_HTTP_PARSE_INVALID_REQUEST; } while (*u != '/') { u--; } if (u < r->uri.data) { return NGX_HTTP_PARSE_INVALID_REQUEST; } while (*(u - 1) != '/') { u--; } break; case '%': quoted_state = state; state = sw_quoted; break; case '?': r->args_start = p; goto args; case '#': goto done; case '+': r->plus_in_uri = 1; default: state = sw_usual; *u++ = ch; break; } ch = *p++; break;#endif case sw_quoted: r->quoted_uri = 1; if (ch >= '0' && ch <= '9') { decoded = (u_char) (ch - '0'); state = sw_quoted_second; ch = *p++; break; } c = (u_char) (ch | 0x20); if (c >= 'a' && c <= 'f') { decoded = (u_char) (c - 'a' + 10); state = sw_quoted_second; ch = *p++; break; } return NGX_HTTP_PARSE_INVALID_REQUEST; case sw_quoted_second: if (ch >= '0' && ch <= '9') { ch = (u_char) ((decoded << 4) + ch - '0'); if (ch == '%') { state = sw_usual; *u++ = ch; ch = *p++; break; } if (ch == '#') { *u++ = ch; ch = *p++; } else if (ch == '\0') { r->zero_in_uri = 1; } state = quoted_state; break; } c = (u_char) (ch | 0x20); if (c >= 'a' && c <= 'f') { ch = (u_char) ((decoded << 4) + c - 'a' + 10); if (ch == '?') { *u++ = ch; ch = *p++; } else if (ch == '+') { r->plus_in_uri = 1; } state = quoted_state; break; } return NGX_HTTP_PARSE_INVALID_REQUEST; } }done: r->uri.len = u - r->uri.data; if (r->uri_ext) { r->exten.len = u - r->uri_ext; r->exten.data = r->uri_ext; } r->uri_ext = NULL; return NGX_OK;args: while (p < r->uri_end) { if (*p++ != '#') { continue; } r->args.len = p - 1 - r->args_start; r->args.data = r->args_start; r->args_start = NULL; break; } r->uri.len = u - r->uri.data; if (r->uri_ext) { r->exten.len = u - r->uri_ext; r->exten.data = r->uri_ext; } r->uri_ext = NULL; return NGX_OK;}ngx_int_tngx_http_parse_unsafe_uri(ngx_http_request_t *r, ngx_str_t *uri, ngx_str_t *args, ngx_uint_t *flags){ u_char ch, *p; size_t len; len = uri->len; p = uri->data; if (len == 0 || p[0] == '?') { goto unsafe; } if (p[0] == '.' && len == 3 && p[1] == '.' && (p[2] == '/'#if (NGX_WIN32) || p[2] == '\\'#endif )) { goto unsafe; } for ( /* void */ ; len; len--) { ch = *p++; if (usual[ch >> 5] & (1 << (ch & 0x1f))) { continue; } if (ch == '?') { args->len = len - 1; args->data = p; uri->len -= len; return NGX_OK; } if (ch == '\0') { *flags |= NGX_HTTP_ZERO_IN_URI; continue; } if ((ch == '/'#if (NGX_WIN32) || ch == '\\'#endif ) && len > 2) { /* detect "/../" */ if (p[0] == '.' && p[1] == '.' && p[2] == '/') { goto unsafe; }#if (NGX_WIN32) if (p[2] == '\\') { goto unsafe; } if (len > 3) { /* detect "/.../" */ if (p[0] == '.' && p[1] == '.' && p[2] == '.' && (p[3] == '/' || p[3] == '\\')) { goto unsafe; } }#endif } } return NGX_OK;unsafe: ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "unsafe URI \"%V\" was detected", uri); return NGX_ERROR;}ngx_int_tngx_http_parse_multi_header_lines(ngx_array_t *headers, ngx_str_t *name, ngx_str_t *value){ ngx_uint_t i; u_char *start, *last, *end, ch; ngx_table_elt_t **h; h = headers->elts; for (i = 0; i < headers->nelts; i++) { ngx_log_debug2(NGX_LOG_DEBUG_HTTP, headers->pool->log, 0, "parse header: \"%V: %V\"", &h[i]->key, &h[i]->value); if (name->len > h[i]->value.len) { continue; } start = h[i]->value.data; end = h[i]->value.data + h[i]->value.len; while (start < end) { if (ngx_strncasecmp(start, name->data, name->len) != 0) { goto skip; } for (start += name->len; start < end && *start == ' '; start++) { /* void */ } if (value == NULL) { if (start == end || *start == ',') { return i; } goto skip; } if (start == end || *start++ != '=') { /* the invalid header value */ goto skip; } while (start < end && *start == ' ') { start++; } for (last = start; last < end && *last != ';'; last++) { /* void */ } value->len = last - start; value->data = start; return i; skip: while (start < end) { ch = *start++; if (ch == ';' || ch == ',') { break; } } while (start < end && *start == ' ') { start++; } } } return NGX_DECLINED;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -