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

📄 ngx_http_proxy_module.c

📁 nginx 反向代理0.7.1版本 用于实现反向代理
💻 C
📖 第 1 页 / 共 5 页
字号:
    ctx = ngx_http_get_module_ctx(r, ngx_http_proxy_module);    if (ctx == NULL) {        return NGX_OK;    }    ctx->status = 0;    ctx->status_count = 0;    ctx->status_start = NULL;    ctx->status_end = NULL;    r->upstream->process_header = ngx_http_proxy_process_status_line;    return NGX_OK;}static ngx_int_tngx_http_proxy_process_status_line(ngx_http_request_t *r){    ngx_int_t              rc;    ngx_http_upstream_t   *u;    ngx_http_proxy_ctx_t  *ctx;    ctx = ngx_http_get_module_ctx(r, ngx_http_proxy_module);    if (ctx == NULL) {        return NGX_ERROR;    }    rc = ngx_http_proxy_parse_status_line(r, ctx);    if (rc == NGX_AGAIN) {        return rc;    }    u = r->upstream;    if (rc == NGX_HTTP_PROXY_PARSE_NO_HEADER) {        ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,                      "upstream sent no valid HTTP/1.0 header");#if 0        if (u->accel) {            return NGX_HTTP_UPSTREAM_INVALID_HEADER;        }#endif        r->http_version = NGX_HTTP_VERSION_9;        u->headers_in.status_n = NGX_HTTP_OK;        u->state->status = NGX_HTTP_OK;        return NGX_OK;    }    u->headers_in.status_n = ctx->status;    u->state->status = ctx->status;    u->headers_in.status_line.len = ctx->status_end - ctx->status_start;    u->headers_in.status_line.data = ngx_palloc(r->pool,                                                u->headers_in.status_line.len);    if (u->headers_in.status_line.data == NULL) {        return NGX_ERROR;    }    ngx_memcpy(u->headers_in.status_line.data, ctx->status_start,               u->headers_in.status_line.len);    ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,                   "http proxy status %ui \"%V\"",                   u->headers_in.status_n, &u->headers_in.status_line);    u->process_header = ngx_http_proxy_process_header;    return ngx_http_proxy_process_header(r);}static ngx_int_tngx_http_proxy_parse_status_line(ngx_http_request_t *r,    ngx_http_proxy_ctx_t *ctx){    u_char                ch;    u_char               *p;    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 (p = u->buffer.pos; p < u->buffer.last; p++) {        ch = *p;        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;            }            ctx->status = ctx->status * 10 + ch - '0';            if (++ctx->status_count == 3) {                state = sw_space_after_status;                ctx->status_start = p - 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:            ctx->status_end = p - 1;            switch (ch) {            case LF:                goto done;            default:                return NGX_HTTP_PROXY_PARSE_NO_HEADER;            }        }    }    u->buffer.pos = p;    r->state = state;    return NGX_AGAIN;done:    u->buffer.pos = p + 1;    if (ctx->status_end == NULL) {        ctx->status_end = p;    }    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_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_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_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_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_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_ctx_t  *ctx;    ctx = ngx_http_get_module_ctx(r, ngx_http_proxy_module);    if (ctx == NULL) {        v->not_found = 1;        return NGX_OK;    }    v->len = ctx->vars.host_header.len;    v->valid = 1;    v->no_cacheable = 0;    v->not_found = 0;    v->data = ctx->vars.host_header.data;    return NGX_OK;}

⌨️ 快捷键说明

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