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

📄 ngx_http_upstream.c

📁 Nginx是一个高性能的HTTP和反向代理服务器
💻 C
📖 第 1 页 / 共 5 页
字号:
        ngx_resolve_name_done(ctx);        ngx_http_finalize_request(r, NGX_HTTP_BAD_GATEWAY);        return;    }    ur = r->upstream->resolved;    ur->naddrs = ctx->naddrs;    ur->addrs = ctx->addrs;#if (NGX_DEBUG)    {    in_addr_t   addr;    ngx_uint_t  i;    for (i = 0; i < ctx->naddrs; i++) {        addr = ntohl(ur->addrs[i]);        ngx_log_debug4(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,                       "name was resolved to %ud.%ud.%ud.%ud",                       (addr >> 24) & 0xff, (addr >> 16) & 0xff,                       (addr >> 8) & 0xff, addr & 0xff);    }    }#endif    if (ngx_http_upstream_create_round_robin_peer(r, ur) != NGX_OK) {        ngx_resolve_name_done(ctx);        ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);        return;    }    ngx_resolve_name_done(ctx);    ngx_http_upstream_connect(r, r->upstream);}static voidngx_http_upstream_rd_check_broken_connection(ngx_http_request_t *r){    ngx_http_upstream_check_broken_connection(r, r->connection->read);}static voidngx_http_upstream_wr_check_broken_connection(ngx_http_request_t *r){    ngx_http_upstream_check_broken_connection(r, r->connection->write);}static voidngx_http_upstream_check_broken_connection(ngx_http_request_t *r,    ngx_event_t *ev){    int                  n;    char                 buf[1];    ngx_err_t            err;    ngx_connection_t     *c;    ngx_http_upstream_t  *u;    ngx_log_debug2(NGX_LOG_DEBUG_HTTP, ev->log, 0,                   "http upstream check client, write event:%d, \"%V\"",                   ev->write, &r->uri);    c = r->connection;    u = r->upstream;    if (c->error) {        ngx_http_upstream_finalize_request(r, u,                                           NGX_HTTP_CLIENT_CLOSED_REQUEST);        return;    }    if (u->peer.connection == NULL) {        return;    }#if (NGX_HAVE_KQUEUE)    if (ngx_event_flags & NGX_USE_KQUEUE_EVENT) {        if (!ev->pending_eof) {            return;        }        ev->eof = 1;        c->error = 1;        if (ev->kq_errno) {            ev->error = 1;        }        if (!u->cacheable && !u->store && u->peer.connection) {            ngx_log_error(NGX_LOG_INFO, ev->log, ev->kq_errno,                          "kevent() reported that client closed prematurely "                          "connection, so upstream connection is closed too");            ngx_http_upstream_finalize_request(r, u,                                               NGX_HTTP_CLIENT_CLOSED_REQUEST);            return;        }        ngx_log_error(NGX_LOG_INFO, ev->log, ev->kq_errno,                      "kevent() reported that client closed "                      "prematurely connection");        if (u->peer.connection == NULL) {            ngx_http_upstream_finalize_request(r, u,                                               NGX_HTTP_CLIENT_CLOSED_REQUEST);            return;        }        return;    }#endif    n = recv(c->fd, buf, 1, MSG_PEEK);    err = ngx_socket_errno;    ngx_log_debug1(NGX_LOG_DEBUG_HTTP, ev->log, err,                   "http upstream recv(): %d", n);    /*     * we do not need to disable the write event because     * that event has NGX_USE_CLEAR_EVENT type     */    if (ev->write && (n >= 0 || err == NGX_EAGAIN)) {        return;    }    if ((ngx_event_flags & NGX_USE_LEVEL_EVENT) && ev->active) {        if (ngx_del_event(ev, NGX_READ_EVENT, 0) == NGX_ERROR) {            ngx_http_upstream_finalize_request(r, u,                                               NGX_HTTP_INTERNAL_SERVER_ERROR);            return;        }    }    if (n > 0) {        return;    }    if (n == -1) {        if (err == NGX_EAGAIN) {            return;        }        ev->error = 1;    } else { /* n == 0 */        err = 0;    }    ev->eof = 1;    c->error = 1;    if (!u->cacheable && !u->store && u->peer.connection) {        ngx_log_error(NGX_LOG_INFO, ev->log, err,                      "client closed prematurely connection, "                      "so upstream connection is closed too");        ngx_http_upstream_finalize_request(r, u,                                           NGX_HTTP_CLIENT_CLOSED_REQUEST);        return;    }    ngx_log_error(NGX_LOG_INFO, ev->log, err,                  "client closed prematurely connection");    if (u->peer.connection == NULL) {        ngx_http_upstream_finalize_request(r, u,                                           NGX_HTTP_CLIENT_CLOSED_REQUEST);        return;    }}static voidngx_http_upstream_connect(ngx_http_request_t *r, ngx_http_upstream_t *u){    ngx_int_t          rc;    ngx_time_t        *tp;    ngx_connection_t  *c;    r->connection->log->action = "connecting to upstream";    r->connection->single_connection = 0;    if (u->state && u->state->response_sec) {        tp = ngx_timeofday();        u->state->response_sec = tp->sec - u->state->response_sec;        u->state->response_msec = tp->msec - u->state->response_msec;    }    u->state = ngx_array_push(r->upstream_states);    if (u->state == NULL) {        ngx_http_upstream_finalize_request(r, u,                                           NGX_HTTP_INTERNAL_SERVER_ERROR);        return;    }    ngx_memzero(u->state, sizeof(ngx_http_upstream_state_t));    tp = ngx_timeofday();    u->state->response_sec = tp->sec;    u->state->response_msec = tp->msec;    rc = ngx_event_connect_peer(&u->peer);    ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,                   "http upstream connect: %i", rc);    if (rc == NGX_ERROR) {        ngx_http_upstream_finalize_request(r, u,                                           NGX_HTTP_INTERNAL_SERVER_ERROR);        return;    }    u->state->peer = u->peer.name;    if (rc == NGX_BUSY) {        ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "no live upstreams");        ngx_http_upstream_next(r, u, NGX_HTTP_UPSTREAM_FT_NOLIVE);        return;    }    if (rc == NGX_DECLINED) {        ngx_http_upstream_next(r, u, NGX_HTTP_UPSTREAM_FT_ERROR);        return;    }    /* rc == NGX_OK || rc == NGX_AGAIN */    c = u->peer.connection;    c->data = r;    c->write->handler = ngx_http_upstream_send_request_handler;    c->read->handler = ngx_http_upstream_process_header;    c->sendfile &= r->connection->sendfile;    u->output.sendfile = c->sendfile;    c->pool = r->pool;    c->read->log = c->write->log = c->log = r->connection->log;    /* init or reinit the ngx_output_chain() and ngx_chain_writer() contexts */    u->writer.out = NULL;    u->writer.last = &u->writer.out;    u->writer.connection = c;    u->writer.limit = 0;    if (u->request_sent) {        if (ngx_http_upstream_reinit(r, u) != NGX_OK) {            ngx_http_upstream_finalize_request(r, u,                                               NGX_HTTP_INTERNAL_SERVER_ERROR);            return;        }    }    if (r->request_body        && r->request_body->buf        && r->request_body->temp_file        && r == r->main)    {        /*         * the r->request_body->buf can be reused for one request only,         * the subrequests should allocate their own temporay bufs         */        u->output.free = ngx_alloc_chain_link(r->pool);        if (u->output.free == NULL) {            ngx_http_upstream_finalize_request(r, u,                                               NGX_HTTP_INTERNAL_SERVER_ERROR);            return;        }        u->output.free->buf = r->request_body->buf;        u->output.free->next = NULL;        u->output.allocated = 1;        r->request_body->buf->pos = r->request_body->buf->start;        r->request_body->buf->last = r->request_body->buf->start;        r->request_body->buf->tag = u->output.tag;    }    u->request_sent = 0;    if (rc == NGX_AGAIN) {        ngx_add_timer(c->write, u->conf->connect_timeout);        return;    }#if (NGX_HTTP_SSL)    if (u->ssl && c->ssl == NULL) {        ngx_http_upstream_ssl_init_connection(r, u, c);        return;    }#endif    ngx_http_upstream_send_request(r, u);}#if (NGX_HTTP_SSL)static voidngx_http_upstream_ssl_init_connection(ngx_http_request_t *r,    ngx_http_upstream_t *u, ngx_connection_t *c){    ngx_int_t   rc;    if (ngx_ssl_create_connection(u->conf->ssl, c,                                  NGX_SSL_BUFFER|NGX_SSL_CLIENT)        == NGX_ERROR)    {        ngx_http_upstream_finalize_request(r, u,                                           NGX_HTTP_INTERNAL_SERVER_ERROR);        return;    }    c->sendfile = 0;    u->output.sendfile = 0;    if (u->peer.set_session(&u->peer, u->peer.data) != NGX_OK) {        ngx_http_upstream_finalize_request(r, u,                                           NGX_HTTP_INTERNAL_SERVER_ERROR);        return;    }    r->connection->log->action = "SSL handshaking to upstream";    rc = ngx_ssl_handshake(c);    if (rc == NGX_AGAIN) {        c->ssl->handler = ngx_http_upstream_ssl_handshake;        return;    }    ngx_http_upstream_ssl_handshake(c);}static voidngx_http_upstream_ssl_handshake(ngx_connection_t *c){    ngx_http_request_t   *r;    ngx_http_upstream_t  *u;    r = c->data;    u = r->upstream;    if (c->ssl->handshaked) {        u->peer.save_session(&u->peer, u->peer.data);        c->write->handler = ngx_http_upstream_send_request_handler;        c->read->handler = ngx_http_upstream_process_header;        ngx_http_upstream_send_request(r, u);        return;    }    ngx_http_upstream_next(r, u, NGX_HTTP_UPSTREAM_FT_ERROR);}#endifstatic ngx_int_tngx_http_upstream_reinit(ngx_http_request_t *r, ngx_http_upstream_t *u){    ngx_chain_t  *cl;    if (u->reinit_request(r) != NGX_OK) {        return NGX_ERROR;    }    ngx_memzero(&u->headers_in, sizeof(ngx_http_upstream_headers_in_t));    if (ngx_list_init(&u->headers_in.headers, r->pool, 8,                      sizeof(ngx_table_elt_t))        != NGX_OK)    {        return NGX_ERROR;    }    /* reinit the request chain */    for (cl = u->request_bufs; cl; cl = cl->next) {        cl->buf->pos = cl->buf->start;        cl->buf->file_pos = 0;    }    /* reinit the subrequest's ngx_output_chain() context */    if (r->request_body && r->request_body->temp_file        && r != r->main && u->output.buf)    {        u->output.free = ngx_alloc_chain_link(r->pool);        if (u->output.free == NULL) {            return NGX_ERROR;        }        u->output.free->buf = u->output.buf;        u->output.free->next = NULL;        u->output.buf->pos = u->output.buf->start;        u->output.buf->last = u->output.buf->start;    }    u->output.buf = NULL;    u->output.in = NULL;    u->output.busy = NULL;    /* reinit u->buffer */#if 0    if (u->cache) {        u->buffer.pos = u->buffer.start + u->cache->ctx.header_size;        u->buffer.last = u->buffer.pos;    } else {        u->buffer.pos = u->buffer.start;        u->buffer.last = u->buffer.start;    }#else        u->buffer.pos = u->buffer.start;        u->buffer.last = u->buffer.start;#endif    return NGX_OK;}static voidngx_http_upstream_send_request(ngx_http_request_t *r, ngx_http_upstream_t *u){    ngx_int_t          rc;    ngx_connection_t  *c;    c = u->peer.connection;    ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0,                   "http upstream send request");    if (!u->request_sent && ngx_http_upstream_test_connect(c) != NGX_OK) {        ngx_http_upstream_next(r, u, NGX_HTTP_UPSTREAM_FT_ERROR);        return;    }

⌨️ 快捷键说明

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