aboutsummaryrefslogtreecommitdiffstats
path: root/app/nginx/src/http/modules/ngx_http_upstream_keepalive_module.c
diff options
context:
space:
mode:
Diffstat (limited to 'app/nginx/src/http/modules/ngx_http_upstream_keepalive_module.c')
-rw-r--r--app/nginx/src/http/modules/ngx_http_upstream_keepalive_module.c529
1 files changed, 0 insertions, 529 deletions
diff --git a/app/nginx/src/http/modules/ngx_http_upstream_keepalive_module.c b/app/nginx/src/http/modules/ngx_http_upstream_keepalive_module.c
deleted file mode 100644
index 0048e6b..0000000
--- a/app/nginx/src/http/modules/ngx_http_upstream_keepalive_module.c
+++ /dev/null
@@ -1,529 +0,0 @@
-
-/*
- * Copyright (C) Maxim Dounin
- * Copyright (C) Nginx, Inc.
- */
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-#include <ngx_http.h>
-
-
-typedef struct {
- ngx_uint_t max_cached;
-
- ngx_queue_t cache;
- ngx_queue_t free;
-
- ngx_http_upstream_init_pt original_init_upstream;
- ngx_http_upstream_init_peer_pt original_init_peer;
-
-} ngx_http_upstream_keepalive_srv_conf_t;
-
-
-typedef struct {
- ngx_http_upstream_keepalive_srv_conf_t *conf;
-
- ngx_queue_t queue;
- ngx_connection_t *connection;
-
- socklen_t socklen;
- ngx_sockaddr_t sockaddr;
-
-} ngx_http_upstream_keepalive_cache_t;
-
-
-typedef struct {
- ngx_http_upstream_keepalive_srv_conf_t *conf;
-
- ngx_http_upstream_t *upstream;
-
- void *data;
-
- ngx_event_get_peer_pt original_get_peer;
- ngx_event_free_peer_pt original_free_peer;
-
-#if (NGX_HTTP_SSL)
- ngx_event_set_peer_session_pt original_set_session;
- ngx_event_save_peer_session_pt original_save_session;
-#endif
-
-} ngx_http_upstream_keepalive_peer_data_t;
-
-
-static ngx_int_t ngx_http_upstream_init_keepalive_peer(ngx_http_request_t *r,
- ngx_http_upstream_srv_conf_t *us);
-static ngx_int_t ngx_http_upstream_get_keepalive_peer(ngx_peer_connection_t *pc,
- void *data);
-static void ngx_http_upstream_free_keepalive_peer(ngx_peer_connection_t *pc,
- void *data, ngx_uint_t state);
-
-static void ngx_http_upstream_keepalive_dummy_handler(ngx_event_t *ev);
-static void ngx_http_upstream_keepalive_close_handler(ngx_event_t *ev);
-static void ngx_http_upstream_keepalive_close(ngx_connection_t *c);
-
-#if (NGX_HTTP_SSL)
-static ngx_int_t ngx_http_upstream_keepalive_set_session(
- ngx_peer_connection_t *pc, void *data);
-static void ngx_http_upstream_keepalive_save_session(ngx_peer_connection_t *pc,
- void *data);
-#endif
-
-static void *ngx_http_upstream_keepalive_create_conf(ngx_conf_t *cf);
-static char *ngx_http_upstream_keepalive(ngx_conf_t *cf, ngx_command_t *cmd,
- void *conf);
-
-
-static ngx_command_t ngx_http_upstream_keepalive_commands[] = {
-
- { ngx_string("keepalive"),
- NGX_HTTP_UPS_CONF|NGX_CONF_TAKE1,
- ngx_http_upstream_keepalive,
- NGX_HTTP_SRV_CONF_OFFSET,
- 0,
- NULL },
-
- ngx_null_command
-};
-
-
-static ngx_http_module_t ngx_http_upstream_keepalive_module_ctx = {
- NULL, /* preconfiguration */
- NULL, /* postconfiguration */
-
- NULL, /* create main configuration */
- NULL, /* init main configuration */
-
- ngx_http_upstream_keepalive_create_conf, /* create server configuration */
- NULL, /* merge server configuration */
-
- NULL, /* create location configuration */
- NULL /* merge location configuration */
-};
-
-
-ngx_module_t ngx_http_upstream_keepalive_module = {
- NGX_MODULE_V1,
- &ngx_http_upstream_keepalive_module_ctx, /* module context */
- ngx_http_upstream_keepalive_commands, /* module directives */
- NGX_HTTP_MODULE, /* module type */
- NULL, /* init master */
- NULL, /* init module */
- NULL, /* init process */
- NULL, /* init thread */
- NULL, /* exit thread */
- NULL, /* exit process */
- NULL, /* exit master */
- NGX_MODULE_V1_PADDING
-};
-
-
-static ngx_int_t
-ngx_http_upstream_init_keepalive(ngx_conf_t *cf,
- ngx_http_upstream_srv_conf_t *us)
-{
- ngx_uint_t i;
- ngx_http_upstream_keepalive_srv_conf_t *kcf;
- ngx_http_upstream_keepalive_cache_t *cached;
-
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, cf->log, 0,
- "init keepalive");
-
- kcf = ngx_http_conf_upstream_srv_conf(us,
- ngx_http_upstream_keepalive_module);
-
- if (kcf->original_init_upstream(cf, us) != NGX_OK) {
- return NGX_ERROR;
- }
-
- kcf->original_init_peer = us->peer.init;
-
- us->peer.init = ngx_http_upstream_init_keepalive_peer;
-
- /* allocate cache items and add to free queue */
-
- cached = ngx_pcalloc(cf->pool,
- sizeof(ngx_http_upstream_keepalive_cache_t) * kcf->max_cached);
- if (cached == NULL) {
- return NGX_ERROR;
- }
-
- ngx_queue_init(&kcf->cache);
- ngx_queue_init(&kcf->free);
-
- for (i = 0; i < kcf->max_cached; i++) {
- ngx_queue_insert_head(&kcf->free, &cached[i].queue);
- cached[i].conf = kcf;
- }
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_http_upstream_init_keepalive_peer(ngx_http_request_t *r,
- ngx_http_upstream_srv_conf_t *us)
-{
- ngx_http_upstream_keepalive_peer_data_t *kp;
- ngx_http_upstream_keepalive_srv_conf_t *kcf;
-
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "init keepalive peer");
-
- kcf = ngx_http_conf_upstream_srv_conf(us,
- ngx_http_upstream_keepalive_module);
-
- kp = ngx_palloc(r->pool, sizeof(ngx_http_upstream_keepalive_peer_data_t));
- if (kp == NULL) {
- return NGX_ERROR;
- }
-
- if (kcf->original_init_peer(r, us) != NGX_OK) {
- return NGX_ERROR;
- }
-
- kp->conf = kcf;
- kp->upstream = r->upstream;
- kp->data = r->upstream->peer.data;
- kp->original_get_peer = r->upstream->peer.get;
- kp->original_free_peer = r->upstream->peer.free;
-
- r->upstream->peer.data = kp;
- r->upstream->peer.get = ngx_http_upstream_get_keepalive_peer;
- r->upstream->peer.free = ngx_http_upstream_free_keepalive_peer;
-
-#if (NGX_HTTP_SSL)
- kp->original_set_session = r->upstream->peer.set_session;
- kp->original_save_session = r->upstream->peer.save_session;
- r->upstream->peer.set_session = ngx_http_upstream_keepalive_set_session;
- r->upstream->peer.save_session = ngx_http_upstream_keepalive_save_session;
-#endif
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_http_upstream_get_keepalive_peer(ngx_peer_connection_t *pc, void *data)
-{
- ngx_http_upstream_keepalive_peer_data_t *kp = data;
- ngx_http_upstream_keepalive_cache_t *item;
-
- ngx_int_t rc;
- ngx_queue_t *q, *cache;
- ngx_connection_t *c;
-
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, pc->log, 0,
- "get keepalive peer");
-
- /* ask balancer */
-
- rc = kp->original_get_peer(pc, kp->data);
-
- if (rc != NGX_OK) {
- return rc;
- }
-
- /* search cache for suitable connection */
-
- cache = &kp->conf->cache;
-
- for (q = ngx_queue_head(cache);
- q != ngx_queue_sentinel(cache);
- q = ngx_queue_next(q))
- {
- item = ngx_queue_data(q, ngx_http_upstream_keepalive_cache_t, queue);
- c = item->connection;
-
- if (ngx_memn2cmp((u_char *) &item->sockaddr, (u_char *) pc->sockaddr,
- item->socklen, pc->socklen)
- == 0)
- {
- ngx_queue_remove(q);
- ngx_queue_insert_head(&kp->conf->free, q);
-
- goto found;
- }
- }
-
- return NGX_OK;
-
-found:
-
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, pc->log, 0,
- "get keepalive peer: using connection %p", c);
-
- c->idle = 0;
- c->sent = 0;
- c->log = pc->log;
- c->read->log = pc->log;
- c->write->log = pc->log;
- c->pool->log = pc->log;
-
- pc->connection = c;
- pc->cached = 1;
-
- return NGX_DONE;
-}
-
-
-static void
-ngx_http_upstream_free_keepalive_peer(ngx_peer_connection_t *pc, void *data,
- ngx_uint_t state)
-{
- ngx_http_upstream_keepalive_peer_data_t *kp = data;
- ngx_http_upstream_keepalive_cache_t *item;
-
- ngx_queue_t *q;
- ngx_connection_t *c;
- ngx_http_upstream_t *u;
-
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, pc->log, 0,
- "free keepalive peer");
-
- /* cache valid connections */
-
- u = kp->upstream;
- c = pc->connection;
-
- if (state & NGX_PEER_FAILED
- || c == NULL
- || c->read->eof
- || c->read->error
- || c->read->timedout
- || c->write->error
- || c->write->timedout)
- {
- goto invalid;
- }
-
- if (!u->keepalive) {
- goto invalid;
- }
-
- if (!u->request_body_sent) {
- goto invalid;
- }
-
- if (ngx_terminate || ngx_exiting) {
- goto invalid;
- }
-
- if (ngx_handle_read_event(c->read, 0) != NGX_OK) {
- goto invalid;
- }
-
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, pc->log, 0,
- "free keepalive peer: saving connection %p", c);
-
- if (ngx_queue_empty(&kp->conf->free)) {
-
- q = ngx_queue_last(&kp->conf->cache);
- ngx_queue_remove(q);
-
- item = ngx_queue_data(q, ngx_http_upstream_keepalive_cache_t, queue);
-
- ngx_http_upstream_keepalive_close(item->connection);
-
- } else {
- q = ngx_queue_head(&kp->conf->free);
- ngx_queue_remove(q);
-
- item = ngx_queue_data(q, ngx_http_upstream_keepalive_cache_t, queue);
- }
-
- ngx_queue_insert_head(&kp->conf->cache, q);
-
- item->connection = c;
-
- pc->connection = NULL;
-
- if (c->read->timer_set) {
- ngx_del_timer(c->read);
- }
- if (c->write->timer_set) {
- ngx_del_timer(c->write);
- }
-
- c->write->handler = ngx_http_upstream_keepalive_dummy_handler;
- c->read->handler = ngx_http_upstream_keepalive_close_handler;
-
- c->data = item;
- c->idle = 1;
- c->log = ngx_cycle->log;
- c->read->log = ngx_cycle->log;
- c->write->log = ngx_cycle->log;
- c->pool->log = ngx_cycle->log;
-
- item->socklen = pc->socklen;
- ngx_memcpy(&item->sockaddr, pc->sockaddr, pc->socklen);
-
- if (c->read->ready) {
- ngx_http_upstream_keepalive_close_handler(c->read);
- }
-
-invalid:
-
- kp->original_free_peer(pc, kp->data, state);
-}
-
-
-static void
-ngx_http_upstream_keepalive_dummy_handler(ngx_event_t *ev)
-{
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, ev->log, 0,
- "keepalive dummy handler");
-}
-
-
-static void
-ngx_http_upstream_keepalive_close_handler(ngx_event_t *ev)
-{
- ngx_http_upstream_keepalive_srv_conf_t *conf;
- ngx_http_upstream_keepalive_cache_t *item;
-
- int n;
- char buf[1];
- ngx_connection_t *c;
-
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, ev->log, 0,
- "keepalive close handler");
-
- c = ev->data;
-
- if (c->close) {
- goto close;
- }
-
- n = recv(c->fd, buf, 1, MSG_PEEK);
-
- if (n == -1 && ngx_socket_errno == NGX_EAGAIN) {
- ev->ready = 0;
-
- if (ngx_handle_read_event(c->read, 0) != NGX_OK) {
- goto close;
- }
-
- return;
- }
-
-close:
-
- item = c->data;
- conf = item->conf;
-
- ngx_http_upstream_keepalive_close(c);
-
- ngx_queue_remove(&item->queue);
- ngx_queue_insert_head(&conf->free, &item->queue);
-}
-
-
-static void
-ngx_http_upstream_keepalive_close(ngx_connection_t *c)
-{
-
-#if (NGX_HTTP_SSL)
-
- if (c->ssl) {
- c->ssl->no_wait_shutdown = 1;
- c->ssl->no_send_shutdown = 1;
-
- if (ngx_ssl_shutdown(c) == NGX_AGAIN) {
- c->ssl->handler = ngx_http_upstream_keepalive_close;
- return;
- }
- }
-
-#endif
-
- ngx_destroy_pool(c->pool);
- ngx_close_connection(c);
-}
-
-
-#if (NGX_HTTP_SSL)
-
-static ngx_int_t
-ngx_http_upstream_keepalive_set_session(ngx_peer_connection_t *pc, void *data)
-{
- ngx_http_upstream_keepalive_peer_data_t *kp = data;
-
- return kp->original_set_session(pc, kp->data);
-}
-
-
-static void
-ngx_http_upstream_keepalive_save_session(ngx_peer_connection_t *pc, void *data)
-{
- ngx_http_upstream_keepalive_peer_data_t *kp = data;
-
- kp->original_save_session(pc, kp->data);
- return;
-}
-
-#endif
-
-
-static void *
-ngx_http_upstream_keepalive_create_conf(ngx_conf_t *cf)
-{
- ngx_http_upstream_keepalive_srv_conf_t *conf;
-
- conf = ngx_pcalloc(cf->pool,
- sizeof(ngx_http_upstream_keepalive_srv_conf_t));
- if (conf == NULL) {
- return NULL;
- }
-
- /*
- * set by ngx_pcalloc():
- *
- * conf->original_init_upstream = NULL;
- * conf->original_init_peer = NULL;
- * conf->max_cached = 0;
- */
-
- return conf;
-}
-
-
-static char *
-ngx_http_upstream_keepalive(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
-{
- ngx_http_upstream_srv_conf_t *uscf;
- ngx_http_upstream_keepalive_srv_conf_t *kcf = conf;
-
- ngx_int_t n;
- ngx_str_t *value;
-
- if (kcf->max_cached) {
- return "is duplicate";
- }
-
- /* read options */
-
- value = cf->args->elts;
-
- n = ngx_atoi(value[1].data, value[1].len);
-
- if (n == NGX_ERROR || n == 0) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "invalid value \"%V\" in \"%V\" directive",
- &value[1], &cmd->name);
- return NGX_CONF_ERROR;
- }
-
- kcf->max_cached = n;
-
- uscf = ngx_http_conf_get_module_srv_conf(cf, ngx_http_upstream_module);
-
- kcf->original_init_upstream = uscf->peer.init_upstream
- ? uscf->peer.init_upstream
- : ngx_http_upstream_init_round_robin;
-
- uscf->peer.init_upstream = ngx_http_upstream_init_keepalive;
-
- return NGX_CONF_OK;
-}