1
0
mirror of https://github.com/apache/httpd.git synced 2025-08-08 15:02:10 +03:00

mod_lua: Add r:flush, r:sendfile as well as additional request information in the request_rec structure

git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1370158 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Daniel Gruno
2012-08-07 10:02:27 +00:00
parent 8010a76346
commit 2e9e74fd6c
3 changed files with 223 additions and 3 deletions

View File

@@ -1,6 +1,9 @@
-*- coding: utf-8 -*- -*- coding: utf-8 -*-
Changes with Apache 2.5.0 Changes with Apache 2.5.0
*) mod_lua: Add functions r:flush and r:sendfile as well as additional
request information to the request_rec structure. [Daniel Gruno]
*) mod_rewrite: Fix crash with dbd RewriteMaps. PR 53663. [Mikhail T. *) mod_rewrite: Fix crash with dbd RewriteMaps. PR 53663. [Mikhail T.
<mi apache aldan algebra com>] <mi apache aldan algebra com>]

View File

@@ -336,6 +336,12 @@ end
<th><strong>Writable</strong></th> <th><strong>Writable</strong></th>
<th><strong>Description</strong></th> <th><strong>Description</strong></th>
</tr> </tr>
<tr>
<td><code>allowoverrides</code></td>
<td>string</td>
<td>no</td>
<td>The AllowOverride options applied to the current request.</td>
</tr>
<tr> <tr>
<td><code>ap_auth_type</code></td> <td><code>ap_auth_type</code></td>
<td>string</td> <td>string</td>
@@ -357,7 +363,24 @@ end
<td>Set to true if this is an HTTP/0.9 style request <td>Set to true if this is an HTTP/0.9 style request
(e.g. <code>GET /foo</code> (with no headers) )</td> (e.g. <code>GET /foo</code> (with no headers) )</td>
</tr> </tr>
<tr>
<td><code>auth_name</code></td>
<td>string</td>
<td>no</td>
<td>The realm name used for authorization (if applicable).</td>
</tr>
<tr>
<td><code>banner</code></td>
<td>string</td>
<td>no</td>
<td>The server banner, f.x. <code>Apache HTTP Server/2.4.3 openssl/0.9.8c</code></td>
</tr>
<tr>
<td><code>basic_auth_pw</code></td>
<td>string</td>
<td>no</td>
<td>The basic auth password sent with this request, if any</td>
</tr>
<tr> <tr>
<td><code>canonical_filename</code></td> <td><code>canonical_filename</code></td>
<td>string</td> <td>string</td>
@@ -448,6 +471,18 @@ end
<td>no</td> <td>no</td>
<td>Whether or not this request is done via HTTPS</td> <td>Whether or not this request is done via HTTPS</td>
</tr> </tr>
<tr>
<td><code>is_initial_req</code></td>
<td>boolean</td>
<td>no</td>
<td>Whether this request is the initial request or a sub-request</td>
</tr>
<tr>
<td><code>limit_req_body</code></td>
<td>number</td>
<td>no</td>
<td>The size limit of the request body for this request, or 0 if no limit.</td>
</tr>
<tr> <tr>
<td><code>log_id</code></td> <td><code>log_id</code></td>
<td>string</td> <td>string</td>
@@ -466,12 +501,24 @@ end
<td>yes</td> <td>yes</td>
<td>A list of notes that can be passed on from one module to another.</td> <td>A list of notes that can be passed on from one module to another.</td>
</tr> </tr>
<tr>
<td><code>options</code></td>
<td>string</td>
<td>no</td>
<td>The Options directive applied to the current request.</td>
</tr>
<tr> <tr>
<td><code>path_info</code></td> <td><code>path_info</code></td>
<td>string</td> <td>string</td>
<td>no</td> <td>no</td>
<td>The PATH_INFO extracted from this request.</td> <td>The PATH_INFO extracted from this request.</td>
</tr> </tr>
<tr>
<td><code>port</code></td>
<td>number</td>
<td>no</td>
<td>The server port used by the request.</td>
</tr>
<tr> <tr>
<td><code>protocol</code></td> <td><code>protocol</code></td>
<td>string</td> <td>string</td>
@@ -491,12 +538,42 @@ end
<td>no</td> <td>no</td>
<td>The contents of the <code>Range:</code> header.</td> <td>The contents of the <code>Range:</code> header.</td>
</tr> </tr>
<tr>
<td><code>remaining</code></td>
<td>number</td>
<td>no</td>
<td>The number of bytes remaining to be read from the request body.</td>
</tr>
<tr>
<td><code>server_built</code></td>
<td>string</td>
<td>no</td>
<td>The time the server executable was built.</td>
</tr>
<tr>
<td><code>server_name</code></td>
<td>string</td>
<td>no</td>
<td>The server name for this request.</td>
</tr>
<tr>
<td><code>some_auth_required</code></td>
<td>boolean</td>
<td>no</td>
<td>Whether some authorization is/was required for this request.</td>
</tr>
<tr> <tr>
<td><code>subprocess_env</code></td> <td><code>subprocess_env</code></td>
<td>table</td> <td>table</td>
<td>yes</td> <td>yes</td>
<td>The environment variables set for this request.</td> <td>The environment variables set for this request.</td>
</tr> </tr>
<tr>
<td><code>started</code></td>
<td>number</td>
<td>no</td>
<td>The time the server was (re)started, in seconds since the epoch (Jan 1st, 1970)</td>
</tr>
<tr> <tr>
<td><code>status</code></td> <td><code>status</code></td>
<td>number</td> <td>number</td>
@@ -537,10 +614,18 @@ end
<p>The request_rec has (at least) the following methods:</p> <p>The request_rec has (at least) the following methods:</p>
<highlight language="lua">
r:flush() -- flushes the output buffer
</highlight>
<highlight language="lua"> <highlight language="lua">
r:addoutputfilter(name|function) -- add an output filter r:addoutputfilter(name|function) -- add an output filter
</highlight> </highlight>
<highlight language="lua">
r:sendfile(filename) -- sends an entire file to the client, using sendfile if supported by the current platform
</highlight>
<highlight language="lua"> <highlight language="lua">
r:parseargs() -- returns a Lua table containing the request's query string arguments r:parseargs() -- returns a Lua table containing the request's query string arguments
</highlight> </highlight>

