ngx_int_t ngx_postgres_upstream_done(ngx_http_request_t *r, ngx_http_upstream_t *u, ngx_postgres_upstream_peer_data_t *pgdt) { ngx_postgres_ctx_t *pgctx; dd("entering"); /* flag for keepalive */ u->headers_in.status_n = NGX_HTTP_OK; pgctx = ngx_http_get_module_ctx(r, ngx_postgres_module); if (pgctx->status >= NGX_HTTP_SPECIAL_RESPONSE) { ngx_postgres_upstream_finalize_request(r, u, pgctx->status); } else { ngx_postgres_upstream_finalize_request(r, u, NGX_OK); } dd("returning NGX_DONE"); return NGX_DONE; }
void ngx_postgres_upstream_next(ngx_http_request_t *r, ngx_http_upstream_t *u, ngx_int_t ft_type) { ngx_uint_t status, state; dd("entering"); ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "http next upstream, %xi", ft_type); #if 0 ngx_http_busy_unlock(u->conf->busy_lock, &u->busy_lock); #endif if (ft_type == NGX_HTTP_UPSTREAM_FT_HTTP_404) { state = NGX_PEER_NEXT; } else { state = NGX_PEER_FAILED; } if (ft_type != NGX_HTTP_UPSTREAM_FT_NOLIVE) { u->peer.free(&u->peer, u->peer.data, state); } if (ft_type == NGX_HTTP_UPSTREAM_FT_TIMEOUT) { ngx_log_error(NGX_LOG_ERR, r->connection->log, NGX_ETIMEDOUT, "upstream timed out"); } if (u->peer.cached && ft_type == NGX_HTTP_UPSTREAM_FT_ERROR) { status = 0; } else { switch(ft_type) { case NGX_HTTP_UPSTREAM_FT_TIMEOUT: status = NGX_HTTP_GATEWAY_TIME_OUT; break; case NGX_HTTP_UPSTREAM_FT_HTTP_500: status = NGX_HTTP_INTERNAL_SERVER_ERROR; break; case NGX_HTTP_UPSTREAM_FT_HTTP_404: status = NGX_HTTP_NOT_FOUND; break; /* * NGX_HTTP_UPSTREAM_FT_BUSY_LOCK and NGX_HTTP_UPSTREAM_FT_MAX_WAITING * never reach here */ default: status = NGX_HTTP_BAD_GATEWAY; } } if (r->connection->error) { ngx_postgres_upstream_finalize_request(r, u, NGX_HTTP_CLIENT_CLOSED_REQUEST); dd("returning"); return; } if (status) { u->state->status = status; if (u->peer.tries == 0 || !(u->conf->next_upstream & ft_type)) { ngx_postgres_upstream_finalize_request(r, u, status); dd("returning"); return; } } if (u->peer.connection) { ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "close http upstream connection: %d", u->peer.connection->fd); #if 0 /* we don't support SSL at this time, was: (NGX_HTTP_SSL) */ if (u->peer.connection->ssl) { u->peer.connection->ssl->no_wait_shutdown = 1; u->peer.connection->ssl->no_send_shutdown = 1; (void) ngx_ssl_shutdown(u->peer.connection); } #endif #if defined(nginx_version) && (nginx_version >= 1001004) if (u->peer.connection->pool) { ngx_destroy_pool(u->peer.connection->pool); } #endif ngx_close_connection(u->peer.connection); } #if 0 if (u->conf->busy_lock && !u->busy_locked) { ngx_http_upstream_busy_lock(p); return; } #endif /* TODO: ngx_http_upstream_connect(r, u); */ if (status == 0) { status = NGX_HTTP_INTERNAL_SERVER_ERROR; } dd("returning"); return ngx_postgres_upstream_finalize_request(r, u, status); }
void ngx_postgres_process_events(ngx_http_request_t *r) { ngx_postgres_upstream_peer_data_t *pgdt; ngx_connection_t *pgxc; ngx_http_upstream_t *u; ngx_int_t rc; dd("entering"); u = r->upstream; pgxc = u->peer.connection; pgdt = u->peer.data; if (!ngx_postgres_upstream_is_my_peer(&u->peer)) { ngx_log_error(NGX_LOG_ERR, pgxc->log, 0, "trying to connect to something that" " is not PostgreSQL database"); goto failed; } switch (pgdt->state) { case state_db_connect: dd("state_db_connect"); rc = ngx_postgres_upstream_connect(r, pgxc, pgdt); break; case state_db_send_query: dd("state_db_send_query"); rc = ngx_postgres_upstream_send_query(r, pgxc, pgdt); break; case state_db_get_result: dd("state_db_get_result"); rc = ngx_postgres_upstream_get_result(r, pgxc, pgdt); break; case state_db_get_ack: dd("state_db_get_ack"); rc = ngx_postgres_upstream_get_ack(r, pgxc, pgdt); break; case state_db_idle: dd("state_db_idle, re-using keepalive connection"); pgxc->log->action = "sending query to PostgreSQL database"; pgdt->state = state_db_send_query; rc = ngx_postgres_upstream_send_query(r, pgxc, pgdt); break; default: dd("unknown state: %d", pgdt->state); ngx_log_error(NGX_LOG_ERR, pgxc->log, 0, "unknown state: %d", pgdt->state); goto failed; } if (rc >= NGX_HTTP_SPECIAL_RESPONSE) { ngx_postgres_upstream_finalize_request(r, u, rc); } else if (rc == NGX_ERROR) { goto failed; } dd("returning"); return; failed: ngx_postgres_upstream_next(r, u, NGX_HTTP_UPSTREAM_FT_ERROR); dd("returning"); }
void ngx_postgres_upstream_finalize_request(ngx_http_request_t *r, ngx_http_upstream_t *u, ngx_int_t rc) { #if defined(nginx_version) && (nginx_version < 1009001) ngx_time_t *tp; #endif dd("entering"); ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "finalize http upstream request: %i", rc); if (u->cleanup) { *u->cleanup = NULL; } if (u->resolved && u->resolved->ctx) { ngx_resolve_name_done(u->resolved->ctx); u->resolved->ctx = NULL; } #if defined(nginx_version) && (nginx_version >= 1009001) if (u->state && u->state->response_time) { u->state->response_time = ngx_current_msec - u->state->response_time; #else 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; #endif if (u->pipe) { u->state->response_length = u->pipe->read_length; } } if (u->finalize_request) { u->finalize_request(r, rc); } if (u->peer.free) { u->peer.free(&u->peer, u->peer.data, 0); } if (u->peer.connection) { #if 0 /* we don't support SSL at this time, was: (NGX_HTTP_SSL) */ /* TODO: do not shutdown persistent connection */ if (u->peer.connection->ssl) { /* * We send the "close notify" shutdown alert to the upstream only * and do not wait its "close notify" shutdown alert. * It is acceptable according to the TLS standard. */ u->peer.connection->ssl->no_wait_shutdown = 1; (void) ngx_ssl_shutdown(u->peer.connection); } #endif ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "close http upstream connection: %d", u->peer.connection->fd); #if defined(nginx_version) && (nginx_version >= 1001004) if (u->peer.connection->pool) { ngx_destroy_pool(u->peer.connection->pool); } #endif ngx_close_connection(u->peer.connection); } u->peer.connection = NULL; if (u->pipe && u->pipe->temp_file) { ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "http upstream temp fd: %d", u->pipe->temp_file->file.fd); } if (u->header_sent && (rc == NGX_ERROR || rc >= NGX_HTTP_SPECIAL_RESPONSE)) { rc = 0; } if (rc == NGX_DECLINED) { dd("returning"); return; } r->connection->log->action = "sending to client"; if (rc == 0) { rc = ngx_http_send_special(r, NGX_HTTP_LAST); } ngx_http_finalize_request(r, rc); dd("returning"); } void ngx_postgres_upstream_next(ngx_http_request_t *r, ngx_http_upstream_t *u, ngx_int_t ft_type) { ngx_uint_t status, state; dd("entering"); ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "http next upstream, %xi", ft_type); #if 0 ngx_http_busy_unlock(u->conf->busy_lock, &u->busy_lock); #endif if (ft_type == NGX_HTTP_UPSTREAM_FT_HTTP_404) { state = NGX_PEER_NEXT; } else { state = NGX_PEER_FAILED; } if (ft_type != NGX_HTTP_UPSTREAM_FT_NOLIVE) { u->peer.free(&u->peer, u->peer.data, state); } if (ft_type == NGX_HTTP_UPSTREAM_FT_TIMEOUT) { ngx_log_error(NGX_LOG_ERR, r->connection->log, NGX_ETIMEDOUT, "upstream timed out"); } if (u->peer.cached && ft_type == NGX_HTTP_UPSTREAM_FT_ERROR) { status = 0; } else { switch(ft_type) { case NGX_HTTP_UPSTREAM_FT_TIMEOUT: status = NGX_HTTP_GATEWAY_TIME_OUT; break; case NGX_HTTP_UPSTREAM_FT_HTTP_500: status = NGX_HTTP_INTERNAL_SERVER_ERROR; break; case NGX_HTTP_UPSTREAM_FT_HTTP_404: status = NGX_HTTP_NOT_FOUND; break; /* * NGX_HTTP_UPSTREAM_FT_BUSY_LOCK and NGX_HTTP_UPSTREAM_FT_MAX_WAITING * never reach here */ default: status = NGX_HTTP_BAD_GATEWAY; } } if (r->connection->error) { ngx_postgres_upstream_finalize_request(r, u, NGX_HTTP_CLIENT_CLOSED_REQUEST); dd("returning"); return; } if (status) { u->state->status = status; if (u->peer.tries == 0 || !(u->conf->next_upstream & ft_type)) { ngx_postgres_upstream_finalize_request(r, u, status); dd("returning"); return; } } if (u->peer.connection) { ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "close http upstream connection: %d", u->peer.connection->fd); #if 0 /* we don't support SSL at this time, was: (NGX_HTTP_SSL) */ if (u->peer.connection->ssl) { u->peer.connection->ssl->no_wait_shutdown = 1; u->peer.connection->ssl->no_send_shutdown = 1; (void) ngx_ssl_shutdown(u->peer.connection); } #endif #if defined(nginx_version) && (nginx_version >= 1001004) if (u->peer.connection->pool) { ngx_destroy_pool(u->peer.connection->pool); } #endif ngx_close_connection(u->peer.connection); } #if 0 if (u->conf->busy_lock && !u->busy_locked) { ngx_http_upstream_busy_lock(p); return; } #endif /* TODO: ngx_http_upstream_connect(r, u); */ if (status == 0) { status = NGX_HTTP_INTERNAL_SERVER_ERROR; } dd("returning"); return ngx_postgres_upstream_finalize_request(r, u, status); }