Apache HTTPD
lua_request.c
Go to the documentation of this file.
1
18#include "mod_lua.h"
19#include "lua_apr.h"
20#include "lua_dbd.h"
21#include "lua_passwd.h"
22#include "scoreboard.h"
23#include "util_md5.h"
24#include "util_script.h"
25#include "util_varbuf.h"
26#include "apr_date.h"
27#include "apr_pools.h"
28#include "apr_thread_mutex.h"
29#include "apr_tables.h"
30#include "util_cookies.h"
31
32#define APR_WANT_BYTEFUNC
33#include "apr_want.h"
34
37
39#define POST_MAX_VARS 500
40
41#ifndef MODLUA_MAX_REG_MATCH
42#define MODLUA_MAX_REG_MATCH 25
43#endif
44
45typedef char *(*req_field_string_f) (request_rec * r);
47typedef req_table_t *(*req_field_apr_table_f) (request_rec * r);
48
49
50void ap_lua_rstack_dump(lua_State *L, request_rec *r, const char *msg)
51{
52 int i;
53 int top = lua_gettop(L);
54 ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, APLOGNO(01484) "Lua Stack Dump: [%s]", msg);
55 for (i = 1; i <= top; i++) {
56 int t = lua_type(L, i);
57 switch (t) {
58 case LUA_TSTRING:{
60 "%d: '%s'", i, lua_tostring(L, i));
61 break;
62 }
63 case LUA_TUSERDATA:{
65 "%d: userdata", i);
66 break;
67 }
70 "%d: lightuserdata", i);
71 break;
72 }
73 case LUA_TNIL:{
75 "%d: NIL", i);
76 break;
77 }
78 case LUA_TNONE:{
80 "%d: None", i);
81 break;
82 }
83 case LUA_TBOOLEAN:{
85 "%d: %s", i,
86 lua_toboolean(L, i) ? "true" : "false");
87 break;
88 }
89 case LUA_TNUMBER:{
91 "%d: %g", i, lua_tonumber(L, i));
92 break;
93 }
94 case LUA_TTABLE:{
96 "%d: <table>", i);
97 break;
98 }
99 case LUA_TFUNCTION:{
101 "%d: <function>", i);
102 break;
103 }
104 default:{
106 "%d: unknown: -[%s]-", i, lua_typename(L, i));
107 break;
108 }
109 }
110 }
111}
112
119{
120 request_rec *r;
121 luaL_checkudata(L, index, "Apache2.Request");
122 r = (request_rec *) lua_unboxpointer(L, index);
123 return r;
124}
125
126/* ------------------ request methods -------------------- */
127/* helper callback for req_parseargs */
128static int req_aprtable2luatable_cb(void *l, const char *key,
129 const char *value)
130{
131 int t;
132 lua_State *L = (lua_State *) l; /* [table<s,t>, table<s,s>] */
133 /* rstack_dump(L, RRR, "start of cb"); */
134 /* L is [table<s,t>, table<s,s>] */
135 /* build complex */
136
137 lua_getfield(L, -1, key); /* [VALUE, table<s,t>, table<s,s>] */
138 /* rstack_dump(L, RRR, "after getfield"); */
139 t = lua_type(L, -1);
140 switch (t) {
141 case LUA_TNIL:
142 case LUA_TNONE:{
143 lua_pop(L, 1); /* [table<s,t>, table<s,s>] */
144 lua_newtable(L); /* [array, table<s,t>, table<s,s>] */
145 lua_pushnumber(L, 1); /* [1, array, table<s,t>, table<s,s>] */
146 lua_pushstring(L, value); /* [string, 1, array, table<s,t>, table<s,s>] */
147 lua_settable(L, -3); /* [array, table<s,t>, table<s,s>] */
148 lua_setfield(L, -2, key); /* [table<s,t>, table<s,s>] */
149 break;
150 }
151 case LUA_TTABLE:{
152 /* [array, table<s,t>, table<s,s>] */
153 int size = lua_rawlen(L, -1);
154 lua_pushnumber(L, size + 1); /* [#, array, table<s,t>, table<s,s>] */
155 lua_pushstring(L, value); /* [string, #, array, table<s,t>, table<s,s>] */
156 lua_settable(L, -3); /* [array, table<s,t>, table<s,s>] */
157 lua_setfield(L, -2, key); /* [table<s,t>, table<s,s>] */
158 break;
159 }
160 }
161
162 /* L is [table<s,t>, table<s,s>] */
163 /* build simple */
164 lua_getfield(L, -2, key); /* [VALUE, table<s,s>, table<s,t>] */
165 if (lua_isnoneornil(L, -1)) { /* only set if not already set */
166 lua_pop(L, 1); /* [table<s,s>, table<s,t>]] */
167 lua_pushstring(L, value); /* [string, table<s,s>, table<s,t>] */
168 lua_setfield(L, -3, key); /* [table<s,s>, table<s,t>] */
169 }
170 else {
171 lua_pop(L, 1);
172 }
173 return 1;
174}
175
176/* helper callback for req_parseargs */
177static int req_aprtable2luatable_cb_len(void *l, const char *key,
178 const char *value, size_t len)
179{
180 int t;
181 lua_State *L = (lua_State *) l; /* [table<s,t>, table<s,s>] */
182 /* rstack_dump(L, RRR, "start of cb"); */
183 /* L is [table<s,t>, table<s,s>] */
184 /* build complex */
185
186 lua_getfield(L, -1, key); /* [VALUE, table<s,t>, table<s,s>] */
187 /* rstack_dump(L, RRR, "after getfield"); */
188 t = lua_type(L, -1);
189 switch (t) {
190 case LUA_TNIL:
191 case LUA_TNONE:{
192 lua_pop(L, 1); /* [table<s,t>, table<s,s>] */
193 lua_newtable(L); /* [array, table<s,t>, table<s,s>] */
194 lua_pushnumber(L, 1); /* [1, array, table<s,t>, table<s,s>] */
195 lua_pushlstring(L, value, len); /* [string, 1, array, table<s,t>, table<s,s>] */
196 lua_settable(L, -3); /* [array, table<s,t>, table<s,s>] */
197 lua_setfield(L, -2, key); /* [table<s,t>, table<s,s>] */
198 break;
199 }
200
201 case LUA_TTABLE:{
202 /* [array, table<s,t>, table<s,s>] */
203 int size = lua_rawlen(L, -1);
204 lua_pushnumber(L, size + 1); /* [#, array, table<s,t>, table<s,s>] */
205 lua_pushlstring(L, value, len); /* [string, #, array, table<s,t>, table<s,s>] */
206 lua_settable(L, -3); /* [array, table<s,t>, table<s,s>] */
207 lua_setfield(L, -2, key); /* [table<s,t>, table<s,s>] */
208 break;
209 }
210 }
211
212 /* L is [table<s,t>, table<s,s>] */
213 /* build simple */
214 lua_getfield(L, -2, key); /* [VALUE, table<s,s>, table<s,t>] */
215 if (lua_isnoneornil(L, -1)) { /* only set if not already set */
216 lua_pop(L, 1); /* [table<s,s>, table<s,t>]] */
217 lua_pushlstring(L, value, len); /* [string, table<s,s>, table<s,t>] */
218 lua_setfield(L, -3, key); /* [table<s,s>, table<s,t>] */
219 }
220 else {
221 lua_pop(L, 1);
222 }
223 return 1;
224}
225
226
227/*
228 =======================================================================================================================
229 lua_read_body(request_rec *r, const char **rbuf, apr_off_t *size): Reads any additional form data sent in POST/PUT
230 requests. Used for multipart POST data.
231 =======================================================================================================================
232 */
233static int lua_read_body(request_rec *r, const char **rbuf, apr_off_t *size,
235{
236 int rc = OK;
237
238 *rbuf = NULL;
239 *size = 0;
240
242 return (rc);
243 }
245
246 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
247 apr_off_t len_read = -1;
248 apr_off_t rpos = 0;
250 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
251
252 if (maxsize != 0 && length > maxsize) {
253 return APR_EINCOMPLETE; /* Only room for incomplete data chunk :( */
254 }
255 *rbuf = (const char *) apr_pcalloc(r->pool, (apr_size_t) (length) + 1);
256 while ((rpos < length)
257 && (len_read = ap_get_client_block(r, (char *) *rbuf + rpos,
258 length - rpos)) > 0) {
259 rpos += len_read;
260 }
261 if (len_read < 0) {
262 return APR_EINCOMPLETE;
263 }
264 *size = rpos;
265 }
266 else {
267 rc = DONE;
268 }
269
270 return (rc);
271}
272
273
274/*
275 * =======================================================================================================================
276 * lua_write_body: Reads any additional form data sent in POST/PUT requests
277 * and writes to a file.
278 * =======================================================================================================================
279 */
281{
283
284 *size = 0;
285
287 return rc;
291 len_read,
292 rpos = 0;
294
295 *size = length;
296 while ((len_read =
298 sizeof(argsbuffer))) > 0) {
299 if ((rpos + len_read) > length)
301 else
302 rsize = len_read;
303
305 NULL);
306 if (rc != APR_SUCCESS)
307 return rc;
308 rpos += rsize;
309 }
310 }
311 else {
312 rc = DONE;
313 }
314
315 return rc;
316}
317
318/* expose apr_table as (r/o) lua table */
320{
321 lua_newtable(L);
322 lua_newtable(L); /* [table, table] */
324 return 2; /* [table<string, string>, table<string, array<string>>] */
325}
326
343{
345 return req_aprtable2luatable(L, r->notes);
346}
352/* r:parseargs() returning a lua table */
354{
357 lua_newtable(L);
358 lua_newtable(L); /* [table, table] */
361 return 2; /* [table<string, string>, table<string, array<string>>] */
362}
363
364/* ap_lua_binstrstr: Binary strstr function for uploaded data with NULL bytes */
365static char* ap_lua_binstrstr (const char * haystack, size_t hsize, const char* needle, size_t nsize)
366{
367 size_t p;
368 if (haystack == NULL) return NULL;
369 if (needle == NULL) return NULL;
370 if (hsize < nsize) return NULL;
371 for (p = 0; p <= (hsize - nsize); ++p) {
372 if (memcmp(haystack + p, needle, nsize) == 0) {
373 return (char*) (haystack + p);
374 }
375 }
376 return NULL;
377}
378
379/* r:parsebody(): Parses regular (url-enocded) or multipart POST data and returns two tables*/
381{
384 int res;
387 char *multipart;
388 const char *contentType;
391 multipart = apr_pcalloc(r->pool, 256);
392 contentType = apr_table_get(r->headers_in, "Content-Type");
393 lua_newtable(L);
394 lua_newtable(L); /* [table, table] */
395 if (contentType != NULL && (sscanf(contentType, "multipart/form-data; boundary=%250c", multipart) == 1)) {
396 char *buffer, *key, *filename;
397 char *start = 0, *end = 0, *crlf = 0;
398 const char *data;
399 int i;
400 size_t vlen = 0;
401 size_t len = 0;
403 return 2;
404 }
405 len = strlen(multipart);
406 i = 0;
407 for
408 (
409 start = strstr((char *) data, multipart);
410 start != NULL;
411 start = end
412 ) {
413 i++;
414 if (i == POST_MAX_VARS) break;
415 crlf = strstr((char *) start, "\r\n\r\n");
416 if (!crlf) break;
418 if (end == NULL) break;
419 key = (char *) apr_pcalloc(r->pool, 256);
420 filename = (char *) apr_pcalloc(r->pool, 256);
421 if (end - crlf <= 8) break;
422 vlen = end - crlf - 8;
423 buffer = (char *) apr_pcalloc(r->pool, vlen+1);
424 memcpy(buffer, crlf + 4, vlen);
425 sscanf(start + len + 2,
426 "Content-Disposition: form-data; name=\"%255[^\"]\"; filename=\"%255[^\"]\"",
427 key, filename);
428 if (*key) {
430 }
431 }
432 }
433 else {
434 char *buffer;
436 if (res == OK) {
437 while(pairs && !apr_is_empty_array(pairs)) {
439 apr_brigade_length(pair->value, 1, &len);
440 size = (apr_size_t) len;
441 buffer = apr_palloc(r->pool, size + 1);
443 buffer[len] = 0;
445 }
446 }
447 }
448 return 2; /* [table<string, string>, table<string, array<string>>] */
449}
450
451
452/*
453 * lua_ap_requestbody; r:requestbody([filename]) - Reads or stores the request
454 * body
455 */
457{
458 const char *filename;
459 request_rec *r;
461
463 filename = luaL_optstring(L, 2, 0);
465
466 if (r) {
468 if (maxSize > 0 && r->remaining > maxSize) {
469 lua_pushnil(L);
470 lua_pushliteral(L, "Request body was larger than the permitted size.");
471 return 2;
472 }
473 if (r->method_number != M_POST && r->method_number != M_PUT)
474 return (0);
475 if (!filename) {
476 const char *data;
477
478 if (lua_read_body(r, &data, &size, maxSize) != OK)
479 return (0);
480
481 lua_pushlstring(L, data, (size_t) size);
483 return (2);
484 } else {
487
490 lua_settop(L, 0);
491 if (rc == APR_SUCCESS) {
494 if (rc != OK) {
495 lua_pushboolean(L, 0);
496 return 1;
497 }
499 return (1);
500 } else
501 lua_pushboolean(L, 0);
502 return (1);
503 }
504 }
505
506 return (0);
507}
508
509/* wrap ap_rputs as r:puts(String) */
510static int req_puts(lua_State *L)
511{
513
514 int argc = lua_gettop(L);
515 int i;
516
517 for (i = 2; i <= argc; i++) {
519 }
520 return 0;
521}
522
523/* wrap ap_rwrite as r:write(String) */
524static int req_write(lua_State *L)
525{
527 size_t n;
528 int rv;
529 const char *buf = luaL_checklstring(L, 2, &n);
530
531 rv = ap_rwrite((void *) buf, n, r);
532 lua_pushinteger(L, rv);
533 return 1;
534}
535
536/* r:add_output_filter(name) */
538{
540 const char *name = luaL_checkstring(L, 2);
541 ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01485) "adding output filter %s",
542 name);
544 return 0;
545}
546
547/* wrap ap_construct_url as r:construct_url(String) */
549{
551 const char *name = luaL_checkstring(L, 2);
553 return 1;
554}
555
556/* wrap ap_escape_html r:escape_html(String) */
558{
560 const char *s = luaL_checkstring(L, 2);
562 return 1;
563}
564
565/* wrap optional ssl_var_lookup as r:ssl_var_lookup(String) */
567{
569 const char *s = luaL_checkstring(L, 2);
570 const char *res = ap_lua_ssl_val(r->pool, r->server, r->connection, r,
571 (char *)s);
573 return 1;
574}
575
576/* BEGIN dispatch mathods for request_rec fields */
577
578/* not really a field, but we treat it like one */
579static const char *req_document_root(request_rec *r)
580{
581 return ap_document_root(r);
582}
583
584static const char *req_context_prefix(request_rec *r)
585{
586 return ap_context_prefix(r);
587}
588
590{
592}
593
595{
596 return r->uri;
597}
598
599static const char *req_method_field(request_rec *r)
600{
601 return r->method;
602}
603static const char *req_handler_field(request_rec *r)
604{
605 return r->handler;
606}
607static const char *req_proxyreq_field(request_rec *r)
608{
609 switch (r->proxyreq) {
610 case PROXYREQ_NONE: return "PROXYREQ_NONE";
611 case PROXYREQ_PROXY: return "PROXYREQ_PROXY";
612 case PROXYREQ_REVERSE: return "PROXYREQ_REVERSE";
613 case PROXYREQ_RESPONSE: return "PROXYREQ_RESPONSE";
614 default: return NULL;
615 }
616}
617static const char *req_hostname_field(request_rec *r)
618{
619 return r->hostname;
620}
621
622static const char *req_args_field(request_rec *r)
623{
624 return r->args;
625}
626
628{
629 return r->path_info;
630}
631
633{
634 return r->canonical_filename;
635}
636
637static const char *req_filename_field(request_rec *r)
638{
639 return r->filename;
640}
641
642static const char *req_user_field(request_rec *r)
643{
644 return r->user;
645}
646
648{
649 return r->unparsed_uri;
650}
651
653{
654 return r->ap_auth_type;
655}
656
658{
659 return r->content_encoding;
660}
661
663{
664 return r->content_type;
665}
666
667static const char *req_range_field(request_rec *r)
668{
669 return r->range;
670}
671
672static const char *req_protocol_field(request_rec *r)
673{
674 return r->protocol;
675}
676
678{
679 return r->the_request;
680}
681
682static const char *req_log_id_field(request_rec *r)
683{
684 return r->log_id;
685}
686
688{
689 return r->useragent_ip;
690}
691
693{
694 return r->remaining;
695}
696
698{
699 return r->status;
700}
701
703{
704 return r->assbackwards;
705}
706
708{
710 t->r = r;
711 t->t = r->headers_in;
712 t->n = "headers_in";
713 return t;
714}
715
717{
719 t->r = r;
720 t->t = r->headers_out;
721 t->n = "headers_out";
722 return t;
723}
724
726{
728 t->r = r;
729 t->t = r->err_headers_out;
730 t->n = "err_headers_out";
731 return t;
732}
733
735{
737 t->r = r;
738 t->t = r->subprocess_env;
739 t->n = "subprocess_env";
740 return t;
741}
742
744{
746 t->r = r;
747 t->t = r->notes;
748 t->n = "notes";
749 return t;
750}
751
756
758{
759 return (int) ap_get_server_port(r);
760}
761
762static int lua_ap_rflush (lua_State *L) {
763
764 int returnValue;
765 request_rec *r;
769 lua_pushboolean(L, (returnValue == 0));
770 return 1;
771}
772
773
774static const char* lua_ap_options(request_rec* r)
775{
776 int opts;
778 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" : "" );
779}
780
782{
783 int opts;
785 if ( (opts & OR_ALL) == OR_ALL) {
786 return "All";
787 }
788 else if (opts == OR_NONE) {
789 return "None";
790 }
791 return apr_psprintf(r->pool, "%s %s %s %s %s", (opts & OR_LIMIT) ? "Limit" : "", (opts & OR_OPTIONS) ? "Options" : "", (opts & OR_FILEINFO) ? "FileInfo" : "", (opts & OR_AUTHCFG) ? "AuthCfg" : "", (opts & OR_INDEXES) ? "Indexes" : "" );
792
793}
794
796{
797 return (int)(ap_scoreboard_image->global->restart_time / 1000000);
798}
799
800static const char* lua_ap_basic_auth_pw(request_rec* r)
801{
802 const char* pw = NULL;
804 return pw ? pw : "";
805}
806
808{
809 return (int) ap_get_limit_req_body(r);
810}
811
813{
814 return ap_is_initial_req(r);
815}
816
821
823{
824
826 const char *filename;
827 request_rec *r;
828
832 filename = lua_tostring(L, 2);
834 if (file_info.filetype == APR_NOFILE || file_info.filetype == APR_DIR) {
835 lua_pushboolean(L, 0);
836 }
837 else {
841
843 r->pool);
844 if (rc == APR_SUCCESS) {
848 }
849 else {
850 lua_pushboolean(L, 0);
851 }
852 }
853
854 return (1);
855}
856
857
858/*
859 * lua_apr_b64encode; r:encode_base64(string) - encodes a string to Base64
860 * format
861 */
863{
864 const char *plain;
865 char *encoded;
866 size_t plain_len, encoded_len;
867 request_rec *r;
868
871 plain = lua_tolstring(L, 2, &plain_len);
873 if (encoded_len) {
874 encoded = apr_palloc(r->pool, encoded_len);
876 if (encoded_len > 0 && encoded[encoded_len - 1] == '\0')
877 encoded_len--;
878 lua_pushlstring(L, encoded, encoded_len);
879 return 1;
880 }
881 return 0;
882}
883
884/*
885 * lua_apr_b64decode; r:decode_base64(string) - decodes a Base64 string
886 */
888{
889 const char *encoded;
890 char *plain;
891 size_t encoded_len, decoded_len;
892 request_rec *r;
893
896 encoded = lua_tolstring(L, 2, &encoded_len);
898 if (decoded_len) {
901 if (decoded_len > 0 && plain[decoded_len - 1] == '\0')
902 decoded_len--;
904 return 1;
905 }
906 return 0;
907}
908
909/*
910 * lua_ap_unescape; r:unescape(string) - Unescapes an URL-encoded string
911 */
913{
914 const char *escaped;
915 char *plain;
916 size_t x,
917 y;
918 request_rec *r;
921 escaped = lua_tolstring(L, 2, &x);
924 if (!y) {
926 return 1;
927 }
928 return 0;
929}
930
931/*
932 * lua_ap_escape; r:escape(string) - URL-escapes a string
933 */
935{
936 const char *plain;
937 char *escaped;
938 size_t x;
939 request_rec *r;
942 plain = lua_tolstring(L, 2, &x);
945 return 1;
946}
947
948/*
949 * lua_apr_md5; r:md5(string) - Calculates an MD5 digest of a string
950 */
951static int lua_apr_md5(lua_State *L)
952{
953 const char *buffer;
954 char *result;
955 size_t len;
956 request_rec *r;
957
960 buffer = lua_tolstring(L, 2, &len);
961 result = ap_md5_binary(r->pool, (const unsigned char *)buffer, len);
963 return 1;
964}
965
966/*
967 * lua_apr_sha1; r:sha1(string) - Calculates the SHA1 digest of a string
968 */
970{
971 unsigned char digest[APR_SHA1_DIGESTSIZE];
973 const char *buffer;
974 char *result;
975 size_t len;
976 request_rec *r;
977
980 result = apr_pcalloc(r->pool, sizeof(digest) * 2 + 1);
981 buffer = lua_tolstring(L, 2, &len);
985
986 ap_bin2hex(digest, sizeof(digest), result);
988 return 1;
989}
990
991/*
992 * lua_apr_htpassword; r:htpassword(string [, algorithm [, cost]]) - Creates
993 * a htpassword hash from a string
994 */
996{
997 passwd_ctx ctx = { 0 };
998 request_rec *r;
999
1002 ctx.passwd = apr_pstrdup(r->pool, lua_tostring(L, 2));
1003 ctx.alg = luaL_optinteger(L, 3, ALG_APMD5);
1004 ctx.cost = luaL_optinteger(L, 4, 0);
1005 ctx.pool = r->pool;
1007 ctx.out_len = MAX_PASSWD_LEN;
1008 if (mk_password_hash(&ctx)) {
1009 lua_pushboolean(L, 0);
1010 lua_pushstring(L, ctx.errstr);
1011 return 2;
1012 } else {
1013 lua_pushstring(L, ctx.out);
1014 }
1015 return 1;
1016}
1017
1018/*
1019 * lua_apr_touch; r:touch(string [, time]) - Sets mtime of a file
1020 */
1022{
1023 request_rec *r;
1024 const char *path;
1027
1030 path = lua_tostring(L, 2);
1033 lua_pushboolean(L, (status == 0));
1034 return 1;
1035}
1036
1037/*
1038 * lua_apr_mkdir; r:mkdir(string [, permissions]) - Creates a directory
1039 */
1041{
1042 request_rec *r;
1043 const char *path;
1046
1049 path = lua_tostring(L, 2);
1052 lua_pushboolean(L, (status == 0));
1053 return 1;
1054}
1055
1056/*
1057 * lua_apr_mkrdir; r:mkrdir(string [, permissions]) - Creates directories
1058 * recursive
1059 */
1061{
1062 request_rec *r;
1063 const char *path;
1066
1069 path = lua_tostring(L, 2);
1072 lua_pushboolean(L, (status == 0));
1073 return 1;
1074}
1075
1076/*
1077 * lua_apr_rmdir; r:rmdir(string) - Removes a directory
1078 */
1080{
1081 request_rec *r;
1082 const char *path;
1084
1087 path = lua_tostring(L, 2);
1089 lua_pushboolean(L, (status == 0));
1090 return 1;
1091}
1092
1093/*
1094 * lua_apr_date_parse_rfc; r.date_parse_rfc(string) - Parses a DateTime string
1095 */
1097{
1098 const char *input;
1100
1102 input = lua_tostring(L, 1);
1104 if (result == 0)
1105 return 0;
1107 return 1;
1108}
1109
1110/*
1111 * lua_ap_mpm_query; r:mpm_query(info) - Queries for MPM info
1112 */
1114{
1115 int x,
1116 y;
1117
1118 x = lua_tointeger(L, 1);
1119 ap_mpm_query(x, &y);
1120 lua_pushinteger(L, y);
1121 return 1;
1122}
1123
1124/*
1125 * lua_ap_expr; r:expr(string) - Evaluates an expr statement.
1126 */
1128{
1129 request_rec *r;
1130 int x = 0;
1131 const char *expr,
1132 *err;
1134
1138 expr = lua_tostring(L, 2);
1139
1140
1141 res.filename = NULL;
1142 res.flags = 0;
1143 res.line_number = 0;
1144 res.module_index = APLOG_MODULE_INDEX;
1145
1146 err = ap_expr_parse(r->pool, r->pool, &res, expr, NULL);
1147 if (!err) {
1148 x = ap_expr_exec(r, &res, &err);
1149 lua_pushboolean(L, x);
1150 if (x < 0) {
1151 lua_pushstring(L, err);
1152 return 2;
1153 }
1154 return 1;
1155 } else {
1156 lua_pushboolean(L, 0);
1157 lua_pushstring(L, err);
1158 return 2;
1159 }
1160 lua_pushboolean(L, 0);
1161 return 1;
1162}
1163
1164
1165/*
1166 * lua_ap_regex; r:regex(string, pattern [, flags])
1167 * - Evaluates a regex and returns captures if matched
1168 */
1170{
1171 request_rec *r;
1172 int i,
1173 rv,
1174 flags;
1175 const char *pattern,
1176 *source;
1177 char *err;
1180
1185 source = lua_tostring(L, 2);
1186 pattern = lua_tostring(L, 3);
1187 flags = luaL_optinteger(L, 4, 0);
1188
1189 rv = ap_regcomp(&regex, pattern, flags);
1190 if (rv) {
1191 lua_pushboolean(L, 0);
1192 err = apr_palloc(r->pool, 256);
1193 ap_regerror(rv, &regex, err, 256);
1194 lua_pushstring(L, err);
1195 return 2;
1196 }
1197
1198 if (regex.re_nsub > MODLUA_MAX_REG_MATCH) {
1199 lua_pushboolean(L, 0);
1200 err = apr_palloc(r->pool, 64);
1201 apr_snprintf(err, 64,
1202 "regcomp found %d matches; only %d allowed.",
1203 regex.re_nsub, MODLUA_MAX_REG_MATCH);
1204 lua_pushstring(L, err);
1205 return 2;
1206 }
1207
1209 if (rv == AP_REG_NOMATCH) {
1210 lua_pushboolean(L, 0);
1211 return 1;
1212 }
1213
1214 lua_newtable(L);
1215 for (i = 0; i <= regex.re_nsub; i++) {
1216 lua_pushinteger(L, i);
1217 if (matches[i].rm_so >= 0 && matches[i].rm_eo >= 0)
1219 apr_pstrndup(r->pool, source + matches[i].rm_so,
1220 matches[i].rm_eo - matches[i].rm_so));
1221 else
1222 lua_pushnil(L);
1223 lua_settable(L, -3);
1224
1225 }
1226 return 1;
1227}
1228
1229
1230
1231
1232/*
1233 * lua_ap_scoreboard_process; r:scoreboard_process(a) - returns scoreboard info
1234 */
1236{
1237 int i;
1239
1242 i = lua_tointeger(L, 2);
1244 if (ps_record) {
1245 lua_newtable(L);
1246
1247 lua_pushstring(L, "connections");
1248 lua_pushnumber(L, ps_record->connections);
1249 lua_settable(L, -3);
1250
1251 lua_pushstring(L, "keepalive");
1252 lua_pushnumber(L, ps_record->keep_alive);
1253 lua_settable(L, -3);
1254
1255 lua_pushstring(L, "lingering_close");
1256 lua_pushnumber(L, ps_record->lingering_close);
1257 lua_settable(L, -3);
1258
1259 lua_pushstring(L, "pid");
1260 lua_pushnumber(L, ps_record->pid);
1261 lua_settable(L, -3);
1262
1263 lua_pushstring(L, "suspended");
1264 lua_pushnumber(L, ps_record->suspended);
1265 lua_settable(L, -3);
1266
1267 lua_pushstring(L, "write_completion");
1268 lua_pushnumber(L, ps_record->write_completion);
1269 lua_settable(L, -3);
1270
1271 lua_pushstring(L, "not_accepting");
1272 lua_pushnumber(L, ps_record->not_accepting);
1273 lua_settable(L, -3);
1274
1275 lua_pushstring(L, "quiescing");
1276 lua_pushnumber(L, ps_record->quiescing);
1277 lua_settable(L, -3);
1278
1279 return 1;
1280 }
1281 return 0;
1282}
1283
1284/*
1285 * lua_ap_scoreboard_worker; r:scoreboard_worker(proc, thread) - Returns thread
1286 * info
1287 */
1289{
1290 int i, j;
1292 request_rec *r = NULL;
1293
1297
1299 if (!r) return 0;
1300
1301 i = lua_tointeger(L, 2);
1302 j = lua_tointeger(L, 3);
1303 ws_record = apr_palloc(r->pool, sizeof *ws_record);
1304
1306 if (ws_record) {
1307 lua_newtable(L);
1308
1309 lua_pushstring(L, "access_count");
1310 lua_pushnumber(L, ws_record->access_count);
1311 lua_settable(L, -3);
1312
1313 lua_pushstring(L, "bytes_served");
1314 lua_pushnumber(L, (lua_Number) ws_record->bytes_served);
1315 lua_settable(L, -3);
1316
1317 lua_pushstring(L, "client");
1318 lua_pushstring(L, ws_record->client);
1319 lua_settable(L, -3);
1320
1321 lua_pushstring(L, "client64");
1322 lua_pushstring(L, ws_record->client64);
1323 lua_settable(L, -3);
1324
1325 lua_pushstring(L, "conn_bytes");
1326 lua_pushnumber(L, (lua_Number) ws_record->conn_bytes);
1327 lua_settable(L, -3);
1328
1329 lua_pushstring(L, "conn_count");
1330 lua_pushnumber(L, ws_record->conn_count);
1331 lua_settable(L, -3);
1332
1333 lua_pushstring(L, "generation");
1334 lua_pushnumber(L, ws_record->generation);
1335 lua_settable(L, -3);
1336
1337 lua_pushstring(L, "last_used");
1338 lua_pushnumber(L, (lua_Number) ws_record->last_used);
1339 lua_settable(L, -3);
1340
1341 lua_pushstring(L, "pid");
1342 lua_pushnumber(L, ws_record->pid);
1343 lua_settable(L, -3);
1344
1345 lua_pushstring(L, "request");
1346 lua_pushstring(L, ws_record->request);
1347 lua_settable(L, -3);
1348
1349 lua_pushstring(L, "start_time");
1350 lua_pushnumber(L, (lua_Number) ws_record->start_time);
1351 lua_settable(L, -3);
1352
1353 lua_pushstring(L, "status");
1354 lua_pushnumber(L, ws_record->status);
1355 lua_settable(L, -3);
1356
1357 lua_pushstring(L, "stop_time");
1358 lua_pushnumber(L, (lua_Number) ws_record->stop_time);
1359 lua_settable(L, -3);
1360
1361 lua_pushstring(L, "tid");
1362
1364 lua_settable(L, -3);
1365
1366 lua_pushstring(L, "vhost");
1367 lua_pushstring(L, ws_record->vhost);
1368 lua_settable(L, -3);
1369#ifdef HAVE_TIMES
1370 lua_pushstring(L, "stimes");
1371 lua_pushnumber(L, ws_record->times.tms_stime);
1372 lua_settable(L, -3);
1373
1374 lua_pushstring(L, "utimes");
1375 lua_pushnumber(L, ws_record->times.tms_utime);
1376 lua_settable(L, -3);
1377#endif
1378 return 1;
1379 }
1380 return 0;
1381}
1382
1383/*
1384 * lua_ap_clock; r:clock() - Returns timestamp with microsecond precision
1385 */
1387{
1389 now = apr_time_now();
1391 return 1;
1392}
1393
1394/*
1395 * lua_ap_add_input_filter; r:add_input_filter(name) - Adds an input filter to
1396 * the chain
1397 */
1399{
1400 request_rec *r;
1401 const char *filterName;
1402 ap_filter_rec_t *filter;
1403
1407 filterName = lua_tostring(L, 2);
1409 if (filter) {
1411 lua_pushboolean(L, 1);
1412 } else
1413 lua_pushboolean(L, 0);
1414 return 1;
1415}
1416
1417
1418/*
1419 * lua_ap_module_info; r:module_info(mod_name) - Returns information about a
1420 * loaded module
1421 */
1423{
1424 const char *moduleName;
1425 module *mod;
1426
1428 moduleName = lua_tostring(L, 1);
1429 mod = ap_find_linked_module(moduleName);
1430 if (mod && mod->cmds) {
1431 const command_rec *cmd;
1432 lua_newtable(L);
1433 lua_pushstring(L, "commands");
1434 lua_newtable(L);
1435 for (cmd = mod->cmds; cmd->name; ++cmd) {
1436 lua_pushstring(L, cmd->name);
1437 lua_pushstring(L, cmd->errmsg);
1438 lua_settable(L, -3);
1439 }
1440 lua_settable(L, -3);
1441 return 1;
1442 }
1443 return 0;
1444}
1445
1446/*
1447 * lua_ap_runtime_dir_relative: r:runtime_dir_relative(file): Returns the
1448 * filename as relative to the runtime dir
1449 */
1451{
1452 request_rec *r;
1453 const char *file;
1454
1457 file = luaL_optstring(L, 2, ".");
1459 return 1;
1460}
1461
1462/*
1463 * lua_ap_set_document_root; r:set_document_root(path) - sets the current doc
1464 * root for the request
1465 */
1467{
1468 request_rec *r;
1469 const char *root;
1470
1474 root = lua_tostring(L, 2);
1475 ap_set_document_root(r, root);
1476 return 0;
1477}
1478
1479/*
1480 * lua_ap_getdir; r:get_direntries(directory) - Gets all entries of a
1481 * directory and returns the directory info as a table
1482 */
1484{
1485 request_rec *r;
1489 const char *directory;
1490
1494 directory = lua_tostring(L, 2);
1496 int i = 0;
1497 lua_newtable(L);
1498 do {
1501 continue; /* ignore un-stat()able files */
1502 }
1503 else if (status != APR_SUCCESS) {
1504 break;
1505 }
1506 lua_pushinteger(L, ++i);
1507 lua_pushstring(L, file_info.name);
1508 lua_settable(L, -3);
1509
1510 } while (1);
1512 return 1;
1513 }
1514 else {
1515 return 0;
1516 }
1517}
1518
1519/*
1520 * lua_ap_stat; r:stat(filename [, wanted]) - Runs stat on a file and
1521 * returns the file info as a table
1522 */
1524{
1525 request_rec *r;
1526 const char *filename;
1529
1533 filename = lua_tostring(L, 2);
1535 if (apr_stat(&file_info, filename, wanted, r->pool) == OK) {
1536 lua_newtable(L);
1537 if (wanted & APR_FINFO_MTIME) {
1538 lua_pushstring(L, "mtime");
1540 lua_settable(L, -3);
1541 }
1542 if (wanted & APR_FINFO_ATIME) {
1543 lua_pushstring(L, "atime");
1545 lua_settable(L, -3);
1546 }
1547 if (wanted & APR_FINFO_CTIME) {
1548 lua_pushstring(L, "ctime");
1550 lua_settable(L, -3);
1551 }
1552 if (wanted & APR_FINFO_SIZE) {
1553 lua_pushstring(L, "size");
1555 lua_settable(L, -3);
1556 }
1557 if (wanted & APR_FINFO_TYPE) {
1558 lua_pushstring(L, "filetype");
1559 lua_pushinteger(L, file_info.filetype);
1560 lua_settable(L, -3);
1561 }
1562 if (wanted & APR_FINFO_PROT) {
1563 lua_pushstring(L, "protection");
1564 lua_pushinteger(L, file_info.protection);
1565 lua_settable(L, -3);
1566 }
1567 return 1;
1568 }
1569 else {
1570 return 0;
1571 }
1572}
1573
1574/*
1575 * lua_ap_loaded_modules; r:loaded_modules() - Returns a list of loaded modules
1576 */
1578{
1579 int i;
1580 lua_newtable(L);
1581 for (i = 0; ap_loaded_modules[i] && ap_loaded_modules[i]->name; i++) {
1582 lua_pushinteger(L, i + 1);
1584 lua_settable(L, -3);
1585 }
1586 return 1;
1587}
1588
1589/*
1590 * lua_ap_server_info; r:server_info() - Returns server info, such as the
1591 * executable filename, server root, mpm etc
1592 */
1594{
1595 lua_newtable(L);
1596
1597 lua_pushstring(L, "server_executable");
1599 lua_settable(L, -3);
1600
1601 lua_pushstring(L, "server_root");
1603 lua_settable(L, -3);
1604
1605 lua_pushstring(L, "scoreboard_fname");
1607 lua_settable(L, -3);
1608
1609 lua_pushstring(L, "server_mpm");
1611 lua_settable(L, -3);
1612
1613 return 1;
1614}
1615
1616
1617/*
1618 * === Auto-scraped functions ===
1619 */
1620
1621
1632{
1633 request_rec *r;
1634 const char *prefix;
1635 const char *document_root;
1639 prefix = lua_tostring(L, 2);
1641 document_root = lua_tostring(L, 3);
1642 ap_set_context_info(r, prefix, document_root);
1643 return 0;
1644}
1645
1646
1657{
1658 char *returnValue;
1659 request_rec *r;
1660 const char *path;
1661 int partial = 0;
1665 path = lua_tostring(L, 2);
1666 if (lua_isboolean(L, 3))
1667 partial = lua_toboolean(L, 3);
1670 return 1;
1671}
1672
1673
1682{
1683 char *returnValue;
1684 request_rec *r;
1685 const char *str;
1689 str = lua_tostring(L, 2);
1692 return 1;
1693}
1694
1704{
1705 int returnValue;
1706 const char *str;
1707 const char *expected;
1708 int ignoreCase = 0;
1710 str = lua_tostring(L, 1);
1712 expected = lua_tostring(L, 2);
1713 if (lua_isboolean(L, 3))
1714 ignoreCase = lua_toboolean(L, 3);
1715 if (!ignoreCase)
1716 returnValue = ap_strcmp_match(str, expected);
1717 else
1718 returnValue = ap_strcasecmp_match(str, expected);
1720 return 1;
1721}
1722
1723
1731{
1732 int returnValue;
1733 request_rec *r;
1738 return 1;
1739}
1740
1751{
1752 char *returnValue;
1753 request_rec *r;
1754 int force_weak;
1758 force_weak = (int)luaL_optinteger(L, 2, 0);
1759 returnValue = ap_make_etag(r, force_weak);
1761 return 1;
1762}
1763
1764
1765
1773{
1774 request_rec *r;
1775 int send_headers = 0;
1778 if (lua_isboolean(L, 2))
1781 return 0;
1782}
1783
1784
1794{
1795 request_rec *r;
1796 int status;
1797 const char *string;
1801 status = lua_tointeger(L, 2);
1803 string = lua_tostring(L, 3);
1804 ap_custom_response(r, status, string);
1805 return 0;
1806}
1807
1808
1816{
1817 int returnValue;
1818 const char *name;
1820 name = lua_tostring(L, 1);
1823 return 1;
1824}
1825
1827{
1828 const char *servername;
1829 request_rec *r;
1834 return 1;
1835}
1836
1837/* ap_state_query (int query_code) item starts a new field */
1839{
1840
1841 int returnValue;
1842 int query_code;
1844 query_code = lua_tointeger(L, 1);
1847 return 1;
1848}
1849
1850/*
1851 * lua_ap_usleep; r:usleep(microseconds)
1852 * - Sleep for the specified number of microseconds.
1853 */
1855{
1859 apr_sleep(msec);
1860 return 0;
1861}
1862
1863/* END dispatch methods for request_rec fields */
1864
1866{
1868 req_fun_t *rft;
1870 const char *name = luaL_checkstring(L, 2);
1871 lua_pop(L, 2);
1872
1873 lua_getfield(L, LUA_REGISTRYINDEX, "Apache2.Request.dispatch");
1874 dispatch = lua_touserdata(L, 1);
1875 lua_pop(L, 1);
1876
1878 if (rft) {
1879 switch (rft->type) {
1881 req_table_t *rs;
1884 "request_rec->dispatching %s -> apr table",
1885 name);
1886 rs = (*func)(r);
1888 return 1;
1889 }
1890
1894 "request_rec->dispatching %s -> lua_CFunction",
1895 name);
1897 return 1;
1898 }
1901 char *rs;
1903 "request_rec->dispatching %s -> string", name);
1904 rs = (*func) (r);
1905 lua_pushstring(L, rs);
1906 return 1;
1907 }
1908 case APL_REQ_FUNTYPE_INT:{
1910 int rs;
1912 "request_rec->dispatching %s -> int", name);
1913 rs = (*func) (r);
1914 lua_pushinteger(L, rs);
1915 return 1;
1916 }
1919 int rs;
1921 "request_rec->dispatching %s -> boolean", name);
1922 rs = (*func) (r);
1923 lua_pushboolean(L, rs);
1924 return 1;
1925 }
1926 }
1927 }
1928
1929 ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01491) "nothing for %s", name);
1930 return 0;
1931}
1932
1933/* helper function for the logging functions below */
1934static int req_log_at(lua_State *L, int level)
1935{
1936 const char *msg;
1938 lua_Debug dbg;
1939
1940 lua_getstack(L, 1, &dbg);
1941 lua_getinfo(L, "Sl", &dbg);
1942
1943 msg = luaL_checkstring(L, 2);
1944 /* Intentional no APLOGNO */
1945 ap_log_rerror(dbg.source, dbg.currentline, APLOG_MODULE_INDEX, level, 0,
1946 r, "%s", msg);
1947 return 0;
1948}
1949
1950/* r:debug(String) and friends which use apache logging */
1951static int req_emerg(lua_State *L)
1952{
1953 return req_log_at(L, APLOG_EMERG);
1954}
1955static int req_alert(lua_State *L)
1956{
1957 return req_log_at(L, APLOG_ALERT);
1958}
1959static int req_crit(lua_State *L)
1960{
1961 return req_log_at(L, APLOG_CRIT);
1962}
1963static int req_err(lua_State *L)
1964{
1965 return req_log_at(L, APLOG_ERR);
1966}
1967static int req_warn(lua_State *L)
1968{
1969 return req_log_at(L, APLOG_WARNING);
1970}
1971static int req_notice(lua_State *L)
1972{
1973 return req_log_at(L, APLOG_NOTICE);
1974}
1975static int req_info(lua_State *L)
1976{
1977 return req_log_at(L, APLOG_INFO);
1978}
1979static int req_debug(lua_State *L)
1980{
1981 return req_log_at(L, APLOG_DEBUG);
1982}
1983
1984static int lua_ivm_get(lua_State *L)
1985{
1986 const char *key, *raw_key;
1988 lua_ivm_object *object = NULL;
1990 key = luaL_checkstring(L, 2);
1991 raw_key = apr_pstrcat(r->pool, "lua_ivm_", key, NULL);
1994 apr_pool_userdata_get((void **)&object, raw_key, pool);
1995 if (object) {
1996 if (object->type == LUA_TBOOLEAN) lua_pushboolean(L, (int) object->number);
1997 else if (object->type == LUA_TNUMBER) lua_pushnumber(L, object->number);
1998 else if (object->type == LUA_TSTRING) lua_pushlstring(L, object->vb.buf, object->size);
2000 return 1;
2001 }
2002 else {
2004 return 0;
2005 }
2006}
2007
2008
2009static int lua_ivm_set(lua_State *L)
2010{
2011 const char *key, *raw_key;
2012 const char *value = NULL;
2014 size_t str_len;
2015 lua_ivm_object *object = NULL;
2017 key = luaL_checkstring(L, 2);
2018 luaL_checkany(L, 3);
2019 raw_key = apr_pstrcat(r->pool, "lua_ivm_", key, NULL);
2020
2023 apr_pool_userdata_get((void **)&object, raw_key, pool);
2024 if (!object) {
2025 object = apr_pcalloc(pool, sizeof(lua_ivm_object));
2026 ap_varbuf_init(pool, &object->vb, 2);
2027 object->size = 1;
2028 object->vb_size = 1;
2029 }
2030 object->type = lua_type(L, 3);
2031 if (object->type == LUA_TNUMBER) object->number = lua_tonumber(L, 3);
2032 else if (object->type == LUA_TBOOLEAN) object->number = lua_tonumber(L, 3);
2033 else if (object->type == LUA_TSTRING) {
2034 value = lua_tolstring(L, 3, &str_len);
2035 str_len++; /* add trailing \0 */
2036 if ( str_len > object->vb_size) {
2038 object->vb_size = str_len;
2039 }
2040 object->size = str_len-1;
2041 memset(object->vb.buf, 0, str_len);
2042 memcpy(object->vb.buf, value, str_len-1);
2043 }
2046 return 0;
2047}
2048
2050{
2051 const char *key, *cookie;
2053 key = luaL_checkstring(L, 2);
2054 cookie = NULL;
2055 ap_cookie_read(r, key, &cookie, 0);
2056 if (cookie != NULL) {
2057 lua_pushstring(L, cookie);
2058 return 1;
2059 }
2060 return 0;
2061}
2062
2064{
2065 const char *key, *value, *out, *path = "", *domain = "";
2066 const char *strexpires = "", *strdomain = "", *strpath = "";
2067 int secure = 0, expires = 0, httponly = 0;
2068 char cdate[APR_RFC822_DATE_LEN+1];
2069 apr_status_t rv;
2071
2072 /* New >= 2.4.8 method: */
2073 if (lua_istable(L, 2)) {
2074
2075 /* key */
2076 lua_pushstring(L, "key");
2077 lua_gettable(L, -2);
2078 key = luaL_checkstring(L, -1);
2079 lua_pop(L, 1);
2080
2081 /* value */
2082 lua_pushstring(L, "value");
2083 lua_gettable(L, -2);
2084 value = luaL_checkstring(L, -1);
2085 lua_pop(L, 1);
2086
2087 /* expiry */
2088 lua_pushstring(L, "expires");
2089 lua_gettable(L, -2);
2090 expires = (int)luaL_optinteger(L, -1, 0);
2091 lua_pop(L, 1);
2092
2093 /* secure */
2094 lua_pushstring(L, "secure");
2095 lua_gettable(L, -2);
2096 if (lua_isboolean(L, -1)) {
2097 secure = lua_toboolean(L, -1);
2098 }
2099 lua_pop(L, 1);
2100
2101 /* httponly */
2102 lua_pushstring(L, "httponly");
2103 lua_gettable(L, -2);
2104 if (lua_isboolean(L, -1)) {
2105 httponly = lua_toboolean(L, -1);
2106 }
2107 lua_pop(L, 1);
2108
2109 /* path */
2110 lua_pushstring(L, "path");
2111 lua_gettable(L, -2);
2112 path = luaL_optstring(L, -1, "/");
2113 lua_pop(L, 1);
2114
2115 /* domain */
2116 lua_pushstring(L, "domain");
2117 lua_gettable(L, -2);
2118 domain = luaL_optstring(L, -1, "");
2119 lua_pop(L, 1);
2120 }
2121 /* Old <= 2.4.7 method: */
2122 else {
2123 key = luaL_checkstring(L, 2);
2124 value = luaL_checkstring(L, 3);
2125 secure = 0;
2126 if (lua_isboolean(L, 4)) {
2127 secure = lua_toboolean(L, 4);
2128 }
2129 expires = luaL_optinteger(L, 5, 0);
2130 }
2131
2132 /* Calculate expiry if set */
2133 if (expires > 0) {
2134 rv = apr_rfc822_date(cdate, apr_time_from_sec(expires));
2135 if (rv == APR_SUCCESS) {
2136 strexpires = apr_psprintf(r->pool, "Expires=%s;", cdate);
2137 }
2138 }
2139
2140 /* Create path segment */
2141 if (path != NULL && strlen(path) > 0) {
2142 strpath = apr_psprintf(r->pool, "Path=%s;", path);
2143 }
2144
2145 /* Create domain segment */
2146 if (domain != NULL && strlen(domain) > 0) {
2147 /* Domain does NOT like quotes in most browsers, so let's avoid that */
2148 strdomain = apr_psprintf(r->pool, "Domain=%s;", domain);
2149 }
2150
2151 /* URL-encode key/value */
2154
2155 /* Create the header */
2156 out = apr_psprintf(r->pool, "%s=%s; %s %s %s %s %s", key, value,
2157 secure ? "Secure;" : "",
2158 expires ? strexpires : "",
2159 httponly ? "HttpOnly;" : "",
2160 *strdomain ? strdomain : "",
2161 *strpath ? strpath : "");
2162
2163 apr_table_add(r->err_headers_out, "Set-Cookie", out);
2164 return 0;
2165}
2166
2168{
2170 unsigned char *data = (unsigned char *)&rval;
2171 if (APR_IS_BIGENDIAN) {
2172 return *input;
2173 }
2174
2175 data[0] = *input >> 56;
2176 data[1] = *input >> 48;
2177 data[2] = *input >> 40;
2178 data[3] = *input >> 32;
2179 data[4] = *input >> 24;
2180 data[5] = *input >> 16;
2181 data[6] = *input >> 8;
2182 data[7] = *input >> 0;
2183
2184 return rval;
2185}
2186
2188{
2189 const char *key = NULL;
2190 unsigned char digest[APR_SHA1_DIGESTSIZE];
2192 char *encoded;
2193 int encoded_len;
2195 key = apr_table_get(r->headers_in, "Sec-WebSocket-Key");
2196 if (key != NULL) {
2198 "Websocket: Got websocket key: %s", key);
2199 key = apr_pstrcat(r->pool, key, "258EAFA5-E914-47DA-95CA-C5AB0DC85B11",
2200 NULL);
2202 apr_sha1_update(&sha1, key, strlen(key));
2205 if (encoded_len) {
2206 encoded = apr_palloc(r->pool, encoded_len);
2208 r->status = 101;
2209 apr_table_setn(r->headers_out, "Upgrade", "websocket");
2210 apr_table_setn(r->headers_out, "Connection", "Upgrade");
2211 apr_table_setn(r->headers_out, "Sec-WebSocket-Accept", encoded);
2212
2213 /* Trick httpd into NOT using the chunked filter, IMPORTANT!!!111*/
2214 apr_table_setn(r->headers_out, "Transfer-Encoding", "chunked");
2215
2216 r->clength = 0;
2217 r->bytes_sent = 0;
2218 r->read_chunked = 0;
2219 ap_rflush(r);
2221 "Websocket: Upgraded from HTTP to Websocket");
2222 lua_pushboolean(L, 1);
2223 return 1;
2224 }
2225 }
2227 "Websocket: Upgrade from HTTP to Websocket failed");
2228 return 0;
2229}
2230
2233 char* buffer, apr_off_t len)
2234{
2236 apr_status_t rv;
2237
2238 rv = ap_get_brigade(c->input_filters, brigade, AP_MODE_READBYTES,
2240 if (rv == APR_SUCCESS) {
2241 delivered = len;
2243 if ((rv == APR_SUCCESS) && (delivered < len)) {
2244 rv = APR_INCOMPLETE;
2245 }
2246 }
2248 return rv;
2249}
2250
2252{
2253 apr_status_t rv;
2255
2257
2262 if (rv == APR_SUCCESS) {
2263 lua_pushboolean(L, 1);
2264 }
2265 else {
2266 lua_pushboolean(L, 0);
2267 }
2269 return 1;
2270}
2271
2273{
2274 apr_status_t rv;
2275 int do_read = 1;
2276 int n = 0;
2277 apr_size_t plen = 0;
2278 unsigned short payload_short = 0;
2280 unsigned char *mask_bytes;
2281 char byte;
2283 conn_rec* c;
2284
2286 c = r->connection;
2287
2289
2290 brigade = apr_brigade_create(r->pool, c->bucket_alloc);
2291
2292 while (do_read) {
2293 do_read = 0;
2294 /* Get opcode and FIN bit */
2295 rv = lua_websocket_readbytes(c, brigade, &byte, 1);
2296 if (rv == APR_SUCCESS) {
2297 unsigned char ubyte, fin, opcode, mask, payload;
2298 ubyte = (unsigned char)byte;
2299 /* fin bit is the first bit */
2300 fin = ubyte >> (CHAR_BIT - 1);
2301 /* opcode is the last four bits (there's 3 reserved bits we don't care about) */
2302 opcode = ubyte & 0xf;
2303
2304 /* Get the payload length and mask bit */
2305 rv = lua_websocket_readbytes(c, brigade, &byte, 1);
2306 if (rv == APR_SUCCESS) {
2307 ubyte = (unsigned char)byte;
2308 /* Mask is the first bit */
2309 mask = ubyte >> (CHAR_BIT - 1);
2310 /* Payload is the last 7 bits */
2311 payload = ubyte & 0x7f;
2312 plen = payload;
2313
2314 /* Extended payload? */
2315 if (payload == 126) {
2317 (char*) &payload_short, 2);
2318
2319 if (rv != APR_SUCCESS) {
2320 return 0;
2321 }
2322
2324 }
2325 /* Super duper extended payload? */
2326 if (payload == 127) {
2328 (char*) &payload_long, 8);
2329
2330 if (rv != APR_SUCCESS) {
2331 return 0;
2332 }
2333
2335 }
2337 "Websocket: Reading %" APR_SIZE_T_FMT " (%s) bytes, masking is %s. %s",
2338 plen,
2339 (payload >= 126) ? "extra payload" : "no extra payload",
2340 mask ? "on" : "off",
2341 fin ? "This is a final frame" : "more to follow");
2342 if (mask) {
2344 (char*) mask_bytes, 4);
2345
2346 if (rv != APR_SUCCESS) {
2347 return 0;
2348 }
2349 }
2350 if (plen < (HUGE_STRING_LEN*1024) && plen > 0) {
2351 apr_size_t remaining = plen;
2352 char *buffer = apr_palloc(r->pool, plen+1);
2353 buffer[plen] = 0;
2354
2355 rv = lua_websocket_readbytes(c, brigade, buffer, remaining);
2356
2357 if (rv != APR_SUCCESS) {
2358 return 0;
2359 }
2360
2362 "Websocket: Frame contained %" APR_SIZE_T_FMT \
2363 " bytes, pushed to Lua stack", remaining);
2364 if (mask) {
2365 for (n = 0; n < plen; n++) {
2366 buffer[n] ^= mask_bytes[n%4];
2367 }
2368 }
2369
2370 lua_pushlstring(L, buffer, (size_t) plen); /* push to stack */
2371 lua_pushboolean(L, fin); /* push FIN bit to stack as boolean */
2372 return 2;
2373 }
2374
2375 /* Decide if we need to react to the opcode or not */
2376 if (opcode == 0x09) { /* ping */
2377 char frame[2];
2378 apr_bucket *b;
2379
2380 frame[0] = 0x8A;
2381 frame[1] = 0;
2382
2383 /* Pong! */
2384 b = apr_bucket_transient_create(frame, 2, c->bucket_alloc);
2386
2387 rv = ap_pass_brigade(c->output_filters, brigade);
2389
2390 if (rv != APR_SUCCESS) {
2391 return 0;
2392 }
2393
2394 do_read = 1;
2395 }
2396 }
2397 }
2398 }
2399 return 0;
2400}
2401
2402
2404{
2405 const char *string;
2406 apr_status_t rv;
2407 size_t len;
2408 int raw = 0;
2409 char prelude;
2411
2412 if (lua_isboolean(L, 3)) {
2413 raw = lua_toboolean(L, 3);
2414 }
2415 string = lua_tolstring(L, 2, &len);
2416
2417 if (raw != 1) {
2419 "Websocket: Writing framed message to client");
2420
2421 prelude = 0x81; /* text frame, FIN */
2422 ap_rputc(prelude, r);
2423 if (len < 126) {
2424 ap_rputc(len, r);
2425 }
2426 else if (len < 65535) {
2428 ap_rputc(126, r);
2429 slen = htons(slen);
2430 ap_rwrite((char*) &slen, 2, r);
2431 }
2432 else {
2434 ap_rputc(127, r);
2435 llen = ap_ntoh64(&llen); /* ntoh doubles as hton */
2436 ap_rwrite((char*) &llen, 8, r);
2437 }
2438 }
2439 else {
2441 "Websocket: Writing raw message to client");
2442 }
2443 ap_rwrite(string, len, r);
2444 rv = ap_rflush(r);
2445 if (rv == APR_SUCCESS) {
2446 lua_pushboolean(L, 1);
2447 }
2448 else {
2449 lua_pushboolean(L, 0);
2450 }
2451 return 1;
2452}
2453
2454
2456{
2458 char prelude[2];
2460
2462
2463 /* Send a header that says: socket is closing. */
2464 prelude[0] = 0x88; /* closing socket opcode */
2465 prelude[1] = 0; /* zero length frame */
2466 ap_rwrite(prelude, 2, r);
2467
2468 /* Close up tell the MPM and filters to back off */
2472 return 0;
2473}
2474
2476{
2479 char prelude[2];
2480 apr_status_t rv;
2483
2484 /* Send a header that says: PING. */
2485 prelude[0] = 0x89; /* ping opcode */
2486 prelude[1] = 0;
2487 plen = 2;
2489
2490
2491 /* Get opcode and FIN bit from pong */
2492 plen = 2;
2494 if (rv == APR_SUCCESS) {
2495 unsigned char opcode = prelude[0];
2496 unsigned char len = prelude[1];
2497 unsigned char mask = len >> 7;
2498 if (mask) len -= 128;
2499 plen = len;
2501 "Websocket: Got PONG opcode: %x", opcode);
2502 if (opcode == 0x8A) {
2503 lua_pushboolean(L, 1);
2504 }
2505 else {
2506 lua_pushboolean(L, 0);
2507 }
2508 if (plen > 0) {
2510 "Websocket: Reading %" APR_SIZE_T_FMT " bytes of PONG", plen);
2511 return 1;
2512 }
2513 if (mask) {
2514 plen = 2;
2516 plen = 2;
2518 }
2519 }
2520 else {
2521 lua_pushboolean(L, 0);
2522 }
2523 return 1;
2524}
2525
2526
2527#define APLUA_REQ_TRACE(lev) static int req_trace##lev(lua_State *L) \
2528{ \
2529 return req_log_at(L, APLOG_TRACE##lev); \
2530}
2531
2540
2541/* handle r.status = 201 */
2543{
2544 const char *key;
2545 /* request_rec* r = lua_touserdata(L, lua_upvalueindex(1)); */
2546 /* const char* key = luaL_checkstring(L, -2); */
2548 key = luaL_checkstring(L, 2);
2549
2550 if (0 == strcmp("args", key)) {
2551 const char *value = luaL_checkstring(L, 3);
2552 r->args = apr_pstrdup(r->pool, value);
2553 return 0;
2554 }
2555
2556 if (0 == strcmp("content_type", key)) {
2557 const char *value = luaL_checkstring(L, 3);
2559 return 0;
2560 }
2561
2562 if (0 == strcmp("filename", key)) {
2563 const char *value = luaL_checkstring(L, 3);
2565 return 0;
2566 }
2567
2568 if (0 == strcmp("handler", key)) {
2569 const char *value = luaL_checkstring(L, 3);
2571 return 0;
2572 }
2573
2574 if (0 == strcmp("proxyreq", key)) {
2575 int value = luaL_checkinteger(L, 3);
2576 r->proxyreq = value;
2577 return 0;
2578 }
2579
2580 if (0 == strcmp("status", key)) {
2581 int code = luaL_checkinteger(L, 3);
2582 r->status = code;
2583 return 0;
2584 }
2585
2586 if (0 == strcmp("uri", key)) {
2587 const char *value = luaL_checkstring(L, 3);
2588 r->uri = apr_pstrdup(r->pool, value);
2589 return 0;
2590 }
2591
2592 if (0 == strcmp("user", key)) {
2593 const char *value = luaL_checkstring(L, 3);
2594 r->user = apr_pstrdup(r->pool, value);
2595 return 0;
2596 }
2597
2600 "Property [%s] may not be set on a request_rec",
2601 key));
2602 lua_error(L);
2603 return 0;
2604}
2605
2606
2607
2608/* helper function for walking config trees */
2610 int x = 0;
2611 const char* value;
2612 ap_directive_t *cfg;
2613 lua_newtable(L);
2614
2615 for (cfg = rcfg; cfg; cfg = cfg->next) {
2616 x++;
2617 lua_pushnumber(L, x);
2618 lua_newtable(L);
2619 value = apr_psprintf(r->pool, "%s %s", cfg->directive, cfg->args);
2620 lua_pushstring(L, "directive");
2622 lua_settable(L, -3);
2623 lua_pushstring(L, "file");
2624 lua_pushstring(L, cfg->filename);
2625 lua_settable(L, -3);
2626 lua_pushstring(L, "line");
2627 lua_pushnumber(L, cfg->line_num);
2628 lua_settable(L, -3);
2629 if (cfg->first_child) {
2630 lua_pushstring(L, "children");
2631 read_cfg_tree(L, r, cfg->first_child);
2632 lua_settable(L, -3);
2633 }
2634 lua_settable(L, -3);
2635 }
2636}
2637
2641
2642 return 1;
2643}
2644
2645
2646/* Hack, hack, hack...! TODO: Make this actually work properly */
2651
2652 for (dir = ap_conftree; dir; dir = dir->next) {
2653 if (ap_strcasestr(dir->directive, "<virtualhost") && dir->first_child) {
2654 for (subdir = dir->first_child; subdir; subdir = subdir->next) {
2655 if (ap_strcasecmp_match(subdir->directive, "servername") &&
2657 read_cfg_tree(L, r, dir->first_child);
2658 return 1;
2659 }
2660 if (ap_strcasecmp_match(subdir->directive, "serveralias") &&
2662 read_cfg_tree(L, r, dir->first_child);
2663 return 1;
2664 }
2665 }
2666 }
2667 }
2668 return 0;
2669}
2670
2671
2672
2673static const struct luaL_Reg request_methods[] = {
2674 {"__index", req_dispatch},
2675 {"__newindex", req_newindex},
2676 /* {"__newindex", req_set_field}, */
2677 {NULL, NULL}
2678};
2679
2680
2681static const struct luaL_Reg connection_methods[] = {
2682 {NULL, NULL}
2683};
2684
2685static const char* lua_ap_auth_name(request_rec* r)
2686{
2687 const char *name;
2688 name = ap_auth_name(r);
2689 return name ? name : "";
2690}
2691
2693{
2694 const char *name;
2696 return name ? name : "localhost";
2697}
2698
2699
2700
2701
2702static const struct luaL_Reg server_methods[] = {
2703 {NULL, NULL}
2704};
2705
2706
2707static req_fun_t *makefun(const void *fun, int type, apr_pool_t *pool)
2708{
2709 req_fun_t *rft = apr_palloc(pool, sizeof(req_fun_t));
2710 rft->fun = fun;
2711 rft->type = type;
2712 return rft;
2713}
2714
2716{
2717
2719
2724 apr_hash_set(dispatch, "document_root", APR_HASH_KEY_STRING,
2726 apr_hash_set(dispatch, "context_prefix", APR_HASH_KEY_STRING,
2728 apr_hash_set(dispatch, "context_document_root", APR_HASH_KEY_STRING,
2766 apr_hash_set(dispatch, "add_output_filter", APR_HASH_KEY_STRING,
2768 apr_hash_set(dispatch, "construct_url", APR_HASH_KEY_STRING,
2772 apr_hash_set(dispatch, "ssl_var_lookup", APR_HASH_KEY_STRING,
2776 apr_hash_set(dispatch, "assbackwards", APR_HASH_KEY_STRING,
2784 apr_hash_set(dispatch, "content_type", APR_HASH_KEY_STRING,
2786 apr_hash_set(dispatch, "content_encoding", APR_HASH_KEY_STRING,
2788 p));
2789 apr_hash_set(dispatch, "ap_auth_type", APR_HASH_KEY_STRING,
2791 apr_hash_set(dispatch, "unparsed_uri", APR_HASH_KEY_STRING,
2797 apr_hash_set(dispatch, "canonical_filename", APR_HASH_KEY_STRING,
2814 apr_hash_set(dispatch, "useragent_ip", APR_HASH_KEY_STRING,
2822 apr_hash_set(dispatch, "headers_in_table", APR_HASH_KEY_STRING,
2826 apr_hash_set(dispatch, "headers_out_table", APR_HASH_KEY_STRING,
2828 apr_hash_set(dispatch, "err_headers_out", APR_HASH_KEY_STRING,
2830 apr_hash_set(dispatch, "err_headers_out_table", APR_HASH_KEY_STRING,
2836 apr_hash_set(dispatch, "subprocess_env", APR_HASH_KEY_STRING,
2838 apr_hash_set(dispatch, "subprocess_env_table", APR_HASH_KEY_STRING,
2848 apr_hash_set(dispatch, "allowoverrides", APR_HASH_KEY_STRING,
2852 apr_hash_set(dispatch, "basic_auth_pw", APR_HASH_KEY_STRING,
2854 apr_hash_set(dispatch, "limit_req_body", APR_HASH_KEY_STRING,
2856 apr_hash_set(dispatch, "server_built", APR_HASH_KEY_STRING,
2858 apr_hash_set(dispatch, "is_initial_req", APR_HASH_KEY_STRING,
2862 apr_hash_set(dispatch, "some_auth_required", APR_HASH_KEY_STRING,
2874 apr_hash_set(dispatch, "get_direntries", APR_HASH_KEY_STRING,
2880 apr_hash_set(dispatch, "base64_encode", APR_HASH_KEY_STRING,
2882 apr_hash_set(dispatch, "base64_decode", APR_HASH_KEY_STRING,
2898 apr_hash_set(dispatch, "date_parse_rfc", APR_HASH_KEY_STRING,
2908 apr_hash_set(dispatch, "scoreboard_process", APR_HASH_KEY_STRING,
2910 apr_hash_set(dispatch, "scoreboard_worker", APR_HASH_KEY_STRING,
2916 apr_hash_set(dispatch, "add_input_filter", APR_HASH_KEY_STRING,
2920 apr_hash_set(dispatch, "loaded_modules", APR_HASH_KEY_STRING,
2922 apr_hash_set(dispatch, "runtime_dir_relative", APR_HASH_KEY_STRING,
2926 apr_hash_set(dispatch, "set_document_root", APR_HASH_KEY_STRING,
2928 apr_hash_set(dispatch, "set_context_info", APR_HASH_KEY_STRING,
2930 apr_hash_set(dispatch, "os_escape_path", APR_HASH_KEY_STRING,
2932 apr_hash_set(dispatch, "escape_logitem", APR_HASH_KEY_STRING,
2934 apr_hash_set(dispatch, "strcmp_match", APR_HASH_KEY_STRING,
2936 apr_hash_set(dispatch, "set_keepalive", APR_HASH_KEY_STRING,
2940 apr_hash_set(dispatch, "send_interim_response", APR_HASH_KEY_STRING,
2942 apr_hash_set(dispatch, "custom_response", APR_HASH_KEY_STRING,
2944 apr_hash_set(dispatch, "exists_config_define", APR_HASH_KEY_STRING,
2948 apr_hash_set(dispatch, "get_server_name_for_url", APR_HASH_KEY_STRING,
2972 apr_hash_set(dispatch, "activeconfig", APR_HASH_KEY_STRING,
2975 lua_setfield(L, LUA_REGISTRYINDEX, "Apache2.Request.dispatch");
2976
2977 luaL_newmetatable(L, "Apache2.Request"); /* [metatable] */
2978 lua_pushvalue(L, -1);
2979
2980 lua_setfield(L, -2, "__index");
2981 luaL_setfuncs_compat(L, request_methods); /* [metatable] */
2982
2983 lua_pop(L, 2);
2984
2985 luaL_newmetatable(L, "Apache2.Connection"); /* [metatable] */
2986 lua_pushvalue(L, -1);
2987
2988 lua_setfield(L, -2, "__index");
2989 luaL_setfuncs_compat(L, connection_methods); /* [metatable] */
2990
2991 lua_pop(L, 2);
2992
2993 luaL_newmetatable(L, "Apache2.Server"); /* [metatable] */
2994 lua_pushvalue(L, -1);
2995
2996 lua_setfield(L, -2, "__index");
2997 luaL_setfuncs_compat(L, server_methods); /* [metatable] */
2998
2999 lua_pop(L, 2);
3000
3001}
3002
3004{
3005 req_table_t* t;
3006 lua_boxpointer(L, c);
3007 luaL_getmetatable(L, "Apache2.Connection");
3008 lua_setmetatable(L, -2);
3009 luaL_getmetatable(L, "Apache2.Connection");
3010
3011 t = apr_pcalloc(c->pool, sizeof(req_table_t));
3012 t->t = c->notes;
3013 t->r = NULL;
3014 t->n = "notes";
3016 lua_setfield(L, -2, "notes");
3017
3018 lua_pushstring(L, c->client_ip);
3019 lua_setfield(L, -2, "client_ip");
3020
3021 lua_pop(L, 1);
3022}
3023
3024
3026{
3027 lua_boxpointer(L, s);
3028 luaL_getmetatable(L, "Apache2.Server");
3029 lua_setmetatable(L, -2);
3030 luaL_getmetatable(L, "Apache2.Server");
3031
3032 lua_pushstring(L, s->server_hostname);
3033 lua_setfield(L, -2, "server_hostname");
3034
3035 lua_pop(L, 1);
3036}
3037
3039{
3040 lua_boxpointer(L, r);
3041 luaL_getmetatable(L, "Apache2.Request");
3042 lua_setmetatable(L, -2);
3043}
int n
Definition ap_regex.h:278
const char * pattern
Definition ap_regex.h:243
const char apr_size_t len
Definition ap_regex.h:187
@ AP_REG_NOMATCH
Definition ap_regex.h:104
const char * string
Definition ap_regex.h:171
char * strstr(char *s1, char *s2)
APR-UTIL date routines.
APR memory allocation.
#define APR_SHA1_DIGESTSIZE
Definition apr_sha1.h:39
APR Table library.
APR Thread Mutex Routines.
APR Standard Headers Support.
apr_status_t apr_dir_make_recursive(const char *path, apr_fileperms_t perm, apr_pool_t *pool)
ap_directive_t * ap_conftree
Definition config.c:69
#define APLOG_USE_MODULE(foo)
char * ap_runtime_dir_relative(apr_pool_t *p, const char *fname)
Definition config.c:1610
request_rec int int apr_table_t const char * path
request_rec * r
const char * ap_show_mpm(void)
Definition mpm_common.c:548
#define HUGE_STRING_LEN
Definition httpd.h:303
#define MAX_STRING_LEN
Definition httpd.h:300
const char * ap_get_server_built(void)
Definition buildmark.c:26
#define OK
Definition httpd.h:456
#define DONE
Definition httpd.h:458
const char * ap_get_server_banner(void)
Definition core.c:3593
ap_filter_rec_t * ap_get_input_filter_handle(const char *name)
apr_status_t ap_pass_brigade(ap_filter_t *filter, apr_bucket_brigade *bucket)
ap_filter_t * ap_add_input_filter_handle(ap_filter_rec_t *f, void *ctx, request_rec *r, conn_rec *c)
ap_filter_t * ap_add_output_filter(const char *name, void *ctx, request_rec *r, conn_rec *c)
apr_status_t ap_get_brigade(ap_filter_t *filter, apr_bucket_brigade *bucket, ap_input_mode_t mode, apr_read_type_e block, apr_off_t readbytes)
#define OPT_ALL
Definition http_core.h:88
#define OPT_SYM_LINKS
Definition http_core.h:76
#define OPT_EXECCGI
Definition http_core.h:78
#define OPT_INDEXES
Definition http_core.h:72
#define OPT_MULTI
Definition http_core.h:86
#define OPT_INCLUDES
Definition http_core.h:74
apr_port_t ap_get_server_port(const request_rec *r)
Definition core.c:1199
apr_off_t ap_get_limit_req_body(const request_rec *r)
Definition core.c:1259
int ap_exists_config_define(const char *name)
Definition core.c:2896
int ap_state_query(int query_code)
Definition core.c:5378
const char * ap_get_server_name(request_rec *r)
Definition core.c:1145
const char * ap_auth_name(request_rec *r)
Definition core.c:807
apr_socket_t * ap_get_conn_socket(conn_rec *c)
Definition core.c:5202
const char * ap_document_root(request_rec *r)
Definition core.c:829
void ap_custom_response(request_rec *r, int status, const char *string)
Definition core.c:1648
int ap_allow_overrides(request_rec *r)
Definition core.c:779
char * ap_construct_url(apr_pool_t *p, const char *uri, request_rec *r)
Definition core.c:1246
const char * ap_get_server_name_for_url(request_rec *r)
Definition core.c:1187
int ap_allow_options(request_rec *r)
Definition core.c:771
#define APLOGNO(n)
Definition http_log.h:117
#define APLOG_NOTICE
Definition http_log.h:69
#define APLOG_INFO
Definition http_log.h:70
#define ap_log_rerror
Definition http_log.h:454
#define APLOG_ERR
Definition http_log.h:67
#define APLOG_MARK
Definition http_log.h:283
#define APLOG_WARNING
Definition http_log.h:68
#define APLOG_ALERT
Definition http_log.h:65
#define APLOG_CRIT
Definition http_log.h:66
#define APLOG_EMERG
Definition http_log.h:64
#define APLOG_TRACE1
Definition http_log.h:72
#define APLOG_DEBUG
Definition http_log.h:71
#define APLOG_MODULE_INDEX
Definition http_log.h:168
const char * ap_server_argv0
Definition config.c:60
const char * ap_server_root
Definition config.c:61
const unsigned char * buf
Definition util_md5.h:50
int int ap_rflush(request_rec *r)
Definition protocol.c:2253
void ap_send_interim_response(request_rec *r, int send_headers)
Definition protocol.c:2316
int ap_get_basic_auth_pw(request_rec *r, const char **pw)
Definition protocol.c:1758
int ap_set_keepalive(request_rec *r)
int ap_should_client_block(request_rec *r)
static APR_INLINE int ap_rputs(const char *str, request_rec *r)
int ap_rputc(int c, request_rec *r)
Definition protocol.c:2117
void ap_set_content_type(request_rec *r, const char *ct)
int ap_rwrite(const void *buf, int nbyte, request_rec *r)
Definition protocol.c:2131
long ap_get_client_block(request_rec *r, char *buffer, apr_size_t bufsiz)
int ap_setup_client_block(request_rec *r, int read_policy)
apr_status_t ap_send_fd(apr_file_t *fd, request_rec *r, apr_off_t offset, apr_size_t length, apr_size_t *nbytes)
Definition protocol.c:1991
char * ap_make_etag(request_rec *r, int force_weak)
Definition http_etag.c:353
int ap_some_auth_required(request_rec *r)
Definition request.c:2125
int ap_is_initial_req(request_rec *r)
Definition request.c:2567
void ap_args_to_table(request_rec *r, apr_table_t **table)
void ap_varbuf_grow(struct ap_varbuf *vb, apr_size_t new_size)
Definition util.c:2971
void ap_varbuf_init(apr_pool_t *pool, struct ap_varbuf *vb, apr_size_t init_size)
Definition util.c:2959
#define APR_INCOMPLETE
Definition apr_errno.h:452
#define APR_EINCOMPLETE
Definition apr_errno.h:328
#define APR_STATUS_IS_INCOMPLETE(s)
Definition apr_errno.h:542
#define APR_BRIGADE_INSERT_TAIL(b, e)
apr_file_t apr_off_t start
apr_brigade_flush void * ctx
int apr_off_t * length
@ APR_BLOCK_READ
Definition apr_buckets.h:58
@ APR_NONBLOCK_READ
Definition apr_buckets.h:59
apr_pool_t apr_dbd_t apr_dbd_results_t ** res
Definition apr_dbd.h:287
const char * mask
Definition apr_date.h:60
const char apr_ssize_t int flags
Definition apr_encode.h:168
const char apr_ssize_t slen
Definition apr_encode.h:168
const char apr_ssize_t int partial
Definition apr_escape.h:188
apr_redis_t * rc
Definition apr_redis.h:173
apr_redis_server_t * rs
Definition apr_redis.h:205
int ap_expr_exec(request_rec *r, const ap_expr_info_t *expr, const char **err)
const char * ap_expr_parse(apr_pool_t *pool, apr_pool_t *ptemp, ap_expr_info_t *info, const char *expr, ap_expr_lookup_fn_t *lookup_fn)
#define OR_LIMIT
#define OR_INDEXES
#define OR_ALL
#define OR_FILEINFO
#define OR_OPTIONS
#define OR_NONE
#define OR_AUTHCFG
#define M_PUT
Definition httpd.h:593
#define M_POST
Definition httpd.h:594
int ap_strcmp_match(const char *str, const char *expected)
Definition util.c:175
int ap_strcasecmp_match(const char *str, const char *expected)
Definition util.c:199
void ap_set_document_root(request_rec *r, const char *document_root)
Definition core.c:857
char * ap_escape_logitem(apr_pool_t *p, const char *str)
Definition util.c:2183
char * ap_strcasestr(const char *s1, const char *s2)
Definition util.c:289
void ap_set_context_info(request_rec *r, const char *prefix, const char *document_root)
Definition core.c:863
void ap_bin2hex(const void *src, apr_size_t srclen, char *dest)
Definition util.c:2314
int ap_unescape_urlencoded(char *query)
Definition util.c:1977
const char * ap_context_prefix(request_rec *r)
Definition core.c:839
const char * ap_context_document_root(request_rec *r)
Definition core.c:848
#define PROXYREQ_NONE
Definition httpd.h:1133
int ap_parse_form_data(request_rec *r, struct ap_filter_t *f, apr_array_header_t **ptr, apr_size_t num, apr_size_t size)
Definition util.c:2787
#define PROXYREQ_PROXY
Definition httpd.h:1134
#define ap_escape_html(p, s)
Definition httpd.h:1860
char * ap_escape_urlencoded(apr_pool_t *p, const char *s)
Definition util.c:2124
#define PROXYREQ_REVERSE
Definition httpd.h:1135
char * ap_os_escape_path(apr_pool_t *p, const char *path, int partial)
Definition util.c:2073
#define PROXYREQ_RESPONSE
Definition httpd.h:1136
@ AP_CONN_CLOSE
Definition httpd.h:1145
apr_size_t size
const char int apr_pool_t * pool
Definition apr_cstr.h:84
const char * input
Definition apr_cstr.h:93
apr_int32_t apr_dir_t * thedir
const char * value
Definition apr_env.h:51
#define APR_SUCCESS
Definition apr_errno.h:225
int apr_status_t
Definition apr_errno.h:44
apr_int32_t apr_fileperms_t
@ APR_DIR
@ APR_NOFILE
const char * key
const char apr_fileperms_t perms
void * data
const char apr_file_t * file
int type
apr_time_t mtime
char * buffer
#define APR_READ
Definition apr_file_io.h:93
#define APR_CREATE
Definition apr_file_io.h:95
#define APR_FOPEN_WRITE
Definition apr_file_io.h:55
#define APR_OS_DEFAULT
#define APR_FPROT_OS_DEFAULT
#define APR_FINFO_ATIME
#define APR_FINFO_MIN
const char apr_int32_t wanted
#define APR_FINFO_NAME
#define APR_FINFO_CTIME
#define APR_FINFO_MTIME
#define APR_FINFO_TYPE
#define APR_FINFO_PROT
#define APR_FINFO_SIZE
apr_array_header_t ** result
apr_pool_t int argc
Definition apr_getopt.h:104
const char * opts
Definition apr_getopt.h:122
#define APR_HASH_KEY_STRING
Definition apr_hash.h:47
apr_vformatter_buff_t * c
Definition apr_lib.h:175
apr_sockaddr_t apr_sockaddr_t apr_sockaddr_t * source
apr_socket_t * sock
apr_interval_time_t t
apr_interval_time_t apr_pollcb_cb_t func
Definition apr_poll.h:422
apr_pool_t * b
Definition apr_pools.h:529
#define apr_pcalloc(p, size)
Definition apr_pools.h:465
apr_dir_t * dir
apr_size_t const char * filename
Definition apr_shm.h:72
const char char ** end
const char * s
Definition apr_strings.h:95
apr_int32_t apr_int32_t apr_int32_t err
apr_cmdtype_e cmd
int int status
#define APR_RFC822_DATE_LEN
Definition apr_time.h:186
apr_int64_t apr_interval_time_t
Definition apr_time.h:55
#define APR_USEC_PER_SEC
Definition apr_time.h:60
apr_int64_t apr_time_t
Definition apr_time.h:45
#define apr_time_from_sec(sec)
Definition apr_time.h:78
apr_status_t ap_mpm_query(int query_code, int *result)
Definition mpm_common.c:421
#define REQUEST_CHUNKED_ERROR
Definition httpd.h:748
void ap_lua_push_apr_table(lua_State *L, req_table_t *t)
Definition lua_apr.c:31
int lua_db_acquire(lua_State *L)
Definition lua_dbd.c:725
int mk_password_hash(passwd_ctx *ctx)
Definition lua_passwd.c:87
#define MAX_PASSWD_LEN
Definition lua_passwd.h:31
#define ALG_APMD5
Definition lua_passwd.h:33
static int req_add_output_filter(lua_State *L)
static int lua_ap_exists_config_define(lua_State *L)
static int req_trace4(lua_State *L)
static int req_puts(lua_State *L)
int(* req_field_int_f)(request_rec *r)
Definition lua_request.c:46
static const char * req_ap_auth_type_field(request_rec *r)
static int req_warn(lua_State *L)
static const char * lua_ap_allowoverrides(request_rec *r)
static int lua_read_body(request_rec *r, const char **rbuf, apr_off_t *size, apr_off_t maxsize)
static int lua_ap_scoreboard_worker(lua_State *L)
static int lua_ap_started(request_rec *r)
static int lua_ap_is_initial_req(request_rec *r)
static const struct luaL_Reg connection_methods[]
static int lua_ap_usleep(lua_State *L)
static int lua_ap_runtime_dir_relative(lua_State *L)
static const char * req_context_document_root(request_rec *r)
static const char * req_hostname_field(request_rec *r)
apr_global_mutex_t * lua_ivm_mutex
Definition mod_lua.c:85
static int lua_apr_mkdir(lua_State *L)
static int req_log_at(lua_State *L, int level)
static int lua_websocket_peek(lua_State *L)
static int req_ssl_is_https_field(request_rec *r)
static int req_ssl_var_lookup(lua_State *L)
static int lua_ap_module_info(lua_State *L)
static int lua_ap_getdir(lua_State *L)
static const char * req_the_request_field(request_rec *r)
static int req_emerg(lua_State *L)
static int lua_ap_regex(lua_State *L)
static int lua_websocket_write(lua_State *L)
static int req_trace7(lua_State *L)
static const char * req_args_field(request_rec *r)
static int req_trace2(lua_State *L)
static int req_parsebody(lua_State *L)
static int req_trace6(lua_State *L)
static const char * req_document_root(request_rec *r)
static int lua_websocket_close(lua_State *L)
static int lua_ap_strcmp_match(lua_State *L)
static apr_status_t lua_websocket_readbytes(conn_rec *c, apr_bucket_brigade *brigade, char *buffer, apr_off_t len)
static int lua_ap_some_auth_required(request_rec *r)
static int lua_ap_server_info(lua_State *L)
static int req_trace3(lua_State *L)
static void read_cfg_tree(lua_State *L, request_rec *r, ap_directive_t *rcfg)
static const char * req_content_type_field(request_rec *r)
static int req_alert(lua_State *L)
static int lua_apr_date_parse_rfc(lua_State *L)
void ap_lua_push_connection(lua_State *L, conn_rec *c)
static const char * req_unparsed_uri_field(request_rec *r)
static const char * req_context_prefix(request_rec *r)
static int lua_ap_state_query(lua_State *L)
static char * req_uri_field(request_rec *r)
static int lua_ap_expr(lua_State *L)
static const char * req_protocol_field(request_rec *r)
void ap_lua_rstack_dump(lua_State *L, request_rec *r, const char *msg)
Definition lua_request.c:50
static const char * req_canonical_filename_field(request_rec *r)
static int lua_ap_get_config(lua_State *L)
static int lua_ap_os_escape_path(lua_State *L)
char *(* req_field_string_f)(request_rec *r)
Definition lua_request.c:45
static int lua_ap_send_interim_response(lua_State *L)
static int lua_ap_stat(lua_State *L)
static int lua_apr_rmdir(lua_State *L)
static req_table_t * req_subprocess_env(request_rec *r)
static int lua_apr_b64encode(lua_State *L)
static int req_assbackwards_field(request_rec *r)
static int lua_apr_mkrdir(lua_State *L)
static int lua_apr_htpassword(lua_State *L)
static const char * req_filename_field(request_rec *r)
static int req_crit(lua_State *L)
static int req_trace8(lua_State *L)
static const char * lua_ap_basic_auth_pw(request_rec *r)
static const char * lua_ap_get_server_name(request_rec *r)
static const char * req_handler_field(request_rec *r)
static int lua_websocket_greet(lua_State *L)
void ap_lua_push_server(lua_State *L, server_rec *s)
static int lua_ap_get_server_name_for_url(lua_State *L)
static const char * req_content_encoding_field(request_rec *r)
static int lua_ap_loaded_modules(lua_State *L)
static int lua_ap_scoreboard_process(lua_State *L)
static int req_err_headers_out_table(lua_State *L)
static const struct luaL_Reg request_methods[]
static int lua_ap_requestbody(lua_State *L)
void ap_lua_push_request(lua_State *L, request_rec *r)
static int lua_ap_unescape(lua_State *L)
static int lua_ap_mpm_query(lua_State *L)
static int req_status_field(request_rec *r)
static int req_notice(lua_State *L)
static int lua_ivm_set(lua_State *L)
static int req_parseargs(lua_State *L)
static const char * req_range_field(request_rec *r)
static int lua_ap_get_active_config(lua_State *L)
static int req_escape_html(lua_State *L)
static int lua_ap_sendfile(lua_State *L)
static const char * req_proxyreq_field(request_rec *r)
static int lua_ap_set_context_info(lua_State *L)
static apr_status_t lua_write_body(request_rec *r, apr_file_t *file, apr_off_t *size)
static req_fun_t * makefun(const void *fun, int type, apr_pool_t *pool)
static int req_notes_table(lua_State *L)
static int lua_apr_md5(lua_State *L)
static int req_trace1(lua_State *L)
static int req_headers_in_table(lua_State *L)
static int lua_get_cookie(lua_State *L)
static int lua_ap_make_etag(lua_State *L)
#define MODLUA_MAX_REG_MATCH
Definition lua_request.c:42
static req_table_t * req_headers_in(request_rec *r)
static int lua_ap_clock(lua_State *L)
static int req_remaining_field(request_rec *r)
static int req_construct_url(lua_State *L)
static int lua_apr_b64decode(lua_State *L)
static int lua_ap_limit_req_body(request_rec *r)
static int req_err(lua_State *L)
static const char * req_user_field(request_rec *r)
static int lua_ap_escape(lua_State *L)
static int lua_websocket_ping(lua_State *L)
static int req_aprtable2luatable_cb(void *l, const char *key, const char *value)
static int req_aprtable2luatable(lua_State *L, apr_table_t *t)
static int lua_apr_touch(lua_State *L)
static request_rec * ap_lua_check_request_rec(lua_State *L, int index)
static const char * lua_ap_auth_name(request_rec *r)
static const char * lua_ap_options(request_rec *r)
static req_table_t * req_err_headers_out(request_rec *r)
static int lua_ap_custom_response(lua_State *L)
static int req_dispatch(lua_State *L)
static int lua_ap_rflush(lua_State *L)
static int lua_ap_set_keepalive(lua_State *L)
#define POST_MAX_VARS
Definition lua_request.c:39
static const char * req_path_info_field(request_rec *r)
static const struct luaL_Reg server_methods[]
static int lua_ap_set_document_root(lua_State *L)
static int req_info(lua_State *L)
req_table_t *(* req_field_apr_table_f)(request_rec *r)
Definition lua_request.c:47
static const char * req_log_id_field(request_rec *r)
static int req_debug(lua_State *L)
static int lua_ap_escape_logitem(lua_State *L)
apr_shm_t * lua_ivm_shm
Definition mod_lua.c:86
static int lua_set_cookie(lua_State *L)
static int req_ap_get_server_port(request_rec *r)
static req_table_t * req_headers_out(request_rec *r)
static int lua_ap_add_input_filter(lua_State *L)
static int req_write(lua_State *L)
static const char * req_useragent_ip_field(request_rec *r)
#define APLUA_REQ_TRACE(lev)
static const char * req_method_field(request_rec *r)
static apr_uint64_t ap_ntoh64(const apr_uint64_t *input)
static int req_newindex(lua_State *L)
static int req_aprtable2luatable_cb_len(void *l, const char *key, const char *value, size_t len)
static int req_trace5(lua_State *L)
static req_table_t * req_notes(request_rec *r)
static int lua_ivm_get(lua_State *L)
void ap_lua_load_request_lmodule(lua_State *L, apr_pool_t *p)
static int req_headers_out_table(lua_State *L)
static int req_subprocess_env_table(lua_State *L)
static int lua_websocket_read(lua_State *L)
static int lua_apr_sha1(lua_State *L)
static char * ap_lua_binstrstr(const char *haystack, size_t hsize, const char *needle, size_t nsize)
#define APL_REQ_FUNTYPE_STRING
Definition lua_request.h:29
#define APL_REQ_FUNTYPE_LUACFUN
Definition lua_request.h:32
#define APL_REQ_FUNTYPE_TABLE
Definition lua_request.h:31
#define APL_REQ_FUNTYPE_BOOLEAN
Definition lua_request.h:33
#define APL_REQ_FUNTYPE_INT
Definition lua_request.h:30
apr_pool_t * p
Definition md_event.c:32
static apr_status_t dispatch(md_store_fs_t *s_fs, md_store_fs_ev_t ev, unsigned int group, const char *fname, apr_filetype_e ftype, apr_pool_t *p)
static const char *const directory
static apr_file_t * out
Definition mod_info.c:85
const char * ap_lua_ssl_val(apr_pool_t *p, server_rec *s, conn_rec *c, request_rec *r, const char *var)
Definition mod_lua.c:1705
int ap_lua_ssl_is_https(conn_rec *c)
Definition mod_lua.c:1711
#define luaL_setfuncs_compat(a, b)
Definition mod_lua.h:64
#define lua_rawlen(L, i)
Definition mod_lua.h:63
static int send_headers(request_rec *r, proxy_conn_rec *conn)
return NULL
Definition mod_so.c:359
int i
Definition mod_so.c:347
Apache scoreboard library.
scoreboard * ap_scoreboard_image
Definition scoreboard.c:44
const char * ap_scoreboard_fname
Definition scoreboard.c:45
void ap_copy_scoreboard_worker(worker_score *dest, int child_num, int thread_num)
Definition scoreboard.c:685
process_score * ap_get_scoreboard_process(int x)
Definition scoreboard.c:702
char * name
Structure used to build the config tree.
struct ap_directive_t * next
const char * filename
struct ap_directive_t * first_child
const char * args
const char * directive
This structure is used for recording information about the registered filters. It associates a name w...
Structure to store things which are per connection.
Definition httpd.h:1152
apr_pool_t * pool
Definition httpd.h:1154
ap_conn_keepalive_e keepalive
Definition httpd.h:1223
struct ap_filter_t * input_filters
Definition httpd.h:1195
struct apr_bucket_alloc_t * bucket_alloc
Definition httpd.h:1201
apr_time_t restart_time
Definition scoreboard.h:129
A structure that represents the current request.
Definition httpd.h:845
char * user
Definition httpd.h:1005
int status
Definition httpd.h:891
apr_off_t bytes_sent
Definition httpd.h:931
char * uri
Definition httpd.h:1016
const char * content_type
Definition httpd.h:992
struct ap_filter_t * output_filters
Definition httpd.h:1070
char * useragent_ip
Definition httpd.h:1101
int assbackwards
Definition httpd.h:868
const char * handler
Definition httpd.h:994
apr_table_t * notes
Definition httpd.h:985
const char * hostname
Definition httpd.h:883
char * the_request
Definition httpd.h:866
int method_number
Definition httpd.h:898
apr_pool_t * pool
Definition httpd.h:847
char * filename
Definition httpd.h:1018
apr_off_t remaining
Definition httpd.h:959
char * unparsed_uri
Definition httpd.h:1014
int proxyreq
Definition httpd.h:873
conn_rec * connection
Definition httpd.h:849
const char * log_id
Definition httpd.h:1059
apr_table_t * err_headers_out
Definition httpd.h:981
char * canonical_filename
Definition httpd.h:1022
apr_table_t * headers_in
Definition httpd.h:976
char * protocol
Definition httpd.h:879
const char * range
Definition httpd.h:938
int read_chunked
Definition httpd.h:949
apr_table_t * subprocess_env
Definition httpd.h:983
server_rec * server
Definition httpd.h:851
apr_off_t clength
Definition httpd.h:940
const char * method
Definition httpd.h:900
char * path_info
Definition httpd.h:1024
char * args
Definition httpd.h:1026
const char * content_encoding
Definition httpd.h:997
char * ap_auth_type
Definition httpd.h:1007
apr_table_t * headers_out
Definition httpd.h:978
global_score * global
Definition scoreboard.h:161
A structure to store information for each virtual server.
Definition httpd.h:1322
const char * digest
Definition testmd5.c:30
static apr_time_t now
Definition testtime.c:33
apr_status_t apr_dir_read(apr_finfo_t *finfo, apr_int32_t wanted, apr_dir_t *thedir)
Definition dir.c:142
apr_status_t apr_dir_make(const char *path, apr_fileperms_t perm, apr_pool_t *pool)
Definition dir.c:297
apr_status_t apr_dir_remove(const char *path, apr_pool_t *pool)
Definition dir.c:343
apr_status_t apr_dir_close(apr_dir_t *thedir)
Definition dir.c:109
apr_status_t apr_dir_open(apr_dir_t **new, const char *dirname, apr_pool_t *pool)
Definition dir.c:75
apr_status_t apr_socket_send(apr_socket_t *sock, const char *buf, apr_size_t *len)
Definition sendrecv.c:30
apr_status_t apr_socket_recv(apr_socket_t *sock, char *buf, apr_size_t *len)
Definition sendrecv.c:70
apr_status_t apr_socket_close(apr_socket_t *thesocket)
Definition sockets.c:211
apr_status_t apr_rfc822_date(char *date_str, apr_time_t t)
Definition timestr.c:42
Apache cookie library.
#define str
#define regex
@ AP_MODE_READBYTES
Definition util_filter.h:43
char * ap_md5_binary(apr_pool_t *p, const unsigned char *buf, int length)
Definition util_md5.c:53
Apache MD5 library.
Apache script tools.
Apache resizable variable length buffer library.
typedef int(WSAAPI *apr_winapi_fpt_WSAPoll)(IN OUT LPWSAPOLLFD fdArray