static int get_uri(lua_State * L) { ngx_http_request_t *r; r = ngx_http_lua_get_request(L); lua_pushlstring(L, (const char *) r->uri.data, r->uri.len); return 1; }
static ngx_http_upstream_main_conf_t * ngx_http_lua_upstream_get_upstream_main_conf(lua_State *L) { ngx_http_request_t *r; r = ngx_http_lua_get_request(L); if (r == NULL) { return ngx_http_cycle_get_module_main_conf(ngx_cycle, ngx_http_upstream_module); } return ngx_http_get_module_main_conf(r, ngx_http_upstream_module); }
static int get_host(lua_State * L) { ngx_http_request_t *r; r = ngx_http_lua_get_request(L); if (r->headers_in.host && r->headers_in.host->value.data) { lua_pushlstring(L, (const char *) r->headers_in.host->value.data, r->headers_in.host->value.len); } else { lua_pushnil(L); } return 1; }
static int ipc_test(lua_State * L) { ngx_http_request_t *r; r = ngx_http_lua_get_request(L); ngx_rbtree_t tree; ngx_rbtree_node_t sentinel; //ngx_rbtree_init(&tree, &sentinel, ngx_string_rbtree_insert_value); ngx_http_lua_mqtt_channel_t channel; ngx_http_lua_mqtt_msg_t msg; ngx_http_lua_mqtt_broadcast(&channel,&msg,r->pool->log,mcf); return 0; }
static int ngx_http_kafka_lua_log(lua_State *L) { ngx_kfk_ctx_t *kfk = ngx_kfk; ngx_http_request_t *r; ngx_http_kafka_ctx_t *ctx; ngx_kfk_topic_t *topic; ngx_kfk_toppar_t *toppar; ngx_uint_t partition; u_char *p; size_t len; int n, type; n = lua_gettop(L); if (n < 3) { return luaL_error(L, "kfk.log: expecting at least 3 arguments but got %d", n); } if (kfk == NULL) { lua_pushnil(L); lua_pushliteral(L, "kafka not start"); return 2; } if (kfk->pending_msgs_cnt + 1 > kfk->cf->buffering_max_msg) { lua_pushnil(L); lua_pushliteral(L, "buffering queue is full, try later"); return 2; } p = (u_char *) luaL_checklstring(L, 1, &len); if (len == 0) { lua_pushnil(L); lua_pushliteral(L, "unknown topic"); return 2; } topic = ngx_http_kafka_topic_find(kfk, p, len); if (topic == NULL || topic->state == NGX_KFK_TOPIC_UNKNOWN) { lua_pushnil(L); lua_pushliteral(L, "unknown topic"); return 2; } if (topic->toppars == NULL || topic->toppars->nelts == 0) { lua_pushnil(L); lua_pushliteral(L, "unknown topic(partition uninitilized)"); return 2; } type = lua_type(L, 2); switch (type) { case LUA_TNIL: partition = (ngx_uint_t)ngx_random() % topic->toppars->nelts; break; case LUA_TSTRING: p = (u_char *) lua_tolstring(L, 2, &len); partition = ngx_http_kafka_partition(p, len, topic->toppars->nelts); break; default: return luaL_argerror(L, 2, "expect string or nil"); } toppar = ngx_http_kafka_toppar_get_valid(topic, partition); if (toppar == NULL) { lua_pushnil(L); lua_pushliteral(L, "broker not available"); return 2; } r = ngx_http_lua_get_request(L); ctx = ngx_http_get_module_ctx(r, ngx_http_kafka_module); if (ctx == NULL) { ctx = ngx_palloc(r->pool, sizeof(ngx_http_kafka_ctx_t)); if (ctx == NULL) { lua_pushnil(L); lua_pushliteral(L, "no enough memory"); return 2; } ctx->topic = topic; ctx->toppar = toppar; } ngx_http_set_ctx(r, ctx, ngx_http_kafka_module); return ngx_http_kafka_lua_push(L); }
static ngx_int_t ngx_http_kafka_lua_push(lua_State *L) { ngx_http_request_t *r; ngx_http_kafka_main_conf_t *kmcf; ngx_http_kafka_ctx_t *ctx; ngx_kfk_toppar_t *toppar; ngx_kfk_buf_t *buf; ngx_str_t msg; ngx_int_t rc; size_t size, len; int32_t *crc; u_char *p, *q; const char *err; int i, n, type; n = lua_gettop(L); size = 0; for (i = 3; i <= n; i++) { type = lua_type(L, i); switch (type) { case LUA_TNUMBER: case LUA_TSTRING: lua_tolstring(L, i, &len); size += len; break; case LUA_TNIL: size += sizeof("nil") - 1; break; case LUA_TBOOLEAN: if (lua_toboolean(L, i)) { size += sizeof("true") - 1; } else { size += sizeof("false") - 1; } break; case LUA_TLIGHTUSERDATA: if (lua_touserdata(L, i) == NULL) { size += sizeof("null") - 1; break; } continue; default: err = lua_pushfstring(L, "string, number, boolean, or nil " "expected, got %s", lua_typename(L, type)); return luaL_argerror(L, i, err); } } r = ngx_http_lua_get_request(L); kmcf = ngx_http_get_module_main_conf(r, ngx_http_kafka_module); if (size > kmcf->msg_max_size) { lua_pushnil(L); lua_pushfstring(L, "message is too long, at most %d bytes", (int)(kmcf->msg_max_size)); return 2; } ctx = ngx_http_get_module_ctx(r, ngx_http_kafka_module); toppar = ctx->toppar; buf = toppar->free; if (buf == NULL) { buf = ngx_http_kafka_get_buf(ngx_kfk, &ngx_kfk->free); if (buf == NULL) { lua_pushnil(L); lua_pushliteral(L, "no bufs"); return 2; } if (buf->no_pool) { if (ngx_http_kafka_init_buf_pool(ngx_kfk, buf) != NGX_OK) { lua_pushnil(L); lua_pushliteral(L, "no enough memory"); return 2; } } toppar->free = buf; } p = ngx_pnalloc(buf->pool, NGX_KFK_MSG_HEADER_SIZE + size); if (p == NULL) { lua_pushnil(L); lua_pushliteral(L, "no enough memory"); return 2; } msg.data = p; msg.len = NGX_KFK_MSG_HEADER_SIZE + size; /* offset */ *(int64_t *)p = 0; p += sizeof(int64_t); /* msg size */ *(int32_t *)p = (int32_t)htonl(14 + len); p += sizeof(int32_t); /* crc(later calculate) */ crc = (int32_t *)p; p += sizeof(int32_t); /* magic */ *(int8_t *)p = 0; p += sizeof(int8_t); /* attr */ *(int8_t *)p = 0; p += sizeof(int8_t); /* key len */ *(int32_t *)p = (int32_t)htonl(-1); p += sizeof(int32_t); /* value len */ *(int32_t *)p = (int32_t)htonl(len); p += sizeof(int32_t); for (i = 3; i <= n; i++) { type = lua_type(L, i); switch (type) { case LUA_TNUMBER: case LUA_TSTRING: q = (u_char *) lua_tolstring(L, i, &len); p = ngx_copy(p, q, len); break; case LUA_TNIL: *p++ = 'n'; *p++ = 'i'; *p++ = 'l'; break; case LUA_TBOOLEAN: if (lua_toboolean(L, i)) { *p++ = 't'; *p++ = 'r'; *p++ = 'u'; *p++ = 'e'; } else { *p++ = 'f'; *p++ = 'a'; *p++ = 'l'; *p++ = 's'; *p++ = 'e'; } break; case LUA_TLIGHTUSERDATA: *p++ = 'n'; *p++ = 'u'; *p++ = 'l'; *p++ = 'l'; break; default: ngx_http_kafka_recycle_msg(buf->pool, &msg); return luaL_error(L, "impossible to reach here"); } } if (p - msg.data > (off_t)(NGX_KFK_MSG_HEADER_SIZE + size)) { ngx_http_kafka_recycle_msg(buf->pool, &msg); return luaL_error(L, "buffer error: %d > %d", (int) (p - msg.data), (int) size); } *crc = (int32_t)htonl(ngx_crc32_long((u_char*)(crc + 1), 10 + size)); if (buf->cnt == -1) { if (ngx_http_kafka_init_chain(buf, ctx) != NGX_OK) { ngx_http_kafka_recycle_msg(buf->pool, &msg); lua_pushnil(L); lua_pushliteral(L, "no enough memory"); return 2; } } ctx->msg = &msg; rc = ngx_http_kafka_enq_buf(r, ctx); if (rc != NGX_OK) { lua_pushnil(L); lua_pushliteral(L, "internal error"); return 2; } lua_pushinteger(L, 1); return 1; }
static int ngx_http_lua_ngx_get_cache_data(lua_State *L) { int n; ngx_http_request_t *r; ngx_http_cache_t *c; ngx_http_file_cache_t *cache, cache_tmp; ngx_http_file_cache_sh_t *sh, sh_tmp; ngx_http_file_cache_node_t *fcn, fcn_tmp; u_char *p; n = lua_gettop(L); if (n != 0) { return luaL_error(L, "expecting no arguments"); } r = ngx_http_lua_get_request(L); if (r == NULL) { return luaL_error(L, "no request object found"); } ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "lua cache.metadata"); // TODO setup empty return lua_createtable(L, 0, 2 /* nrec */); /* return table */ c = r->cache; if (!c) { /* empty response */ return 1; } /* make copies of all structs, to avoid locking for too long */ fcn = c->node; cache = c->file_cache; sh = cache ? cache->sh : NULL; memset(&cache_tmp, 0, sizeof(cache_tmp)); memset(&fcn_tmp, 0, sizeof(fcn_tmp)); memset(&sh_tmp, 0, sizeof(sh_tmp)); ngx_shmtx_lock(&c->file_cache->shpool->mutex); if (fcn) { fcn_tmp = *c->node; } if (cache) { cache_tmp = *c->file_cache; if (sh) { sh_tmp = *cache->sh; cache_tmp.sh = &sh_tmp; } } ngx_shmtx_unlock(&c->file_cache->shpool->mutex); p = ngx_pnalloc(r->pool, 2*NGX_HTTP_CACHE_KEY_LEN); if (!p) { return luaL_error(L, "Cannot allocate space for cache key string"); } ngx_hex_dump(p, c->key, NGX_HTTP_CACHE_KEY_LEN); lua_pushlstring(L, "key", sizeof("key")-1); lua_pushlstring(L, (char*)p, 2*NGX_HTTP_CACHE_KEY_LEN); lua_rawset(L, -3); lua_pushlstring(L, "crc32", sizeof("crc32")-1); lua_pushnumber(L, c->crc32); lua_rawset(L, -3); lua_pushlstring(L, "valid_sec", sizeof("valid_sec")-1); lua_pushnumber(L, c->valid_sec); lua_rawset(L, -3); lua_pushlstring(L, "last_modified", sizeof("last_modified")-1); lua_pushnumber(L, c->last_modified); lua_rawset(L, -3); lua_pushlstring(L, "date", sizeof("date")-1); lua_pushnumber(L, c->date); lua_rawset(L, -3); lua_pushlstring(L, "length", sizeof("length")-1); lua_pushnumber(L, c->length); lua_rawset(L, -3); lua_pushlstring(L, "fs_size", sizeof("fs_size")-1); lua_pushnumber(L, c->fs_size); lua_rawset(L, -3); lua_pushlstring(L, "min_uses", sizeof("min_uses")-1); lua_pushnumber(L, c->min_uses); lua_rawset(L, -3); lua_pushlstring(L, "error", sizeof("error")-1); lua_pushnumber(L, c->error); lua_rawset(L, -3); lua_pushlstring(L, "valid_msec", sizeof("valid_msec")-1); lua_pushnumber(L, c->valid_msec); lua_rawset(L, -3); /* shared memory block */ if (sh) { lua_createtable(L, 0, 2 /* nrec */); /* subtable */ lua_pushlstring(L, "size", sizeof("size")-1); lua_pushnumber(L, sh_tmp.size); lua_rawset(L, -3); lua_setfield(L, -2, "sh"); } /* cache entry */ if (cache) { lua_createtable(L, 0, 8 /* nrec */); /* subtable */ lua_pushlstring(L, "max_size", sizeof("max_size")-1); lua_pushnumber(L, cache_tmp.max_size); lua_rawset(L, -3); lua_pushlstring(L, "bsize", sizeof("bsize")-1); lua_pushnumber(L, cache_tmp.bsize); lua_rawset(L, -3); lua_pushlstring(L, "inactive", sizeof("inactive")-1); lua_pushnumber(L, cache_tmp.inactive); lua_rawset(L, -3); lua_pushlstring(L, "files", sizeof("files")-1); lua_pushnumber(L, cache_tmp.files); lua_rawset(L, -3); lua_pushlstring(L, "loader_files", sizeof("loader_files")-1); lua_pushnumber(L, cache_tmp.loader_files); lua_rawset(L, -3); lua_pushlstring(L, "loader_sleep", sizeof("loader_sleep")-1); lua_pushnumber(L, cache_tmp.loader_sleep); lua_rawset(L, -3); lua_pushlstring(L, "loader_threshold", sizeof("loader_threshold")-1); lua_pushnumber(L, cache_tmp.inactive); lua_rawset(L, -3); lua_setfield(L, -2, "cache"); } /* file_cache_node */ if (fcn) { lua_createtable(L, 0, 11 /* nrec */); /* subtable */ lua_pushlstring(L, "count", sizeof("count")-1); lua_pushnumber(L, fcn_tmp.count); lua_rawset(L, -3); lua_pushlstring(L, "uses", sizeof("uses")-1); lua_pushnumber(L, fcn_tmp.uses); lua_rawset(L, -3); lua_pushlstring(L, "valid_msec", sizeof("valid_msec")-1); lua_pushnumber(L, fcn_tmp.valid_msec); lua_rawset(L, -3); lua_pushlstring(L, "error", sizeof("error")-1); lua_pushnumber(L, fcn_tmp.error); lua_rawset(L, -3); lua_pushlstring(L, "exists", sizeof("exists")-1); lua_pushnumber(L, fcn_tmp.exists); lua_rawset(L, -3); lua_pushlstring(L, "updating", sizeof("updating")-1); lua_pushnumber(L, fcn_tmp.updating); lua_rawset(L, -3); lua_pushlstring(L, "deleting", sizeof("deleting")-1); lua_pushnumber(L, fcn_tmp.deleting); lua_rawset(L, -3); lua_pushlstring(L, "exists", sizeof("exists")-1); lua_pushnumber(L, fcn_tmp.exists); lua_rawset(L, -3); lua_pushlstring(L, "expire", sizeof("expire")-1); lua_pushnumber(L, fcn_tmp.expire); lua_rawset(L, -3); lua_pushlstring(L, "valid_sec", sizeof("valid_sec")-1); lua_pushnumber(L, fcn_tmp.valid_sec); lua_rawset(L, -3); lua_pushlstring(L, "fs_size", sizeof("fs_size")-1); lua_pushnumber(L, fcn_tmp.fs_size); lua_rawset(L, -3); lua_setfield(L, -2, "fcn"); } return 1; }
static int ngx_http_lua_ngx_cache_purge(lua_State *L) { int n; ngx_http_request_t *r; ngx_http_cache_t *c; ngx_http_file_cache_t *cache; n = lua_gettop(L); if (n != 0) { return luaL_error(L, "expecting no arguments"); } r = ngx_http_lua_get_request(L); if (!r->cache || !r->cache->node || !r->cache->node->exists || r->cache->node->deleting) { lua_pushboolean (L, 0); return 1; } /* Inspired by Piotr Sikora's Purge module. * https://github.com/FRiCKLE/ngx_cache_purge */ ngx_shmtx_lock(&r->cache->file_cache->shpool->mutex); if (!r->cache || !r->cache->node || !r->cache->node->exists) { /* race between concurrent purges, backoff */ ngx_shmtx_unlock(&r->cache->file_cache->shpool->mutex); lua_pushboolean (L, 0); return 1; } c = r->cache; cache = c->file_cache; # if defined(nginx_version) && (nginx_version >= 1000001) cache->sh->size -= c->node->fs_size; c->node->fs_size = 0; # else cache->sh->size -= (c->node->length + cache->bsize - 1) / cache->bsize; c->node->length = 0; # endif c->node->exists = 0; # if defined(nginx_version) \ && ((nginx_version >= 8001) \ || ((nginx_version < 8000) && (nginx_version >= 7060))) c->node->updating = 0; # endif ngx_shmtx_unlock(&r->cache->file_cache->shpool->mutex); if (ngx_delete_file(r->cache->file.name.data) == NGX_FILE_ERROR) { ngx_log_error(NGX_LOG_WARN, r->connection->log, ngx_errno, ngx_delete_file_n " \"%s\" failed while " "attempting to purge bad stale.", r->cache->file.name.data); } lua_pushboolean (L, 1); return 1; }
static int ngx_http_lua_ngx_set_cache_data(lua_State *L) { ngx_http_request_t *r; ngx_http_cache_t *c, c_tmp; ngx_http_file_cache_node_t *fcn, fcn_tmp; int n; /* top of stack when we start. */ struct { uint valid_sec:1; uint last_modified:1; uint date:1; uint min_uses:1; uint valid_msec:1; uint fcn_uses:1; uint fcn_valid_msec:1; uint fcn_expire:1; uint fcn_valid_sec:1; } isset; n = lua_gettop(L); if (n != 1) { return luaL_error(L, "only one argument is expected, but got %d", n); } luaL_checktype(L, -1, LUA_TTABLE); r = ngx_http_lua_get_request(L); if (lua_type(L, -1) != LUA_TTABLE) { return luaL_error(L, "the argument is not a table, " "but a %s", lua_typename(L, lua_type(L, -1))); } c = r->cache; if (!c) { lua_pushboolean(L, 0); return 1; } /* setup dummy copies of structs, to write into */ fcn = c->node; memset(&c_tmp, 0, sizeof(c_tmp)); memset(&fcn_tmp, 0, sizeof(fcn_tmp)); memset(&isset, 0, sizeof(isset)); ASSIGN_NUMBER_OR_RET("valid_sec", c_tmp.valid_sec, isset.valid_sec); ASSIGN_NUMBER_OR_RET("last_modified", c_tmp.last_modified, isset.last_modified); ASSIGN_NUMBER_OR_RET("date", c_tmp.date, isset.date); ASSIGN_NUMBER_OR_RET("min_uses", c_tmp.min_uses, isset.min_uses); ASSIGN_NUMBER_OR_RET("valid_msec", c_tmp.valid_msec, isset.valid_msec); /* pop all we pushed on stack */ lua_pop(L, lua_gettop(L)-n); /* file_cache_node */ if (fcn && lua_type(L, n+1) == LUA_TTABLE) { /* push the fcn subtable onto the stack */ lua_getfield(L, n, "fcn"); ASSIGN_NUMBER_OR_RET("uses", fcn_tmp.uses, isset.fcn_uses); ASSIGN_NUMBER_OR_RET("valid_msec", fcn_tmp.valid_msec, isset.fcn_valid_msec); ASSIGN_NUMBER_OR_RET("expire", fcn_tmp.expire, isset.fcn_expire); ASSIGN_NUMBER_OR_RET("valid_sec", fcn_tmp.valid_sec, isset.fcn_valid_sec); /* pop all the entries we pushed on the stack*/ lua_pop(L, lua_gettop(L)-n); } /* write out changes */ ngx_shmtx_lock(&c->file_cache->shpool->mutex); if (isset.valid_sec) { c->valid_sec = c_tmp.valid_sec; if (c->buf && c->buf->pos) { ngx_http_file_cache_header_t *h; h = (ngx_http_file_cache_header_t *) c->buf->pos; h->valid_sec = c->valid_sec; } } ASSIGN_IF_SET(c->last_modified, c_tmp.last_modified, isset.last_modified); ASSIGN_IF_SET(c->date, c_tmp.date, isset.date); ASSIGN_IF_SET(c->min_uses, c_tmp.min_uses, isset.min_uses); ASSIGN_IF_SET(c->valid_msec, c_tmp.valid_msec, isset.valid_msec); if (fcn) { ASSIGN_IF_SET(fcn->uses, fcn_tmp.uses, isset.fcn_uses); ASSIGN_IF_SET(fcn->valid_msec, fcn_tmp.valid_msec,isset.fcn_valid_msec); ASSIGN_IF_SET(fcn->expire, fcn_tmp.expire, isset.fcn_expire); ASSIGN_IF_SET(fcn->valid_sec, fcn_tmp.valid_sec, isset.fcn_valid_sec); } ngx_shmtx_unlock(&c->file_cache->shpool->mutex); /* pop the parameter off */ lua_pop(L, 1); /* push a true as a return */ lua_pushboolean(L, 1); return 1; }