View File

@@ -18,6 +18,7 @@
#include "mod_lua.h" #include "mod_lua.h"
#include "util_script.h" #include "util_script.h"
#include "lua_apr.h" #include "lua_apr.h"
#include "scoreboard.h"
APLOG_USE_MODULE(lua); APLOG_USE_MODULE(lua);
@@ -371,6 +372,11 @@ static const char *req_useragent_ip_field(request_rec *r)
return r->useragent_ip; return r->useragent_ip;
} }
static int req_remaining_field(request_rec *r)
{
return r->remaining;
}
static int req_status_field(request_rec *r) static int req_status_field(request_rec *r)
{ {
return r->status; return r->status;
@@ -411,7 +417,103 @@ static int req_ssl_is_https_field(request_rec *r)
return ap_lua_ssl_is_https(r->connection); return ap_lua_ssl_is_https(r->connection);
} }
/* END dispatch mathods for request_rec fields */ static int lua_ap_rflush (lua_State *L) {
int returnValue;
request_rec *r;
luaL_checktype(L, 1, LUA_TUSERDATA);
r = ap_lua_check_request_rec(L, 1);
returnValue = ap_rflush(r);
lua_pushboolean(L, (returnValue == 0));
return 1;
}
static int lua_ap_port(request_rec* r)
{
return (int) ap_get_server_port(r);
}
static const char* lua_ap_options(request_rec* r)
{
int opts;
opts = ap_allow_options(r);
return apr_psprintf(r->pool, "%s %s %s %s %s %s", (opts&OPT_INDEXES) ? "Indexes" : "", (opts&OPT_INCLUDES) ? "Includes" : "", (opts&OPT_SYM_LINKS) ? "FollowSymLinks" : "", (opts&OPT_EXECCGI) ? "ExecCGI" : "", (opts&OPT_MULTI) ? "MultiViews" : "", (opts&OPT_ALL) == OPT_ALL ? "All" : "" );
}
static const char* lua_ap_allowoverrides(request_rec* r)
{
int opts;
opts = ap_allow_overrides(r);
return apr_psprintf(r->pool, "%s %s %s %s %s %s", (opts&OR_NONE) ? "None" : "", (opts&OR_LIMIT) ? "Limit" : "", (opts&OR_OPTIONS) ? "Options" : "", (opts&OR_FILEINFO) ? "FileInfo" : "", (opts&OR_AUTHCFG) ? "AuthCfg" : "", (opts&OR_INDEXES) ? "Indexes" : "" );
}
static int lua_ap_started(request_rec* r)
{
return ap_scoreboard_image->global->restart_time;
}
static const char* lua_ap_basic_auth_pw(request_rec* r)
{
const char* pw = NULL;
ap_get_basic_auth_pw(r, &pw);
return pw ? pw : "";
}
static int lua_ap_limit_req_body(request_rec* r)
{
return (int) ap_get_limit_req_body(r);
}
static int lua_ap_is_initial_req(request_rec *r)
{
return ap_is_initial_req(r);
}
static int lua_ap_some_auth_required(request_rec *r)
{
return ap_some_auth_required(r);
}
static int lua_ap_sendfile(lua_State *L)
{
apr_finfo_t file_info;
const char *filename;
request_rec *r;
luaL_checktype(L, 1, LUA_TUSERDATA);
luaL_checktype(L, 2, LUA_TSTRING);
r = ap_lua_check_request_rec(L, 1);
filename = lua_tostring(L, 2);
apr_stat(&file_info, filename, APR_FINFO_NORM, r->pool);
if (file_info.filetype == APR_NOFILE || file_info.filetype == APR_DIR) {
lua_pushboolean(L, 0);
}
else {
if (r) {
apr_size_t sent;
apr_status_t rc;
apr_file_t *file;
rc = apr_file_open(&file, filename, APR_READ, APR_OS_DEFAULT,
r->pool);
if (rc == APR_SUCCESS) {
ap_send_fd(file, r, 0, file_info.size, &sent);
apr_file_close(file);
lua_pushinteger(L, sent);
}
else
lua_pushboolean(L, 0);
}
else
lua_pushboolean(L, 0);
}
return (1);
}
/* END dispatch methods for request_rec fields */
static int req_dispatch(lua_State *L) static int req_dispatch(lua_State *L)
{ {
@@ -751,7 +853,37 @@ AP_LUA_DECLARE(void) ap_lua_load_request_lmodule(lua_State *L, apr_pool_t *p)
makefun(&req_notes, APL_REQ_FUNTYPE_TABLE, p)); makefun(&req_notes, APL_REQ_FUNTYPE_TABLE, p));
apr_hash_set(dispatch, "subprocess_env", APR_HASH_KEY_STRING, apr_hash_set(dispatch, "subprocess_env", APR_HASH_KEY_STRING,
makefun(&req_subprocess_env, APL_REQ_FUNTYPE_TABLE, p)); makefun(&req_subprocess_env, APL_REQ_FUNTYPE_TABLE, p));
apr_hash_set(dispatch, "flush", APR_HASH_KEY_STRING,
makefun(&lua_ap_rflush, APL_REQ_FUNTYPE_LUACFUN, p));
apr_hash_set(dispatch, "port", APR_HASH_KEY_STRING,
makefun(&lua_ap_port, APL_REQ_FUNTYPE_INT, p));
apr_hash_set(dispatch, "banner", APR_HASH_KEY_STRING,
makefun(&ap_get_server_banner, APL_REQ_FUNTYPE_STRING, p));
apr_hash_set(dispatch, "options", APR_HASH_KEY_STRING,
makefun(&lua_ap_options, APL_REQ_FUNTYPE_STRING, p));
apr_hash_set(dispatch, "allowoverrides", APR_HASH_KEY_STRING,
makefun(&lua_ap_allowoverrides, APL_REQ_FUNTYPE_STRING, p));
apr_hash_set(dispatch, "started", APR_HASH_KEY_STRING,
makefun(&lua_ap_started, APL_REQ_FUNTYPE_INT, p));
apr_hash_set(dispatch, "basic_auth_pw", APR_HASH_KEY_STRING,
makefun(&lua_ap_basic_auth_pw, APL_REQ_FUNTYPE_STRING, p));
apr_hash_set(dispatch, "limit_req_body", APR_HASH_KEY_STRING,
makefun(&lua_ap_limit_req_body, APL_REQ_FUNTYPE_INT, p));
apr_hash_set(dispatch, "server_built", APR_HASH_KEY_STRING,
makefun(&ap_get_server_built, APL_REQ_FUNTYPE_STRING, p));
apr_hash_set(dispatch, "is_initial_req", APR_HASH_KEY_STRING,
makefun(&lua_ap_is_initial_req, APL_REQ_FUNTYPE_BOOLEAN, p));
apr_hash_set(dispatch, "remaining", APR_HASH_KEY_STRING,
makefun(&req_remaining_field, APL_REQ_FUNTYPE_INT, p));
apr_hash_set(dispatch, "some_auth_required", APR_HASH_KEY_STRING,
makefun(&lua_ap_some_auth_required, APL_REQ_FUNTYPE_BOOLEAN, p));
apr_hash_set(dispatch, "server_name", APR_HASH_KEY_STRING,
makefun(&ap_get_server_name, APL_REQ_FUNTYPE_STRING, p));
apr_hash_set(dispatch, "auth_name", APR_HASH_KEY_STRING,
makefun(&ap_auth_name, APL_REQ_FUNTYPE_STRING, p));
apr_hash_set(dispatch, "sendfile", APR_HASH_KEY_STRING,
makefun(&lua_ap_sendfile, APL_REQ_FUNTYPE_LUACFUN, p));
lua_pushlightuserdata(L, dispatch); lua_pushlightuserdata(L, dispatch);
lua_setfield(L, LUA_REGISTRYINDEX, "Apache2.Request.dispatch"); lua_setfield(L, LUA_REGISTRYINDEX, "Apache2.Request.dispatch");