feature: implemented the *_by_lua_block {...} directives that do not require extra escaping when inlining Lua code in nginx.conf.
This commit is contained in:
Родитель
b5de0c2f9d
Коммит
6b558cd4bd
|
@ -153,6 +153,7 @@ src/uthread.[ch]
|
|||
src/timer.[ch]
|
||||
src/config.[ch]
|
||||
src/worker.[ch]
|
||||
src/lex.[ch]
|
||||
*.plist
|
||||
lua
|
||||
ttimer
|
||||
|
|
2
config
2
config
|
@ -283,6 +283,7 @@ NGX_ADDON_SRCS="$NGX_ADDON_SRCS \
|
|||
$ngx_addon_dir/src/ngx_http_lua_timer.c \
|
||||
$ngx_addon_dir/src/ngx_http_lua_config.c \
|
||||
$ngx_addon_dir/src/ngx_http_lua_worker.c \
|
||||
$ngx_addon_dir/src/ngx_http_lua_lex.c \
|
||||
"
|
||||
|
||||
NGX_ADDON_DEPS="$NGX_ADDON_DEPS \
|
||||
|
@ -336,6 +337,7 @@ NGX_ADDON_DEPS="$NGX_ADDON_DEPS \
|
|||
$ngx_addon_dir/src/ngx_http_lua_timer.h \
|
||||
$ngx_addon_dir/src/ngx_http_lua_config.h \
|
||||
$ngx_addon_dir/src/ngx_http_lua_worker.h \
|
||||
$ngx_addon_dir/src/ngx_http_lua_lex.h \
|
||||
"
|
||||
|
||||
CFLAGS="$CFLAGS -DNDK_SET_VAR"
|
||||
|
|
|
@ -24,6 +24,11 @@
|
|||
#include "ngx_http_lua_initby.h"
|
||||
#include "ngx_http_lua_initworkerby.h"
|
||||
#include "ngx_http_lua_shdict.h"
|
||||
#include "ngx_http_lua_lex.h"
|
||||
|
||||
|
||||
typedef struct ngx_http_lua_block_parser_ctx_s
|
||||
ngx_http_lua_block_parser_ctx_t;
|
||||
|
||||
|
||||
#if defined(NDK) && NDK
|
||||
|
@ -35,6 +40,17 @@ static ngx_int_t ngx_http_lua_set_by_lua_init(ngx_http_request_t *r);
|
|||
|
||||
static u_char *ngx_http_lua_gen_chunk_name(ngx_conf_t *cf, const char *tag,
|
||||
size_t tag_len);
|
||||
static char *ngx_http_lua_conf_lua_block_parse(ngx_conf_t *cf,
|
||||
ngx_command_t *cmd);
|
||||
static ngx_int_t ngx_http_lua_conf_read_lua_token(ngx_conf_t *cf,
|
||||
ngx_http_lua_block_parser_ctx_t *ctx);
|
||||
|
||||
|
||||
struct ngx_http_lua_block_parser_ctx_s {
|
||||
ngx_uint_t start_line;
|
||||
int token_len;
|
||||
int expect_right_lbracket;
|
||||
};
|
||||
|
||||
|
||||
char *
|
||||
|
@ -372,6 +388,25 @@ ngx_http_lua_filter_set_by_lua_file(ngx_http_request_t *r, ngx_str_t *val,
|
|||
#endif /* defined(NDK) && NDK */
|
||||
|
||||
|
||||
char *
|
||||
ngx_http_lua_rewrite_by_lua_block(ngx_conf_t *cf, ngx_command_t *cmd,
|
||||
void *conf)
|
||||
{
|
||||
char *rv;
|
||||
ngx_conf_t save;
|
||||
|
||||
save = *cf;
|
||||
cf->handler = ngx_http_lua_rewrite_by_lua;
|
||||
cf->handler_conf = conf;
|
||||
|
||||
rv = ngx_http_lua_conf_lua_block_parse(cf, cmd);
|
||||
|
||||
*cf = save;
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
char *
|
||||
ngx_http_lua_rewrite_by_lua(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
||||
{
|
||||
|
@ -467,6 +502,25 @@ ngx_http_lua_rewrite_by_lua(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
|||
}
|
||||
|
||||
|
||||
char *
|
||||
ngx_http_lua_access_by_lua_block(ngx_conf_t *cf, ngx_command_t *cmd,
|
||||
void *conf)
|
||||
{
|
||||
char *rv;
|
||||
ngx_conf_t save;
|
||||
|
||||
save = *cf;
|
||||
cf->handler = ngx_http_lua_access_by_lua;
|
||||
cf->handler_conf = conf;
|
||||
|
||||
rv = ngx_http_lua_conf_lua_block_parse(cf, cmd);
|
||||
|
||||
*cf = save;
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
char *
|
||||
ngx_http_lua_access_by_lua(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
||||
{
|
||||
|
@ -558,6 +612,25 @@ ngx_http_lua_access_by_lua(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
|||
}
|
||||
|
||||
|
||||
char *
|
||||
ngx_http_lua_content_by_lua_block(ngx_conf_t *cf, ngx_command_t *cmd,
|
||||
void *conf)
|
||||
{
|
||||
char *rv;
|
||||
ngx_conf_t save;
|
||||
|
||||
save = *cf;
|
||||
cf->handler = ngx_http_lua_content_by_lua;
|
||||
cf->handler_conf = conf;
|
||||
|
||||
rv = ngx_http_lua_conf_lua_block_parse(cf, cmd);
|
||||
|
||||
*cf = save;
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
char *
|
||||
ngx_http_lua_content_by_lua(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
||||
{
|
||||
|
@ -583,6 +656,9 @@ ngx_http_lua_content_by_lua(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
|||
|
||||
value = cf->args->elts;
|
||||
|
||||
dd("value[0]: %.*s", (int) value[0].len, value[0].data);
|
||||
dd("value[1]: %.*s", (int) value[1].len, value[1].data);
|
||||
|
||||
if (value[1].len == 0) {
|
||||
/* Oops...Invalid location conf */
|
||||
ngx_conf_log_error(NGX_LOG_ERR, cf, 0,
|
||||
|
@ -659,6 +735,25 @@ ngx_http_lua_content_by_lua(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
|||
}
|
||||
|
||||
|
||||
char *
|
||||
ngx_http_lua_log_by_lua_block(ngx_conf_t *cf, ngx_command_t *cmd,
|
||||
void *conf)
|
||||
{
|
||||
char *rv;
|
||||
ngx_conf_t save;
|
||||
|
||||
save = *cf;
|
||||
cf->handler = ngx_http_lua_log_by_lua;
|
||||
cf->handler_conf = conf;
|
||||
|
||||
rv = ngx_http_lua_conf_lua_block_parse(cf, cmd);
|
||||
|
||||
*cf = save;
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
char *
|
||||
ngx_http_lua_log_by_lua(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
||||
{
|
||||
|
@ -749,6 +844,25 @@ ngx_http_lua_log_by_lua(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
|||
}
|
||||
|
||||
|
||||
char *
|
||||
ngx_http_lua_header_filter_by_lua_block(ngx_conf_t *cf, ngx_command_t *cmd,
|
||||
void *conf)
|
||||
{
|
||||
char *rv;
|
||||
ngx_conf_t save;
|
||||
|
||||
save = *cf;
|
||||
cf->handler = ngx_http_lua_header_filter_by_lua;
|
||||
cf->handler_conf = conf;
|
||||
|
||||
rv = ngx_http_lua_conf_lua_block_parse(cf, cmd);
|
||||
|
||||
*cf = save;
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
char *
|
||||
ngx_http_lua_header_filter_by_lua(ngx_conf_t *cf, ngx_command_t *cmd,
|
||||
void *conf)
|
||||
|
@ -830,6 +944,25 @@ ngx_http_lua_header_filter_by_lua(ngx_conf_t *cf, ngx_command_t *cmd,
|
|||
}
|
||||
|
||||
|
||||
char *
|
||||
ngx_http_lua_body_filter_by_lua_block(ngx_conf_t *cf, ngx_command_t *cmd,
|
||||
void *conf)
|
||||
{
|
||||
char *rv;
|
||||
ngx_conf_t save;
|
||||
|
||||
save = *cf;
|
||||
cf->handler = ngx_http_lua_body_filter_by_lua;
|
||||
cf->handler_conf = conf;
|
||||
|
||||
rv = ngx_http_lua_conf_lua_block_parse(cf, cmd);
|
||||
|
||||
*cf = save;
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
char *
|
||||
ngx_http_lua_body_filter_by_lua(ngx_conf_t *cf, ngx_command_t *cmd,
|
||||
void *conf)
|
||||
|
@ -912,6 +1045,25 @@ ngx_http_lua_body_filter_by_lua(ngx_conf_t *cf, ngx_command_t *cmd,
|
|||
}
|
||||
|
||||
|
||||
char *
|
||||
ngx_http_lua_init_by_lua_block(ngx_conf_t *cf, ngx_command_t *cmd,
|
||||
void *conf)
|
||||
{
|
||||
char *rv;
|
||||
ngx_conf_t save;
|
||||
|
||||
save = *cf;
|
||||
cf->handler = ngx_http_lua_init_by_lua;
|
||||
cf->handler_conf = conf;
|
||||
|
||||
rv = ngx_http_lua_conf_lua_block_parse(cf, cmd);
|
||||
|
||||
*cf = save;
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
char *
|
||||
ngx_http_lua_init_by_lua(ngx_conf_t *cf, ngx_command_t *cmd,
|
||||
void *conf)
|
||||
|
@ -960,6 +1112,25 @@ ngx_http_lua_init_by_lua(ngx_conf_t *cf, ngx_command_t *cmd,
|
|||
}
|
||||
|
||||
|
||||
char *
|
||||
ngx_http_lua_init_worker_by_lua_block(ngx_conf_t *cf, ngx_command_t *cmd,
|
||||
void *conf)
|
||||
{
|
||||
char *rv;
|
||||
ngx_conf_t save;
|
||||
|
||||
save = *cf;
|
||||
cf->handler = ngx_http_lua_init_worker_by_lua;
|
||||
cf->handler_conf = conf;
|
||||
|
||||
rv = ngx_http_lua_conf_lua_block_parse(cf, cmd);
|
||||
|
||||
*cf = save;
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
char *
|
||||
ngx_http_lua_init_worker_by_lua(ngx_conf_t *cf, ngx_command_t *cmd,
|
||||
void *conf)
|
||||
|
@ -1078,4 +1249,361 @@ found:
|
|||
}
|
||||
|
||||
|
||||
/* a specialized version of the standard ngx_conf_parse() function */
|
||||
static char *
|
||||
ngx_http_lua_conf_lua_block_parse(ngx_conf_t *cf, ngx_command_t *cmd)
|
||||
{
|
||||
ngx_http_lua_block_parser_ctx_t ctx;
|
||||
|
||||
int level = 1;
|
||||
char *rv;
|
||||
u_char *p;
|
||||
size_t len;
|
||||
ngx_str_t *src, *dst;
|
||||
ngx_int_t rc;
|
||||
ngx_uint_t i, start_line;
|
||||
ngx_array_t *saved;
|
||||
enum {
|
||||
parse_block = 0,
|
||||
parse_param
|
||||
} type;
|
||||
enum {
|
||||
found_left_curly = 0,
|
||||
found_right_curly,
|
||||
found_left_lbracket_str,
|
||||
found_left_lbracket_cmt,
|
||||
found_right_lbracket,
|
||||
found_comment_line,
|
||||
found_double_quoted,
|
||||
found_single_quoted
|
||||
};
|
||||
|
||||
if (cf->conf_file->file.fd != NGX_INVALID_FILE) {
|
||||
|
||||
type = parse_block;
|
||||
|
||||
} else {
|
||||
type = parse_param;
|
||||
}
|
||||
|
||||
saved = cf->args;
|
||||
|
||||
cf->args = ngx_array_create(cf->temp_pool, 4, sizeof(ngx_str_t));
|
||||
if (cf->args == NULL) {
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
ctx.token_len = 0;
|
||||
ctx.expect_right_lbracket = 0;
|
||||
start_line = cf->conf_file->line;
|
||||
|
||||
dd("init start line: %d", (int) start_line);
|
||||
|
||||
ctx.start_line = start_line;
|
||||
|
||||
for ( ;; ) {
|
||||
rc = ngx_http_lua_conf_read_lua_token(cf, &ctx);
|
||||
|
||||
dd("parser start line: %d", (int) start_line);
|
||||
|
||||
switch (rc) {
|
||||
|
||||
case NGX_ERROR:
|
||||
goto done;
|
||||
|
||||
case found_left_curly:
|
||||
if (ctx.expect_right_lbracket) {
|
||||
break;
|
||||
}
|
||||
|
||||
ctx.start_line = cf->conf_file->line;
|
||||
|
||||
if (type == parse_param) {
|
||||
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
|
||||
"block directives are not supported "
|
||||
"in -g option");
|
||||
goto failed;
|
||||
}
|
||||
|
||||
level++;
|
||||
dd("seen block start: level=%d", (int) level);
|
||||
break;
|
||||
|
||||
case found_right_curly:
|
||||
if (ctx.expect_right_lbracket) {
|
||||
break;
|
||||
}
|
||||
|
||||
level--;
|
||||
dd("seen block done: level=%d", (int) level);
|
||||
|
||||
if (type != parse_block || level < 0) {
|
||||
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
|
||||
"unexpected \"}\": level %d, "
|
||||
"starting at line %ui", level,
|
||||
start_line);
|
||||
goto failed;
|
||||
}
|
||||
|
||||
if (level == 0) {
|
||||
ngx_http_lua_assert(cf->handler);
|
||||
|
||||
src = cf->args->elts;
|
||||
|
||||
for (len = 0, i = 0; i < cf->args->nelts; i++) {
|
||||
len += src[i].len;
|
||||
}
|
||||
|
||||
dd("saved nelts: %d", (int) saved->nelts);
|
||||
dd("temp nelts: %d", (int) cf->args->nelts);
|
||||
ngx_http_lua_assert(saved->nelts == 1);
|
||||
|
||||
dst = ngx_array_push(saved);
|
||||
if (dst == NULL) {
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
dst->len = len;
|
||||
dst->len--; /* skip the trailing '}' block terminator */
|
||||
|
||||
p = ngx_palloc(cf->pool, len);
|
||||
if (p == NULL) {
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
dst->data = p;
|
||||
|
||||
for (i = 0; i < cf->args->nelts; i++) {
|
||||
p = ngx_copy(p, src[i].data, src[i].len);
|
||||
}
|
||||
|
||||
p[-1] = '\0'; /* override the last '}' char to null */
|
||||
|
||||
cf->args = saved;
|
||||
|
||||
rv = (*cf->handler)(cf, cmd, cf->handler_conf);
|
||||
if (rv == NGX_CONF_OK) {
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (rv == NGX_CONF_ERROR) {
|
||||
goto failed;
|
||||
}
|
||||
|
||||
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, rv);
|
||||
|
||||
goto failed;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case found_left_lbracket_str:
|
||||
if (ctx.expect_right_lbracket) {
|
||||
break;
|
||||
}
|
||||
|
||||
ctx.expect_right_lbracket = ctx.token_len;
|
||||
ctx.start_line = cf->conf_file->line;
|
||||
break;
|
||||
|
||||
case found_left_lbracket_cmt:
|
||||
if (ctx.expect_right_lbracket) {
|
||||
break;
|
||||
}
|
||||
|
||||
ctx.expect_right_lbracket = ctx.token_len - (sizeof("--") - 1);
|
||||
ctx.start_line = cf->conf_file->line;
|
||||
break;
|
||||
|
||||
case found_right_lbracket:
|
||||
if (!ctx.expect_right_lbracket) {
|
||||
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
|
||||
"unexpected lua closing long-bracket");
|
||||
goto failed;
|
||||
}
|
||||
|
||||
if (ctx.token_len != ctx.expect_right_lbracket) {
|
||||
/* unmatched long brackets */
|
||||
break;
|
||||
}
|
||||
|
||||
ctx.expect_right_lbracket = 0;
|
||||
break;
|
||||
|
||||
case found_comment_line:
|
||||
case found_double_quoted:
|
||||
case found_single_quoted:
|
||||
if (ctx.expect_right_lbracket) {
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
|
||||
"unknown return value from the lexer: %i", rc);
|
||||
goto failed;
|
||||
}
|
||||
}
|
||||
|
||||
failed:
|
||||
|
||||
rc = NGX_ERROR;
|
||||
|
||||
done:
|
||||
|
||||
if (rc == NGX_ERROR) {
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
return NGX_CONF_OK;
|
||||
}
|
||||
|
||||
|
||||
static ngx_int_t
|
||||
ngx_http_lua_conf_read_lua_token(ngx_conf_t *cf,
|
||||
ngx_http_lua_block_parser_ctx_t *ctx)
|
||||
{
|
||||
enum {
|
||||
OVEC_SIZE = 2
|
||||
};
|
||||
int i, rc;
|
||||
int ovec[OVEC_SIZE];
|
||||
u_char *start, ch;
|
||||
off_t file_size;
|
||||
size_t len, buf_size;
|
||||
ssize_t n, size;
|
||||
ngx_uint_t start_line;
|
||||
ngx_str_t *word;
|
||||
ngx_buf_t *b;
|
||||
#if nginx_version >= 1009002
|
||||
ngx_buf_t *dump;
|
||||
#endif
|
||||
|
||||
b = cf->conf_file->buffer;
|
||||
#if nginx_version >= 1009002
|
||||
dump = cf->conf_file->dump;
|
||||
#endif
|
||||
start = b->pos;
|
||||
start_line = cf->conf_file->line;
|
||||
buf_size = b->end - b->start;
|
||||
|
||||
dd("lexer start line: %d", (int) start_line);
|
||||
|
||||
file_size = ngx_file_size(&cf->conf_file->file.info);
|
||||
|
||||
for ( ;; ) {
|
||||
|
||||
if (b->pos >= b->last) {
|
||||
|
||||
if (cf->conf_file->file.offset >= file_size) {
|
||||
|
||||
cf->conf_file->line = ctx->start_line;
|
||||
|
||||
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
|
||||
"unexpected end of file, expecting "
|
||||
"terminating characters for lua code "
|
||||
"block");
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
len = b->pos - start;
|
||||
|
||||
if (len == buf_size) {
|
||||
|
||||
cf->conf_file->line = start_line;
|
||||
|
||||
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
|
||||
"too long lua code block, probably "
|
||||
"missing terminating characters");
|
||||
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
if (len) {
|
||||
ngx_memmove(b->start, start, len);
|
||||
}
|
||||
|
||||
size = (ssize_t) (file_size - cf->conf_file->file.offset);
|
||||
|
||||
if (size > b->end - (b->start + len)) {
|
||||
size = b->end - (b->start + len);
|
||||
}
|
||||
|
||||
n = ngx_read_file(&cf->conf_file->file, b->start + len, size,
|
||||
cf->conf_file->file.offset);
|
||||
|
||||
if (n == NGX_ERROR) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
if (n != size) {
|
||||
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
|
||||
ngx_read_file_n " returned "
|
||||
"only %z bytes instead of %z",
|
||||
n, size);
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
b->pos = b->start + len;
|
||||
b->last = b->pos + n;
|
||||
start = b->start;
|
||||
|
||||
#if nginx_version >= 1009002
|
||||
if (dump) {
|
||||
dump->last = ngx_cpymem(dump->last, b->pos, size);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
rc = ngx_http_lua_lex(b->pos, b->last - b->pos, ovec);
|
||||
|
||||
if (rc < 0) { /* no match */
|
||||
if (ctx->expect_right_lbracket) {
|
||||
cf->conf_file->line = ctx->start_line;
|
||||
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
|
||||
"Lua code block missing the closing "
|
||||
"long bracket");
|
||||
|
||||
} else {
|
||||
cf->conf_file->line = start_line;
|
||||
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
|
||||
"Lua code block missing the \"}\" "
|
||||
"character");
|
||||
}
|
||||
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
for (i = 0; i < ovec[1]; i++) {
|
||||
ch = b->pos[i];
|
||||
if (ch == LF) {
|
||||
cf->conf_file->line++;
|
||||
}
|
||||
}
|
||||
|
||||
b->pos += ovec[1];
|
||||
|
||||
ctx->token_len = ovec[1] - ovec[0];
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
word = ngx_array_push(cf->args);
|
||||
if (word == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
word->data = ngx_pnalloc(cf->temp_pool, b->pos - start);
|
||||
if (word->data == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
len = b->pos - start;
|
||||
ngx_memcpy(word->data, start, len);
|
||||
word->len = len;
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
/* vi:set ft=c ts=4 sw=4 et fdm=marker: */
|
||||
|
|
|
@ -17,20 +17,36 @@ char *ngx_http_lua_package_cpath(ngx_conf_t *cf, ngx_command_t *cmd,
|
|||
void *conf);
|
||||
char *ngx_http_lua_package_path(ngx_conf_t *cf, ngx_command_t *cmd,
|
||||
void *conf);
|
||||
char *ngx_http_lua_content_by_lua_block(ngx_conf_t *cf, ngx_command_t *cmd,
|
||||
void *conf);
|
||||
char *ngx_http_lua_content_by_lua(ngx_conf_t *cf, ngx_command_t *cmd,
|
||||
void *conf);
|
||||
char *ngx_http_lua_rewrite_by_lua_block(ngx_conf_t *cf, ngx_command_t *cmd,
|
||||
void *conf);
|
||||
char *ngx_http_lua_rewrite_by_lua(ngx_conf_t *cf, ngx_command_t *cmd,
|
||||
void *conf);
|
||||
char *ngx_http_lua_access_by_lua_block(ngx_conf_t *cf, ngx_command_t *cmd,
|
||||
void *conf);
|
||||
char *ngx_http_lua_access_by_lua(ngx_conf_t *cf, ngx_command_t *cmd,
|
||||
void *conf);
|
||||
char *ngx_http_lua_log_by_lua_block(ngx_conf_t *cf, ngx_command_t *cmd,
|
||||
void *conf);
|
||||
char *ngx_http_lua_log_by_lua(ngx_conf_t *cf, ngx_command_t *cmd,
|
||||
void *conf);
|
||||
char *ngx_http_lua_header_filter_by_lua_block(ngx_conf_t *cf,
|
||||
ngx_command_t *cmd, void *conf);
|
||||
char *ngx_http_lua_header_filter_by_lua(ngx_conf_t *cf, ngx_command_t *cmd,
|
||||
void *conf);
|
||||
char *ngx_http_lua_body_filter_by_lua_block(ngx_conf_t *cf,
|
||||
ngx_command_t *cmd, void *conf);
|
||||
char *ngx_http_lua_body_filter_by_lua(ngx_conf_t *cf, ngx_command_t *cmd,
|
||||
void *conf);
|
||||
char *ngx_http_lua_init_by_lua_block(ngx_conf_t *cf, ngx_command_t *cmd,
|
||||
void *conf);
|
||||
char *ngx_http_lua_init_by_lua(ngx_conf_t *cf, ngx_command_t *cmd,
|
||||
void *conf);
|
||||
char *ngx_http_lua_init_worker_by_lua_block(ngx_conf_t *cf,
|
||||
ngx_command_t *cmd, void *conf);
|
||||
char *ngx_http_lua_init_worker_by_lua(ngx_conf_t *cf, ngx_command_t *cmd,
|
||||
void *conf);
|
||||
char *ngx_http_lua_code_cache(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -0,0 +1,17 @@
|
|||
|
||||
/*
|
||||
* Copyright (C) Yichun Zhang (agentzh)
|
||||
*/
|
||||
|
||||
|
||||
#ifndef _NGX_HTTP_LUA_LEX_H_INCLUDED_
|
||||
#define _NGX_HTTP_LUA_LEX_H_INCLUDED_
|
||||
|
||||
|
||||
#include "ngx_http_lua_common.h"
|
||||
|
||||
|
||||
int ngx_http_lua_lex(const u_char *const s, size_t len, int *const ovec);
|
||||
|
||||
|
||||
#endif
|
|
@ -149,6 +149,13 @@ static ngx_command_t ngx_http_lua_cmds[] = {
|
|||
offsetof(ngx_http_lua_loc_conf_t, log_socket_errors),
|
||||
NULL },
|
||||
|
||||
{ ngx_string("init_by_lua_block"),
|
||||
NGX_HTTP_MAIN_CONF|NGX_CONF_BLOCK|NGX_CONF_NOARGS,
|
||||
ngx_http_lua_init_by_lua_block,
|
||||
NGX_HTTP_MAIN_CONF_OFFSET,
|
||||
0,
|
||||
(void *) ngx_http_lua_init_by_inline },
|
||||
|
||||
{ ngx_string("init_by_lua"),
|
||||
NGX_HTTP_MAIN_CONF|NGX_CONF_TAKE1,
|
||||
ngx_http_lua_init_by_lua,
|
||||
|
@ -163,6 +170,13 @@ static ngx_command_t ngx_http_lua_cmds[] = {
|
|||
0,
|
||||
(void *) ngx_http_lua_init_by_file },
|
||||
|
||||
{ ngx_string("init_worker_by_lua_block"),
|
||||
NGX_HTTP_MAIN_CONF|NGX_CONF_BLOCK|NGX_CONF_NOARGS,
|
||||
ngx_http_lua_init_worker_by_lua_block,
|
||||
NGX_HTTP_MAIN_CONF_OFFSET,
|
||||
0,
|
||||
(void *) ngx_http_lua_init_worker_by_inline },
|
||||
|
||||
{ ngx_string("init_worker_by_lua"),
|
||||
NGX_HTTP_MAIN_CONF|NGX_CONF_TAKE1,
|
||||
ngx_http_lua_init_worker_by_lua,
|
||||
|
@ -197,7 +211,7 @@ static ngx_command_t ngx_http_lua_cmds[] = {
|
|||
(void *) ngx_http_lua_filter_set_by_lua_file },
|
||||
#endif
|
||||
|
||||
/* rewrite_by_lua <inline script> */
|
||||
/* rewrite_by_lua "<inline script>" */
|
||||
{ ngx_string("rewrite_by_lua"),
|
||||
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF
|
||||
|NGX_CONF_TAKE1,
|
||||
|
@ -206,7 +220,16 @@ static ngx_command_t ngx_http_lua_cmds[] = {
|
|||
0,
|
||||
(void *) ngx_http_lua_rewrite_handler_inline },
|
||||
|
||||
/* access_by_lua <inline script> */
|
||||
/* rewrite_by_lua_block { <inline script> } */
|
||||
{ ngx_string("rewrite_by_lua_block"),
|
||||
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF
|
||||
|NGX_CONF_BLOCK|NGX_CONF_NOARGS,
|
||||
ngx_http_lua_rewrite_by_lua_block,
|
||||
NGX_HTTP_LOC_CONF_OFFSET,
|
||||
0,
|
||||
(void *) ngx_http_lua_rewrite_handler_inline },
|
||||
|
||||
/* access_by_lua "<inline script>" */
|
||||
{ ngx_string("access_by_lua"),
|
||||
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF
|
||||
|NGX_CONF_TAKE1,
|
||||
|
@ -215,7 +238,16 @@ static ngx_command_t ngx_http_lua_cmds[] = {
|
|||
0,
|
||||
(void *) ngx_http_lua_access_handler_inline },
|
||||
|
||||
/* content_by_lua <inline script> */
|
||||
/* access_by_lua_block { <inline script> } */
|
||||
{ ngx_string("access_by_lua_block"),
|
||||
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF
|
||||
|NGX_CONF_BLOCK|NGX_CONF_NOARGS,
|
||||
ngx_http_lua_access_by_lua_block,
|
||||
NGX_HTTP_LOC_CONF_OFFSET,
|
||||
0,
|
||||
(void *) ngx_http_lua_access_handler_inline },
|
||||
|
||||
/* content_by_lua "<inline script>" */
|
||||
{ ngx_string("content_by_lua"),
|
||||
NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF|NGX_CONF_TAKE1,
|
||||
ngx_http_lua_content_by_lua,
|
||||
|
@ -223,6 +255,14 @@ static ngx_command_t ngx_http_lua_cmds[] = {
|
|||
0,
|
||||
(void *) ngx_http_lua_content_handler_inline },
|
||||
|
||||
/* content_by_lua_block { <inline script> } */
|
||||
{ ngx_string("content_by_lua_block"),
|
||||
NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF|NGX_CONF_BLOCK|NGX_CONF_NOARGS,
|
||||
ngx_http_lua_content_by_lua_block,
|
||||
NGX_HTTP_LOC_CONF_OFFSET,
|
||||
0,
|
||||
(void *) ngx_http_lua_content_handler_inline },
|
||||
|
||||
/* log_by_lua <inline script> */
|
||||
{ ngx_string("log_by_lua"),
|
||||
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF
|
||||
|
@ -232,6 +272,15 @@ static ngx_command_t ngx_http_lua_cmds[] = {
|
|||
0,
|
||||
(void *) ngx_http_lua_log_handler_inline },
|
||||
|
||||
/* log_by_lua_block { <inline script> } */
|
||||
{ ngx_string("log_by_lua_block"),
|
||||
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF
|
||||
|NGX_CONF_BLOCK|NGX_CONF_NOARGS,
|
||||
ngx_http_lua_log_by_lua_block,
|
||||
NGX_HTTP_LOC_CONF_OFFSET,
|
||||
0,
|
||||
(void *) ngx_http_lua_log_handler_inline },
|
||||
|
||||
{ ngx_string("rewrite_by_lua_file"),
|
||||
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF
|
||||
|NGX_CONF_TAKE1,
|
||||
|
@ -280,6 +329,15 @@ static ngx_command_t ngx_http_lua_cmds[] = {
|
|||
0,
|
||||
(void *) ngx_http_lua_header_filter_inline },
|
||||
|
||||
/* header_filter_by_lua_block { <inline script> } */
|
||||
{ ngx_string("header_filter_by_lua_block"),
|
||||
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF
|
||||
|NGX_CONF_BLOCK|NGX_CONF_NOARGS,
|
||||
ngx_http_lua_header_filter_by_lua_block,
|
||||
NGX_HTTP_LOC_CONF_OFFSET,
|
||||
0,
|
||||
(void *) ngx_http_lua_header_filter_inline },
|
||||
|
||||
{ ngx_string("header_filter_by_lua_file"),
|
||||
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF
|
||||
|NGX_CONF_TAKE1,
|
||||
|
@ -296,6 +354,15 @@ static ngx_command_t ngx_http_lua_cmds[] = {
|
|||
0,
|
||||
(void *) ngx_http_lua_body_filter_inline },
|
||||
|
||||
/* body_filter_by_lua_block { <inline script> } */
|
||||
{ ngx_string("body_filter_by_lua_block"),
|
||||
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF
|
||||
|NGX_CONF_BLOCK|NGX_CONF_NOARGS,
|
||||
ngx_http_lua_body_filter_by_lua_block,
|
||||
NGX_HTTP_LOC_CONF_OFFSET,
|
||||
0,
|
||||
(void *) ngx_http_lua_body_filter_inline },
|
||||
|
||||
{ ngx_string("body_filter_by_lua_file"),
|
||||
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF
|
||||
|NGX_CONF_TAKE1,
|
||||
|
|
|
@ -0,0 +1,383 @@
|
|||
# vim:set ft= ts=4 sw=4 et fdm=marker:
|
||||
use lib 'lib';
|
||||
use Test::Nginx::Socket::Lua;
|
||||
|
||||
#worker_connections(1014);
|
||||
#master_on();
|
||||
#workers(2);
|
||||
#log_level('warn');
|
||||
|
||||
repeat_each(2);
|
||||
#repeat_each(1);
|
||||
|
||||
plan tests => repeat_each() * (blocks() * 3 + 2);
|
||||
|
||||
#no_diff();
|
||||
no_long_string();
|
||||
run_tests();
|
||||
|
||||
__DATA__
|
||||
|
||||
=== TEST 1: content_by_lua_block (simplest)
|
||||
--- config
|
||||
location = /t {
|
||||
content_by_lua_block {
|
||||
ngx.say("hello, world")
|
||||
}
|
||||
}
|
||||
--- request
|
||||
GET /t
|
||||
--- response_body
|
||||
hello, world
|
||||
--- no_error_log
|
||||
[error]
|
||||
|
||||
|
||||
|
||||
=== TEST 2: content_by_lua_block (nested curly braces)
|
||||
--- config
|
||||
location = /t {
|
||||
content_by_lua_block {
|
||||
local a = {
|
||||
dogs = {32, 78, 96},
|
||||
cat = "kitty",
|
||||
}
|
||||
ngx.say("a.dogs[1] = ", a.dogs[1])
|
||||
ngx.say("a.dogs[2] = ", a.dogs[2])
|
||||
ngx.say("a.dogs[3] = ", a.dogs[3])
|
||||
ngx.say("a.cat = ", a.cat)
|
||||
}
|
||||
}
|
||||
--- request
|
||||
GET /t
|
||||
--- response_body
|
||||
a.dogs[1] = 32
|
||||
a.dogs[2] = 78
|
||||
a.dogs[3] = 96
|
||||
a.cat = kitty
|
||||
|
||||
--- no_error_log
|
||||
[error]
|
||||
|
||||
|
||||
|
||||
=== TEST 3: content_by_lua_block (curly braces in strings)
|
||||
--- config
|
||||
location = /t {
|
||||
content_by_lua_block {
|
||||
ngx.say("}1, 2)")
|
||||
ngx.say('{1, 2)')
|
||||
}
|
||||
}
|
||||
--- request
|
||||
GET /t
|
||||
--- response_body
|
||||
}1, 2)
|
||||
{1, 2)
|
||||
|
||||
--- no_error_log
|
||||
[error]
|
||||
|
||||
|
||||
|
||||
=== TEST 4: content_by_lua_block (curly braces in strings, with escaped terminators)
|
||||
--- config
|
||||
location = /t {
|
||||
content_by_lua_block {
|
||||
ngx.say("\"}1, 2)")
|
||||
ngx.say('\'{1, 2)')
|
||||
}
|
||||
}
|
||||
--- request
|
||||
GET /t
|
||||
--- response_body
|
||||
"}1, 2)
|
||||
'{1, 2)
|
||||
|
||||
--- no_error_log
|
||||
[error]
|
||||
|
||||
|
||||
|
||||
=== TEST 5: content_by_lua_block (curly braces in long brackets)
|
||||
--- config
|
||||
location = /t {
|
||||
content_by_lua_block {
|
||||
--[[
|
||||
{{{
|
||||
|
||||
}
|
||||
]]
|
||||
--[==[
|
||||
}}}
|
||||
|
||||
{
|
||||
]==]
|
||||
ngx.say("ok")
|
||||
}
|
||||
}
|
||||
--- request
|
||||
GET /t
|
||||
--- response_body
|
||||
ok
|
||||
--- no_error_log
|
||||
[error]
|
||||
|
||||
|
||||
|
||||
=== TEST 6: content_by_lua_block ("nested" long brackets)
|
||||
--- config
|
||||
location = /t {
|
||||
content_by_lua_block {
|
||||
--[[
|
||||
]=]
|
||||
' "
|
||||
}
|
||||
]]
|
||||
ngx.say("ok")
|
||||
}
|
||||
}
|
||||
--- request
|
||||
GET /t
|
||||
--- response_body
|
||||
ok
|
||||
--- no_error_log
|
||||
[error]
|
||||
|
||||
|
||||
|
||||
=== TEST 7: content_by_lua_block (curly braces in line comments)
|
||||
--- config
|
||||
location = /t {
|
||||
content_by_lua_block {
|
||||
--}} {}
|
||||
ngx.say("ok")
|
||||
}
|
||||
}
|
||||
--- request
|
||||
GET /t
|
||||
--- response_body
|
||||
ok
|
||||
--- no_error_log
|
||||
[error]
|
||||
|
||||
|
||||
|
||||
=== TEST 8: content_by_lua_block (cosockets)
|
||||
--- config
|
||||
server_tokens off;
|
||||
location = /t {
|
||||
content_by_lua_block {
|
||||
local sock = ngx.socket.tcp()
|
||||
local port = ngx.var.port
|
||||
local ok, err = sock:connect('127.0.0.1', tonumber(ngx.var.server_port))
|
||||
if not ok then
|
||||
ngx.say("failed to connect: ", err)
|
||||
return
|
||||
end
|
||||
|
||||
ngx.say('connected: ', ok)
|
||||
|
||||
local req = "GET /foo HTTP/1.0\r\nHost: localhost\r\nConnection: close\r\n\r\n"
|
||||
-- req = "OK"
|
||||
|
||||
local bytes, err = sock:send(req)
|
||||
if not bytes then
|
||||
ngx.say("failed to send request: ", err)
|
||||
return
|
||||
end
|
||||
|
||||
ngx.say("request sent: ", bytes)
|
||||
|
||||
while true do
|
||||
local line, err, part = sock:receive()
|
||||
if line then
|
||||
ngx.say("received: ", line)
|
||||
|
||||
else
|
||||
ngx.say("failed to receive a line: ", err, " [", part, "]")
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
ok, err = sock:close()
|
||||
ngx.say("close: ", ok, " ", err)
|
||||
}
|
||||
}
|
||||
|
||||
location /foo {
|
||||
content_by_lua_block { ngx.say("foo") }
|
||||
more_clear_headers Date;
|
||||
}
|
||||
|
||||
--- request
|
||||
GET /t
|
||||
--- response_body
|
||||
connected: 1
|
||||
request sent: 57
|
||||
received: HTTP/1.1 200 OK
|
||||
received: Server: nginx
|
||||
received: Content-Type: text/plain
|
||||
received: Content-Length: 4
|
||||
received: Connection: close
|
||||
received:
|
||||
received: foo
|
||||
failed to receive a line: closed []
|
||||
close: 1 nil
|
||||
--- no_error_log
|
||||
[error]
|
||||
|
||||
|
||||
|
||||
=== TEST 9: all in one
|
||||
--- http_config
|
||||
init_by_lua_block {
|
||||
glob = "init by lua }here{"
|
||||
}
|
||||
|
||||
init_worker_by_lua_block {
|
||||
glob = glob .. ", init worker }here{"
|
||||
}
|
||||
--- config
|
||||
location = /t {
|
||||
set $a '';
|
||||
rewrite_by_lua_block {
|
||||
local s = ngx.var.a
|
||||
s = s .. "}rewrite{\n"
|
||||
ngx.var.a = s
|
||||
}
|
||||
access_by_lua_block {
|
||||
local s = ngx.var.a
|
||||
s = s .. '}access{\n'
|
||||
ngx.var.a = s
|
||||
}
|
||||
content_by_lua_block {
|
||||
local s = ngx.var.a
|
||||
s = s .. [[}content{]]
|
||||
ngx.say(s)
|
||||
ngx.say("glob: ", glob)
|
||||
}
|
||||
log_by_lua_block {
|
||||
print("log by lua running \"}{!\"")
|
||||
}
|
||||
header_filter_by_lua_block {
|
||||
ngx.header["Foo"] = "\"Hello, world\""
|
||||
ngx.header["Content-Length"] = nil
|
||||
}
|
||||
body_filter_by_lua_block {
|
||||
local data, eof = ngx.arg[1], ngx.arg[2]
|
||||
print("eof = ", eof)
|
||||
if eof then
|
||||
if not data then
|
||||
data = ""
|
||||
end
|
||||
data = data .. "}body filter{\n"
|
||||
print("data: ", data)
|
||||
ngx.arg[1] = data
|
||||
end
|
||||
}
|
||||
}
|
||||
--- request
|
||||
GET /t
|
||||
--- response_body
|
||||
}rewrite{
|
||||
}access{
|
||||
}content{
|
||||
glob: init by lua }here{, init worker }here{
|
||||
}body filter{
|
||||
|
||||
--- response_headers
|
||||
Foo: "Hello, world"
|
||||
--- error_log
|
||||
log by lua running "}{!"
|
||||
--- no_error_log
|
||||
[error]
|
||||
|
||||
|
||||
|
||||
=== TEST 10: missing ]] (string)
|
||||
--- config
|
||||
location = /t {
|
||||
content_by_lua_block {
|
||||
ngx.say([[hello, world")
|
||||
}
|
||||
}
|
||||
--- request
|
||||
GET /t
|
||||
--- response_body
|
||||
hello, world
|
||||
--- no_error_log
|
||||
[error]
|
||||
--- must_die
|
||||
--- error_log eval
|
||||
qr/\[emerg\] .*? Lua code block missing the closing long bracket in .*?\bnginx\.conf:40/
|
||||
|
||||
|
||||
|
||||
=== TEST 11: missing ]] (comment)
|
||||
--- config
|
||||
location = /t {
|
||||
content_by_lua_block {
|
||||
ngx.say(--[[hello, world")
|
||||
}
|
||||
}
|
||||
--- request
|
||||
GET /t
|
||||
--- response_body
|
||||
hello, world
|
||||
--- no_error_log
|
||||
[error]
|
||||
--- must_die
|
||||
--- error_log eval
|
||||
qr/\[emerg\] .*? Lua code block missing the closing long bracket in .*?\bnginx\.conf:40/
|
||||
|
||||
|
||||
|
||||
=== TEST 12: missing }
|
||||
FIXME: we need better diagnostics by actually loading the inlined Lua code while parsing
|
||||
the *_by_lua_block directive.
|
||||
|
||||
--- config
|
||||
location = /t {
|
||||
content_by_lua_block {
|
||||
ngx.say("hello")
|
||||
--- request
|
||||
GET /t
|
||||
--- response_body
|
||||
hello, world
|
||||
--- no_error_log
|
||||
[error]
|
||||
--- error_log
|
||||
"events" directive is not allowed here
|
||||
--- must_die
|
||||
|
||||
|
||||
|
||||
=== TEST 13: content_by_lua_block (compact)
|
||||
--- config
|
||||
location = /t {
|
||||
content_by_lua_block {ngx.say("hello, world", {"!"})}
|
||||
}
|
||||
--- request
|
||||
GET /t
|
||||
--- response_body
|
||||
hello, world!
|
||||
--- no_error_log
|
||||
[error]
|
||||
|
||||
|
||||
|
||||
=== TEST 14: content_by_lua_block (unexpected closing long brackets)
|
||||
--- config
|
||||
location = /t {
|
||||
content_by_lua_block {
|
||||
]=]
|
||||
}
|
||||
}
|
||||
--- request
|
||||
GET /t
|
||||
--- no_error_log
|
||||
[error]
|
||||
--- error_log eval
|
||||
qr{\[emerg\] .*? unexpected lua closing long-bracket in .*?/nginx\.conf:40}
|
||||
--- must_die
|
|
@ -0,0 +1,18 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
if [ -z "$1" ]; then
|
||||
level=0
|
||||
else
|
||||
level="$1"
|
||||
fi
|
||||
|
||||
#echo '{' '}' '\[=*\[' '--\[=*\[' '\]=*\]' '--[^\n]*' '"(?:\\[^\n]|[^"\n\\])*"' $'\'(?:\\\\[^\\n]|[^\'\\n\\\\])*\''
|
||||
|
||||
# we need the re.pl script here:
|
||||
# https://github.com/openresty/sregex/blob/dfa-multi-re/re.pl
|
||||
re.pl -W --no-main -c --cc="clang -O2" \
|
||||
--func-name ngx_http_lua_lex \
|
||||
--header ngx_http_lua_lex.h -o src/ngx_http_lua_lex.c \
|
||||
--debug=$level -n 8 \
|
||||
-- '{' '}' '\[=*\[' '--\[=*\[' '\]=*\]' '--[^\n]*' '"(?:\\[^\n]|[^"\n\\])*"' $'\'(?:\\\\[^\\n]|[^\'\\n\\\\])*\'' \
|
||||
|| exit 1
|
Загрузка…
Ссылка в новой задаче