char * ngx_http_lua_set_by_lua(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) { ngx_str_t *value; ngx_str_t target; ndk_set_var_t filter; u_char *p; ngx_http_lua_set_var_data_t *filter_data; /* * value[0] = "set_by_lua" * value[1] = target variable name * value[2] = lua script to be executed * value[3..] = real params * */ value = cf->args->elts; target = value[1]; filter.type = NDK_SET_VAR_MULTI_VALUE_DATA; filter.func = cmd->post; filter.size = cf->args->nelts - 2; /* get number of real params + 1 (lua script) */ filter_data = ngx_palloc(cf->pool, sizeof(ngx_http_lua_set_var_data_t)); if (filter_data == NULL) { return NGX_CONF_ERROR; } filter_data->size = filter.size; p = ngx_palloc(cf->pool, NGX_HTTP_LUA_INLINE_KEY_LEN + 1); if (p == NULL) { return NGX_CONF_ERROR; } filter_data->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[2].data, value[2].len); *p = '\0'; filter.data = filter_data; return ndk_set_var_multi_value_core(cf, &target, &value[2], &filter); }
char * ngx_http_lua_content_by_lua(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) { ngx_str_t *value; ngx_http_core_loc_conf_t *clcf; ngx_http_lua_loc_conf_t *llcf = conf; u_char *p; ngx_http_compile_complex_value_t ccv; dd("enter"); /* must specifiy a content handler */ if (cmd->post == NULL) { return NGX_CONF_ERROR; } if (llcf->content_handler) { return "is duplicate"; } value = cf->args->elts; if (value[1].len == 0) { /* Oops...Invalid location conf */ ngx_conf_log_error(NGX_LOG_ERR, cf, 0, "Invalid location config: no runnable Lua code"); return NGX_CONF_ERROR; } if (cmd->post == ngx_http_lua_content_handler_inline) { /* Don't eval nginx variables for inline lua code */ llcf->content_src.value = value[1]; p = ngx_palloc(cf->pool, NGX_HTTP_LUA_INLINE_KEY_LEN + 1); if (p == NULL) { return NGX_CONF_ERROR; } llcf->content_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'; } else { ngx_memzero(&ccv, sizeof(ngx_http_compile_complex_value_t)); ccv.cf = cf; ccv.value = &value[1]; ccv.complex_value = &llcf->content_src; if (ngx_http_compile_complex_value(&ccv) != NGX_OK) { return NGX_CONF_ERROR; } if (llcf->content_src.lengths == NULL) { /* no variable found */ p = ngx_palloc(cf->pool, NGX_HTTP_LUA_FILE_KEY_LEN + 1); if (p == NULL) { return NGX_CONF_ERROR; } llcf->content_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'; } } llcf->content_handler = cmd->post; /* register location content handler */ clcf = ngx_http_conf_get_module_loc_conf(cf, ngx_http_core_module); if (clcf == NULL) { return NGX_CONF_ERROR; } clcf->handler = ngx_http_lua_content_handler; return NGX_CONF_OK; }
char * ngx_http_lua_rewrite_by_lua(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) { ngx_str_t *value; ngx_http_lua_loc_conf_t *llcf = conf; u_char *p; ngx_http_compile_complex_value_t ccv; dd("enter"); #if defined(nginx_version) && nginx_version >= 8042 && nginx_version <= 8053 return "does not work with " NGINX_VER; #endif /* must specifiy a content handler */ if (cmd->post == NULL) { return NGX_CONF_ERROR; } if (llcf->rewrite_handler) { return "is duplicate"; } value = cf->args->elts; if (value[1].len == 0) { /* Oops...Invalid location conf */ ngx_conf_log_error(NGX_LOG_ERR, cf, 0, "Invalid location config: no runnable Lua code"); return NGX_CONF_ERROR; } if (cmd->post == ngx_http_lua_rewrite_handler_inline) { /* Don't eval nginx variables for inline lua code */ llcf->rewrite_src.value = value[1]; p = ngx_palloc(cf->pool, NGX_HTTP_LUA_INLINE_KEY_LEN + 1); if (p == NULL) { return NGX_CONF_ERROR; } llcf->rewrite_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'; } else { ngx_memzero(&ccv, sizeof(ngx_http_compile_complex_value_t)); ccv.cf = cf; ccv.value = &value[1]; ccv.complex_value = &llcf->rewrite_src; if (ngx_http_compile_complex_value(&ccv) != NGX_OK) { return NGX_CONF_ERROR; } if (llcf->rewrite_src.lengths == NULL) { /* no variable found */ p = ngx_palloc(cf->pool, NGX_HTTP_LUA_FILE_KEY_LEN + 1); if (p == NULL) { return NGX_CONF_ERROR; } llcf->rewrite_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'; } } llcf->rewrite_handler = cmd->post; if (! ngx_http_lua_requires_rewrite) { ngx_http_lua_requires_rewrite = 1; } return NGX_CONF_OK; }
char * ngx_http_lua_balancer_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; ngx_http_upstream_srv_conf_t *uscf; dd("enter"); /* must specify a content handler */ if (cmd->post == NULL) { return NGX_CONF_ERROR; } if (lscf->balancer.handler) { return "is duplicate"; } value = cf->args->elts; lscf->balancer.handler = (ngx_http_lua_srv_conf_handler_pt) cmd->post; if (cmd->post == ngx_http_lua_balancer_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.src.data = name; lscf->balancer.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.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.src = value[1]; p = ngx_palloc(cf->pool, NGX_HTTP_LUA_INLINE_KEY_LEN + 1); if (p == NULL) { return NGX_CONF_ERROR; } lscf->balancer.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'; } uscf = ngx_http_conf_get_module_srv_conf(cf, ngx_http_upstream_module); if (uscf->peer.init_upstream) { ngx_conf_log_error(NGX_LOG_WARN, cf, 0, "load balancing method redefined"); } uscf->peer.init_upstream = ngx_http_lua_balancer_init; uscf->flags = NGX_HTTP_UPSTREAM_CREATE |NGX_HTTP_UPSTREAM_WEIGHT |NGX_HTTP_UPSTREAM_MAX_FAILS |NGX_HTTP_UPSTREAM_FAIL_TIMEOUT |NGX_HTTP_UPSTREAM_DOWN; return NGX_CONF_OK; }
ngx_int_t ngx_http_lua_cache_loadfile(lua_State *L, const u_char *script, const u_char *cache_key, char **err, unsigned enabled) { int rc; u_char buf[NGX_HTTP_LUA_FILE_KEY_LEN + 1]; u_char *p; /* calculate digest of script file path */ dd("code cache enabled: %d", (int) enabled); if (enabled) { if (cache_key == NULL) { dd("CACHE file key not pre-calculated...calculating"); p = ngx_copy(buf, NGX_HTTP_LUA_FILE_TAG, NGX_HTTP_LUA_FILE_TAG_LEN); p = ngx_http_lua_digest_hex(p, script, ngx_strlen(script)); *p = '\0'; cache_key = buf; } else { dd("CACHE file key already pre-calculated"); } dd("XXX cache key for file: [%s]", cache_key); if (ngx_http_lua_cache_load_code(L, (char *) cache_key) == NGX_OK) { /* code chunk loaded from cache, sp++ */ dd("Code cache hit! cache key='%s', stack top=%d, file path='%s'", cache_key, lua_gettop(L), script); return NGX_OK; } dd("Code cache missed! cache key='%s', stack top=%d, file path='%s'", cache_key, lua_gettop(L), script); } /* load closure factory of script file to the top of lua stack, sp++ */ rc = ngx_http_lua_clfactory_loadfile(L, (char *) script); if (rc != 0) { /* Oops! error occured when loading Lua script */ if (rc == LUA_ERRMEM) { *err = "memory allocation error"; } else { if (lua_isstring(L, -1)) { *err = (char *) lua_tostring(L, -1); } else { *err = "syntax error"; } } return NGX_ERROR; } if (enabled) { /* store closure factory and gen new closure at the top of lua stack * to code cache */ rc = ngx_http_lua_cache_store_code(L, (char *) cache_key); if (rc != NGX_OK) { *err = "fail to generate new closure from the closure factory"; return NGX_ERROR; } } else { /* call closure factory to generate new closure */ rc = lua_pcall(L, 0, 1, 0); if (rc != 0) { dd("Error: failed to call closure factory!!"); return NGX_ERROR; } ngx_http_lua_clear_package_loaded(L); } return NGX_OK; }
char * ngx_http_lua_access_by_lua(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) { u_char *p, *chunkname; ngx_str_t *value; ngx_http_lua_main_conf_t *lmcf; ngx_http_lua_loc_conf_t *llcf = conf; ngx_http_compile_complex_value_t ccv; dd("enter"); /* must specifiy a content handler */ if (cmd->post == NULL) { return NGX_CONF_ERROR; } if (llcf->access_handler) { return "is duplicate"; } value = cf->args->elts; if (value[1].len == 0) { /* Oops...Invalid location conf */ ngx_conf_log_error(NGX_LOG_ERR, cf, 0, "invalid location config: no runnable Lua code"); return NGX_CONF_ERROR; } if (cmd->post == ngx_http_lua_access_handler_inline) { chunkname = ngx_http_lua_gen_chunk_name(cf, "access_by_lua", sizeof("access_by_lua") - 1); if (chunkname == NULL) { return NGX_CONF_ERROR; } llcf->access_chunkname = chunkname; /* Don't eval nginx variables for inline lua code */ llcf->access_src.value = value[1]; p = ngx_palloc(cf->pool, NGX_HTTP_LUA_INLINE_KEY_LEN + 1); if (p == NULL) { return NGX_CONF_ERROR; } llcf->access_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'; } else { ngx_memzero(&ccv, sizeof(ngx_http_compile_complex_value_t)); ccv.cf = cf; ccv.value = &value[1]; ccv.complex_value = &llcf->access_src; if (ngx_http_compile_complex_value(&ccv) != NGX_OK) { return NGX_CONF_ERROR; } if (llcf->access_src.lengths == NULL) { /* no variable found */ p = ngx_palloc(cf->pool, NGX_HTTP_LUA_FILE_KEY_LEN + 1); if (p == NULL) { return NGX_CONF_ERROR; } llcf->access_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'; } } llcf->access_handler = (ngx_http_handler_pt) cmd->post; lmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_lua_module); lmcf->requires_access = 1; lmcf->requires_capture_filter = 1; return NGX_CONF_OK; }
/* conf parser for directive ssl_session_store_by_lua */ char * ngx_http_lua_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 specifiy a content handler */ if (cmd->post == NULL) { return NGX_CONF_ERROR; } if (lscf->srv.ssl_sess_store_handler) { return "is duplicate"; } if (ngx_http_lua_ssl_init(cf->log) != NGX_OK) { return NGX_CONF_ERROR; } value = cf->args->elts; lscf->srv.ssl_sess_store_handler = (ngx_http_lua_srv_conf_handler_pt) cmd->post; if (cmd->post == ngx_http_lua_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->srv.ssl_sess_store_src.data = name; lscf->srv.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->srv.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->srv.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->srv.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; }