1 2 /* 3 * Copyright (C) Xiaozhe Wang (chaoslawful) 4 * Copyright (C) Yichun Zhang (agentzh) 5 */ 6 7 8 #ifndef _NGX_HTTP_LUA_COMMON_H_INCLUDED_ 9 #define _NGX_HTTP_LUA_COMMON_H_INCLUDED_ 10 11 12 #include "ngx_http_lua_autoconf.h" 13 14 #include <nginx.h> 15 #include <ngx_core.h> 16 #include <ngx_http.h> 17 #include <ngx_md5.h> 18 19 #include <setjmp.h> 20 #include <stdint.h> 21 22 #include <luajit.h> 23 #include <lualib.h> 24 #include <lauxlib.h> 25 26 27 #if defined(NDK) && NDK 28 #include <ndk.h> 29 30 typedef struct { 31 size_t size; 32 int ref; 33 u_char *key; 34 ngx_str_t script; 35 } ngx_http_lua_set_var_data_t; 36 #endif 37 38 39 #ifdef NGX_LUA_USE_ASSERT 40 #include <assert.h> 41 # define ngx_http_lua_assert(a) assert(a) 42 #else 43 # define ngx_http_lua_assert(a) 44 #endif 45 46 47 /** 48 * max positive +1.7976931348623158e+308 49 * min positive +2.2250738585072014e-308 50 */ 51 #ifndef NGX_DOUBLE_LEN 52 #define NGX_DOUBLE_LEN 25 53 #endif 54 55 56 #if (NGX_PCRE) 57 #include <pcre.h> 58 # if (PCRE_MAJOR > 8) || (PCRE_MAJOR == 8 && PCRE_MINOR >= 21) 59 # define LUA_HAVE_PCRE_JIT 1 60 # else 61 # define LUA_HAVE_PCRE_JIT 0 62 # endif 63 #endif 64 65 66 #if (nginx_version < 1006000) 67 # error at least nginx 1.6.0 is required but found an older version 68 #endif 69 70 #if LUA_VERSION_NUM != 501 71 # error unsupported Lua language version 72 #endif 73 74 #if !defined(LUAJIT_VERSION_NUM) || (LUAJIT_VERSION_NUM < 20000) 75 # error unsupported LuaJIT version 76 #endif 77 78 79 #if (!defined OPENSSL_NO_OCSP && defined SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB) 80 # define NGX_HTTP_LUA_USE_OCSP 1 81 #endif 82 83 #ifndef NGX_HTTP_PERMANENT_REDIRECT 84 # define NGX_HTTP_PERMANENT_REDIRECT 308 85 #endif 86 87 #ifndef NGX_HAVE_SHA1 88 # if (nginx_version >= 1011002) 89 # define NGX_HAVE_SHA1 1 90 # endif 91 #endif 92 93 #ifndef MD5_DIGEST_LENGTH 94 # define MD5_DIGEST_LENGTH 16 95 #endif 96 97 #ifndef NGX_HTTP_LUA_MAX_ARGS 98 # define NGX_HTTP_LUA_MAX_ARGS 100 99 #endif 100 101 #ifndef NGX_HTTP_LUA_MAX_HEADERS 102 # define NGX_HTTP_LUA_MAX_HEADERS 100 103 #endif 104 105 106 /* Nginx HTTP Lua Inline tag prefix */ 107 108 #define NGX_HTTP_LUA_INLINE_TAG "nhli_" 109 110 #define NGX_HTTP_LUA_INLINE_TAG_LEN \ 111 (sizeof(NGX_HTTP_LUA_INLINE_TAG) - 1) 112 113 #define NGX_HTTP_LUA_INLINE_KEY_LEN \ 114 (NGX_HTTP_LUA_INLINE_TAG_LEN + 2 * MD5_DIGEST_LENGTH) 115 116 /* Nginx HTTP Lua File tag prefix */ 117 118 #define NGX_HTTP_LUA_FILE_TAG "nhlf_" 119 120 #define NGX_HTTP_LUA_FILE_TAG_LEN \ 121 (sizeof(NGX_HTTP_LUA_FILE_TAG) - 1) 122 123 #define NGX_HTTP_LUA_FILE_KEY_LEN \ 124 (NGX_HTTP_LUA_FILE_TAG_LEN + 2 * MD5_DIGEST_LENGTH) 125 126 127 /* must be within 16 bit */ 128 #define NGX_HTTP_LUA_CONTEXT_SET 0x0001 129 #define NGX_HTTP_LUA_CONTEXT_REWRITE 0x0002 130 #define NGX_HTTP_LUA_CONTEXT_ACCESS 0x0004 131 #define NGX_HTTP_LUA_CONTEXT_CONTENT 0x0008 132 #define NGX_HTTP_LUA_CONTEXT_LOG 0x0010 133 #define NGX_HTTP_LUA_CONTEXT_HEADER_FILTER 0x0020 134 #define NGX_HTTP_LUA_CONTEXT_BODY_FILTER 0x0040 135 #define NGX_HTTP_LUA_CONTEXT_TIMER 0x0080 136 #define NGX_HTTP_LUA_CONTEXT_INIT_WORKER 0x0100 137 #define NGX_HTTP_LUA_CONTEXT_BALANCER 0x0200 138 #define NGX_HTTP_LUA_CONTEXT_SSL_CERT 0x0400 139 #define NGX_HTTP_LUA_CONTEXT_SSL_SESS_STORE 0x0800 140 #define NGX_HTTP_LUA_CONTEXT_SSL_SESS_FETCH 0x1000 141 #define NGX_HTTP_LUA_CONTEXT_EXIT_WORKER 0x2000 142 143 144 #define NGX_HTTP_LUA_FFI_NO_REQ_CTX -100 145 #define NGX_HTTP_LUA_FFI_BAD_CONTEXT -101 146 147 148 #if (NGX_PTR_SIZE >= 8 && !defined(_WIN64)) 149 # define ngx_http_lua_lightudata_mask(ludata) \ 150 ((void *) ((uintptr_t) (&ngx_http_lua_##ludata) & ((1UL << 47) - 1))) 151 #else 152 # define ngx_http_lua_lightudata_mask(ludata) \ 153 (&ngx_http_lua_##ludata) 154 #endif 155 156 157 typedef struct ngx_http_lua_co_ctx_s ngx_http_lua_co_ctx_t; 158 159 typedef struct ngx_http_lua_sema_mm_s ngx_http_lua_sema_mm_t; 160 161 typedef union ngx_http_lua_srv_conf_u ngx_http_lua_srv_conf_t; 162 163 typedef struct ngx_http_lua_main_conf_s ngx_http_lua_main_conf_t; 164 165 typedef struct ngx_http_lua_header_val_s ngx_http_lua_header_val_t; 166 167 typedef struct ngx_http_lua_posted_thread_s ngx_http_lua_posted_thread_t; 168 169 typedef struct ngx_http_lua_balancer_peer_data_s 170 ngx_http_lua_balancer_peer_data_t; 171 172 typedef ngx_int_t (*ngx_http_lua_main_conf_handler_pt)(ngx_log_t *log, 173 ngx_http_lua_main_conf_t *lmcf, lua_State *L); 174 175 typedef ngx_int_t (*ngx_http_lua_srv_conf_handler_pt)(ngx_http_request_t *r, 176 ngx_http_lua_srv_conf_t *lscf, lua_State *L); 177 178 typedef ngx_int_t (*ngx_http_lua_set_header_pt)(ngx_http_request_t *r, 179 ngx_http_lua_header_val_t *hv, ngx_str_t *value); 180 181 182 typedef struct { 183 u_char *package; 184 lua_CFunction loader; 185 } ngx_http_lua_preload_hook_t; 186 187 188 typedef struct { 189 int ref; 190 lua_State *co; 191 ngx_queue_t queue; 192 } ngx_http_lua_thread_ref_t; 193 194 195 struct ngx_http_lua_main_conf_s { 196 lua_State *lua; 197 ngx_pool_cleanup_t *vm_cleanup; 198 199 ngx_str_t lua_path; 200 ngx_str_t lua_cpath; 201 202 ngx_cycle_t *cycle; 203 ngx_pool_t *pool; 204 205 ngx_int_t max_pending_timers; 206 ngx_int_t pending_timers; 207 208 ngx_int_t max_running_timers; 209 ngx_int_t running_timers; 210 211 ngx_connection_t *watcher; /* for watching the process exit event */ 212 213 ngx_int_t lua_thread_cache_max_entries; 214 215 #if (NGX_PCRE) 216 ngx_int_t regex_cache_entries; 217 ngx_int_t regex_cache_max_entries; 218 ngx_int_t regex_match_limit; 219 # if (LUA_HAVE_PCRE_JIT) 220 pcre_jit_stack *jit_stack; 221 # endif 222 #endif 223 224 ngx_array_t *shm_zones; /* of ngx_shm_zone_t* */ 225 226 ngx_array_t *shdict_zones; /* shm zones of "shdict" */ 227 228 ngx_array_t *preload_hooks; /* of ngx_http_lua_preload_hook_t */ 229 230 ngx_flag_t postponed_to_rewrite_phase_end; 231 ngx_flag_t postponed_to_access_phase_end; 232 233 ngx_http_lua_main_conf_handler_pt init_handler; 234 ngx_str_t init_src; 235 236 ngx_http_lua_main_conf_handler_pt init_worker_handler; 237 ngx_str_t init_worker_src; 238 239 ngx_http_lua_main_conf_handler_pt exit_worker_handler; 240 ngx_str_t exit_worker_src; 241 242 ngx_http_lua_balancer_peer_data_t *balancer_peer_data; 243 /* neither yielding nor recursion is possible in 244 * balancer_by_lua*, so there cannot be any races among 245 * concurrent requests and it is safe to store the peer 246 * data pointer in the main conf. 247 */ 248 249 ngx_chain_t *body_filter_chain; 250 /* neither yielding nor recursion is possible in 251 * body_filter_by_lua*, so there cannot be any races among 252 * concurrent requests when storing the chain 253 * data pointer in the main conf. 254 */ 255 256 ngx_http_variable_value_t *setby_args; 257 /* neither yielding nor recursion is possible in 258 * set_by_lua*, so there cannot be any races among 259 * concurrent requests when storing the args pointer 260 * in the main conf. 261 */ 262 263 size_t setby_nargs; 264 /* neither yielding nor recursion is possible in 265 * set_by_lua*, so there cannot be any races among 266 * concurrent requests when storing the nargs in the 267 * main conf. 268 */ 269 270 ngx_uint_t shm_zones_inited; 271 272 ngx_http_lua_sema_mm_t *sema_mm; 273 274 ngx_uint_t malloc_trim_cycle; /* a cycle is defined as the number 275 of reqeusts */ 276 ngx_uint_t malloc_trim_req_count; 277 278 #if (nginx_version >= 1011011) 279 /* the following 2 fields are only used by ngx.req.raw_headers() for now */ 280 ngx_buf_t **busy_buf_ptrs; 281 ngx_int_t busy_buf_ptr_count; 282 #endif 283 284 ngx_int_t host_var_index; 285 286 ngx_flag_t set_sa_restart; 287 288 ngx_queue_t free_lua_threads; /* of ngx_http_lua_thread_ref_t */ 289 ngx_queue_t cached_lua_threads; /* of ngx_http_lua_thread_ref_t */ 290 291 unsigned requires_header_filter:1; 292 unsigned requires_body_filter:1; 293 unsigned requires_capture_filter:1; 294 unsigned requires_rewrite:1; 295 unsigned requires_access:1; 296 unsigned requires_log:1; 297 unsigned requires_shm:1; 298 unsigned requires_capture_log:1; 299 }; 300 301 302 union ngx_http_lua_srv_conf_u { 303 #if (NGX_HTTP_SSL) 304 struct { 305 ngx_http_lua_srv_conf_handler_pt ssl_cert_handler; 306 ngx_str_t ssl_cert_src; 307 u_char *ssl_cert_src_key; 308 int ssl_cert_src_ref; 309 310 ngx_http_lua_srv_conf_handler_pt ssl_sess_store_handler; 311 ngx_str_t ssl_sess_store_src; 312 u_char *ssl_sess_store_src_key; 313 int ssl_sess_store_src_ref; 314 315 ngx_http_lua_srv_conf_handler_pt ssl_sess_fetch_handler; 316 ngx_str_t ssl_sess_fetch_src; 317 u_char *ssl_sess_fetch_src_key; 318 int ssl_sess_fetch_src_ref; 319 } srv; 320 #endif 321 322 struct { 323 ngx_http_lua_srv_conf_handler_pt handler; 324 ngx_str_t src; 325 u_char *src_key; 326 int src_ref; 327 } balancer; 328 }; 329 330 331 typedef struct { 332 #if (NGX_HTTP_SSL) 333 ngx_ssl_t *ssl; /* shared by SSL cosockets */ 334 ngx_uint_t ssl_protocols; 335 ngx_str_t ssl_ciphers; 336 ngx_uint_t ssl_verify_depth; 337 ngx_str_t ssl_trusted_certificate; 338 ngx_str_t ssl_crl; 339 #endif 340 341 ngx_flag_t force_read_body; /* whether force request body to 342 be read */ 343 344 ngx_flag_t enable_code_cache; /* whether to enable 345 code cache */ 346 347 ngx_flag_t http10_buffering; 348 349 ngx_http_handler_pt rewrite_handler; 350 ngx_http_handler_pt access_handler; 351 ngx_http_handler_pt content_handler; 352 ngx_http_handler_pt log_handler; 353 ngx_http_handler_pt header_filter_handler; 354 355 ngx_http_output_body_filter_pt body_filter_handler; 356 357 u_char *rewrite_chunkname; 358 ngx_http_complex_value_t rewrite_src; /* rewrite_by_lua 359 inline script/script 360 file path */ 361 362 u_char *rewrite_src_key; /* cached key for rewrite_src */ 363 int rewrite_src_ref; 364 365 u_char *access_chunkname; 366 ngx_http_complex_value_t access_src; /* access_by_lua 367 inline script/script 368 file path */ 369 370 u_char *access_src_key; /* cached key for access_src */ 371 int access_src_ref; 372 373 u_char *content_chunkname; 374 ngx_http_complex_value_t content_src; /* content_by_lua 375 inline script/script 376 file path */ 377 378 u_char *content_src_key; /* cached key for content_src */ 379 int content_src_ref; 380 381 382 u_char *log_chunkname; 383 ngx_http_complex_value_t log_src; /* log_by_lua inline script/script 384 file path */ 385 386 u_char *log_src_key; /* cached key for log_src */ 387 int log_src_ref; 388 389 ngx_http_complex_value_t header_filter_src; /* header_filter_by_lua 390 inline script/script 391 file path */ 392 393 u_char *header_filter_src_key; 394 /* cached key for header_filter_src */ 395 int header_filter_src_ref; 396 397 398 ngx_http_complex_value_t body_filter_src; 399 u_char *body_filter_src_key; 400 int body_filter_src_ref; 401 402 ngx_msec_t keepalive_timeout; 403 ngx_msec_t connect_timeout; 404 ngx_msec_t send_timeout; 405 ngx_msec_t read_timeout; 406 407 size_t send_lowat; 408 size_t buffer_size; 409 410 ngx_uint_t pool_size; 411 412 ngx_flag_t transform_underscores_in_resp_headers; 413 ngx_flag_t log_socket_errors; 414 ngx_flag_t check_client_abort; 415 ngx_flag_t use_default_type; 416 } ngx_http_lua_loc_conf_t; 417 418 419 typedef enum { 420 NGX_HTTP_LUA_USER_CORO_NOP = 0, 421 NGX_HTTP_LUA_USER_CORO_RESUME = 1, 422 NGX_HTTP_LUA_USER_CORO_YIELD = 2, 423 NGX_HTTP_LUA_USER_THREAD_RESUME = 3, 424 } ngx_http_lua_user_coro_op_t; 425 426 427 typedef enum { 428 NGX_HTTP_LUA_CO_RUNNING = 0, /* coroutine running */ 429 NGX_HTTP_LUA_CO_SUSPENDED = 1, /* coroutine suspended */ 430 NGX_HTTP_LUA_CO_NORMAL = 2, /* coroutine normal */ 431 NGX_HTTP_LUA_CO_DEAD = 3, /* coroutine dead */ 432 NGX_HTTP_LUA_CO_ZOMBIE = 4, /* coroutine zombie */ 433 } ngx_http_lua_co_status_t; 434 435 436 struct ngx_http_lua_posted_thread_s { 437 ngx_http_lua_co_ctx_t *co_ctx; 438 ngx_http_lua_posted_thread_t *next; 439 }; 440 441 442 struct ngx_http_lua_co_ctx_s { 443 void *data; /* user state for cosockets */ 444 445 lua_State *co; 446 ngx_http_lua_co_ctx_t *parent_co_ctx; 447 448 ngx_http_lua_posted_thread_t *zombie_child_threads; 449 ngx_http_lua_posted_thread_t **next_zombie_child_thread; 450 451 ngx_http_cleanup_pt cleanup; 452 453 ngx_int_t *sr_statuses; /* all capture subrequest statuses */ 454 455 ngx_http_headers_out_t **sr_headers; 456 457 ngx_str_t *sr_bodies; /* all captured subrequest bodies */ 458 459 uint8_t *sr_flags; 460 461 unsigned nsubreqs; /* number of subrequests of the 462 * current request */ 463 464 unsigned pending_subreqs; /* number of subrequests being 465 waited */ 466 467 ngx_event_t sleep; /* used for ngx.sleep */ 468 469 ngx_queue_t sem_wait_queue; 470 471 #ifdef NGX_LUA_USE_ASSERT 472 int co_top; /* stack top after yielding/creation, 473 only for sanity checks */ 474 #endif 475 476 int co_ref; /* reference to anchor the thread 477 coroutines (entry coroutine and user 478 threads) in the Lua registry, 479 preventing the thread coroutine 480 from beging collected by the 481 Lua GC */ 482 483 unsigned waited_by_parent:1; /* whether being waited by 484 a parent coroutine */ 485 486 unsigned co_status:3; /* the current coroutine's status */ 487 488 unsigned flushing:1; /* indicates whether the current 489 coroutine is waiting for 490 ngx.flush(true) */ 491 492 unsigned is_uthread:1; /* whether the current coroutine is 493 a user thread */ 494 495 unsigned thread_spawn_yielded:1; /* yielded from 496 the ngx.thread.spawn() 497 call */ 498 unsigned sem_resume_status:1; 499 500 unsigned is_wrap:1; /* set when creating coroutines via 501 coroutine.wrap */ 502 503 unsigned propagate_error:1; /* set when propagating an error 504 from a coroutine to its 505 parent */ 506 }; 507 508 509 typedef struct { 510 lua_State *vm; 511 ngx_int_t count; 512 } ngx_http_lua_vm_state_t; 513 514 515 typedef struct ngx_http_lua_ctx_s { 516 /* for lua_code_cache off: */ 517 ngx_http_lua_vm_state_t *vm_state; 518 519 ngx_http_request_t *request; 520 ngx_http_handler_pt resume_handler; 521 522 ngx_http_lua_co_ctx_t *cur_co_ctx; /* co ctx for the current coroutine */ 523 524 /* FIXME: we should use rbtree here to prevent O(n) lookup overhead */ 525 ngx_list_t *user_co_ctx; /* coroutine contexts for user 526 coroutines */ 527 528 ngx_http_lua_co_ctx_t entry_co_ctx; /* coroutine context for the 529 entry coroutine */ 530 531 ngx_http_lua_co_ctx_t *on_abort_co_ctx; /* coroutine context for the 532 on_abort thread */ 533 534 int ctx_ref; /* reference to anchor 535 request ctx data in lua 536 registry */ 537 538 unsigned flushing_coros; /* number of coroutines waiting on 539 ngx.flush(true) */ 540 541 ngx_chain_t *out; /* buffered output chain for HTTP 1.0 */ 542 ngx_chain_t *free_bufs; 543 ngx_chain_t *busy_bufs; 544 ngx_chain_t *free_recv_bufs; 545 546 ngx_http_cleanup_pt *cleanup; 547 548 ngx_http_cleanup_t *free_cleanup; /* free list of cleanup records */ 549 550 ngx_chain_t *body; /* buffered subrequest response body 551 chains */ 552 553 ngx_chain_t **last_body; /* for the "body" field */ 554 555 ngx_str_t exec_uri; 556 ngx_str_t exec_args; 557 558 ngx_int_t exit_code; 559 560 void *downstream; /* can be either 561 ngx_http_lua_socket_tcp_upstream_t 562 or ngx_http_lua_co_ctx_t */ 563 564 ngx_uint_t index; /* index of the current 565 subrequest in its parent 566 request */ 567 568 ngx_http_lua_posted_thread_t *posted_threads; 569 570 int uthreads; /* number of active user threads */ 571 572 uint16_t context; /* the current running directive context 573 (or running phase) for the current 574 Lua chunk */ 575 576 unsigned run_post_subrequest:1; /* whether it has run 577 post_subrequest 578 (for subrequests only) */ 579 580 unsigned waiting_more_body:1; /* 1: waiting for more 581 request body data; 582 0: no need to wait */ 583 584 unsigned co_op:2; /* coroutine API operation */ 585 586 unsigned exited:1; 587 588 unsigned eof:1; /* 1: last_buf has been sent; 589 0: last_buf not sent yet */ 590 591 unsigned capture:1; /* 1: response body of current request 592 is to be captured by the lua 593 capture filter, 594 0: not to be captured */ 595 596 597 unsigned read_body_done:1; /* 1: request body has been all 598 read; 0: body has not been 599 all read */ 600 601 unsigned headers_set:1; /* whether the user has set custom 602 response headers */ 603 unsigned mime_set:1; /* whether the user has set Content-Type 604 response header */ 605 606 unsigned entered_rewrite_phase:1; 607 unsigned entered_access_phase:1; 608 unsigned entered_content_phase:1; 609 610 unsigned buffering:1; /* HTTP 1.0 response body buffering flag */ 611 612 unsigned no_abort:1; /* prohibit "world abortion" via ngx.exit() 613 and etc */ 614 615 unsigned header_sent:1; /* r->header_sent is not sufficient for 616 * this because special header filters 617 * like ngx_image_filter may intercept 618 * the header. so we should always test 619 * both flags. see the test case in 620 * t/020-subrequest.t */ 621 622 unsigned seen_last_in_filter:1; /* used by body_filter_by_lua* */ 623 unsigned seen_last_for_subreq:1; /* used by body capture filter */ 624 unsigned writing_raw_req_socket:1; /* used by raw downstream 625 socket */ 626 unsigned acquired_raw_req_socket:1; /* whether a raw req socket 627 is acquired */ 628 unsigned seen_body_data:1; 629 } ngx_http_lua_ctx_t; 630 631 632 struct ngx_http_lua_header_val_s { 633 ngx_http_complex_value_t value; 634 ngx_uint_t hash; 635 ngx_str_t key; 636 ngx_http_lua_set_header_pt handler; 637 ngx_uint_t offset; 638 unsigned no_override; 639 }; 640 641 642 typedef struct { 643 ngx_str_t name; 644 ngx_uint_t offset; 645 ngx_http_lua_set_header_pt handler; 646 } ngx_http_lua_set_header_t; 647 648 649 extern ngx_module_t ngx_http_lua_module; 650 extern ngx_http_output_header_filter_pt ngx_http_lua_next_header_filter; 651 extern ngx_http_output_body_filter_pt ngx_http_lua_next_body_filter; 652 653 654 #endif /* _NGX_HTTP_LUA_COMMON_H_INCLUDED_ */ 655 656 /* vi:set ft=c ts=4 sw=4 et fdm=marker: */ 657