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

📄 ngx_http_proxy_module.c

📁 Nginx ("engine x") 是一个高性能的 HTTP 和 反向代理 服务器
💻 C
📖 第 1 页 / 共 5 页
字号:
    ngx_http_upstream_t  *u;    enum  {        sw_start = 0,        sw_H,        sw_HT,        sw_HTT,        sw_HTTP,        sw_first_major_digit,        sw_major_digit,        sw_first_minor_digit,        sw_minor_digit,        sw_status,        sw_space_after_status,        sw_status_text,        sw_almost_done    } state;    u = r->upstream;    state = r->state;    for (pos = u->buffer.pos; pos < u->buffer.last; pos++) {        ch = *pos;        switch (state) {        /* "HTTP/" */        case sw_start:            switch (ch) {            case 'H':                state = sw_H;                break;            default:                return NGX_HTTP_PROXY_PARSE_NO_HEADER;            }            break;        case sw_H:            switch (ch) {            case 'T':                state = sw_HT;                break;            default:                return NGX_HTTP_PROXY_PARSE_NO_HEADER;            }            break;        case sw_HT:            switch (ch) {            case 'T':                state = sw_HTT;                break;            default:                return NGX_HTTP_PROXY_PARSE_NO_HEADER;            }            break;        case sw_HTT:            switch (ch) {            case 'P':                state = sw_HTTP;                break;            default:                return NGX_HTTP_PROXY_PARSE_NO_HEADER;            }            break;        case sw_HTTP:            switch (ch) {            case '/':                state = sw_first_major_digit;                break;            default:                return NGX_HTTP_PROXY_PARSE_NO_HEADER;            }            break;        /* the first digit of major HTTP version */        case sw_first_major_digit:            if (ch < '1' || ch > '9') {                return NGX_HTTP_PROXY_PARSE_NO_HEADER;            }            state = sw_major_digit;            break;        /* the major HTTP version or dot */        case sw_major_digit:            if (ch == '.') {                state = sw_first_minor_digit;                break;            }            if (ch < '0' || ch > '9') {                return NGX_HTTP_PROXY_PARSE_NO_HEADER;            }            break;        /* the first digit of minor HTTP version */        case sw_first_minor_digit:            if (ch < '0' || ch > '9') {                return NGX_HTTP_PROXY_PARSE_NO_HEADER;            }            state = sw_minor_digit;            break;        /* the minor HTTP version or the end of the request line */        case sw_minor_digit:            if (ch == ' ') {                state = sw_status;                break;            }            if (ch < '0' || ch > '9') {                return NGX_HTTP_PROXY_PARSE_NO_HEADER;            }            break;        /* HTTP status code */        case sw_status:            if (ch == ' ') {                break;            }            if (ch < '0' || ch > '9') {                return NGX_HTTP_PROXY_PARSE_NO_HEADER;            }            p->status = p->status * 10 + ch - '0';            if (++p->status_count == 3) {                state = sw_space_after_status;                p->status_start = pos - 2;            }            break;         /* space or end of line */         case sw_space_after_status:            switch (ch) {            case ' ':                state = sw_status_text;                break;            case '.':                    /* IIS may send 403.1, 403.2, etc */                state = sw_status_text;                break;            case CR:                state = sw_almost_done;                break;            case LF:                goto done;            default:                return NGX_HTTP_PROXY_PARSE_NO_HEADER;            }            break;        /* any text until end of line */        case sw_status_text:            switch (ch) {            case CR:                state = sw_almost_done;                break;            case LF:                goto done;            }            break;        /* end of status line */        case sw_almost_done:            p->status_end = pos - 1;            switch (ch) {            case LF:                goto done;            default:                return NGX_HTTP_PROXY_PARSE_NO_HEADER;            }        }    }    u->buffer.pos = pos;    r->state = state;    return NGX_AGAIN;done:    u->buffer.pos = pos + 1;    if (p->status_end == NULL) {        p->status_end = pos;    }    r->state = sw_start;    return NGX_OK;}static ngx_int_tngx_http_proxy_process_header(ngx_http_request_t *r){    ngx_int_t                       rc;    ngx_uint_t                      i;    ngx_table_elt_t                *h;    ngx_http_upstream_header_t     *hh;    ngx_http_upstream_main_conf_t  *umcf;    umcf = ngx_http_get_module_main_conf(r, ngx_http_upstream_module);    for ( ;;  ) {        rc = ngx_http_parse_header_line(r, &r->upstream->buffer);        if (rc == NGX_OK) {            /* a header line has been parsed successfully */            h = ngx_list_push(&r->upstream->headers_in.headers);            if (h == NULL) {                return NGX_HTTP_INTERNAL_SERVER_ERROR;            }            h->hash = r->header_hash;            h->key.len = r->header_name_end - r->header_name_start;            h->value.len = r->header_end - r->header_start;            h->key.data = ngx_palloc(r->pool,                               h->key.len + 1 + h->value.len + 1 + h->key.len);            if (h->key.data == NULL) {                return NGX_HTTP_INTERNAL_SERVER_ERROR;            }            h->value.data = h->key.data + h->key.len + 1;            h->lowcase_key = h->key.data + h->key.len + 1 + h->value.len + 1;            ngx_cpystrn(h->key.data, r->header_name_start, h->key.len + 1);            ngx_cpystrn(h->value.data, r->header_start, h->value.len + 1);            if (h->key.len == r->lowcase_index) {                ngx_memcpy(h->lowcase_key, r->lowcase_header, h->key.len);            } else {                for (i = 0; i < h->key.len; i++) {                    h->lowcase_key[i] = ngx_tolower(h->key.data[i]);                }            }            hh = ngx_hash_find(&umcf->headers_in_hash, h->hash,                               h->lowcase_key, h->key.len);            if (hh && hh->handler(r, h, hh->offset) != NGX_OK) {                return NGX_HTTP_INTERNAL_SERVER_ERROR;            }            ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,                           "http proxy header: \"%V: %V\"",                           &h->key, &h->value);            continue;        }        if (rc == NGX_HTTP_PARSE_HEADER_DONE) {            /* a whole header has been parsed successfully */            ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,                           "http proxy header done");            /*             * if no "Server" and "Date" in header line,             * then add the special empty headers             */            if (r->upstream->headers_in.server == NULL) {                h = ngx_list_push(&r->upstream->headers_in.headers);                if (h == NULL) {                    return NGX_HTTP_INTERNAL_SERVER_ERROR;                }                h->hash = ngx_hash(ngx_hash(ngx_hash(ngx_hash(                                    ngx_hash('s', 'e'), 'r'), 'v'), 'e'), 'r');                h->key.len = sizeof("Server") - 1;                h->key.data = (u_char *) "Server";                h->value.len = 0;                h->value.data = NULL;                h->lowcase_key = (u_char *) "server";            }            if (r->upstream->headers_in.date == NULL) {                h = ngx_list_push(&r->upstream->headers_in.headers);                if (h == NULL) {                    return NGX_HTTP_INTERNAL_SERVER_ERROR;                }                h->hash = ngx_hash(ngx_hash(ngx_hash('d', 'a'), 't'), 'e');                h->key.len = sizeof("Date") - 1;                h->key.data = (u_char *) "Date";                h->value.len = 0;                h->value.data = NULL;                h->lowcase_key = (u_char *) "date";            }            return NGX_OK;        }        if (rc == NGX_AGAIN) {            return NGX_AGAIN;        }        /* there was error while a header line parsing */        ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,                      "upstream sent invalid header");        return NGX_HTTP_UPSTREAM_INVALID_HEADER;    }}static voidngx_http_proxy_abort_request(ngx_http_request_t *r){    ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,                   "abort http proxy request");    return;}static voidngx_http_proxy_finalize_request(ngx_http_request_t *r, ngx_int_t rc){    ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,                   "finalize http proxy request");    return;}static ngx_int_tngx_http_proxy_host_variable(ngx_http_request_t *r,    ngx_http_variable_value_t *v, uintptr_t data){    ngx_http_proxy_loc_conf_t  *plcf;    plcf = ngx_http_get_module_loc_conf(r, ngx_http_proxy_module);    v->len = plcf->host_header.len;    v->valid = 1;    v->no_cacheable = 0;    v->not_found = 0;    v->data = plcf->host_header.data;    return NGX_OK;}static ngx_int_tngx_http_proxy_port_variable(ngx_http_request_t *r,    ngx_http_variable_value_t *v, uintptr_t data){    ngx_http_proxy_loc_conf_t  *plcf;    plcf = ngx_http_get_module_loc_conf(r, ngx_http_proxy_module);    v->len = plcf->port.len;    v->valid = 1;    v->no_cacheable = 0;    v->not_found = 0;    v->data = plcf->port.data;    return NGX_OK;}static ngx_int_tngx_http_proxy_add_x_forwarded_for_variable(ngx_http_request_t *r,    ngx_http_variable_value_t *v, uintptr_t data){    u_char  *p;    v->valid = 1;    v->no_cacheable = 0;    v->not_found = 0;    if (r->headers_in.x_forwarded_for == NULL) {        v->len = r->connection->addr_text.len;        v->data = r->connection->addr_text.data;        return NGX_OK;    }    v->len = r->headers_in.x_forwarded_for->value.len             + sizeof(", ") - 1 + r->connection->addr_text.len;    p = ngx_palloc(r->pool, v->len);    if (p == NULL) {        return NGX_ERROR;    }    v->data = p;    p = ngx_copy(p, r->headers_in.x_forwarded_for->value.data,                 r->headers_in.x_forwarded_for->value.len);    *p++ = ','; *p++ = ' ';    ngx_memcpy(p, r->connection->addr_text.data, r->connection->addr_text.len);    return NGX_OK;}static ngx_int_tngx_http_proxy_internal_body_length_variable(ngx_http_request_t *r,    ngx_http_variable_value_t *v, uintptr_t data){    ngx_http_proxy_ctx_t  *p;    p = ngx_http_get_module_ctx(r, ngx_http_proxy_module);    if (p == NULL) {        v->not_found = 1;        return NGX_OK;    }    v->valid = 1;    v->no_cacheable = 0;    v->not_found = 0;    v->data = ngx_palloc(r->connection->pool, NGX_SIZE_T_LEN);    if (v->data == NULL) {        return NGX_ERROR;    }    v->len = ngx_sprintf(v->data, "%uz", p->internal_body_length) - v->data;    return NGX_OK;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -