LCOV - code coverage report
Current view: top level - home/build/openresty-1.13.6.1/build/ngx_lua-0.10.11/src - ngx_http_lua_bodyfilterby.c (source / functions) Hit Total Coverage
Test: coverage ngix Lines: 0 231 0.0 %
Date: 2020-03-03 04:25:50 Functions: 0 8 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : 
       2             : /*
       3             :  * Copyright (C) Xiaozhe Wang (chaoslawful)
       4             :  * Copyright (C) Yichun Zhang (agentzh)
       5             :  */
       6             : 
       7             : 
       8             : #ifndef DDEBUG
       9             : #define DDEBUG 0
      10             : #endif
      11             : #include "ddebug.h"
      12             : 
      13             : 
      14             : #include "ngx_http_lua_bodyfilterby.h"
      15             : #include "ngx_http_lua_exception.h"
      16             : #include "ngx_http_lua_util.h"
      17             : #include "ngx_http_lua_pcrefix.h"
      18             : #include "ngx_http_lua_time.h"
      19             : #include "ngx_http_lua_log.h"
      20             : #include "ngx_http_lua_regex.h"
      21             : #include "ngx_http_lua_cache.h"
      22             : #include "ngx_http_lua_headers.h"
      23             : #include "ngx_http_lua_variable.h"
      24             : #include "ngx_http_lua_string.h"
      25             : #include "ngx_http_lua_misc.h"
      26             : #include "ngx_http_lua_consts.h"
      27             : #include "ngx_http_lua_output.h"
      28             : 
      29             : 
      30             : static void ngx_http_lua_body_filter_by_lua_env(lua_State *L,
      31             :     ngx_http_request_t *r, ngx_chain_t *in);
      32             : static ngx_http_output_body_filter_pt ngx_http_next_body_filter;
      33             : 
      34             : 
      35             : /* key for the ngx_chain_t *in pointer in the Lua thread */
      36             : #define ngx_http_lua_chain_key  "__ngx_cl"
      37             : 
      38             : 
      39             : /**
      40             :  * Set environment table for the given code closure.
      41             :  *
      42             :  * Before:
      43             :  *         | code closure | <- top
      44             :  *         |      ...     |
      45             :  *
      46             :  * After:
      47             :  *         | code closure | <- top
      48             :  *         |      ...     |
      49             :  * */
      50             : static void
      51           0 : ngx_http_lua_body_filter_by_lua_env(lua_State *L, ngx_http_request_t *r,
      52             :     ngx_chain_t *in)
      53             : {
      54             :     /*  set nginx request pointer to current lua thread's globals table */
      55           0 :     ngx_http_lua_set_req(L, r);
      56             : 
      57           0 :     lua_pushlightuserdata(L, in);
      58           0 :     lua_setglobal(L, ngx_http_lua_chain_key);
      59             : 
      60             :     /**
      61             :      * we want to create empty environment for current script
      62             :      *
      63             :      * setmetatable({}, {__index = _G})
      64             :      *
      65             :      * if a function or symbol is not defined in our env, __index will lookup
      66             :      * in the global env.
      67             :      *
      68             :      * all variables created in the script-env will be thrown away at the end
      69             :      * of the script run.
      70             :      * */
      71           0 :     ngx_http_lua_create_new_globals_table(L, 0 /* narr */, 1 /* nrec */);
      72             : 
      73             :     /*  {{{ make new env inheriting main thread's globals table */
      74           0 :     lua_createtable(L, 0, 1 /* nrec */);    /*  the metatable for the new
      75             :                                                 env */
      76           0 :     ngx_http_lua_get_globals_table(L);
      77           0 :     lua_setfield(L, -2, "__index");
      78           0 :     lua_setmetatable(L, -2);    /*  setmetatable({}, {__index = _G}) */
      79             :     /*  }}} */
      80             : 
      81           0 :     lua_setfenv(L, -2);    /*  set new running env for the code closure */
      82           0 : }
      83             : 
      84             : 
      85             : ngx_int_t
      86           0 : ngx_http_lua_body_filter_by_chunk(lua_State *L, ngx_http_request_t *r,
      87             :     ngx_chain_t *in)
      88             : {
      89             :     ngx_int_t        rc;
      90             :     u_char          *err_msg;
      91             :     size_t           len;
      92             : #if (NGX_PCRE)
      93             :     ngx_pool_t      *old_pool;
      94             : #endif
      95             : 
      96             :     dd("initialize nginx context in Lua VM, code chunk at stack top  sp = 1");
      97           0 :     ngx_http_lua_body_filter_by_lua_env(L, r, in);
      98             : 
      99             : #if (NGX_PCRE)
     100             :     /* XXX: work-around to nginx regex subsystem */
     101           0 :     old_pool = ngx_http_lua_pcre_malloc_init(r->pool);
     102             : #endif
     103             : 
     104           0 :     lua_pushcfunction(L, ngx_http_lua_traceback);
     105           0 :     lua_insert(L, 1);  /* put it under chunk and args */
     106             : 
     107             :     dd("protected call user code");
     108           0 :     rc = lua_pcall(L, 0, 1, 1);
     109             : 
     110           0 :     lua_remove(L, 1);  /* remove traceback function */
     111             : 
     112             : #if (NGX_PCRE)
     113             :     /* XXX: work-around to nginx regex subsystem */
     114           0 :     ngx_http_lua_pcre_malloc_done(old_pool);
     115             : #endif
     116             : 
     117           0 :     if (rc != 0) {
     118             : 
     119             :         /*  error occurred */
     120           0 :         err_msg = (u_char *) lua_tolstring(L, -1, &len);
     121             : 
     122           0 :         if (err_msg == NULL) {
     123           0 :             err_msg = (u_char *) "unknown reason";
     124           0 :             len = sizeof("unknown reason") - 1;
     125             :         }
     126             : 
     127           0 :         ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
     128             :                       "failed to run body_filter_by_lua*: %*s", len, err_msg);
     129             : 
     130           0 :         lua_settop(L, 0);    /*  clear remaining elems on stack */
     131             : 
     132           0 :         return NGX_ERROR;
     133             :     }
     134             : 
     135             :     /* rc == 0 */
     136             : 
     137           0 :     rc = (ngx_int_t) lua_tointeger(L, -1);
     138             : 
     139             :     dd("got return value: %d", (int) rc);
     140             : 
     141           0 :     lua_settop(L, 0);
     142             : 
     143           0 :     if (rc == NGX_ERROR || rc >= NGX_HTTP_SPECIAL_RESPONSE) {
     144           0 :         return NGX_ERROR;
     145             :     }
     146             : 
     147           0 :     return NGX_OK;
     148             : }
     149             : 
     150             : 
     151             : ngx_int_t
     152           0 : ngx_http_lua_body_filter_inline(ngx_http_request_t *r, ngx_chain_t *in)
     153             : {
     154             :     lua_State                   *L;
     155             :     ngx_int_t                    rc;
     156             :     ngx_http_lua_loc_conf_t     *llcf;
     157             : 
     158           0 :     llcf = ngx_http_get_module_loc_conf(r, ngx_http_lua_module);
     159             : 
     160           0 :     L = ngx_http_lua_get_lua_vm(r, NULL);
     161             : 
     162             :     /*  load Lua inline script (w/ cache) sp = 1 */
     163           0 :     rc = ngx_http_lua_cache_loadbuffer(r->connection->log, L,
     164           0 :                                        llcf->body_filter_src.value.data,
     165             :                                        llcf->body_filter_src.value.len,
     166           0 :                                        llcf->body_filter_src_key,
     167             :                                        "=body_filter_by_lua");
     168           0 :     if (rc != NGX_OK) {
     169           0 :         return NGX_ERROR;
     170             :     }
     171             : 
     172           0 :     rc = ngx_http_lua_body_filter_by_chunk(L, r, in);
     173             : 
     174             :     dd("body filter by chunk returns %d", (int) rc);
     175             : 
     176           0 :     if (rc != NGX_OK) {
     177           0 :         return NGX_ERROR;
     178             :     }
     179             : 
     180           0 :     return NGX_OK;
     181             : }
     182             : 
     183             : 
     184             : ngx_int_t
     185           0 : ngx_http_lua_body_filter_file(ngx_http_request_t *r, ngx_chain_t *in)
     186             : {
     187             :     lua_State                       *L;
     188             :     ngx_int_t                        rc;
     189             :     u_char                          *script_path;
     190             :     ngx_http_lua_loc_conf_t         *llcf;
     191             :     ngx_str_t                        eval_src;
     192             : 
     193           0 :     llcf = ngx_http_get_module_loc_conf(r, ngx_http_lua_module);
     194             : 
     195             :     /* Eval nginx variables in code path string first */
     196           0 :     if (ngx_http_complex_value(r, &llcf->body_filter_src, &eval_src)
     197             :         != NGX_OK)
     198             :     {
     199           0 :         return NGX_ERROR;
     200             :     }
     201             : 
     202           0 :     script_path = ngx_http_lua_rebase_path(r->pool, eval_src.data,
     203             :                                            eval_src.len);
     204             : 
     205           0 :     if (script_path == NULL) {
     206           0 :         return NGX_ERROR;
     207             :     }
     208             : 
     209           0 :     L = ngx_http_lua_get_lua_vm(r, NULL);
     210             : 
     211             :     /*  load Lua script file (w/ cache)        sp = 1 */
     212           0 :     rc = ngx_http_lua_cache_loadfile(r->connection->log, L, script_path,
     213           0 :                                      llcf->body_filter_src_key);
     214           0 :     if (rc != NGX_OK) {
     215           0 :         return NGX_ERROR;
     216             :     }
     217             : 
     218             :     /*  make sure we have a valid code chunk */
     219           0 :     ngx_http_lua_assert(lua_isfunction(L, -1));
     220             : 
     221           0 :     rc = ngx_http_lua_body_filter_by_chunk(L, r, in);
     222             : 
     223           0 :     if (rc != NGX_OK) {
     224           0 :         return NGX_ERROR;
     225             :     }
     226             : 
     227           0 :     return NGX_OK;
     228             : }
     229             : 
     230             : 
     231             : static ngx_int_t
     232           0 : ngx_http_lua_body_filter(ngx_http_request_t *r, ngx_chain_t *in)
     233             : {
     234             :     ngx_http_lua_loc_conf_t     *llcf;
     235             :     ngx_http_lua_ctx_t          *ctx;
     236             :     ngx_int_t                    rc;
     237             :     uint16_t                     old_context;
     238             :     ngx_http_cleanup_t          *cln;
     239             :     lua_State                   *L;
     240             :     ngx_chain_t                 *out;
     241             : 
     242           0 :     ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
     243             :                    "lua body filter for user lua code, uri \"%V\"", &r->uri);
     244             : 
     245           0 :     if (in == NULL) {
     246           0 :         return ngx_http_next_body_filter(r, in);
     247             :     }
     248             : 
     249           0 :     llcf = ngx_http_get_module_loc_conf(r, ngx_http_lua_module);
     250             : 
     251           0 :     if (llcf->body_filter_handler == NULL) {
     252             :         dd("no body filter handler found");
     253           0 :         return ngx_http_next_body_filter(r, in);
     254             :     }
     255             : 
     256           0 :     ctx = ngx_http_get_module_ctx(r, ngx_http_lua_module);
     257             : 
     258             :     dd("ctx = %p", ctx);
     259             : 
     260           0 :     if (ctx == NULL) {
     261           0 :         ctx = ngx_http_lua_create_ctx(r);
     262           0 :         if (ctx == NULL) {
     263           0 :             return NGX_ERROR;
     264             :         }
     265             :     }
     266             : 
     267           0 :     if (ctx->seen_last_in_filter) {
     268           0 :         for (/* void */; in; in = in->next) {
     269             :             dd("mark the buf as consumed: %d", (int) ngx_buf_size(in->buf));
     270           0 :             in->buf->pos = in->buf->last;
     271           0 :             in->buf->file_pos = in->buf->file_last;
     272             :         }
     273             : 
     274           0 :         return NGX_OK;
     275             :     }
     276             : 
     277           0 :     if (ctx->cleanup == NULL) {
     278           0 :         cln = ngx_http_cleanup_add(r, 0);
     279           0 :         if (cln == NULL) {
     280           0 :             return NGX_ERROR;
     281             :         }
     282             : 
     283           0 :         cln->handler = ngx_http_lua_request_cleanup_handler;
     284           0 :         cln->data = ctx;
     285           0 :         ctx->cleanup = &cln->handler;
     286             :     }
     287             : 
     288           0 :     old_context = ctx->context;
     289           0 :     ctx->context = NGX_HTTP_LUA_CONTEXT_BODY_FILTER;
     290             : 
     291             :     dd("calling body filter handler");
     292           0 :     rc = llcf->body_filter_handler(r, in);
     293             : 
     294             :     dd("calling body filter handler returned %d", (int) rc);
     295             : 
     296           0 :     ctx->context = old_context;
     297             : 
     298           0 :     if (rc != NGX_OK) {
     299           0 :         return NGX_ERROR;
     300             :     }
     301             : 
     302           0 :     L = ngx_http_lua_get_lua_vm(r, ctx);
     303             : 
     304           0 :     lua_getglobal(L, ngx_http_lua_chain_key);
     305           0 :     out = lua_touserdata(L, -1);
     306           0 :     lua_pop(L, 1);
     307             : 
     308           0 :     if (in == out) {
     309           0 :         return ngx_http_next_body_filter(r, in);
     310             :     }
     311             : 
     312           0 :     if (out == NULL) {
     313             :         /* do not forward NULL to the next filters because the input is
     314             :          * not NULL */
     315           0 :         return NGX_OK;
     316             :     }
     317             : 
     318             :     /* in != out */
     319           0 :     rc = ngx_http_next_body_filter(r, out);
     320           0 :     if (rc == NGX_ERROR) {
     321           0 :         return NGX_ERROR;
     322             :     }
     323             : 
     324             : #if nginx_version >= 1001004
     325           0 :     ngx_chain_update_chains(r->pool,
     326             : #else
     327             :     ngx_chain_update_chains(
     328             : #endif
     329             :                             &ctx->free_bufs, &ctx->busy_bufs, &out,
     330             :                             (ngx_buf_tag_t) &ngx_http_lua_module);
     331             : 
     332           0 :     return rc;
     333             : }
     334             : 
     335             : 
     336             : ngx_int_t
     337           0 : ngx_http_lua_body_filter_init(void)
     338             : {
     339             :     dd("calling body filter init");
     340           0 :     ngx_http_next_body_filter = ngx_http_top_body_filter;
     341           0 :     ngx_http_top_body_filter = ngx_http_lua_body_filter;
     342             : 
     343           0 :     return NGX_OK;
     344             : }
     345             : 
     346             : 
     347             : int
     348           0 : ngx_http_lua_body_filter_param_get(lua_State *L)
     349             : {
     350             :     u_char              *data, *p;
     351             :     size_t               size;
     352             :     ngx_chain_t         *cl;
     353             :     ngx_buf_t           *b;
     354             :     int                  idx;
     355             :     ngx_chain_t         *in;
     356             : 
     357           0 :     idx = luaL_checkint(L, 2);
     358             : 
     359             :     dd("index: %d", idx);
     360             : 
     361           0 :     if (idx != 1 && idx != 2) {
     362           0 :         lua_pushnil(L);
     363           0 :         return 1;
     364             :     }
     365             : 
     366           0 :     lua_getglobal(L, ngx_http_lua_chain_key);
     367           0 :     in = lua_touserdata(L, -1);
     368             : 
     369           0 :     if (idx == 2) {
     370             :         /* asking for the eof argument */
     371             : 
     372           0 :         for (cl = in; cl; cl = cl->next) {
     373           0 :             if (cl->buf->last_buf || cl->buf->last_in_chain) {
     374           0 :                 lua_pushboolean(L, 1);
     375           0 :                 return 1;
     376             :             }
     377             :         }
     378             : 
     379           0 :         lua_pushboolean(L, 0);
     380           0 :         return 1;
     381             :     }
     382             : 
     383             :     /* idx == 1 */
     384             : 
     385           0 :     size = 0;
     386             : 
     387           0 :     if (in == NULL) {
     388             :         /* being a cleared chain on the Lua land */
     389           0 :         lua_pushliteral(L, "");
     390           0 :         return 1;
     391             :     }
     392             : 
     393           0 :     if (in->next == NULL) {
     394             : 
     395             :         dd("seen only single buffer");
     396             : 
     397           0 :         b = in->buf;
     398           0 :         lua_pushlstring(L, (char *) b->pos, b->last - b->pos);
     399           0 :         return 1;
     400             :     }
     401             : 
     402             :     dd("seen multiple buffers");
     403             : 
     404           0 :     for (cl = in; cl; cl = cl->next) {
     405           0 :         b = cl->buf;
     406             : 
     407           0 :         size += b->last - b->pos;
     408             : 
     409           0 :         if (b->last_buf || b->last_in_chain) {
     410             :             break;
     411             :         }
     412             :     }
     413             : 
     414           0 :     data = (u_char *) lua_newuserdata(L, size);
     415             : 
     416           0 :     for (p = data, cl = in; cl; cl = cl->next) {
     417           0 :         b = cl->buf;
     418           0 :         p = ngx_copy(p, b->pos, b->last - b->pos);
     419             : 
     420           0 :         if (b->last_buf || b->last_in_chain) {
     421             :             break;
     422             :         }
     423             :     }
     424             : 
     425           0 :     lua_pushlstring(L, (char *) data, size);
     426           0 :     return 1;
     427             : }
     428             : 
     429             : 
     430             : int
     431           0 : ngx_http_lua_body_filter_param_set(lua_State *L, ngx_http_request_t *r,
     432             :     ngx_http_lua_ctx_t *ctx)
     433             : {
     434             :     int                      type;
     435             :     int                      idx;
     436             :     int                      found;
     437             :     u_char                  *data;
     438             :     size_t                   size;
     439             :     unsigned                 last;
     440           0 :     unsigned                 flush = 0;
     441             :     ngx_buf_t               *b;
     442             :     ngx_chain_t             *cl;
     443             :     ngx_chain_t             *in;
     444             : 
     445           0 :     idx = luaL_checkint(L, 2);
     446             : 
     447             :     dd("index: %d", idx);
     448             : 
     449           0 :     if (idx != 1 && idx != 2) {
     450           0 :         return luaL_error(L, "bad index: %d", idx);
     451             :     }
     452             : 
     453           0 :     if (idx == 2) {
     454             :         /* overwriting the eof flag */
     455           0 :         last = lua_toboolean(L, 3);
     456             : 
     457           0 :         lua_getglobal(L, ngx_http_lua_chain_key);
     458           0 :         in = lua_touserdata(L, -1);
     459           0 :         lua_pop(L, 1);
     460             : 
     461           0 :         if (last) {
     462           0 :             ctx->seen_last_in_filter = 1;
     463             : 
     464             :             /* the "in" chain cannot be NULL and we set the "last_buf" or
     465             :              * "last_in_chain" flag in the last buf of "in" */
     466             : 
     467           0 :             for (cl = in; cl; cl = cl->next) {
     468           0 :                 if (cl->next == NULL) {
     469           0 :                     if (r == r->main) {
     470           0 :                         cl->buf->last_buf = 1;
     471             : 
     472             :                     } else {
     473           0 :                         cl->buf->last_in_chain = 1;
     474             :                     }
     475             : 
     476           0 :                     break;
     477             :                 }
     478             :             }
     479             : 
     480             :         } else {
     481             :             /* last == 0 */
     482             : 
     483           0 :             found = 0;
     484             : 
     485           0 :             for (cl = in; cl; cl = cl->next) {
     486           0 :                 b = cl->buf;
     487             : 
     488           0 :                 if (b->last_buf) {
     489           0 :                     b->last_buf = 0;
     490           0 :                     found = 1;
     491             :                 }
     492             : 
     493           0 :                 if (b->last_in_chain) {
     494           0 :                     b->last_in_chain = 0;
     495           0 :                     found = 1;
     496             :                 }
     497             : 
     498           0 :                 if (found && b->last == b->pos && !ngx_buf_in_memory(b)) {
     499             :                     /* make it a special sync buf to make
     500             :                      * ngx_http_write_filter_module happy. */
     501           0 :                     b->sync = 1;
     502             :                 }
     503             :             }
     504             : 
     505           0 :             ctx->seen_last_in_filter = 0;
     506             :         }
     507             : 
     508           0 :         return 0;
     509             :     }
     510             : 
     511             :     /* idx == 1, overwriting the chunk data */
     512             : 
     513           0 :     type = lua_type(L, 3);
     514             : 
     515           0 :     switch (type) {
     516           0 :     case LUA_TSTRING:
     517             :     case LUA_TNUMBER:
     518           0 :         data = (u_char *) lua_tolstring(L, 3, &size);
     519           0 :         break;
     520             : 
     521           0 :     case LUA_TNIL:
     522             :         /* discard the buffers */
     523             : 
     524           0 :         lua_getglobal(L, ngx_http_lua_chain_key); /* key val */
     525           0 :         in = lua_touserdata(L, -1);
     526           0 :         lua_pop(L, 1);
     527             : 
     528           0 :         last = 0;
     529             : 
     530           0 :         for (cl = in; cl; cl = cl->next) {
     531           0 :             b = cl->buf;
     532             : 
     533           0 :             if (b->flush) {
     534           0 :                 flush = 1;
     535             :             }
     536             : 
     537           0 :             if (b->last_in_chain || b->last_buf) {
     538           0 :                 last = 1;
     539             :             }
     540             : 
     541             :             dd("mark the buf as consumed: %d", (int) ngx_buf_size(b));
     542           0 :             b->pos = b->last;
     543             :         }
     544             : 
     545             :         /* cl == NULL */
     546             : 
     547           0 :         goto done;
     548             : 
     549           0 :     case LUA_TTABLE:
     550           0 :         size = ngx_http_lua_calc_strlen_in_table(L, 3 /* index */, 3 /* arg */,
     551             :                                                  1 /* strict */);
     552           0 :         data = NULL;
     553           0 :         break;
     554             : 
     555           0 :     default:
     556           0 :         return luaL_error(L, "bad chunk data type: %s",
     557             :                           lua_typename(L, type));
     558             :     }
     559             : 
     560           0 :     lua_getglobal(L, ngx_http_lua_chain_key);
     561           0 :     in = lua_touserdata(L, -1);
     562           0 :     lua_pop(L, 1);
     563             : 
     564           0 :     last = 0;
     565             : 
     566           0 :     for (cl = in; cl; cl = cl->next) {
     567           0 :         b = cl->buf;
     568             : 
     569           0 :         if (b->flush) {
     570           0 :             flush = 1;
     571             :         }
     572             : 
     573           0 :         if (b->last_buf || b->last_in_chain) {
     574           0 :             last = 1;
     575             :         }
     576             : 
     577             :         dd("mark the buf as consumed: %d", (int) ngx_buf_size(cl->buf));
     578           0 :         cl->buf->pos = cl->buf->last;
     579             :     }
     580             : 
     581             :     /* cl == NULL */
     582             : 
     583           0 :     if (size == 0) {
     584           0 :         goto done;
     585             :     }
     586             : 
     587           0 :     cl = ngx_http_lua_chain_get_free_buf(r->connection->log, r->pool,
     588             :                                          &ctx->free_bufs, size);
     589           0 :     if (cl == NULL) {
     590           0 :         return luaL_error(L, "no memory");
     591             :     }
     592             : 
     593           0 :     if (type == LUA_TTABLE) {
     594           0 :         cl->buf->last = ngx_http_lua_copy_str_in_table(L, 3, cl->buf->last);
     595             : 
     596             :     } else {
     597           0 :         cl->buf->last = ngx_copy(cl->buf->pos, data, size);
     598             :     }
     599             : 
     600           0 : done:
     601             : 
     602           0 :     if (last || flush) {
     603           0 :         if (cl == NULL) {
     604           0 :             cl = ngx_http_lua_chain_get_free_buf(r->connection->log,
     605             :                                                  r->pool,
     606             :                                                  &ctx->free_bufs, 0);
     607           0 :             if (cl == NULL) {
     608           0 :                 return luaL_error(L, "no memory");
     609             :             }
     610             :         }
     611             : 
     612           0 :         if (last) {
     613           0 :             ctx->seen_last_in_filter = 1;
     614             : 
     615           0 :             if (r == r->main) {
     616           0 :                 cl->buf->last_buf = 1;
     617             : 
     618             :             } else {
     619           0 :                 cl->buf->last_in_chain = 1;
     620             :             }
     621             :         }
     622             : 
     623           0 :         if (flush) {
     624           0 :             cl->buf->flush = 1;
     625             :         }
     626             :     }
     627             : 
     628           0 :     lua_pushlightuserdata(L, cl);
     629           0 :     lua_setglobal(L, ngx_http_lua_chain_key);
     630           0 :     return 0;
     631             : }
     632             : 
     633             : /* vi:set ft=c ts=4 sw=4 et fdm=marker: */

Generated by: LCOV version 1.13