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_contentby.c (source / functions) Hit Total Coverage
Test: coverage ngix Lines: 64 140 45.7 %
Date: 2020-03-03 04:25:50 Functions: 5 7 71.4 %
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_contentby.h"
      15             : #include "ngx_http_lua_util.h"
      16             : #include "ngx_http_lua_exception.h"
      17             : #include "ngx_http_lua_cache.h"
      18             : #include "ngx_http_lua_probe.h"
      19             : 
      20             : 
      21             : static void ngx_http_lua_content_phase_post_read(ngx_http_request_t *r);
      22             : 
      23             : 
      24             : ngx_int_t
      25           1 : ngx_http_lua_content_by_chunk(lua_State *L, ngx_http_request_t *r)
      26             : {
      27             :     int                      co_ref;
      28             :     ngx_int_t                rc;
      29             :     lua_State               *co;
      30             :     ngx_event_t             *rev;
      31             :     ngx_http_lua_ctx_t      *ctx;
      32             :     ngx_http_cleanup_t      *cln;
      33             : 
      34             :     ngx_http_lua_loc_conf_t      *llcf;
      35             : 
      36             :     dd("content by chunk");
      37             : 
      38           1 :     ctx = ngx_http_get_module_ctx(r, ngx_http_lua_module);
      39             : 
      40           1 :     if (ctx == NULL) {
      41           0 :         ctx = ngx_http_lua_create_ctx(r);
      42           0 :         if (ctx == NULL) {
      43           0 :             return NGX_HTTP_INTERNAL_SERVER_ERROR;
      44             :         }
      45             : 
      46             :     } else {
      47             :         dd("reset ctx");
      48           1 :         ngx_http_lua_reset_ctx(r, L, ctx);
      49             :     }
      50             : 
      51           1 :     ctx->entered_content_phase = 1;
      52             : 
      53             :     /*  {{{ new coroutine to handle request */
      54           1 :     co = ngx_http_lua_new_thread(r, L, &co_ref);
      55             : 
      56           1 :     if (co == NULL) {
      57           0 :         ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
      58             :                       "lua: failed to create new coroutine to handle request");
      59             : 
      60           0 :         return NGX_HTTP_INTERNAL_SERVER_ERROR;
      61             :     }
      62             : 
      63             :     /*  move code closure to new coroutine */
      64           1 :     lua_xmove(L, co, 1);
      65             : 
      66             :     /*  set closure's env table to new coroutine's globals table */
      67           1 :     ngx_http_lua_get_globals_table(co);
      68           1 :     lua_setfenv(co, -2);
      69             : 
      70             :     /*  save nginx request in coroutine globals table */
      71           1 :     ngx_http_lua_set_req(co, r);
      72             : 
      73           1 :     ctx->cur_co_ctx = &ctx->entry_co_ctx;
      74           1 :     ctx->cur_co_ctx->co = co;
      75           1 :     ctx->cur_co_ctx->co_ref = co_ref;
      76             : #ifdef NGX_LUA_USE_ASSERT
      77           1 :     ctx->cur_co_ctx->co_top = 1;
      78             : #endif
      79             : 
      80             :     /*  {{{ register request cleanup hooks */
      81           1 :     if (ctx->cleanup == NULL) {
      82           1 :         cln = ngx_http_cleanup_add(r, 0);
      83           1 :         if (cln == NULL) {
      84           0 :             return NGX_HTTP_INTERNAL_SERVER_ERROR;
      85             :         }
      86             : 
      87           1 :         cln->handler = ngx_http_lua_request_cleanup_handler;
      88           1 :         cln->data = ctx;
      89           1 :         ctx->cleanup = &cln->handler;
      90             :     }
      91             :     /*  }}} */
      92             : 
      93           1 :     ctx->context = NGX_HTTP_LUA_CONTEXT_CONTENT;
      94             : 
      95           1 :     llcf = ngx_http_get_module_loc_conf(r, ngx_http_lua_module);
      96             : 
      97           1 :     if (llcf->check_client_abort) {
      98           0 :         r->read_event_handler = ngx_http_lua_rd_check_broken_connection;
      99             : 
     100             : #if (NGX_HTTP_V2)
     101           0 :         if (!r->stream) {
     102             : #endif
     103             : 
     104           0 :         rev = r->connection->read;
     105             : 
     106           0 :         if (!rev->active) {
     107           0 :             if (ngx_add_event(rev, NGX_READ_EVENT, 0) != NGX_OK) {
     108           0 :                 return NGX_ERROR;
     109             :             }
     110             :         }
     111             : 
     112             : #if (NGX_HTTP_V2)
     113             :         }
     114             : #endif
     115             : 
     116             :     } else {
     117           1 :         r->read_event_handler = ngx_http_block_reading;
     118             :     }
     119             : 
     120           1 :     rc = ngx_http_lua_run_thread(L, r, ctx, 0);
     121             : 
     122           1 :     if (rc == NGX_ERROR || rc >= NGX_OK) {
     123           0 :         return rc;
     124             :     }
     125             : 
     126           1 :     if (rc == NGX_AGAIN) {
     127           1 :         return ngx_http_lua_content_run_posted_threads(L, r, ctx, 0);
     128             :     }
     129             : 
     130           0 :     if (rc == NGX_DONE) {
     131           0 :         return ngx_http_lua_content_run_posted_threads(L, r, ctx, 1);
     132             :     }
     133             : 
     134           0 :     return NGX_OK;
     135             : }
     136             : 
     137             : 
     138             : void
     139           1 : ngx_http_lua_content_wev_handler(ngx_http_request_t *r)
     140             : {
     141             :     ngx_http_lua_ctx_t          *ctx;
     142             : 
     143           1 :     ctx = ngx_http_get_module_ctx(r, ngx_http_lua_module);
     144           1 :     if (ctx == NULL) {
     145           0 :         return;
     146             :     }
     147             : 
     148           1 :     (void) ctx->resume_handler(r);
     149             : }
     150             : 
     151             : 
     152             : ngx_int_t
     153           1 : ngx_http_lua_content_handler(ngx_http_request_t *r)
     154             : {
     155             :     ngx_http_lua_loc_conf_t     *llcf;
     156             :     ngx_http_lua_ctx_t          *ctx;
     157             :     ngx_int_t                    rc;
     158             : 
     159           1 :     ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
     160             :                    "lua content handler, uri:\"%V\" c:%ud", &r->uri,
     161             :                    r->main->count);
     162             : 
     163           1 :     llcf = ngx_http_get_module_loc_conf(r, ngx_http_lua_module);
     164             : 
     165           1 :     if (llcf->content_handler == NULL) {
     166             :         dd("no content handler found");
     167           0 :         return NGX_DECLINED;
     168             :     }
     169             : 
     170           1 :     ctx = ngx_http_get_module_ctx(r, ngx_http_lua_module);
     171             : 
     172             :     dd("ctx = %p", ctx);
     173             : 
     174           1 :     if (ctx == NULL) {
     175           1 :         ctx = ngx_http_lua_create_ctx(r);
     176           1 :         if (ctx == NULL) {
     177           0 :             return NGX_HTTP_INTERNAL_SERVER_ERROR;
     178             :         }
     179             :     }
     180             : 
     181             :     dd("entered? %d", (int) ctx->entered_content_phase);
     182             : 
     183           1 :     if (ctx->waiting_more_body) {
     184           0 :         return NGX_DONE;
     185             :     }
     186             : 
     187           1 :     if (ctx->entered_content_phase) {
     188             :         dd("calling wev handler");
     189           0 :         rc = ctx->resume_handler(r);
     190             :         dd("wev handler returns %d", (int) rc);
     191           0 :         return rc;
     192             :     }
     193             : 
     194           1 :     if (llcf->force_read_body && !ctx->read_body_done) {
     195           0 :         r->request_body_in_single_buf = 1;
     196           0 :         r->request_body_in_persistent_file = 1;
     197           0 :         r->request_body_in_clean_file = 1;
     198             : 
     199           0 :         rc = ngx_http_read_client_request_body(r,
     200             :                                         ngx_http_lua_content_phase_post_read);
     201             : 
     202           0 :         if (rc == NGX_ERROR || rc >= NGX_HTTP_SPECIAL_RESPONSE) {
     203             : #if (nginx_version < 1002006) ||                                             \
     204             :         (nginx_version >= 1003000 && nginx_version < 1003009)
     205             :             r->main->count--;
     206             : #endif
     207           0 :             return rc;
     208             :         }
     209             : 
     210           0 :         if (rc == NGX_AGAIN) {
     211           0 :             ctx->waiting_more_body = 1;
     212             : 
     213           0 :             return NGX_DONE;
     214             :         }
     215             :     }
     216             : 
     217             :     dd("setting entered");
     218             : 
     219           1 :     ctx->entered_content_phase = 1;
     220             : 
     221             :     dd("calling content handler");
     222           1 :     return llcf->content_handler(r);
     223             : }
     224             : 
     225             : 
     226             : /* post read callback for the content phase */
     227             : static void
     228           0 : ngx_http_lua_content_phase_post_read(ngx_http_request_t *r)
     229             : {
     230             :     ngx_http_lua_ctx_t  *ctx;
     231             : 
     232           0 :     ctx = ngx_http_get_module_ctx(r, ngx_http_lua_module);
     233             : 
     234           0 :     ctx->read_body_done = 1;
     235             : 
     236           0 :     if (ctx->waiting_more_body) {
     237           0 :         ctx->waiting_more_body = 0;
     238           0 :         ngx_http_lua_finalize_request(r, ngx_http_lua_content_handler(r));
     239             : 
     240             :     } else {
     241           0 :         r->main->count--;
     242             :     }
     243           0 : }
     244             : 
     245             : 
     246             : ngx_int_t
     247           0 : ngx_http_lua_content_handler_file(ngx_http_request_t *r)
     248             : {
     249             :     lua_State                       *L;
     250             :     ngx_int_t                        rc;
     251             :     u_char                          *script_path;
     252             :     ngx_http_lua_loc_conf_t         *llcf;
     253             :     ngx_str_t                        eval_src;
     254             : 
     255           0 :     llcf = ngx_http_get_module_loc_conf(r, ngx_http_lua_module);
     256             : 
     257           0 :     if (ngx_http_complex_value(r, &llcf->content_src, &eval_src) != NGX_OK) {
     258           0 :         return NGX_ERROR;
     259             :     }
     260             : 
     261           0 :     script_path = ngx_http_lua_rebase_path(r->pool, eval_src.data,
     262             :                                            eval_src.len);
     263             : 
     264           0 :     if (script_path == NULL) {
     265           0 :         return NGX_ERROR;
     266             :     }
     267             : 
     268           0 :     L = ngx_http_lua_get_lua_vm(r, NULL);
     269             : 
     270             :     /*  load Lua script file (w/ cache)        sp = 1 */
     271           0 :     rc = ngx_http_lua_cache_loadfile(r->connection->log, L, script_path,
     272           0 :                                      llcf->content_src_key);
     273           0 :     if (rc != NGX_OK) {
     274           0 :         if (rc < NGX_HTTP_SPECIAL_RESPONSE) {
     275           0 :             return NGX_HTTP_INTERNAL_SERVER_ERROR;
     276             :         }
     277             : 
     278           0 :         return rc;
     279             :     }
     280             : 
     281             :     /*  make sure we have a valid code chunk */
     282           0 :     ngx_http_lua_assert(lua_isfunction(L, -1));
     283             : 
     284           0 :     return ngx_http_lua_content_by_chunk(L, r);
     285             : }
     286             : 
     287             : 
     288             : ngx_int_t
     289           1 : ngx_http_lua_content_handler_inline(ngx_http_request_t *r)
     290             : {
     291             :     lua_State                   *L;
     292             :     ngx_int_t                    rc;
     293             :     ngx_http_lua_loc_conf_t     *llcf;
     294             : 
     295           1 :     llcf = ngx_http_get_module_loc_conf(r, ngx_http_lua_module);
     296             : 
     297           1 :     L = ngx_http_lua_get_lua_vm(r, NULL);
     298             : 
     299             :     /*  load Lua inline script (w/ cache) sp = 1 */
     300           2 :     rc = ngx_http_lua_cache_loadbuffer(r->connection->log, L,
     301           1 :                                        llcf->content_src.value.data,
     302             :                                        llcf->content_src.value.len,
     303           1 :                                        llcf->content_src_key,
     304             :                                        (const char *)
     305           1 :                                        llcf->content_chunkname);
     306           1 :     if (rc != NGX_OK) {
     307           0 :         return NGX_HTTP_INTERNAL_SERVER_ERROR;
     308             :     }
     309             : 
     310           1 :     return ngx_http_lua_content_by_chunk(L, r);
     311             : }
     312             : 
     313             : 
     314             : ngx_int_t
     315           1 : ngx_http_lua_content_run_posted_threads(lua_State *L, ngx_http_request_t *r,
     316             :     ngx_http_lua_ctx_t *ctx, int n)
     317             : {
     318             :     ngx_int_t                        rc;
     319             :     ngx_http_lua_posted_thread_t    *pt;
     320             : 
     321             :     dd("run posted threads: %p", ctx->posted_threads);
     322             : 
     323             :     for ( ;; ) {
     324           1 :         pt = ctx->posted_threads;
     325           1 :         if (pt == NULL) {
     326           1 :             goto done;
     327             :         }
     328             : 
     329           0 :         ctx->posted_threads = pt->next;
     330             : 
     331             :         ngx_http_lua_probe_run_posted_thread(r, pt->co_ctx->co,
     332             :                                              (int) pt->co_ctx->co_status);
     333             : 
     334             :         dd("posted thread status: %d", pt->co_ctx->co_status);
     335             : 
     336           0 :         if (pt->co_ctx->co_status != NGX_HTTP_LUA_CO_RUNNING) {
     337           0 :             continue;
     338             :         }
     339             : 
     340           0 :         ctx->cur_co_ctx = pt->co_ctx;
     341             : 
     342           0 :         rc = ngx_http_lua_run_thread(L, r, ctx, 0);
     343             : 
     344           0 :         if (rc == NGX_AGAIN) {
     345           0 :             continue;
     346             :         }
     347             : 
     348           0 :         if (rc == NGX_DONE) {
     349           0 :             n++;
     350           0 :             continue;
     351             :         }
     352             : 
     353           0 :         if (rc == NGX_OK) {
     354           0 :             while (n > 0) {
     355           0 :                 ngx_http_lua_finalize_request(r, NGX_DONE);
     356           0 :                 n--;
     357             :             }
     358             : 
     359           0 :             return NGX_OK;
     360             :         }
     361             : 
     362             :         /* rc == NGX_ERROR || rc > NGX_OK */
     363             : 
     364           0 :         return rc;
     365             :     }
     366             : 
     367           1 : done:
     368             : 
     369           1 :     if (n == 1) {
     370           0 :         return NGX_DONE;
     371             :     }
     372             : 
     373           1 :     if (n == 0) {
     374           1 :         r->main->count++;
     375           1 :         return NGX_DONE;
     376             :     }
     377             : 
     378             :     /* n > 1 */
     379             : 
     380             :     do {
     381           0 :         ngx_http_lua_finalize_request(r, NGX_DONE);
     382           0 :     } while (--n > 1);
     383             : 
     384           0 :     return NGX_DONE;
     385             : }
     386             : 
     387             : /* vi:set ft=c ts=4 sw=4 et fdm=marker: */

Generated by: LCOV version 1.13