diff --git a/config b/config index 044deb974e..44554a5da4 100644 --- a/config +++ b/config @@ -361,6 +361,8 @@ HTTP_LUA_SRCS=" \ $ngx_addon_dir/src/ngx_http_lua_ssl_session_fetchby.c \ $ngx_addon_dir/src/ngx_http_lua_ssl.c \ $ngx_addon_dir/src/ngx_http_lua_log_ringbuf.c \ + $ngx_addon_dir/src/ngx_http_lua_balancer_ssl_session_fetchby.c \ + $ngx_addon_dir/src/ngx_http_lua_balancer_ssl_session_storeby.c \ " HTTP_LUA_DEPS=" \ @@ -422,6 +424,8 @@ HTTP_LUA_DEPS=" \ $ngx_addon_dir/src/ngx_http_lua_ssl_session_fetchby.h \ $ngx_addon_dir/src/ngx_http_lua_ssl.h \ $ngx_addon_dir/src/ngx_http_lua_log_ringbuf.h \ + $ngx_addon_dir/src/ngx_http_lua_balancer_ssl_session_fetchby.h \ + $ngx_addon_dir/src/ngx_http_lua_balancer_ssl_session_storeby.h \ " CFLAGS="$CFLAGS -DNDK_SET_VAR" diff --git a/src/ngx_http_lua_balancer.c b/src/ngx_http_lua_balancer.c index fdf2af31a7..940d642674 100644 --- a/src/ngx_http_lua_balancer.c +++ b/src/ngx_http_lua_balancer.c @@ -14,30 +14,8 @@ #include "ngx_http_lua_balancer.h" #include "ngx_http_lua_util.h" #include "ngx_http_lua_directive.h" - - -struct ngx_http_lua_balancer_peer_data_s { - /* the round robin data must be first */ - ngx_http_upstream_rr_peer_data_t rrp; - - ngx_http_lua_srv_conf_t *conf; - ngx_http_request_t *request; - - ngx_uint_t more_tries; - ngx_uint_t total_tries; - - struct sockaddr *sockaddr; - socklen_t socklen; - - ngx_str_t *host; - in_port_t port; - - int last_peer_state; - -#if !(HAVE_NGX_UPSTREAM_TIMEOUT_FIELDS) - unsigned cloned_upstream_conf; /* :1 */ -#endif -}; +#include "ngx_http_lua_balancer_ssl_session_storeby.h" +#include "ngx_http_lua_balancer_ssl_session_fetchby.h" #if (NGX_HTTP_SSL) @@ -438,8 +416,11 @@ ngx_http_lua_balancer_set_session(ngx_peer_connection_t *pc, void *data) ngx_http_lua_balancer_peer_data_t *bp = data; if (bp->sockaddr && bp->socklen) { - /* TODO */ - return NGX_OK; + if (bp->conf->balancer.ssl_sess_fetch_handler) { + return ngx_http_lua_balancer_ssl_sess_fetch(pc, data); + } else { + return NGX_OK; + } } return ngx_http_upstream_set_round_robin_peer_session(pc, &bp->rrp); @@ -452,7 +433,10 @@ ngx_http_lua_balancer_save_session(ngx_peer_connection_t *pc, void *data) ngx_http_lua_balancer_peer_data_t *bp = data; if (bp->sockaddr && bp->socklen) { - /* TODO */ + if (bp->conf->balancer.ssl_sess_store_handler) { + ngx_http_lua_balancer_ssl_sess_store(pc, data); + } + return; } diff --git a/src/ngx_http_lua_balancer.h b/src/ngx_http_lua_balancer.h index bb49dc02ca..532f9548fd 100644 --- a/src/ngx_http_lua_balancer.h +++ b/src/ngx_http_lua_balancer.h @@ -10,6 +10,28 @@ #include "ngx_http_lua_common.h" +struct ngx_http_lua_balancer_peer_data_s { + /* the round robin data must be first */ + ngx_http_upstream_rr_peer_data_t rrp; + + ngx_http_lua_srv_conf_t *conf; + ngx_http_request_t *request; + + ngx_uint_t more_tries; + ngx_uint_t total_tries; + + struct sockaddr *sockaddr; + socklen_t socklen; + + ngx_str_t *host; + in_port_t port; + + int last_peer_state; + +#if !(HAVE_NGX_UPSTREAM_TIMEOUT_FIELDS) + unsigned cloned_upstream_conf; /* :1 */ +#endif +}; ngx_int_t ngx_http_lua_balancer_handler_inline(ngx_http_request_t *r, ngx_http_lua_srv_conf_t *lscf, lua_State *L); diff --git a/src/ngx_http_lua_balancer_ssl_session_fetchby.c b/src/ngx_http_lua_balancer_ssl_session_fetchby.c new file mode 100644 index 0000000000..32ac115322 --- /dev/null +++ b/src/ngx_http_lua_balancer_ssl_session_fetchby.c @@ -0,0 +1,272 @@ + +/* + * Copyright (C) Chenglong Zhang (kone) + */ + + +#ifndef DDEBUG +#define DDEBUG 0 +#endif +#include "ddebug.h" + +#include "ngx_http_lua_balancer_ssl_session_fetchby.h" +#include "ngx_http_lua_cache.h" +#include "ngx_http_lua_util.h" +#include "ngx_http_lua_directive.h" +#include "ngx_http_lua_balancer.h" + + +#if (NGX_HTTP_SSL) +static ngx_int_t ngx_http_lua_balancer_ssl_sess_fetch_by_chunk(lua_State *L, + ngx_http_request_t *r); + + +ngx_int_t +ngx_http_lua_balancer_ssl_sess_fetch_handler_file(ngx_http_request_t *r, + ngx_http_lua_srv_conf_t *lscf, lua_State *L) +{ + ngx_int_t rc; + + rc = ngx_http_lua_cache_loadfile(r->connection->log, L, + lscf->balancer.ssl_sess_fetch_src.data, + lscf->balancer.ssl_sess_fetch_src_key); + if (rc != NGX_OK) { + return rc; + } + + /* make sure we have a valid code chunk */ + ngx_http_lua_assert(lua_isfunction(L, -1)); + + return ngx_http_lua_balancer_ssl_sess_fetch_by_chunk(L, r); +} + + +ngx_int_t +ngx_http_lua_balancer_ssl_sess_fetch_handler_inline(ngx_http_request_t *r, + ngx_http_lua_srv_conf_t *lscf, lua_State *L) +{ + ngx_int_t rc; + + rc = ngx_http_lua_cache_loadbuffer(r->connection->log, L, + lscf->balancer.ssl_sess_fetch_src.data, + lscf->balancer.ssl_sess_fetch_src.len, + lscf->balancer.ssl_sess_fetch_src_key, + "=balancer_ssl_session_fetch_by_lua"); + if (rc != NGX_OK) { + return rc; + } + + /* make sure we have a valid code chunk */ + ngx_http_lua_assert(lua_isfunction(L, -1)); + + return ngx_http_lua_balancer_ssl_sess_fetch_by_chunk(L, r); +} + + +ngx_int_t +ngx_http_lua_balancer_ssl_sess_fetch(ngx_peer_connection_t *pc, void *data) +{ + lua_State *L; + ngx_int_t rc; + ngx_http_request_t *r; + ngx_http_lua_ctx_t *ctx; + ngx_http_lua_srv_conf_t *lscf; + ngx_http_lua_balancer_peer_data_t *bp = data; + + ngx_log_debug0(NGX_LOG_DEBUG_HTTP, pc->log, 0, + "balancer ssl session fetch"); + + lscf = bp->conf; + + r = bp->request; + + ngx_http_lua_assert(lscf->balancer.ssl_sess_fetch_handler && r); + + ctx = ngx_http_get_module_ctx(r, ngx_http_lua_module); + + if (ctx == NULL) { + ctx = ngx_http_lua_create_ctx(r); + if (ctx == NULL) { + return NGX_ERROR; + } + + L = ngx_http_lua_get_lua_vm(r, ctx); + + } else { + L = ngx_http_lua_get_lua_vm(r, ctx); + + dd("reset ctx"); + ngx_http_lua_reset_ctx(r, L, ctx); + } + + ctx->context = NGX_HTTP_LUA_CONTEXT_BALANCER_SSL_SESS_FETCH; + + rc = lscf->balancer.ssl_sess_fetch_handler(r, lscf, L); + + if (rc == NGX_ERROR) { + return NGX_ERROR; + } + + if (ctx->exited && ctx->exit_code != NGX_OK) { + rc = ctx->exit_code; + if (rc == NGX_ERROR + || rc == NGX_BUSY + || rc == NGX_DECLINED +#ifdef HAVE_BALANCER_STATUS_CODE_PATCH + || rc >= NGX_HTTP_SPECIAL_RESPONSE +#endif + ) { + return rc; + } + + if (rc > NGX_OK) { + return NGX_ERROR; + } + } + + return NGX_OK; +} + + +char * +ngx_http_lua_balancer_ssl_sess_fetch_by_lua_block(ngx_conf_t *cf, + ngx_command_t *cmd, void *conf) +{ + char *rv; + ngx_conf_t save; + + save = *cf; + cf->handler = ngx_http_lua_balancer_ssl_sess_fetch_by_lua; + cf->handler_conf = conf; + + rv = ngx_http_lua_conf_lua_block_parse(cf, cmd); + + *cf = save; + + return rv; +} + + +char * +ngx_http_lua_balancer_ssl_sess_fetch_by_lua(ngx_conf_t *cf, ngx_command_t *cmd, + void *conf) +{ + u_char *p; + u_char *name; + ngx_str_t *value; + ngx_http_lua_srv_conf_t *lscf = conf; + + dd("enter"); + + /* must specify a content handler */ + if (cmd->post == NULL) { + return NGX_CONF_ERROR; + } + + if(lscf->balancer.ssl_sess_fetch_handler) { + return "is duplicate"; + } + + value = cf->args->elts; + + lscf->balancer.ssl_sess_fetch_handler = + (ngx_http_lua_srv_conf_handler_pt) cmd->post; + + if (cmd->post == ngx_http_lua_balancer_ssl_sess_fetch_handler_file) { + /* Lua code in an external file */ + + name = ngx_http_lua_rebase_path(cf->pool, value[1].data, + value[1].len); + if (name == NULL) { + return NGX_CONF_ERROR; + } + + lscf->balancer.ssl_sess_fetch_src.data = name; + lscf->balancer.ssl_sess_fetch_src.len = ngx_strlen(name); + + p = ngx_palloc(cf->pool, NGX_HTTP_LUA_FILE_KEY_LEN + 1); + if (p == NULL) { + return NGX_CONF_ERROR; + } + + lscf->balancer.ssl_sess_fetch_src_key = p; + + p = ngx_copy(p, NGX_HTTP_LUA_FILE_TAG, NGX_HTTP_LUA_FILE_TAG_LEN); + p = ngx_http_lua_digest_hex(p, value[1].data, value[1].len); + *p = '\0'; + + } else { + /* inlined Lua code */ + + lscf->balancer.ssl_sess_fetch_src = value[1]; + + p = ngx_palloc(cf->pool, NGX_HTTP_LUA_INLINE_KEY_LEN + 1); + if (p == NULL) { + return NGX_CONF_ERROR; + } + + lscf->balancer.ssl_sess_fetch_src_key = p; + + p = ngx_copy(p, NGX_HTTP_LUA_INLINE_TAG, NGX_HTTP_LUA_INLINE_TAG_LEN); + p = ngx_http_lua_digest_hex(p, value[1].data, value[1].len); + *p = '\0'; + } + + return NGX_CONF_OK; +} + + +static ngx_int_t +ngx_http_lua_balancer_ssl_sess_fetch_by_chunk(lua_State *L, + ngx_http_request_t *r) +{ + u_char *err_msg; + size_t len; + ngx_int_t rc; + + /* init nginx context in Lua VM */ + ngx_http_lua_set_req(L, r); + ngx_http_lua_create_new_globals_table(L, 0 /* narr */, 1 /* nrec */); + + /* {{{ make new env inheriting main thread's globals table */ + lua_createtable(L, 0, 1 /* nrec */); /* the metatable for the new env */ + ngx_http_lua_get_globals_table(L); + lua_setfield(L, -2, "__index"); + lua_setmetatable(L, -2); /* setmetatable({}, {__index = _G}) */ + /* }}} */ + + lua_setfenv(L, -2); /* set new running env for the code closure */ + + lua_pushcfunction(L, ngx_http_lua_traceback); + lua_insert(L, 1); /* put it under chunk and args */ + + /* protected call user code */ + rc = lua_pcall(L, 0, 1, 1); + + lua_remove(L, 1); /* remove traceback function */ + + dd("rc == %d", (int) rc); + + if (rc != 0) { + /* error occurred when running loaded code */ + err_msg = (u_char *) lua_tolstring(L, -1, &len); + + if (err_msg == NULL) { + err_msg = (u_char *) "unknown reason"; + len = sizeof("unknown reason") - 1; + } + + ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, + "failed to run balancer_ssl_session_fetch_by_lua*: %*s", + len, err_msg); + + lua_settop(L, 0); /* clear remaining elems on stack */ + + return NGX_ERROR; + } + + lua_settop(L, 0); /* clear remaining elems on stack */ + return rc; +} + +#endif /* NGX_HTTP_SSL */ diff --git a/src/ngx_http_lua_balancer_ssl_session_fetchby.h b/src/ngx_http_lua_balancer_ssl_session_fetchby.h new file mode 100644 index 0000000000..9ebbe97483 --- /dev/null +++ b/src/ngx_http_lua_balancer_ssl_session_fetchby.h @@ -0,0 +1,28 @@ + +/* + * Copyright (C) Chenglong Zhang (kone) + */ + + +#ifndef _NGX_HTTP_LUA_BALANCER_SSL_SESSION_FETCHBY_H_INCLUDED_ +#define _NGX_HTTP_LUA_BALANCER_SSL_SESSION_FETCHBY_H_INCLUDED_ + + +#include "ngx_http_lua_common.h" + +ngx_int_t ngx_http_lua_balancer_ssl_sess_fetch(ngx_peer_connection_t *pc, + void *data); + +ngx_int_t ngx_http_lua_balancer_ssl_sess_fetch_handler_inline( + ngx_http_request_t *r, ngx_http_lua_srv_conf_t *lscf, lua_State *L); + +ngx_int_t ngx_http_lua_balancer_ssl_sess_fetch_handler_file( + ngx_http_request_t *r, ngx_http_lua_srv_conf_t *lscf, lua_State *L); + +char *ngx_http_lua_balancer_ssl_sess_fetch_by_lua(ngx_conf_t *cf, + ngx_command_t *cmd, void *conf); + +char *ngx_http_lua_balancer_ssl_sess_fetch_by_lua_block(ngx_conf_t *cf, + ngx_command_t *cmd, void *conf); + +#endif /* _NGX_HTTP_LUA_BALANCER_SSL_SESSION_FETCHBY_H_INCLUDED_ */ diff --git a/src/ngx_http_lua_balancer_ssl_session_storeby.c b/src/ngx_http_lua_balancer_ssl_session_storeby.c new file mode 100644 index 0000000000..a78c3f4dc3 --- /dev/null +++ b/src/ngx_http_lua_balancer_ssl_session_storeby.c @@ -0,0 +1,316 @@ + +/* + * Copyright (C) Chenglong Zhang (kone) + */ + + +#ifndef DDEBUG +#define DDEBUG 0 +#endif +#include "ddebug.h" + +#include "ngx_http_lua_balancer_ssl_session_storeby.h" +#include "ngx_http_lua_cache.h" +#include "ngx_http_lua_util.h" +#include "ngx_http_lua_directive.h" +#include "ngx_http_lua_balancer.h" + + +#if (NGX_HTTP_SSL) +static ngx_int_t ngx_http_lua_balancer_ssl_sess_store_by_chunk(lua_State *L, + ngx_http_request_t *r); + + +ngx_int_t +ngx_http_lua_balancer_ssl_sess_store_handler_file(ngx_http_request_t *r, + ngx_http_lua_srv_conf_t *lscf, lua_State *L) +{ + ngx_int_t rc; + + rc = ngx_http_lua_cache_loadfile(r->connection->log, L, + lscf->balancer.ssl_sess_store_src.data, + lscf->balancer.ssl_sess_store_src_key); + if (rc != NGX_OK) { + return rc; + } + + /* make sure we have a valid code chunk */ + ngx_http_lua_assert(lua_isfunction(L, -1)); + + return ngx_http_lua_balancer_ssl_sess_store_by_chunk(L, r); +} + + +ngx_int_t +ngx_http_lua_balancer_ssl_sess_store_handler_inline(ngx_http_request_t *r, + ngx_http_lua_srv_conf_t *lscf, lua_State *L) +{ + ngx_int_t rc; + + rc = ngx_http_lua_cache_loadbuffer(r->connection->log, L, + lscf->balancer.ssl_sess_store_src.data, + lscf->balancer.ssl_sess_store_src.len, + lscf->balancer.ssl_sess_store_src_key, + "=balancer_ssl_session_store_by_lua"); + + if (rc != NGX_OK) { + return rc; + } + + /* make sure we have a valid code chunk */ + ngx_http_lua_assert(lua_isfunction(L, -1)); + + return ngx_http_lua_balancer_ssl_sess_store_by_chunk(L, r); +} + + +void +ngx_http_lua_balancer_ssl_sess_store(ngx_peer_connection_t *pc, void *data) +{ + lua_State *L; + ngx_int_t rc; + ngx_http_request_t *r; + ngx_http_lua_ctx_t *ctx; + ngx_http_lua_srv_conf_t *lscf; + ngx_http_lua_balancer_peer_data_t *bp = data; + + ngx_log_debug0(NGX_LOG_DEBUG_HTTP, pc->log, 0, + "balancer ssl session store"); + + lscf = bp->conf; + + r = bp->request; + + ngx_http_lua_assert(lscf->balancer.ssl_sess_store_handler && r); + + ctx = ngx_http_get_module_ctx(r, ngx_http_lua_module); + + if (ctx == NULL) { + ctx = ngx_http_lua_create_ctx(r); + if (ctx == NULL) { + return; + } + + L = ngx_http_lua_get_lua_vm(r, ctx); + + } else { + L = ngx_http_lua_get_lua_vm(r, ctx); + + dd("reset ctx"); + ngx_http_lua_reset_ctx(r, L, ctx); + } + + ctx->context = NGX_HTTP_LUA_CONTEXT_BALANCER_SSL_SESS_STORE; + + rc = lscf->balancer.ssl_sess_store_handler(r, lscf, L); + + if (rc == NGX_ERROR) { + return; + } + + if (ctx->exited && ctx->exit_code != NGX_OK) { + rc = ctx->exit_code; + if (rc == NGX_ERROR + || rc == NGX_BUSY + || rc == NGX_DECLINED +#ifdef HAVE_BALANCER_STATUS_CODE_PATCH + || rc >= NGX_HTTP_SPECIAL_RESPONSE +#endif + ) { + return; + } + + if (rc > NGX_OK) { + return; + } + } + + return; +} + + +char * +ngx_http_lua_balancer_ssl_sess_store_by_lua_block(ngx_conf_t *cf, + ngx_command_t *cmd, void *conf) +{ + char *rv; + ngx_conf_t save; + + save = *cf; + cf->handler = ngx_http_lua_balancer_ssl_sess_store_by_lua; + cf->handler_conf = conf; + + rv = ngx_http_lua_conf_lua_block_parse(cf, cmd); + + *cf = save; + + return rv; +} + + +char * +ngx_http_lua_balancer_ssl_sess_store_by_lua(ngx_conf_t *cf, ngx_command_t *cmd, + void *conf) +{ + u_char *p; + u_char *name; + ngx_str_t *value; + ngx_http_lua_srv_conf_t *lscf = conf; + + dd("enter"); + + /* must specify a content handler */ + if (cmd->post == NULL) { + return NGX_CONF_ERROR; + } + + if(lscf->balancer.ssl_sess_store_handler) { + return "is duplicate"; + } + + value = cf->args->elts; + + lscf->balancer.ssl_sess_store_handler = + (ngx_http_lua_srv_conf_handler_pt) cmd->post; + + if (cmd->post == ngx_http_lua_balancer_ssl_sess_store_handler_file) { + /* Lua code in an external file */ + + name = ngx_http_lua_rebase_path(cf->pool, value[1].data, + value[1].len); + if (name == NULL) { + return NGX_CONF_ERROR; + } + + lscf->balancer.ssl_sess_store_src.data = name; + lscf->balancer.ssl_sess_store_src.len = ngx_strlen(name); + + p = ngx_palloc(cf->pool, NGX_HTTP_LUA_FILE_KEY_LEN + 1); + if (p == NULL) { + return NGX_CONF_ERROR; + } + + lscf->balancer.ssl_sess_store_src_key = p; + + p = ngx_copy(p, NGX_HTTP_LUA_FILE_TAG, NGX_HTTP_LUA_FILE_TAG_LEN); + p = ngx_http_lua_digest_hex(p, value[1].data, value[1].len); + *p = '\0'; + + } else { + /* inlined Lua code */ + + lscf->balancer.ssl_sess_store_src = value[1]; + + p = ngx_palloc(cf->pool, NGX_HTTP_LUA_INLINE_KEY_LEN + 1); + if (p == NULL) { + return NGX_CONF_ERROR; + } + + lscf->balancer.ssl_sess_store_src_key = p; + + p = ngx_copy(p, NGX_HTTP_LUA_INLINE_TAG, NGX_HTTP_LUA_INLINE_TAG_LEN); + p = ngx_http_lua_digest_hex(p, value[1].data, value[1].len); + *p = '\0'; + } + + return NGX_CONF_OK; +} + + +static ngx_int_t +ngx_http_lua_balancer_ssl_sess_store_by_chunk(lua_State *L, + ngx_http_request_t *r) +{ + u_char *err_msg; + size_t len; + ngx_int_t rc; + + /* init nginx context in Lua VM */ + ngx_http_lua_set_req(L, r); + ngx_http_lua_create_new_globals_table(L, 0 /* narr */, 1 /* nrec */); + + /* {{{ make new env inheriting main thread's globals table */ + lua_createtable(L, 0, 1 /* nrec */); /* the metatable for the new env */ + ngx_http_lua_get_globals_table(L); + lua_setfield(L, -2, "__index"); + lua_setmetatable(L, -2); /* setmetatable({}, {__index = _G}) */ + /* }}} */ + + lua_setfenv(L, -2); /* set new running env for the code closure */ + + lua_pushcfunction(L, ngx_http_lua_traceback); + lua_insert(L, 1); /* put it under chunk and args */ + + /* protected call user code */ + rc = lua_pcall(L, 0, 1, 1); + + lua_remove(L, 1); /* remove traceback function */ + + dd("rc == %d", (int) rc); + + if (rc != 0) { + /* error occurred when running loaded code */ + err_msg = (u_char *) lua_tolstring(L, -1, &len); + + if (err_msg == NULL) { + err_msg = (u_char *) "unknown reason"; + len = sizeof("unknown reason") - 1; + } + + ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, + "failed to run balancer_ssl_session_store_by_lua*: %*s", + len, err_msg); + + lua_settop(L, 0); /* clear remaining elems on stack */ + + return NGX_ERROR; + } + + lua_settop(L, 0); /* clear remaining elems on stack */ + return rc; +} + + +void +ngx_http_lua_ffi_ssl_free_session(void *session) +{ + ngx_ssl_free_session(session); +} + + +int +ngx_http_lua_ffi_ssl_set_upstream_session(ngx_http_request_t *r, void *session, + char **err) +{ + if (r->upstream == NULL + || r->upstream->peer.connection == NULL + || r->upstream->peer.connection->ssl == NULL) { + *err = "bad request"; + return NGX_ERROR; + } + + return ngx_ssl_set_session(r->upstream->peer.connection, session); +} + + +int +ngx_http_lua_ffi_ssl_get_upstream_session(ngx_http_request_t *r, + void **session, char **err) +{ + ngx_ssl_session_t *ssl_session; + + if (r->upstream == NULL + || r->upstream->peer.connection == NULL + || r->upstream->peer.connection->ssl == NULL) { + *err = "bad request"; + return NGX_ERROR; + } + + ssl_session = ngx_ssl_get_session(r->upstream->peer.connection); + + *session = ssl_session; + + return NGX_OK; +} + +#endif /* NGX_HTTP_SSL */ diff --git a/src/ngx_http_lua_balancer_ssl_session_storeby.h b/src/ngx_http_lua_balancer_ssl_session_storeby.h new file mode 100644 index 0000000000..9ad3ed7e87 --- /dev/null +++ b/src/ngx_http_lua_balancer_ssl_session_storeby.h @@ -0,0 +1,28 @@ + +/* + * Copyright (C) Chenglong Zhang (kone) + */ + + +#ifndef _NGX_HTTP_LUA_BALANCER_SSL_SESSION_STOREBY_H_INCLUDED_ +#define _NGX_HTTP_LUA_BALANCER_SSL_SESSION_STOREBY_H_INCLUDED_ + + +#include "ngx_http_lua_common.h" + +void ngx_http_lua_balancer_ssl_sess_store(ngx_peer_connection_t *pc, + void *data); + +ngx_int_t ngx_http_lua_balancer_ssl_sess_store_handler_inline( + ngx_http_request_t *r, ngx_http_lua_srv_conf_t *lscf, lua_State *L); + +ngx_int_t ngx_http_lua_balancer_ssl_sess_store_handler_file( + ngx_http_request_t *r, ngx_http_lua_srv_conf_t *lscf, lua_State *L); + +char *ngx_http_lua_balancer_ssl_sess_store_by_lua(ngx_conf_t *cf, + ngx_command_t *cmd, void *conf); + +char *ngx_http_lua_balancer_ssl_sess_store_by_lua_block(ngx_conf_t *cf, + ngx_command_t *cmd, void *conf); + +#endif /* _NGX_HTTP_LUA_BALANCER_SSL_SESSION_STOREBY_H_INCLUDED_ */ diff --git a/src/ngx_http_lua_common.h b/src/ngx_http_lua_common.h index 01ef2bec8b..a6cca95c2d 100644 --- a/src/ngx_http_lua_common.h +++ b/src/ngx_http_lua_common.h @@ -119,20 +119,21 @@ typedef struct { /* must be within 16 bit */ -#define NGX_HTTP_LUA_CONTEXT_SET 0x0001 -#define NGX_HTTP_LUA_CONTEXT_REWRITE 0x0002 -#define NGX_HTTP_LUA_CONTEXT_ACCESS 0x0004 -#define NGX_HTTP_LUA_CONTEXT_CONTENT 0x0008 -#define NGX_HTTP_LUA_CONTEXT_LOG 0x0010 -#define NGX_HTTP_LUA_CONTEXT_HEADER_FILTER 0x0020 -#define NGX_HTTP_LUA_CONTEXT_BODY_FILTER 0x0040 -#define NGX_HTTP_LUA_CONTEXT_TIMER 0x0080 -#define NGX_HTTP_LUA_CONTEXT_INIT_WORKER 0x0100 -#define NGX_HTTP_LUA_CONTEXT_BALANCER 0x0200 -#define NGX_HTTP_LUA_CONTEXT_SSL_CERT 0x0400 -#define NGX_HTTP_LUA_CONTEXT_SSL_SESS_STORE 0x0800 -#define NGX_HTTP_LUA_CONTEXT_SSL_SESS_FETCH 0x1000 - +#define NGX_HTTP_LUA_CONTEXT_SET 0x0001 +#define NGX_HTTP_LUA_CONTEXT_REWRITE 0x0002 +#define NGX_HTTP_LUA_CONTEXT_ACCESS 0x0004 +#define NGX_HTTP_LUA_CONTEXT_CONTENT 0x0008 +#define NGX_HTTP_LUA_CONTEXT_LOG 0x0010 +#define NGX_HTTP_LUA_CONTEXT_HEADER_FILTER 0x0020 +#define NGX_HTTP_LUA_CONTEXT_BODY_FILTER 0x0040 +#define NGX_HTTP_LUA_CONTEXT_TIMER 0x0080 +#define NGX_HTTP_LUA_CONTEXT_INIT_WORKER 0x0100 +#define NGX_HTTP_LUA_CONTEXT_BALANCER 0x0200 +#define NGX_HTTP_LUA_CONTEXT_SSL_CERT 0x0400 +#define NGX_HTTP_LUA_CONTEXT_SSL_SESS_STORE 0x0800 +#define NGX_HTTP_LUA_CONTEXT_SSL_SESS_FETCH 0x1000 +#define NGX_HTTP_LUA_CONTEXT_BALANCER_SSL_SESS_STORE 0x2000 +#define NGX_HTTP_LUA_CONTEXT_BALANCER_SSL_SESS_FETCH 0x4000 #ifndef NGX_LUA_NO_FFI_API #define NGX_HTTP_LUA_FFI_NO_REQ_CTX -100 @@ -260,6 +261,14 @@ union ngx_http_lua_srv_conf_u { u_char *src_key; ngx_http_lua_srv_conf_handler_pt handler; + + ngx_http_lua_srv_conf_handler_pt ssl_sess_store_handler; + ngx_str_t ssl_sess_store_src; + u_char *ssl_sess_store_src_key; + + ngx_http_lua_srv_conf_handler_pt ssl_sess_fetch_handler; + ngx_str_t ssl_sess_fetch_src; + u_char *ssl_sess_fetch_src_key; } balancer; }; diff --git a/src/ngx_http_lua_module.c b/src/ngx_http_lua_module.c index ae8bc0e36f..b54f4e1ce1 100644 --- a/src/ngx_http_lua_module.c +++ b/src/ngx_http_lua_module.c @@ -29,6 +29,8 @@ #include "ngx_http_lua_ssl_session_storeby.h" #include "ngx_http_lua_ssl_session_fetchby.h" #include "ngx_http_lua_headers.h" +#include "ngx_http_lua_balancer_ssl_session_storeby.h" +#include "ngx_http_lua_balancer_ssl_session_fetchby.h" static void *ngx_http_lua_create_main_conf(ngx_conf_t *cf); @@ -581,6 +583,34 @@ static ngx_command_t ngx_http_lua_cmds[] = { offsetof(ngx_http_lua_loc_conf_t, ssl_crl), NULL }, + { ngx_string("balancer_ssl_session_fetch_by_lua_block"), + NGX_HTTP_UPS_CONF|NGX_CONF_BLOCK|NGX_CONF_NOARGS, + ngx_http_lua_balancer_ssl_sess_fetch_by_lua_block, + NGX_HTTP_SRV_CONF_OFFSET, + 0, + (void *) ngx_http_lua_balancer_ssl_sess_fetch_handler_inline }, + + { ngx_string("balancer_ssl_session_fetch_by_lua_file"), + NGX_HTTP_UPS_CONF|NGX_CONF_TAKE1, + ngx_http_lua_balancer_ssl_sess_fetch_by_lua, + NGX_HTTP_SRV_CONF_OFFSET, + 0, + (void *) ngx_http_lua_balancer_ssl_sess_fetch_handler_file }, + + { ngx_string("balancer_ssl_session_store_by_lua_block"), + NGX_HTTP_UPS_CONF|NGX_CONF_BLOCK|NGX_CONF_NOARGS, + ngx_http_lua_balancer_ssl_sess_store_by_lua_block, + NGX_HTTP_SRV_CONF_OFFSET, + 0, + (void *) ngx_http_lua_balancer_ssl_sess_store_handler_inline }, + + { ngx_string("balancer_ssl_session_store_by_lua_file"), + NGX_HTTP_UPS_CONF|NGX_CONF_TAKE1, + ngx_http_lua_balancer_ssl_sess_store_by_lua, + NGX_HTTP_SRV_CONF_OFFSET, + 0, + (void *) ngx_http_lua_balancer_ssl_sess_store_handler_file }, + #endif /* NGX_HTTP_SSL */ { ngx_string("lua_malloc_trim"), diff --git a/src/ngx_http_lua_phase.c b/src/ngx_http_lua_phase.c index 304c88ae13..ec4b29bcbc 100644 --- a/src/ngx_http_lua_phase.c +++ b/src/ngx_http_lua_phase.c @@ -92,6 +92,14 @@ ngx_http_lua_ngx_get_phase(lua_State *L) lua_pushliteral(L, "ssl_session_fetch"); break; + case NGX_HTTP_LUA_CONTEXT_BALANCER_SSL_SESS_STORE: + lua_pushliteral(L, "balancer_ssl_session_store"); + break; + + case NGX_HTTP_LUA_CONTEXT_BALANCER_SSL_SESS_FETCH: + lua_pushliteral(L, "balancer_ssl_session_fetch"); + break; + default: return luaL_error(L, "unknown phase: %#x", (int) ctx->context); } diff --git a/src/ngx_http_lua_util.h b/src/ngx_http_lua_util.h index 7dcc6f7585..dbf500a01c 100644 --- a/src/ngx_http_lua_util.h +++ b/src/ngx_http_lua_util.h @@ -85,6 +85,10 @@ extern char ngx_http_lua_headers_metatable_key; "ssl_session_store_by_lua*" \ : (c) == NGX_HTTP_LUA_CONTEXT_SSL_SESS_FETCH ? \ "ssl_session_fetch_by_lua*" \ + : (c) == NGX_HTTP_LUA_CONTEXT_BALANCER_SSL_SESS_STORE ? \ + "balancer_ssl_session_store_by_lua*" \ + : (c) == NGX_HTTP_LUA_CONTEXT_BALANCER_SSL_SESS_FETCH ? \ + "balancer_ssl_session_fetch_by_lua*" \ : "(unknown)")