#include <ngx_stream.h>
+static void ngx_stream_close_connection(ngx_connection_t *c);
static u_char *ngx_stream_log_error(ngx_log_t *log, u_char *buf, size_t len);
static void ngx_stream_init_session(ngx_connection_t *c);
if (cmcf->limit_conn_handler) {
rc = cmcf->limit_conn_handler(s);
- if (rc != NGX_DECLINED) {
- ngx_stream_close_connection(c);
+ if (rc == NGX_ERROR) {
+ ngx_stream_finalize_session(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
+ return;
+ }
+
+ if (rc == NGX_ABORT) {
+ ngx_stream_finalize_session(s, NGX_STREAM_SERVICE_UNAVAILABLE);
return;
}
}
if (cmcf->access_handler) {
rc = cmcf->access_handler(s);
- if (rc != NGX_OK && rc != NGX_DECLINED) {
- ngx_stream_close_connection(c);
+ if (rc == NGX_ERROR) {
+ ngx_stream_finalize_session(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
+ return;
+ }
+
+ if (rc == NGX_ABORT) {
+ ngx_stream_finalize_session(s, NGX_STREAM_FORBIDDEN);
return;
}
}
{
ngx_connection_error(c, ngx_socket_errno,
"setsockopt(TCP_NODELAY) failed");
- ngx_stream_close_connection(c);
+ ngx_stream_finalize_session(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
return;
}
ngx_log_error(NGX_LOG_ERR, c->log, 0,
"no \"ssl_certificate\" is defined "
"in server listening on SSL port");
- ngx_stream_close_connection(c);
+ ngx_stream_finalize_session(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
return;
}
s->ctx = ngx_pcalloc(c->pool, sizeof(void *) * ngx_stream_max_module);
if (s->ctx == NULL) {
- ngx_stream_close_connection(c);
+ ngx_stream_finalize_session(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
return;
}
ngx_stream_session_t *s;
ngx_stream_ssl_conf_t *sslcf;
+ s = c->data;
+
if (ngx_ssl_create_connection(ssl, c, 0) == NGX_ERROR) {
- ngx_stream_close_connection(c);
+ ngx_stream_finalize_session(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
return;
}
if (ngx_ssl_handshake(c) == NGX_AGAIN) {
-
- s = c->data;
-
sslcf = ngx_stream_get_module_srv_conf(s, ngx_stream_ssl_module);
ngx_add_timer(c->read, sslcf->handshake_timeout);
ngx_stream_ssl_handshake_handler(ngx_connection_t *c)
{
if (!c->ssl->handshaked) {
- ngx_stream_close_connection(c);
+ ngx_stream_finalize_session(c->data, NGX_STREAM_INTERNAL_SERVER_ERROR);
return;
}
void
+ngx_stream_finalize_session(ngx_stream_session_t *s, ngx_uint_t rc)
+{
+ ngx_log_debug1(NGX_LOG_DEBUG_STREAM, s->connection->log, 0,
+ "finalize stream session: %i", rc);
+
+ s->status = rc;
+
+ ngx_stream_close_connection(s->connection);
+}
+
+
+static void
ngx_stream_close_connection(ngx_connection_t *c)
{
ngx_pool_t *pool;
static void ngx_stream_proxy_process(ngx_stream_session_t *s,
ngx_uint_t from_upstream, ngx_uint_t do_write);
static void ngx_stream_proxy_next_upstream(ngx_stream_session_t *s);
-static void ngx_stream_proxy_finalize(ngx_stream_session_t *s, ngx_int_t rc);
+static void ngx_stream_proxy_finalize(ngx_stream_session_t *s, ngx_uint_t rc);
static u_char *ngx_stream_proxy_log_error(ngx_log_t *log, u_char *buf,
size_t len);
u = ngx_pcalloc(c->pool, sizeof(ngx_stream_upstream_t));
if (u == NULL) {
- ngx_stream_proxy_finalize(s, NGX_ERROR);
+ ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
return;
}
u->peer.log_error = NGX_ERROR_ERR;
if (ngx_stream_proxy_set_local(s, u, pscf->local) != NGX_OK) {
- ngx_stream_proxy_finalize(s, NGX_ERROR);
+ ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
return;
}
if (c->type == SOCK_STREAM) {
p = ngx_pnalloc(c->pool, pscf->buffer_size);
if (p == NULL) {
- ngx_stream_proxy_finalize(s, NGX_ERROR);
+ ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
return;
}
p = ngx_proxy_protocol_write(c, u->downstream_buf.last,
u->downstream_buf.end);
if (p == NULL) {
- ngx_stream_proxy_finalize(s, NGX_ERROR);
+ ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
return;
}
if (pscf->upstream_value) {
if (ngx_stream_proxy_eval(s, pscf) != NGX_OK) {
- ngx_stream_proxy_finalize(s, NGX_ERROR);
+ ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
return;
}
}
{
ngx_log_error(NGX_LOG_ERR, c->log, 0,
"no port in upstream \"%V\"", host);
- ngx_stream_proxy_finalize(s, NGX_ERROR);
+ ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
return;
}
if (ngx_stream_upstream_create_round_robin_peer(s, u->resolved)
!= NGX_OK)
{
- ngx_stream_proxy_finalize(s, NGX_ERROR);
+ ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
return;
}
if (u->resolved->port == 0) {
ngx_log_error(NGX_LOG_ERR, c->log, 0,
"no port in upstream \"%V\"", host);
- ngx_stream_proxy_finalize(s, NGX_ERROR);
+ ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
return;
}
ctx = ngx_resolve_start(cscf->resolver, &temp);
if (ctx == NULL) {
- ngx_stream_proxy_finalize(s, NGX_ERROR);
+ ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
return;
}
if (ctx == NGX_NO_RESOLVER) {
ngx_log_error(NGX_LOG_ERR, c->log, 0,
"no resolver defined to resolve %V", host);
- ngx_stream_proxy_finalize(s, NGX_ERROR);
+ ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
return;
}
if (ngx_resolve_name(ctx) != NGX_OK) {
u->resolved->ctx = NULL;
- ngx_stream_proxy_finalize(s, NGX_ERROR);
+ ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
return;
}
if (uscf == NULL) {
ngx_log_error(NGX_LOG_ALERT, c->log, 0, "no upstream configuration");
- ngx_stream_proxy_finalize(s, NGX_ERROR);
+ ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
return;
}
#endif
if (uscf->peer.init(s, uscf) != NGX_OK) {
- ngx_stream_proxy_finalize(s, NGX_ERROR);
+ ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
return;
}
ngx_log_debug1(NGX_LOG_DEBUG_STREAM, c->log, 0, "proxy connect: %i", rc);
if (rc == NGX_ERROR) {
- ngx_stream_proxy_finalize(s, NGX_ERROR);
+ ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
return;
}
if (rc == NGX_BUSY) {
ngx_log_error(NGX_LOG_ERR, c->log, 0, "no live upstreams");
- ngx_stream_proxy_finalize(s, NGX_DECLINED);
+ ngx_stream_proxy_finalize(s, NGX_STREAM_BAD_GATEWAY);
return;
}
if (u->upstream_buf.start == NULL) {
p = ngx_pnalloc(c->pool, pscf->buffer_size);
if (p == NULL) {
- ngx_stream_proxy_finalize(s, NGX_ERROR);
+ ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
return;
}
p = ngx_proxy_protocol_write(c, buf, buf + NGX_PROXY_PROTOCOL_MAX_HEADER);
if (p == NULL) {
- ngx_stream_proxy_finalize(s, NGX_ERROR);
+ ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
return NGX_ERROR;
}
if (n == NGX_AGAIN) {
if (ngx_handle_write_event(pc->write, 0) != NGX_OK) {
- ngx_stream_proxy_finalize(s, NGX_ERROR);
+ ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
return NGX_ERROR;
}
}
if (n == NGX_ERROR) {
- ngx_stream_proxy_finalize(s, NGX_DECLINED);
+ ngx_stream_proxy_finalize(s, NGX_STREAM_OK);
return NGX_ERROR;
}
ngx_log_error(NGX_LOG_ERR, c->log, 0,
"could not send PROXY protocol header at once");
- ngx_stream_proxy_finalize(s, NGX_DECLINED);
+ ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
return NGX_ERROR;
}
if (ngx_ssl_create_connection(pscf->ssl, pc, NGX_SSL_BUFFER|NGX_SSL_CLIENT)
!= NGX_OK)
{
- ngx_stream_proxy_finalize(s, NGX_ERROR);
+ ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
return;
}
if (pscf->ssl_server_name || pscf->ssl_verify) {
if (ngx_stream_proxy_ssl_name(s) != NGX_OK) {
- ngx_stream_proxy_finalize(s, NGX_ERROR);
+ ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
return;
}
}
if (pscf->ssl_session_reuse) {
if (u->peer.set_session(&u->peer, u->peer.data) != NGX_OK) {
- ngx_stream_proxy_finalize(s, NGX_ERROR);
+ ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
return;
}
}
&ctx->name, ctx->state,
ngx_resolver_strerror(ctx->state));
- ngx_stream_proxy_finalize(s, NGX_ERROR);
+ ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
return;
}
#endif
if (ngx_stream_upstream_create_round_robin_peer(s, ur) != NGX_OK) {
- ngx_stream_proxy_finalize(s, NGX_ERROR);
+ ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
return;
}
if (!ev->ready) {
if (ngx_handle_read_event(ev, 0) != NGX_OK) {
- ngx_stream_proxy_finalize(s, NGX_ERROR);
+ ngx_stream_proxy_finalize(s,
+ NGX_STREAM_INTERNAL_SERVER_ERROR);
return;
}
}
ngx_connection_error(c, NGX_ETIMEDOUT, "connection timed out");
- ngx_stream_proxy_finalize(s, NGX_DECLINED);
+ ngx_stream_proxy_finalize(s, NGX_STREAM_OK);
return;
}
"stream connection delayed");
if (ngx_handle_read_event(ev, 0) != NGX_OK) {
- ngx_stream_proxy_finalize(s, NGX_ERROR);
+ ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
}
return;
c->log->handler = handler;
- ngx_stream_proxy_finalize(s, NGX_OK);
+ ngx_stream_proxy_finalize(s, NGX_STREAM_OK);
return;
}
return;
}
- ngx_stream_proxy_finalize(s, NGX_DECLINED);
+ ngx_stream_proxy_finalize(s, NGX_STREAM_OK);
return;
}
c->log->handler = handler;
- ngx_stream_proxy_finalize(s, NGX_OK);
+ ngx_stream_proxy_finalize(s, NGX_STREAM_OK);
return;
}
flags = src->read->eof ? NGX_CLOSE_EVENT : 0;
if (!src->shared && ngx_handle_read_event(src->read, flags) != NGX_OK) {
- ngx_stream_proxy_finalize(s, NGX_ERROR);
+ ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
return;
}
if (dst) {
if (!dst->shared && ngx_handle_write_event(dst->write, 0) != NGX_OK) {
- ngx_stream_proxy_finalize(s, NGX_ERROR);
+ ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
return;
}
|| !pscf->next_upstream
|| (timeout && ngx_current_msec - u->peer.start_time >= timeout))
{
- ngx_stream_proxy_finalize(s, NGX_DECLINED);
+ ngx_stream_proxy_finalize(s, NGX_STREAM_BAD_GATEWAY);
return;
}
static void
-ngx_stream_proxy_finalize(ngx_stream_session_t *s, ngx_int_t rc)
+ngx_stream_proxy_finalize(ngx_stream_session_t *s, ngx_uint_t rc)
{
ngx_connection_t *pc;
ngx_stream_upstream_t *u;
noupstream:
- ngx_stream_close_connection(s->connection);
+ ngx_stream_finalize_session(s, rc);
}