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_headerfilterby.c (source / functions) Hit Total Coverage
Test: coverage ngix Lines: 0 93 0.0 %
Date: 2020-03-03 04:25:50 Functions: 0 6 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : 
       2             : /*
       3             :  * Copyright (C) Yichun Zhang (agentzh)
       4             :  */
       5             : 
       6             : 
       7             : #ifndef DDEBUG
       8             : #define DDEBUG 0
       9             : #endif
      10             : #include "ddebug.h"
      11             : 
      12             : #include "ngx_http_lua_headerfilterby.h"
      13             : #include "ngx_http_lua_exception.h"
      14             : #include "ngx_http_lua_util.h"
      15             : #include "ngx_http_lua_pcrefix.h"
      16             : #include "ngx_http_lua_time.h"
      17             : #include "ngx_http_lua_log.h"
      18             : #include "ngx_http_lua_regex.h"
      19             : #include "ngx_http_lua_cache.h"
      20             : #include "ngx_http_lua_headers.h"
      21             : #include "ngx_http_lua_variable.h"
      22             : #include "ngx_http_lua_string.h"
      23             : #include "ngx_http_lua_misc.h"
      24             : #include "ngx_http_lua_consts.h"
      25             : #include "ngx_http_lua_shdict.h"
      26             : 
      27             : 
      28             : static ngx_http_output_header_filter_pt ngx_http_next_header_filter;
      29             : 
      30             : 
      31             : /**
      32             :  * Set environment table for the given code closure.
      33             :  *
      34             :  * Before:
      35             :  *         | code closure | <- top
      36             :  *         |      ...     |
      37             :  *
      38             :  * After:
      39             :  *         | code closure | <- top
      40             :  *         |      ...     |
      41             :  * */
      42             : static void
      43           0 : ngx_http_lua_header_filter_by_lua_env(lua_State *L, ngx_http_request_t *r)
      44             : {
      45             :     /*  set nginx request pointer to current lua thread's globals table */
      46           0 :     ngx_http_lua_set_req(L, r);
      47             : 
      48             :     /**
      49             :      * we want to create empty environment for current script
      50             :      *
      51             :      * newt = {}
      52             :      * newt["_G"] = newt
      53             :      * setmetatable(newt, {__index = _G})
      54             :      *
      55             :      * if a function or symbol is not defined in our env, __index will lookup
      56             :      * in the global env.
      57             :      *
      58             :      * all variables created in the script-env will be thrown away at the end
      59             :      * of the script run.
      60             :      * */
      61           0 :     ngx_http_lua_create_new_globals_table(L, 0 /* narr */, 1 /* nrec */);
      62             : 
      63             :     /*  {{{ make new env inheriting main thread's globals table */
      64           0 :     lua_createtable(L, 0, 1 /* nrec */);   /* the metatable for the new env */
      65           0 :     ngx_http_lua_get_globals_table(L);
      66           0 :     lua_setfield(L, -2, "__index");
      67           0 :     lua_setmetatable(L, -2);    /*  setmetatable({}, {__index = _G}) */
      68             :     /*  }}} */
      69             : 
      70           0 :     lua_setfenv(L, -2);    /*  set new running env for the code closure */
      71           0 : }
      72             : 
      73             : 
      74             : ngx_int_t
      75           0 : ngx_http_lua_header_filter_by_chunk(lua_State *L, ngx_http_request_t *r)
      76             : {
      77           0 :     int              old_exit_code = 0;
      78             :     ngx_int_t        rc;
      79             :     u_char          *err_msg;
      80             :     size_t           len;
      81             : #if (NGX_PCRE)
      82             :     ngx_pool_t      *old_pool;
      83             : #endif
      84             :     ngx_http_lua_ctx_t          *ctx;
      85             : 
      86           0 :     ctx = ngx_http_get_module_ctx(r, ngx_http_lua_module);
      87           0 :     if (ctx->exited) {
      88           0 :         old_exit_code = ctx->exit_code;
      89             :     }
      90             : 
      91             :     /*  initialize nginx context in Lua VM, code chunk at stack top    sp = 1 */
      92           0 :     ngx_http_lua_header_filter_by_lua_env(L, r);
      93             : 
      94             : #if (NGX_PCRE)
      95             :     /* XXX: work-around to nginx regex subsystem */
      96           0 :     old_pool = ngx_http_lua_pcre_malloc_init(r->pool);
      97             : #endif
      98             : 
      99           0 :     lua_pushcfunction(L, ngx_http_lua_traceback);
     100           0 :     lua_insert(L, 1);  /* put it under chunk and args */
     101             : 
     102             :     /*  protected call user code */
     103           0 :     rc = lua_pcall(L, 0, 1, 1);
     104             : 
     105           0 :     lua_remove(L, 1);  /* remove traceback function */
     106             : 
     107             : #if (NGX_PCRE)
     108             :     /* XXX: work-around to nginx regex subsystem */
     109           0 :     ngx_http_lua_pcre_malloc_done(old_pool);
     110             : #endif
     111             : 
     112             :     dd("rc == %d", (int) rc);
     113             : 
     114           0 :     if (rc != 0) {
     115             :         /*  error occurred when running loaded code */
     116           0 :         err_msg = (u_char *) lua_tolstring(L, -1, &len);
     117             : 
     118           0 :         if (err_msg == NULL) {
     119           0 :             err_msg = (u_char *) "unknown reason";
     120           0 :             len = sizeof("unknown reason") - 1;
     121             :         }
     122             : 
     123           0 :         ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
     124             :                       "failed to run header_filter_by_lua*: %*s", len, err_msg);
     125             : 
     126           0 :         lua_settop(L, 0); /*  clear remaining elems on stack */
     127             : 
     128           0 :         return NGX_ERROR;
     129             :     }
     130             : 
     131             :     dd("exited: %d, exit code: %d, old exit code: %d",
     132             :        (int) ctx->exited, (int) ctx->exit_code, (int) old_exit_code);
     133             : 
     134             : #if 1
     135             :     /*  clear Lua stack */
     136           0 :     lua_settop(L, 0);
     137             : #endif
     138             : 
     139           0 :     if (ctx->exited && ctx->exit_code != old_exit_code) {
     140           0 :         if (ctx->exit_code == NGX_ERROR) {
     141           0 :             return NGX_ERROR;
     142             :         }
     143             : 
     144             :         dd("finalize request with %d", (int) ctx->exit_code);
     145             : 
     146           0 :         rc = ngx_http_filter_finalize_request(r, &ngx_http_lua_module,
     147             :                                               ctx->exit_code);
     148           0 :         if (rc == NGX_ERROR || rc == NGX_AGAIN) {
     149           0 :             return rc;
     150             :         }
     151             : 
     152           0 :         return NGX_DECLINED;
     153             :     }
     154             : 
     155           0 :     return NGX_OK;
     156             : }
     157             : 
     158             : 
     159             : ngx_int_t
     160           0 : ngx_http_lua_header_filter_inline(ngx_http_request_t *r)
     161             : {
     162             :     lua_State                   *L;
     163             :     ngx_int_t                    rc;
     164             :     ngx_http_lua_loc_conf_t     *llcf;
     165             : 
     166           0 :     llcf = ngx_http_get_module_loc_conf(r, ngx_http_lua_module);
     167             : 
     168           0 :     L = ngx_http_lua_get_lua_vm(r, NULL);
     169             : 
     170             :     /*  load Lua inline script (w/ cache) sp = 1 */
     171           0 :     rc = ngx_http_lua_cache_loadbuffer(r->connection->log, L,
     172           0 :                                        llcf->header_filter_src.value.data,
     173             :                                        llcf->header_filter_src.value.len,
     174           0 :                                        llcf->header_filter_src_key,
     175             :                                        "=header_filter_by_lua");
     176           0 :     if (rc != NGX_OK) {
     177           0 :         return NGX_ERROR;
     178             :     }
     179             : 
     180             :     dd("calling header filter by chunk");
     181             : 
     182           0 :     return ngx_http_lua_header_filter_by_chunk(L, r);
     183             : }
     184             : 
     185             : 
     186             : ngx_int_t
     187           0 : ngx_http_lua_header_filter_file(ngx_http_request_t *r)
     188             : {
     189             :     lua_State                       *L;
     190             :     ngx_int_t                        rc;
     191             :     u_char                          *script_path;
     192             :     ngx_http_lua_loc_conf_t         *llcf;
     193             :     ngx_str_t                        eval_src;
     194             : 
     195           0 :     llcf = ngx_http_get_module_loc_conf(r, ngx_http_lua_module);
     196             : 
     197             :     /* Eval nginx variables in code path string first */
     198           0 :     if (ngx_http_complex_value(r, &llcf->header_filter_src, &eval_src)
     199             :         != NGX_OK)
     200             :     {
     201           0 :         return NGX_ERROR;
     202             :     }
     203             : 
     204           0 :     script_path = ngx_http_lua_rebase_path(r->pool, eval_src.data,
     205             :                                            eval_src.len);
     206             : 
     207           0 :     if (script_path == NULL) {
     208           0 :         return NGX_ERROR;
     209             :     }
     210             : 
     211           0 :     L = ngx_http_lua_get_lua_vm(r, NULL);
     212             : 
     213             :     /*  load Lua script file (w/ cache)        sp = 1 */
     214           0 :     rc = ngx_http_lua_cache_loadfile(r->connection->log, L, script_path,
     215           0 :                                      llcf->header_filter_src_key);
     216           0 :     if (rc != NGX_OK) {
     217           0 :         return NGX_ERROR;
     218             :     }
     219             : 
     220             :     /*  make sure we have a valid code chunk */
     221           0 :     ngx_http_lua_assert(lua_isfunction(L, -1));
     222             : 
     223           0 :     return ngx_http_lua_header_filter_by_chunk(L, r);
     224             : }
     225             : 
     226             : 
     227             : static ngx_int_t
     228           0 : ngx_http_lua_header_filter(ngx_http_request_t *r)
     229             : {
     230             :     ngx_http_lua_loc_conf_t     *llcf;
     231             :     ngx_http_lua_ctx_t          *ctx;
     232             :     ngx_int_t                    rc;
     233             :     ngx_http_cleanup_t          *cln;
     234             :     uint16_t                     old_context;
     235             : 
     236           0 :     ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
     237             :                    "lua header filter for user lua code, uri \"%V\"", &r->uri);
     238             : 
     239           0 :     llcf = ngx_http_get_module_loc_conf(r, ngx_http_lua_module);
     240             : 
     241           0 :     if (llcf->body_filter_handler) {
     242           0 :         r->filter_need_in_memory = 1;
     243             :     }
     244             : 
     245           0 :     if (llcf->header_filter_handler == NULL) {
     246             :         dd("no header filter handler found");
     247           0 :         return ngx_http_next_header_filter(r);
     248             :     }
     249             : 
     250           0 :     ctx = ngx_http_get_module_ctx(r, ngx_http_lua_module);
     251             : 
     252             :     dd("ctx = %p", ctx);
     253             : 
     254           0 :     if (ctx == NULL) {
     255           0 :         ctx = ngx_http_lua_create_ctx(r);
     256           0 :         if (ctx == NULL) {
     257           0 :             return NGX_ERROR;
     258             :         }
     259             :     }
     260             : 
     261           0 :     if (ctx->cleanup == NULL) {
     262           0 :         cln = ngx_http_cleanup_add(r, 0);
     263           0 :         if (cln == NULL) {
     264           0 :             return NGX_ERROR;
     265             :         }
     266             : 
     267           0 :         cln->handler = ngx_http_lua_request_cleanup_handler;
     268           0 :         cln->data = ctx;
     269           0 :         ctx->cleanup = &cln->handler;
     270             :     }
     271             : 
     272           0 :     old_context = ctx->context;
     273           0 :     ctx->context = NGX_HTTP_LUA_CONTEXT_HEADER_FILTER;
     274             : 
     275             :     dd("calling header filter handler");
     276           0 :     rc = llcf->header_filter_handler(r);
     277             : 
     278           0 :     ctx->context = old_context;
     279             : 
     280           0 :     if (rc == NGX_DECLINED) {
     281           0 :         return NGX_OK;
     282             :     }
     283             : 
     284           0 :     if (rc == NGX_AGAIN || rc == NGX_ERROR) {
     285           0 :         return rc;
     286             :     }
     287             : 
     288           0 :     return ngx_http_next_header_filter(r);
     289             : }
     290             : 
     291             : 
     292             : ngx_int_t
     293           0 : ngx_http_lua_header_filter_init(void)
     294             : {
     295             :     dd("calling header filter init");
     296           0 :     ngx_http_next_header_filter = ngx_http_top_header_filter;
     297           0 :     ngx_http_top_header_filter = ngx_http_lua_header_filter;
     298             : 
     299           0 :     return NGX_OK;
     300             : }
     301             : 
     302             : /* vi:set ft=c ts=4 sw=4 et fdm=marker: */

Generated by: LCOV version 1.13