diff --git a/src/ngx_http_lua_output.c b/src/ngx_http_lua_output.c index 327282aabe..dca498e8cb 100644 --- a/src/ngx_http_lua_output.c +++ b/src/ngx_http_lua_output.c @@ -11,10 +11,12 @@ static int ngx_http_lua_ngx_say(lua_State *L); static int ngx_http_lua_ngx_print(lua_State *L); +static int ngx_http_lua_ngx_print_raw_header(lua_State *L); +static int ngx_http_lua_ngx_print_raw(lua_State *L); static int ngx_http_lua_ngx_flush(lua_State *L); static int ngx_http_lua_ngx_eof(lua_State *L); static int ngx_http_lua_ngx_send_headers(lua_State *L); -static int ngx_http_lua_ngx_echo(lua_State *L, unsigned newline); +static int ngx_http_lua_ngx_echo(lua_State *L, unsigned newline, unsigned raw); static void ngx_http_lua_flush_cleanup(void *data); @@ -22,7 +24,7 @@ static int ngx_http_lua_ngx_print(lua_State *L) { dd("calling lua print"); - return ngx_http_lua_ngx_echo(L, 0); + return ngx_http_lua_ngx_echo(L, 0, 0); } @@ -30,12 +32,49 @@ static int ngx_http_lua_ngx_say(lua_State *L) { dd("calling"); - return ngx_http_lua_ngx_echo(L, 1); + return ngx_http_lua_ngx_echo(L, 1, 0); } static int -ngx_http_lua_ngx_echo(lua_State *L, unsigned newline) +ngx_http_lua_ngx_print_raw(lua_State *L) +{ + dd("calling lua print raw"); + return ngx_http_lua_ngx_echo(L, 0, 1); +} + + +static int +ngx_http_lua_ngx_print_raw_header(lua_State *L) +{ + ngx_http_request_t *r; + ngx_http_lua_ctx_t *ctx; + + dd("calling lua print raw header"); + + lua_pushlightuserdata(L, &ngx_http_lua_request_key); + lua_rawget(L, LUA_GLOBALSINDEX); + r = lua_touserdata(L, -1); + lua_pop(L, 1); + + if (r == NULL) { + return luaL_error(L, "no request object found"); + } + + ctx = ngx_http_get_module_ctx(r, ngx_http_lua_module); + + if (ctx == NULL) { + return luaL_error(L, "no request ctx found"); + } + + ctx->headers_sent = 1; + + return ngx_http_lua_ngx_echo(L, 0, 1); +} + + +static int +ngx_http_lua_ngx_echo(lua_State *L, unsigned newline, unsigned raw) { ngx_http_request_t *r; ngx_http_lua_ctx_t *ctx; @@ -217,7 +256,7 @@ ngx_http_lua_ngx_echo(lua_State *L, unsigned newline) ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, newline ? "lua say response" : "lua print response"); - rc = ngx_http_lua_send_chain_link(r, ctx, cl); + rc = ngx_http_lua_send_chain_link(r, ctx, cl, raw); if (rc == NGX_ERROR || rc >= NGX_HTTP_SPECIAL_RESPONSE) { return luaL_error(L, "failed to send data through the output filters"); @@ -531,7 +570,7 @@ ngx_http_lua_ngx_flush(lua_State *L) ctx->flush_buf = cl; } - rc = ngx_http_lua_send_chain_link(r, ctx, cl); + rc = ngx_http_lua_send_chain_link(r, ctx, cl, 0); if (rc == NGX_ERROR || rc >= NGX_HTTP_SPECIAL_RESPONSE) { return luaL_error(L, "failed to send chain link: %d", (int) rc); @@ -622,7 +661,7 @@ ngx_http_lua_ngx_eof(lua_State *L) ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "lua send eof"); - rc = ngx_http_lua_send_chain_link(r, ctx, NULL/*indicate last_buf*/); + rc = ngx_http_lua_send_chain_link(r, ctx, NULL/*indicate last_buf*/, 0); if (rc == NGX_ERROR || rc >= NGX_HTTP_SPECIAL_RESPONSE) { return luaL_error(L, "failed to send eof buf"); @@ -641,6 +680,12 @@ ngx_http_lua_inject_output_api(lua_State *L) lua_pushcfunction(L, ngx_http_lua_ngx_print); lua_setfield(L, -2, "print"); + lua_pushcfunction(L, ngx_http_lua_ngx_print_raw); + lua_setfield(L, -2, "rawprint"); + + lua_pushcfunction(L, ngx_http_lua_ngx_print_raw_header); + lua_setfield(L, -2, "rawprint_headers"); + lua_pushcfunction(L, ngx_http_lua_ngx_say); lua_setfield(L, -2, "say"); diff --git a/src/ngx_http_lua_util.c b/src/ngx_http_lua_util.c index 7a8aad43f1..436f945ee6 100644 --- a/src/ngx_http_lua_util.c +++ b/src/ngx_http_lua_util.c @@ -84,7 +84,7 @@ static int ngx_http_lua_param_set(lua_State *L); static void ngx_http_lua_del_all_threads(ngx_http_request_t *r, lua_State *L, ngx_http_lua_ctx_t *ctx); static ngx_int_t ngx_http_lua_output_filter(ngx_http_request_t *r, - ngx_chain_t *in); + ngx_chain_t *in, ngx_int_t raw); static ngx_int_t ngx_http_lua_send_special(ngx_http_request_t *r, ngx_uint_t flags); static void ngx_http_lua_finalize_coroutines(ngx_http_request_t *r, @@ -494,7 +494,7 @@ ngx_http_lua_send_header_if_needed(ngx_http_request_t *r, ngx_int_t ngx_http_lua_send_chain_link(ngx_http_request_t *r, ngx_http_lua_ctx_t *ctx, - ngx_chain_t *in) + ngx_chain_t *in, unsigned raw) { ngx_int_t rc; ngx_chain_t *cl; @@ -548,7 +548,7 @@ ngx_http_lua_send_chain_link(ngx_http_request_t *r, ngx_http_lua_ctx_t *ctx, if (ctx->out) { - rc = ngx_http_lua_output_filter(r, ctx->out); + rc = ngx_http_lua_output_filter(r, ctx->out, raw); if (rc == NGX_ERROR || rc >= NGX_HTTP_SPECIAL_RESPONSE) { return rc; @@ -597,7 +597,7 @@ ngx_http_lua_send_chain_link(ngx_http_request_t *r, ngx_http_lua_ctx_t *ctx, return NGX_OK; } - return ngx_http_lua_output_filter(r, in); + return ngx_http_lua_output_filter(r, in, raw); } @@ -624,7 +624,7 @@ ngx_http_lua_send_special(ngx_http_request_t *r, ngx_uint_t flags) static ngx_int_t -ngx_http_lua_output_filter(ngx_http_request_t *r, ngx_chain_t *in) +ngx_http_lua_output_filter(ngx_http_request_t *r, ngx_chain_t *in, ngx_int_t raw) { ngx_int_t rc; ngx_http_request_t *ar; /* active request */ @@ -641,7 +641,11 @@ ngx_http_lua_output_filter(ngx_http_request_t *r, ngx_chain_t *in) return rc; } - return ngx_http_output_filter(r, in); + if (raw) { + return ngx_http_write_filter(r, in); + } else { + return ngx_http_output_filter(r, in); + } } @@ -1462,7 +1466,7 @@ ngx_http_lua_run_thread(lua_State *L, ngx_http_request_t *r, done: if (ctx->entered_content_phase && r->connection->fd != -1) { rc = ngx_http_lua_send_chain_link(r, ctx, - NULL /* last_buf */); + NULL /* last_buf */, 0); if (rc == NGX_ERROR || rc >= NGX_HTTP_SPECIAL_RESPONSE) { return rc; @@ -1537,7 +1541,7 @@ ngx_http_lua_wev_handler(ngx_http_request_t *r) "lua wev handler flushing output: buffered 0x%uxd", c->buffered); - rc = ngx_http_lua_output_filter(r, NULL); + rc = ngx_http_lua_output_filter(r, NULL, 0); if (rc == NGX_ERROR || rc > NGX_OK) { if (ctx->entered_content_phase) { @@ -2158,7 +2162,7 @@ ngx_http_lua_handle_exit(lua_State *L, ngx_http_request_t *r, ngx_http_lua_request_cleanup(r); if (ctx->buffering && r->headers_out.status) { - rc = ngx_http_lua_send_chain_link(r, ctx, NULL /* indicate last_buf */); + rc = ngx_http_lua_send_chain_link(r, ctx, NULL /* indicate last_buf */, 0); if (rc == NGX_ERROR || rc >= NGX_HTTP_SPECIAL_RESPONSE) { return rc; @@ -2176,7 +2180,7 @@ ngx_http_lua_handle_exit(lua_State *L, ngx_http_request_t *r, || (ctx->exit_code >= NGX_HTTP_OK && ctx->exit_code < NGX_HTTP_SPECIAL_RESPONSE)) { - rc = ngx_http_lua_send_chain_link(r, ctx, NULL /* indicate last_buf */); + rc = ngx_http_lua_send_chain_link(r, ctx, NULL /* indicate last_buf */, 0); if (rc == NGX_ERROR || rc >= NGX_HTTP_SPECIAL_RESPONSE) { return rc; diff --git a/src/ngx_http_lua_util.h b/src/ngx_http_lua_util.h index b06c383dcf..353e2c84b9 100644 --- a/src/ngx_http_lua_util.h +++ b/src/ngx_http_lua_util.h @@ -97,7 +97,7 @@ ngx_int_t ngx_http_lua_send_header_if_needed(ngx_http_request_t *r, ngx_http_lua_ctx_t *ctx); ngx_int_t ngx_http_lua_send_chain_link(ngx_http_request_t *r, - ngx_http_lua_ctx_t *ctx, ngx_chain_t *cl); + ngx_http_lua_ctx_t *ctx, ngx_chain_t *cl, unsigned raw); void ngx_http_lua_discard_bufs(ngx_pool_t *pool, ngx_chain_t *in);