📄 ngx_http_upstream.c
字号:
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 + -