⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ngx_http_parse.c

📁 Nginx是一个高性能的HTTP和反向代理服务器
💻 C
📖 第 1 页 / 共 3 页
字号:
#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 + -