2
* Copyright 2004 Apache Software Foundation
4
* Licensed under the Apache License, Version 2.0 (the "License"); you
5
* may not use this file except in compliance with the License. You
6
* may obtain a copy of the License at
8
* http://www.apache.org/licenses/LICENSE-2.0
10
* Unless required by applicable law or agreed to in writing, software
11
* distributed under the License is distributed on an "AS IS" BASIS,
12
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
13
* implied. See the License for the specific language governing
14
* permissions and limitations under the License.
16
* Originally developed by Gregory Trubetskoy.
21
* $Id: mod_python.c,v 1.113 2004/02/16 19:47:27 grisha Exp $
23
* See accompanying documentation and source code comments
28
#include "mod_python.h"
30
/* List of available Python obCallBacks/Interpreters
31
* (In a Python dictionary) */
32
static PyObject * interpreters = NULL;
34
apr_pool_t *child_init_pool = NULL;
39
* Creates a new Python interpeter.
42
static PyInterpreterState *make_interpreter(const char *name, server_rec *srv)
44
PyThreadState *tstate;
46
/* create a new interpeter */
47
tstate = Py_NewInterpreter();
50
/* couldn't create an interpreter, this is bad */
51
ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, 0, srv,
52
"make_interpreter: Py_NewInterpreter() returned NULL. No more memory?");
56
/* release the thread state */
57
PyThreadState_Swap(NULL);
59
/* Strictly speaking we don't need that tstate created
60
* by Py_NewInterpreter but is preferable to waste it than re-write
61
* a cousin to Py_NewInterpreter
62
* XXX (maybe we can destroy it?)
64
return tstate->interp;
70
* This function instantiates an obCallBack object.
71
* NOTE: The obCallBack object is instantiated by Python
72
* code. This C module calls into Python code which returns
73
* the reference to obCallBack.
76
static PyObject * make_obcallback(server_rec *s)
80
PyObject *obCallBack = NULL;
82
/* This makes _apache appear imported, and subsequent
84
* will not give an error.
86
/* Py_InitModule("_apache", _apache_module_methods); */
89
/* Now execute the equivalent of
92
* in the __main__ module to start up Python.
95
if (! ((m = PyImport_ImportModule(MODULENAME)))) {
96
ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, 0, s,
97
"make_obcallback: could not import %s.\n", MODULENAME);
101
if (m && ! ((obCallBack = PyObject_CallMethod(m, INITFUNC, NULL)))) {
102
ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, 0, s,
103
"make_obcallback: could not call %s.\n", INITFUNC);
113
* Get interpreter given its name.
114
* NOTE: This function will acquire lock
117
static interpreterdata *get_interpreter(const char *name, server_rec *srv)
120
PyThreadState *tstate;
121
interpreterdata *idata = NULL;
124
name = MAIN_INTERPRETER;
127
PyEval_AcquireLock();
133
p = PyDict_GetItemString(interpreters, (char *)name);
136
PyInterpreterState *istate = make_interpreter(name, srv);
138
idata = (interpreterdata *)malloc(sizeof(interpreterdata));
139
idata->istate = istate;
140
/* obcallback will be created on first use */
141
idata->obcallback = NULL;
142
p = PyCObject_FromVoidPtr((void *) idata, NULL);
143
PyDict_SetItemString(interpreters, (char *)name, p);
147
idata = (interpreterdata *)PyCObject_AsVoidPtr(p);
151
PyEval_ReleaseLock();
155
ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, 0, srv,
156
"get_interpreter: cannot get interpreter data (no more memory?)");
160
/* create thread state and acquire lock */
161
tstate = PyThreadState_New(idata->istate);
163
PyEval_AcquireThread(tstate);
165
PyThreadState_Swap(tstate);
168
if (!idata->obcallback) {
170
idata->obcallback = make_obcallback(srv);
172
if (!idata->obcallback)
175
PyEval_ReleaseThread(tstate);
177
PyThreadState_Delete(tstate);
187
** release_interpreter
189
* Release interpreter.
190
* NOTE: This function will release lock
193
static void release_interpreter(void)
195
PyThreadState *tstate = PyThreadState_Get();
197
PyEval_ReleaseThread(tstate);
199
PyThreadState_Delete(tstate);
205
* This function gets called for clean ups registered
206
* with register_cleanup(). Clean ups registered via
207
* PythonCleanupHandler run in python_cleanup_handler()
211
apr_status_t python_cleanup(void *data)
213
interpreterdata *idata;
215
cleanup_info *ci = (cleanup_info *)data;
217
/* get/create interpreter */
219
idata = get_interpreter(ci->interpreter, ci->request_rec->server);
221
idata = get_interpreter(ci->interpreter, ci->server_rec);
224
Py_DECREF(ci->handler);
225
Py_XDECREF(ci->data);
227
return APR_SUCCESS; /* this is ignored anyway */
231
* Call the cleanup function.
233
if (! PyObject_CallFunction(ci->handler, "O", ci->data)) {
241
PyErr_Fetch(&ptype, &pvalue, &ptb);
242
handler = PyObject_Str(ci->handler);
243
stype = PyObject_Str(ptype);
244
svalue = PyObject_Str(pvalue);
250
if (ci->request_rec) {
251
ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, 0,
253
"python_cleanup: Error calling cleanup object %s",
254
PyString_AsString(handler));
255
ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, 0,
257
" %s: %s", PyString_AsString(stype),
258
PyString_AsString(svalue));
261
ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, 0,
263
"python_cleanup: Error calling cleanup object %s",
264
PyString_AsString(handler));
265
ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, 0,
267
" %s: %s", PyString_AsString(stype),
268
PyString_AsString(svalue));
276
Py_DECREF(ci->handler);
280
release_interpreter();
285
static apr_status_t init_mutexes(server_rec *s, apr_pool_t *p, py_global_config *glb)
295
/* figre out maximum possible concurrent connections */
296
/* MAX_DAEMON_USED seems to account for MaxClients, as opposed to
297
MAX_DAEMONS, which is ServerLimit
299
ap_mpm_query(AP_MPMQ_IS_THREADED, &is_threaded);
300
if (is_threaded != AP_MPMQ_NOT_SUPPORTED) {
301
ap_mpm_query(AP_MPMQ_MAX_THREADS, &max_threads);
303
ap_mpm_query(AP_MPMQ_IS_FORKED, &is_forked);
304
if (is_forked != AP_MPMQ_NOT_SUPPORTED) {
305
/* XXX This looks strange, and it is. prefork.c seems to use
306
MAX_DAEMON_USED the same way that worker.c uses
307
MAX_DAEMONS (prefork is wrong IMO) */
308
ap_mpm_query(AP_MPMQ_MAX_DAEMON_USED, &max_procs);
309
if (max_procs == -1) {
310
ap_mpm_query(AP_MPMQ_MAX_DAEMONS, &max_procs);
313
max_clients = (((max_threads <= 0) ? 1 : max_threads) *
314
((max_procs <= 0) ? 1 : max_procs));
316
/* XXX On some systems the locking mechanism chosen uses valuable
317
system resources, notably on RH 8 it will use sysv ipc for
318
which Linux by default provides only 128 semaphores
319
system-wide, and on many other systems flock is used, which
320
results in a relatively large number of open files. So for now
321
we get by with MAX_LOCKS constant for lack of a better
324
The optimal number of necessary locks is not clear, perhaps a
325
small number is more than sufficient - if someone took the
326
time to run some research on this, that'd be most welcome!
328
locks = (max_clients > MAX_LOCKS) ? MAX_LOCKS : max_clients;
330
ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, s,
331
"mod_python: Creating %d session mutexes based "
332
"on %d max processes and %d max threads.",
333
locks, max_procs, max_threads);
335
glb->g_locks = (apr_global_mutex_t **)
336
apr_palloc(p, locks * sizeof(apr_global_mutex_t *));
338
glb->parent_pid = getpid();
340
for (n=0; n<locks; n++) {
342
apr_global_mutex_t **mutex = glb->g_locks;
344
#if !defined(OS2) && !defined(WIN32) && !defined(BEOS) && !defined(NETWARE)
347
snprintf(fname, 255, "/tmp/mpmtx%d%d", glb->parent_pid, n);
351
rc = apr_global_mutex_create(&mutex[n], fname, APR_LOCK_DEFAULT,
353
if (rc != APR_SUCCESS) {
354
ap_log_error(APLOG_MARK, APLOG_ERR, rc, s,
355
"mod_python: Failed to create global mutex %d of %d (%s).",
356
n, locks, (!fname) ? "<null>" : fname);
358
/* we were able to crate at least two, so lets just print a
359
warning/hint and proceed
361
ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
362
"mod_python: We can probably continue, but with diminished ability "
363
"to process session locks.");
364
ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
365
"mod_python: Hint: On Linux, the problem may be the number of "
366
"available semaphores, check 'sysctl kernel.sem'");
367
/* now free two locks so that if there is another
368
module or two that wants a lock, it will be ok */
369
apr_global_mutex_destroy(mutex[n-1]);
372
apr_global_mutex_destroy(mutex[n-2]);
384
/*XXX As of httpd 2.0.4, the below should be just
385
a call to unixd_set_global_mutex_perms(mutex[n]); and
386
nothing else... For now, while 2.0.48 isn't commonplace yet,
387
this ugly code should be here */
389
#if !defined(OS2) && !defined(WIN32) && !defined(BEOS) && !defined(NETWARE)
391
chown(fname, unixd_config.user_id, -1);
392
unixd_set_global_mutex_perms(mutex[n]);
400
static apr_status_t reinit_mutexes(server_rec *s, apr_pool_t *p, py_global_config *glb)
404
for (n=0; n< glb->nlocks; n++) {
406
apr_global_mutex_t **mutex = glb->g_locks;
408
#if !defined(OS2) && !defined(WIN32) && !defined(BEOS) && !defined(NETWARE)
410
snprintf(fname, 255, "/tmp/mpmtx%d%d", glb->parent_pid, n);
414
rc = apr_global_mutex_child_init(&mutex[n], fname, p);
416
if (rc != APR_SUCCESS) {
417
ap_log_error(APLOG_MARK, APLOG_STARTUP, rc, s,
418
"mod_python: Failed to reinit global mutex %s.",
419
(!fname) ? "<null>" : fname);
427
** python_create_global_config
429
* This creates the part of config that survives
434
static py_global_config *python_create_global_config(server_rec *s)
436
apr_pool_t *pool = s->process->pool;
437
py_global_config *glb;
439
/* do we already have it in s->process->pool? */
440
apr_pool_userdata_get((void **)&glb, MP_CONFIG_KEY, pool);
446
/* otherwise, create it */
448
glb = (py_global_config *)apr_palloc(pool, sizeof(*glb));
450
apr_pool_userdata_set(glb, MP_CONFIG_KEY,
451
apr_pool_cleanup_null,
460
* Called by Apache at mod_python initialization time.
463
static int python_init(apr_pool_t *p, apr_pool_t *ptemp,
464
apr_pool_t *plog, server_rec *s)
468
py_global_config *glb;
469
const char *userdata_key = "python_init";
472
apr_pool_userdata_get(&data, userdata_key, s->process->pool);
474
apr_pool_userdata_set((const void *)1, userdata_key,
475
apr_pool_cleanup_null, s->process->pool);
479
/* mod_python version */
480
ap_add_version_component(p, VERSION_COMPONENT);
483
sprintf(buff, "Python/%.200s", strtok((char *)Py_GetVersion(), " "));
484
ap_add_version_component(p, buff);
487
glb = python_create_global_config(s);
488
if ((rc = init_mutexes(s, p, glb)) != APR_SUCCESS) {
492
/* initialize global Python interpreter if necessary */
493
if (! Py_IsInitialized())
496
/* initialze the interpreter */
500
/* create and acquire the interpreter lock */
501
PyEval_InitThreads();
503
/* Release the thread state because we will never use
504
* the main interpreter, only sub interpreters created later. */
505
PyThreadState_Swap(NULL);
507
/* create the obCallBack dictionary */
508
interpreters = PyDict_New();
509
if (! interpreters) {
510
ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, 0, s,
511
"python_init: PyDict_New() failed! No more memory?");
516
/* release the lock; now other threads can run */
517
PyEval_ReleaseLock();
525
** python_create_config
527
* Called by create_dir_config and create_srv_config
530
static py_config *python_create_config(apr_pool_t *p)
533
(py_config *) apr_pcalloc(p, sizeof(py_config));
535
conf->authoritative = 1;
536
conf->options = apr_table_make(p, 4);
537
conf->directives = apr_table_make(p, 4);
538
conf->hlists = apr_hash_make(p);
539
conf->in_filters = apr_hash_make(p);
540
conf->out_filters = apr_hash_make(p);
547
** python_create_dir_config
549
* Allocate memory and initialize the strucure that will
550
* hold configuration parametes.
552
* This function is called on every hit it seems.
555
static void *python_create_dir_config(apr_pool_t *p, char *dir)
558
py_config *conf = python_create_config(p);
560
/* make sure directory ends with a slash */
561
if (dir && (dir[strlen(dir) - 1] != SLASH))
562
conf->config_dir = apr_pstrcat(p, dir, SLASH_S, NULL);
564
conf->config_dir = apr_pstrdup(p, dir);
570
** python_create_srv_config
572
* Allocate memory and initialize the strucure that will
573
* hold configuration parametes.
576
static void *python_create_srv_config(apr_pool_t *p, server_rec *srv)
579
py_config *conf = python_create_config(p);
585
** python_merge_dir_config
589
static void *python_merge_config(apr_pool_t *p, void *current_conf,
593
py_config *merged_conf =
594
(py_config *) apr_pcalloc(p, sizeof(py_config));
595
py_config *cc = (py_config *) current_conf;
596
py_config *nc = (py_config *) new_conf;
598
apr_hash_index_t *hi;
603
/* we basically allow the local configuration to override global,
604
* by first copying current values and then new values on top
608
merged_conf->directives = apr_table_make(p, 4);
609
merged_conf->options = apr_table_make(p, 4);
610
merged_conf->hlists = apr_hash_make(p);
611
merged_conf->in_filters = apr_hash_make(p);
612
merged_conf->out_filters = apr_hash_make(p);
616
merged_conf->authoritative = cc->authoritative;
617
merged_conf->config_dir = apr_pstrdup(p, cc->config_dir);
618
apr_table_overlap(merged_conf->directives, cc->directives,
619
APR_OVERLAP_TABLES_SET);
620
apr_table_overlap(merged_conf->options, cc->options,
621
APR_OVERLAP_TABLES_SET);
623
for (hi = apr_hash_first(p, cc->hlists); hi; hi=apr_hash_next(hi)) {
624
apr_hash_this(hi, (const void **)&key, &klen, (void **)&hle);
625
apr_hash_set(merged_conf->hlists, key, klen, (void *)hle);
628
for (hi = apr_hash_first(p, cc->in_filters); hi; hi=apr_hash_next(hi)) {
629
apr_hash_this(hi, (const void **)&key, &klen, (void **)&hle);
630
apr_hash_set(merged_conf->in_filters, key, klen, (void *)hle);
633
for (hi = apr_hash_first(p, cc->out_filters); hi; hi=apr_hash_next(hi)) {
634
apr_hash_this(hi, (const void **)&key, &klen, (void **)&hle);
635
apr_hash_set(merged_conf->out_filters, key, klen, (void *)hle);
640
if (nc->authoritative != merged_conf->authoritative)
641
merged_conf->authoritative = nc->authoritative;
643
merged_conf->config_dir = apr_pstrdup(p, nc->config_dir);
645
apr_table_overlap(merged_conf->directives, nc->directives,
646
APR_OVERLAP_TABLES_SET);
647
apr_table_overlap(merged_conf->options, nc->options,
648
APR_OVERLAP_TABLES_SET);
650
for (hi = apr_hash_first(p, nc->hlists); hi; hi=apr_hash_next(hi)) {
651
apr_hash_this(hi, (const void**)&key, &klen, (void **)&hle);
652
apr_hash_set(merged_conf->hlists, key, klen, (void *)hle);
655
for (hi = apr_hash_first(p, nc->in_filters); hi; hi=apr_hash_next(hi)) {
656
apr_hash_this(hi, (const void**)&key, &klen, (void **)&hle);
657
apr_hash_set(merged_conf->in_filters, key, klen, (void *)hle);
660
for (hi = apr_hash_first(p, nc->out_filters); hi; hi=apr_hash_next(hi)) {
661
apr_hash_this(hi, (const void**)&key, &klen, (void **)&hle);
662
apr_hash_set(merged_conf->out_filters, key, klen, (void *)hle);
665
return (void *) merged_conf;
671
* Called by non-handler directives
675
static const char *python_directive(cmd_parms *cmd, void * mconfig,
676
char *key, const char *val)
680
conf = (py_config *) mconfig;
681
apr_table_set(conf->directives, key, val);
686
static void python_directive_hl_add(apr_pool_t *p,
688
const char *phase, const char *handler,
689
const char *directory, const int silent)
694
head = (hl_entry *)apr_hash_get(hlists, phase, APR_HASH_KEY_STRING);
696
/* it's possible that handler is multiple handlers separated
699
while (*(h = ap_getword_white(p, &handler)) != '\0') {
701
head = hlist_new(p, h, directory, silent);
702
apr_hash_set(hlists, phase, APR_HASH_KEY_STRING, head);
705
hlist_append(p, head, h, directory, silent);
711
** python_directive_handler
713
* Called by Python*Handler directives.
715
* When used within the same directory, this will have a
716
* cumulative, rather than overriding effect - i.e. values
717
* from same directives specified multiple times will be appended.
721
static const char *python_directive_handler(cmd_parms *cmd, py_config* conf,
722
char *key, const char *val, int silent)
724
/* a handler may be restricted to certain file type by
725
* extention using the "| .ext1 .ext2" syntax. When this
726
* is the case, we will end up with a directive concatenated
727
* with the extension, one per, e.g.
728
* "PythonHandler foo | .ext1 .ext2" will result in
729
* PythonHandler.ext1 foo
730
* PythonHandler.ext2 foo
733
const char *exts = val;
734
val = ap_getword(cmd->pool, &exts, '|');
737
python_directive_hl_add(cmd->pool, conf->hlists, key, val,
738
conf->config_dir, silent);
745
while (apr_isspace(*exts)) exts++;
747
/* repeat for every extension */
748
while (*(ext = ap_getword_white(cmd->pool, &exts)) != '\0') {
751
/* append extention to the directive name */
752
s = apr_pstrcat(cmd->pool, key, ext, NULL);
754
python_directive_hl_add(cmd->pool, conf->hlists, s, val,
755
conf->config_dir, silent);
763
** python_directive_flag
765
* Called for FLAG directives.
769
static const char *python_directive_flag(void * mconfig,
774
conf = (py_config *) mconfig;
777
apr_table_set(conf->directives, key, "1");
780
apr_table_unset(conf->directives, key);
786
static apr_status_t python_cleanup_handler(void *data);
789
** get_request_object
791
* This creates or retrieves a previously created request object.
792
* The pointer to request object is stored in req->request_config.
795
static requestobject *get_request_object(request_rec *req, const char *interp_name, char *phase)
797
py_req_config *req_config;
798
requestobject *request_obj = NULL;
800
/* see if there is a request object already */
801
req_config = (py_req_config *) ap_get_module_config(req->request_config,
805
request_obj = req_config->request_obj;
808
/* if ((req->path_info) && */
809
/* (req->path_info[strlen(req->path_info) - 1] == SLASH)) */
812
/* i = strlen(req->path_info); */
813
/* /\* take out the slash *\/ */
814
/* req->path_info[i - 1] = 0; */
816
/* Py_BEGIN_ALLOW_THREADS */
817
/* ap_add_cgi_vars(req); */
818
/* Py_END_ALLOW_THREADS */
820
/* request_obj = (requestobject *)MpRequest_FromRequest(req); */
821
/* if (!request_obj) return NULL; */
823
/* /\* put the slash back in *\/ */
824
/* req->path_info[i - 1] = SLASH; */
825
/* req->path_info[i] = 0; */
827
/* /\* and also make PATH_INFO == req->subprocess_env *\/ */
828
/* apr_table_set(req->subprocess_env, "PATH_INFO", req->path_info); */
832
Py_BEGIN_ALLOW_THREADS
833
ap_add_cgi_vars(req);
836
request_obj = (requestobject *)MpRequest_FromRequest(req);
837
if (!request_obj) return NULL;
840
/* store the pointer to this object in request_config */
841
req_config = apr_pcalloc(req->pool, sizeof(py_req_config));
842
req_config->request_obj = request_obj;
843
req_config->dynhls = apr_hash_make(req->pool);
844
ap_set_module_config(req->request_config, &python_module, req_config);
846
/* register the clean up directive handler */
847
apr_pool_cleanup_register(req->pool, (void *)req,
848
python_cleanup_handler,
849
apr_pool_cleanup_null);
851
/* make a note of which subinterpreter we're running under */
853
request_obj->interpreter = apr_pstrdup(req->pool, interp_name);
855
request_obj->interpreter = apr_pstrdup(req->pool, MAIN_INTERPRETER);
857
/* make a note of which phase we are in right now */
858
Py_XDECREF(request_obj->phase);
860
request_obj->phase = PyString_FromString(phase);
862
request_obj->phase = PyString_FromString("");
868
** select_interpreter_name
871
* figure out the name of the interpreter we should be using
872
* If this is for a handler, then hle is required. If this is
873
* for a filter, then fname and is_input are required. If con
874
* is specified, then its a connection handler.
877
static const char *select_interp_name(request_rec *req, conn_rec *con, py_config *conf,
878
hl_entry *hle, const char *fname, int is_input)
882
if ((s = apr_table_get(conf->directives, "PythonInterpreter"))) {
883
/* forced by configuration */
887
if ((s = apr_table_get(conf->directives, "PythonInterpPerDirectory"))) {
889
/* base interpreter on directory where the file is found */
890
if (req && ap_is_directory(req->pool, req->filename))
891
return ap_make_dirstr_parent(req->pool,
892
apr_pstrcat(req->pool, req->filename,
895
if (req && req->filename)
896
return ap_make_dirstr_parent(req->pool, req->filename);
899
* In early phases of the request, req->filename is not known,
900
* so this would have to run in the global interpreter.
905
else if (apr_table_get(conf->directives, "PythonInterpPerDirective")) {
908
* base interpreter name on directory where the handler directive
909
* was last found. If it was in http.conf, then we will use the
910
* global interpreter.
917
fh = (py_handler *)apr_hash_get(conf->in_filters, fname,
918
APR_HASH_KEY_STRING);
921
fh = (py_handler *)apr_hash_get(conf->out_filters, fname,
922
APR_HASH_KEY_STRING);
930
if (s && (s[0] == '\0'))
936
/* - default: per server - */
938
return con->base_server->server_hostname;
940
return req->server->server_hostname;
949
* A generic python handler. Most handlers should use this.
952
static int python_handler(request_rec *req, char *phase)
955
PyObject *resultobject = NULL;
956
interpreterdata *idata;
957
requestobject *request_obj;
960
const char *interp_name = NULL;
962
hl_entry *hle = NULL;
963
hl_entry *dynhle = NULL;
965
py_req_config *req_conf;
967
/* get configuration */
968
conf = (py_config *) ap_get_module_config(req->per_dir_config,
970
/* get file extension */
971
if (req->filename) { /* filename is null until after transhandler */
972
/* get rid of preceeding path */
973
if ((ext = (char *)ap_strrchr_c(req->filename, '/')) == NULL)
978
ap_getword(req->pool, (const char **)&ext, '.');
980
ext = apr_pstrcat(req->pool, ".", ext, NULL);
983
/* is there an hlist entry, i.e. a handler? */
984
/* try with extension */
986
hle = (hl_entry *)apr_hash_get(conf->hlists,
987
apr_pstrcat(req->pool, phase, ext, NULL),
988
APR_HASH_KEY_STRING);
991
/* try without extension if we don't match */
993
hle = (hl_entry *)apr_hash_get(conf->hlists, phase, APR_HASH_KEY_STRING);
995
/* also blank out ext since we didn't succeed with it. this is tested
1000
req_conf = (py_req_config *) ap_get_module_config(req->request_config,
1003
dynhle = (hl_entry *)apr_hash_get(req_conf->dynhls, phase,
1004
APR_HASH_KEY_STRING);
1007
if (! (hle || dynhle)) {
1008
/* nothing to do here */
1012
/* determine interpreter to use */
1013
interp_name = select_interp_name(req, NULL, conf, hle, NULL, 0);
1015
/* get/create interpreter */
1016
idata = get_interpreter(interp_name, req->server);
1019
return HTTP_INTERNAL_SERVER_ERROR;
1021
/* create/acquire request object */
1022
request_obj = get_request_object(req, interp_name, phase);
1024
/* remember the extension if any. used by publisher */
1026
request_obj->extension = apr_pstrdup(req->pool, ext);
1028
/* create a hahdler list object */
1029
request_obj->hlo = (hlistobject *)MpHList_FromHLEntry(hle);
1031
/* add dynamically registered handlers, if any */
1033
MpHList_Append(request_obj->hlo, dynhle);
1037
* Here is where we call into Python!
1038
* This is the C equivalent of
1039
* >>> resultobject = obCallBack.Dispatch(request_object, phase)
1041
resultobject = PyObject_CallMethod(idata->obcallback, "HandlerDispatch", "O",
1044
/* release the lock and destroy tstate*/
1045
release_interpreter();
1047
if (! resultobject) {
1048
ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, 0, req,
1049
"python_handler: Dispatch() returned nothing.");
1050
return HTTP_INTERNAL_SERVER_ERROR;
1053
/* Attempt to analyze the result as a string indicating which
1055
if (! PyInt_Check(resultobject)) {
1056
ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, 0, req,
1057
"python_handler: Dispatch() returned non-integer.");
1058
return HTTP_INTERNAL_SERVER_ERROR;
1061
result = PyInt_AsLong(resultobject);
1063
/* authen handlers need one more thing
1064
* if authentication failed and this handler is not
1065
* authoritative, let the others handle it
1067
if (strcmp(phase, "PythonAuthenHandler") == 0) {
1068
/* This is a prevention measure for what is likely a bug
1069
in mod_auth.c whereby r->user is used even if null.
1070
XXX Remove in the future
1072
if (result == OK && !req->user) {
1073
ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, 0, req,
1074
"python_handler: After PythonAuthenHandler req->user is NULL. "
1075
"Assign something to req.user if returning OK to avoid this error.");
1076
return HTTP_INTERNAL_SERVER_ERROR;
1078
if (result == HTTP_UNAUTHORIZED)
1080
if (! conf->authoritative)
1084
* This will insert a WWW-Authenticate header
1085
* to let the browser know that we are using
1086
* Basic authentication. This function does check
1087
* to make sure that auth is indeed Basic, no
1088
* need to do that here.
1090
ap_note_basic_auth_failure(req);
1097
/* When the script sets an error status by using req.status,
1098
* it can then either provide its own HTML error message or have
1099
* Apache provide one. To have Apache provide one, you need to send
1100
* no output and return the error from the handler function. However,
1101
* if the script is providing HTML, then the return value of the
1102
* handler should be OK, else the user will get both the script
1103
* output and the Apache output.
1106
/* Another note on status. req->status is used to build req->status_line
1107
* unless status_line is not NULL. req->status has no effect on how the
1108
* server will behave. The error behaviour is dictated by the return
1109
* value of this handler. When the handler returns anything other than OK,
1110
* the server will display the error that matches req->status, unless it is
1111
* 200 (HTTP_OK), in which case it will just show the error matching the return
1112
* value. If the req->status and the return of the handle do not match,
1113
* then the server will first show what req->status shows, then it will
1114
* print "Additionally, X error was recieved", where X is the return code
1115
* of the handle. If the req->status or return code is a weird number that the
1116
* server doesn't know, it will default to 500 Internal Server Error.
1120
Py_XDECREF(resultobject);
1122
/* return the translated result (or default result) to the Server. */
1128
** python_cleanup_handler
1130
* Runs handler registered via PythonCleanupHandler. Clean ups
1131
* registered via register_cleanup() run in python_cleanup() above.
1134
static apr_status_t python_cleanup_handler(void *data)
1138
py_req_config *req_config;
1139
request_rec *req = (request_rec *)data;
1141
rc = python_handler((request_rec *)data, "PythonCleanupHandler");
1143
req_config = (py_req_config *) ap_get_module_config(req->request_config,
1146
if (req_config && req_config->request_obj) {
1148
interpreterdata *idata;
1149
requestobject *request_obj = req_config->request_obj;
1151
/* get interpreter */
1152
idata = get_interpreter(NULL, req->server);
1154
return APR_SUCCESS; /* this return code is ignored by httpd anyway */
1156
Py_XDECREF(request_obj);
1158
/* release interpreter */
1159
release_interpreter();
1167
** python_connection
1169
* connection handler
1172
static apr_status_t python_connection(conn_rec *con)
1175
PyObject *resultobject = NULL;
1176
interpreterdata *idata;
1177
connobject *conn_obj;
1180
const char *interp_name = NULL;
1181
hl_entry *hle = NULL;
1183
/* get configuration */
1184
conf = (py_config *) ap_get_module_config(con->base_server->module_config,
1187
/* is there a handler? */
1188
hle = (hl_entry *)apr_hash_get(conf->hlists, "PythonConnectionHandler",
1189
APR_HASH_KEY_STRING);
1192
/* nothing to do here */
1196
/* determine interpreter to use */
1197
interp_name = select_interp_name(NULL, con, conf, hle, NULL, 0);
1199
/* get/create interpreter */
1200
idata = get_interpreter(interp_name, con->base_server);
1203
return HTTP_INTERNAL_SERVER_ERROR;
1205
/* create connection object */
1206
conn_obj = (connobject*) MpConn_FromConn(con);
1208
/* create a hahdler list object */
1209
conn_obj->hlo = (hlistobject *)MpHList_FromHLEntry(hle);
1212
* Here is where we call into Python!
1213
* This is the C equivalent of
1214
* >>> resultobject = obCallBack.Dispatch(request_object, phase)
1216
resultobject = PyObject_CallMethod(idata->obcallback, "ConnectionDispatch", "O",
1219
/* release the lock and destroy tstate*/
1220
release_interpreter();
1222
if (! resultobject) {
1223
ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, 0, con->base_server,
1224
"python_connection: ConnectionDispatch() returned nothing.");
1225
return HTTP_INTERNAL_SERVER_ERROR;
1228
/* Attempt to analyze the result as a string indicating which
1230
if (! PyInt_Check(resultobject)) {
1231
ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, 0, con->base_server,
1232
"python_connection: ConnectionDispatch() returned non-integer.");
1233
return HTTP_INTERNAL_SERVER_ERROR;
1236
result = PyInt_AsLong(resultobject);
1240
Py_XDECREF(resultobject);
1242
/* return the translated result (or default result) to the Server. */
1252
static apr_status_t python_filter(int is_input, ap_filter_t *f,
1253
apr_bucket_brigade *bb,
1254
ap_input_mode_t mode,
1255
apr_read_type_e block,
1256
apr_size_t readbytes) {
1258
PyObject *resultobject = NULL;
1259
interpreterdata *idata;
1260
requestobject *request_obj;
1262
const char * interp_name = NULL;
1264
filterobject *filter;
1265
python_filter_ctx *ctx;
1268
/* we only allow request level filters so far */
1271
/* create ctx if not there yet */
1273
ctx = (python_filter_ctx *) apr_pcalloc(req->pool, sizeof(python_filter_ctx));
1274
f->ctx = (void *)ctx;
1277
ctx = (python_filter_ctx *) f->ctx;
1280
/* are we in transparent mode? transparent mode is on after an error,
1281
so a fitler can spit out an error without causing infinite loop */
1282
if (ctx->transparent) {
1284
return ap_get_brigade(f->next, bb, mode, block, readbytes);
1286
return ap_pass_brigade(f->next, bb);
1289
/* get configuration */
1290
conf = (py_config *) ap_get_module_config(req->per_dir_config,
1293
/* determine interpreter to use */
1294
interp_name = select_interp_name(req, NULL, conf, NULL, f->frec->name, is_input);
1296
/* get/create interpreter */
1297
idata = get_interpreter(interp_name, req->server);
1300
return HTTP_INTERNAL_SERVER_ERROR;
1302
/* create/acquire request object */
1303
request_obj = get_request_object(req, interp_name,
1304
is_input?"PythonInputFilter":"PythonOutputFilter");
1306
/* the name of python function to call */
1308
fh = apr_hash_get(conf->in_filters, f->frec->name, APR_HASH_KEY_STRING);
1310
fh = apr_hash_get(conf->out_filters, f->frec->name, APR_HASH_KEY_STRING);
1313
filter = (filterobject *)MpFilter_FromFilter(f, bb, is_input, mode, readbytes,
1314
fh->handler, fh->dir);
1316
Py_INCREF(request_obj);
1317
filter->request_obj = request_obj;
1320
* Here is where we call into Python!
1321
* This is the C equivalent of
1322
* >>> resultobject = obCallBack.FilterDispatch(filter_object)
1324
resultobject = PyObject_CallMethod(idata->obcallback, "FilterDispatch", "O",
1328
Py_XDECREF(resultobject);
1330
/* release interpreter */
1331
release_interpreter();
1337
** python_input_filter
1342
static apr_status_t python_input_filter(ap_filter_t *f,
1343
apr_bucket_brigade *bb,
1344
ap_input_mode_t mode,
1345
apr_read_type_e block,
1346
apr_off_t readbytes)
1348
return python_filter(1, f, bb, mode, block, readbytes);
1353
** python_output_filter
1358
static apr_status_t python_output_filter(ap_filter_t *f,
1359
apr_bucket_brigade *bb)
1361
return python_filter(0, f, bb, 0, 0, 0);
1366
** directive_PythonImport
1368
* This function called whenever PythonImport directive
1369
* is encountered. Note that this function does not actually
1370
* import anything, it just remembers what needs to be imported.
1371
* The actual importing is done later
1372
* in the ChildInitHandler. This is because this function here
1373
* is called before the python_init and before the suid and fork.
1376
static const char *directive_PythonImport(cmd_parms *cmd, void *mconfig,
1377
const char *module, const char *interp_name)
1379
py_config *conf = ap_get_module_config(cmd->server->module_config,
1383
conf->imports = hlist_new(cmd->pool, module, interp_name, 0);
1385
hlist_append(cmd->pool, conf->imports, module, interp_name, 0);
1392
** directive_PythonPath
1394
* This function called whenever PythonPath directive
1397
static const char *directive_PythonPath(cmd_parms *cmd, void *mconfig,
1400
const char *rc = python_directive(cmd, mconfig, "PythonPath", val);
1403
py_config *conf = ap_get_module_config(cmd->server->module_config,
1405
return python_directive(cmd, conf, "PythonPath", val);
1411
** directive_PythonInterpreter
1413
* This function called whenever PythonInterpreter directive
1416
static const char *directive_PythonInterpreter(cmd_parms *cmd, void *mconfig,
1418
const char *rc = python_directive(cmd, mconfig, "PythonInterpreter", val);
1421
py_config *conf = ap_get_module_config(cmd->server->module_config,
1423
return python_directive(cmd, conf, "PythonInterpreter", val);
1429
** directive_PythonDebug
1431
* This function called whenever PythonDebug directive
1434
static const char *directive_PythonDebug(cmd_parms *cmd, void *mconfig,
1436
const char *rc = python_directive_flag(mconfig, "PythonDebug", val);
1439
py_config *conf = ap_get_module_config(cmd->server->module_config,
1442
return python_directive_flag(conf, "PythonDebug", val);
1448
** directive_PythonEnablePdb
1450
* This function called whenever PythonEnablePdb directive
1453
static const char *directive_PythonEnablePdb(cmd_parms *cmd, void *mconfig,
1455
const char *rc = python_directive_flag(mconfig, "PythonEnablePdb", val);
1458
py_config *conf = ap_get_module_config(cmd->server->module_config,
1460
return python_directive_flag(conf, "PythonEnablePdb", val);
1466
** directive_PythonInterpPerDirective
1468
* This function called whenever PythonInterpPerDirective directive
1472
static const char *directive_PythonInterpPerDirective(cmd_parms *cmd,
1473
void *mconfig, int val) {
1474
const char *rc = python_directive_flag(mconfig, "PythonInterpPerDirective", val);
1477
py_config *conf = ap_get_module_config(cmd->server->module_config,
1479
return python_directive_flag(conf, "PythonInterpPerDirective", val);
1485
** directive_PythonInterpPerDirectory
1487
* This function called whenever PythonInterpPerDirectory directive
1491
static const char *directive_PythonInterpPerDirectory(cmd_parms *cmd,
1492
void *mconfig, int val) {
1493
return python_directive_flag(mconfig, "PythonInterpPerDirectory", val);
1497
** directive_PythonAutoReload
1499
* This function called whenever PythonAutoReload directive
1503
static const char *directive_PythonAutoReload(cmd_parms *cmd,
1504
void *mconfig, int val) {
1505
const char *rc = python_directive_flag(mconfig, "PythonAutoReload", val);
1508
py_config *conf = ap_get_module_config(cmd->server->module_config,
1510
return python_directive_flag(conf, "PythonAutoReload", val);
1516
** directive_PythonOption
1518
* This function is called every time PythonOption directive
1519
* is encountered. It sticks the option into a table containing
1520
* a list of options. This table is part of the local config structure.
1523
static const char *directive_PythonOption(cmd_parms *cmd, void * mconfig,
1524
const char *key, const char *val)
1529
conf = (py_config *) mconfig;
1530
apr_table_set(conf->options, key, val);
1532
conf = ap_get_module_config(cmd->server->module_config,
1534
apr_table_set(conf->options, key, val);
1540
** directive_PythonOptimize
1542
* This function called whenever PythonOptimize directive
1546
static const char *directive_PythonOptimize(cmd_parms *cmd, void *mconfig,
1548
if ((val) && (Py_OptimizeFlag != 2))
1549
Py_OptimizeFlag = 2;
1554
** Python*Handler directives
1558
static const char *directive_PythonAccessHandler(cmd_parms *cmd, void *mconfig,
1560
return python_directive_handler(cmd, mconfig, "PythonAccessHandler", val, NOTSILENT);
1562
static const char *directive_PythonAuthenHandler(cmd_parms *cmd, void *mconfig,
1564
return python_directive_handler(cmd, mconfig, "PythonAuthenHandler", val, NOTSILENT);
1566
static const char *directive_PythonAuthzHandler(cmd_parms *cmd, void *mconfig,
1568
return python_directive_handler(cmd, mconfig, "PythonAuthzHandler", val, NOTSILENT);
1570
static const char *directive_PythonCleanupHandler(cmd_parms *cmd, void *mconfig,
1572
return python_directive_handler(cmd, mconfig, "PythonCleanupHandler", val, NOTSILENT);
1574
static const char *directive_PythonConnectionHandler(cmd_parms *cmd, void *mconfig,
1576
py_config *conf = ap_get_module_config(cmd->server->module_config,
1578
return python_directive_handler(cmd, conf, "PythonConnectionHandler", val, NOTSILENT);
1580
static const char *directive_PythonFixupHandler(cmd_parms *cmd, void *mconfig,
1582
return python_directive_handler(cmd, mconfig, "PythonFixupHandler", val, NOTSILENT);
1584
static const char *directive_PythonHandler(cmd_parms *cmd, void *mconfig,
1586
return python_directive_handler(cmd, mconfig, "PythonHandler", val, NOTSILENT);
1588
static const char *directive_PythonHeaderParserHandler(cmd_parms *cmd, void *mconfig,
1590
return python_directive_handler(cmd, mconfig, "PythonHeaderParserHandler", val, NOTSILENT);
1592
static const char *directive_PythonInitHandler(cmd_parms *cmd, void *mconfig,
1594
return python_directive_handler(cmd, mconfig, "PythonInitHandler", val, NOTSILENT);
1596
static const char *directive_PythonHandlerModule(cmd_parms *cmd, void *mconfig,
1600
* This handler explodes into all other handlers, but their absense will be
1603
py_config *srv_conf = ap_get_module_config(cmd->server->module_config,
1606
python_directive_handler(cmd, mconfig, "PythonPostReadRequestHandler", val, SILENT);
1607
python_directive_handler(cmd, mconfig, "PythonTransHandler", val, SILENT);
1608
python_directive_handler(cmd, mconfig, "PythonHeaderParserHandler", val, SILENT);
1609
python_directive_handler(cmd, mconfig, "PythonAccessHandler", val, SILENT);
1610
python_directive_handler(cmd, mconfig, "PythonAuthzHandler", val, SILENT);
1611
python_directive_handler(cmd, mconfig, "PythonTypeHandler", val, SILENT);
1612
python_directive_handler(cmd, mconfig, "PythonHandler", val, SILENT);
1613
python_directive_handler(cmd, mconfig, "PythonInitHandler", val, SILENT);
1614
python_directive_handler(cmd, mconfig, "PythonLogHandler", val, SILENT);
1615
python_directive_handler(cmd, mconfig, "PythonCleanupHandler", val, SILENT);
1617
python_directive_handler(cmd, srv_conf, "PythonConnectionHandler", val, SILENT);
1621
static const char *directive_PythonPostReadRequestHandler(cmd_parms *cmd,
1625
if (strchr((char *)val, '|'))
1626
return "PythonPostReadRequestHandler does not accept \"| .ext\" syntax.";
1628
return python_directive_handler(cmd, mconfig, "PythonPostReadRequestHandler", val,NOTSILENT);
1631
static const char *directive_PythonTransHandler(cmd_parms *cmd, void *mconfig,
1633
if (strchr((char *)val, '|'))
1634
return "PythonTransHandler does not accept \"| .ext\" syntax.";
1636
return python_directive_handler(cmd, mconfig, "PythonTransHandler", val, NOTSILENT);
1638
static const char *directive_PythonTypeHandler(cmd_parms *cmd, void *mconfig,
1640
return python_directive_handler(cmd, mconfig, "PythonTypeHandler", val, NOTSILENT);
1642
static const char *directive_PythonLogHandler(cmd_parms *cmd, void *mconfig,
1644
return python_directive_handler(cmd, mconfig, "PythonLogHandler", val, NOTSILENT);
1646
static const char *directive_PythonInputFilter(cmd_parms *cmd, void *mconfig,
1647
const char *handler, const char *name) {
1651
ap_filter_rec_t *frec;
1654
name = apr_pstrdup(cmd->pool, handler);
1656
/* register the filter NOTE - this only works so long as the
1657
directive is only allowed in the main config. For .htaccess we
1658
would have to make sure not to duplicate this */
1659
frec = ap_register_input_filter(name, python_input_filter, NULL, AP_FTYPE_RESOURCE);
1661
conf = (py_config *) mconfig;
1663
fh = (py_handler *) apr_pcalloc(cmd->pool, sizeof(py_handler));
1664
fh->handler = (char *)handler;
1665
fh->dir = conf->config_dir;
1667
apr_hash_set(conf->in_filters, frec->name, APR_HASH_KEY_STRING, fh);
1672
static const char *directive_PythonOutputFilter(cmd_parms *cmd, void *mconfig,
1673
const char *handler, const char *name) {
1676
ap_filter_rec_t *frec;
1679
name = apr_pstrdup(cmd->pool, handler);
1681
/* register the filter NOTE - this only works so long as the
1682
directive is only allowed in the main config. For .htaccess we
1683
would have to make sure not to duplicate this */
1684
frec = ap_register_output_filter(name, python_output_filter, NULL, AP_FTYPE_RESOURCE);
1686
conf = (py_config *) mconfig;
1688
fh = (py_handler *) apr_pcalloc(cmd->pool, sizeof(py_handler));
1689
fh->handler = (char *)handler;
1690
fh->dir = conf->config_dir;
1692
apr_hash_set(conf->out_filters, frec->name, APR_HASH_KEY_STRING, fh);
1700
* We create a thread state just so we can run Py_Finalize()
1703
static apr_status_t python_finalize(void *data)
1705
interpreterdata *idata;
1707
idata = get_interpreter(NULL, NULL);
1714
PyEval_ReleaseLock();
1728
static void PythonChildInitHandler(apr_pool_t *p, server_rec *s)
1733
py_config *conf = ap_get_module_config(s->module_config, &python_module);
1734
py_global_config *glb;
1736
/* accordig Py C Docs we must do this after forking */
1739
PyEval_AcquireLock();
1743
PyEval_ReleaseLock();
1747
* Cleanups registered first will be called last. This will
1748
* end the Python interpreter *after* all other cleanups.
1751
apr_pool_cleanup_register(p, NULL, python_finalize, apr_pool_cleanup_null);
1757
/* this will return it if it already exists */
1758
glb = python_create_global_config(s);
1760
reinit_mutexes(s, p, glb);
1763
* remember the pool in a global var. we may use it
1764
* later in server.register_cleanup()
1766
child_init_pool = p;
1769
* Now run PythonImports
1772
hle = conf->imports;
1775
interpreterdata *idata;
1776
const char *module_name = hle->handler;
1777
const char *interp_name = hle->directory;
1780
/* get interpreter */
1781
idata = get_interpreter(interp_name, s);
1785
/* set up PythonPath */
1786
ppath = apr_table_get(conf->directives, "PythonPath");
1789
PyObject *globals, *locals, *newpath, *sys;
1791
globals = PyDict_New();
1792
locals = PyDict_New();
1794
sys = PyImport_ImportModuleEx("sys", globals, locals, NULL);
1798
PyDict_SetItemString(globals, "sys", sys);
1799
newpath = PyRun_String((char *)ppath, Py_eval_input, globals, locals);
1803
if (PyObject_SetAttrString(sys, "path", newpath) == -1)
1807
Py_XDECREF(newpath);
1808
Py_XDECREF(globals);
1814
release_interpreter();
1819
/* now import the specified module */
1820
if (! PyImport_ImportModule((char *)module_name)) {
1821
if (PyErr_Occurred())
1823
ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, 0, s,
1824
"directive_PythonImport: error importing %s", module_name);
1827
/* release interpreter */
1828
release_interpreter();
1835
static int PythonConnectionHandler(conn_rec *con) {
1836
return python_connection(con);
1838
static int PythonAccessHandler(request_rec *req) {
1839
return python_handler(req, "PythonAccessHandler");
1841
static int PythonAuthenHandler(request_rec *req) {
1842
return python_handler(req, "PythonAuthenHandler");
1844
static int PythonAuthzHandler(request_rec *req) {
1845
return python_handler(req, "PythonAuthzHandler");
1847
static int PythonFixupHandler(request_rec *req) {
1848
return python_handler(req, "PythonFixupHandler");
1850
static int PythonHandler(request_rec *req) {
1852
* In Apache 2.0, all handlers receive a request and have
1853
* a chance to process them. Therefore, we need to only
1854
* handle those that we explicitly agreed to handle (see
1857
if (!req->handler || (strcmp(req->handler, "mod_python") &&
1858
strcmp(req->handler, "python-program")))
1861
return python_handler(req, "PythonHandler");
1863
static int PythonHeaderParserHandler(request_rec *req) {
1866
/* run PythonInitHandler, if not already */
1867
if (! apr_table_get(req->notes, "python_init_ran")) {
1868
rc = python_handler(req, "PythonInitHandler");
1869
if ((rc != OK) && (rc != DECLINED))
1872
return python_handler(req, "PythonHeaderParserHandler");
1874
static int PythonLogHandler(request_rec *req) {
1875
return python_handler(req, "PythonLogHandler");
1877
static int PythonPostReadRequestHandler(request_rec *req) {
1880
/* run PythonInitHandler */
1881
rc = python_handler(req, "PythonInitHandler");
1882
apr_table_set(req->notes, "python_init_ran", "1");
1883
if ((rc != OK) && (rc != DECLINED))
1886
return python_handler(req, "PythonPostReadRequestHandler");
1888
static int PythonTransHandler(request_rec *req) {
1889
return python_handler(req, "PythonTransHandler");
1891
static int PythonTypeHandler(request_rec *req) {
1892
return python_handler(req, "PythonTypeHandler");
1895
static void python_register_hooks(apr_pool_t *p)
1898
/* module initializer */
1899
ap_hook_post_config(python_init,
1900
NULL, NULL, APR_HOOK_MIDDLE);
1902
/* [0] raw connection handling */
1903
ap_hook_process_connection(PythonConnectionHandler,
1904
NULL, NULL, APR_HOOK_MIDDLE);
1906
/* [1] post read_request handling */
1907
ap_hook_post_read_request(PythonPostReadRequestHandler,
1908
NULL, NULL, APR_HOOK_MIDDLE);
1910
/* [2] filename-to-URI translation */
1911
ap_hook_translate_name(PythonTransHandler,
1912
NULL, NULL, APR_HOOK_MIDDLE);
1914
/* [3] header parser */
1915
ap_hook_header_parser(PythonHeaderParserHandler,
1916
NULL, NULL, APR_HOOK_MIDDLE);
1918
/* [4] check access by host address */
1919
ap_hook_access_checker(PythonAccessHandler,
1920
NULL, NULL, APR_HOOK_MIDDLE);
1922
/* [5] check/validate user_id */
1923
ap_hook_check_user_id(PythonAuthenHandler,
1924
NULL, NULL, APR_HOOK_MIDDLE);
1926
/* [6] check user_id is valid *here* */
1927
ap_hook_auth_checker(PythonAuthzHandler,
1928
NULL, NULL, APR_HOOK_MIDDLE);
1930
/* [7] MIME type checker/setter */
1931
ap_hook_type_checker(PythonTypeHandler,
1932
NULL, NULL, APR_HOOK_MIDDLE);
1935
ap_hook_fixups(PythonFixupHandler,
1936
NULL, NULL, APR_HOOK_MIDDLE);
1938
/* [9] filter insert opportunity */
1939
/* ap_hook_insert_filter(PythonInsertFilter,
1940
NULL, NULL, APR_HOOK_MIDDLE); */
1942
/* [10] is for the handlers; see below */
1943
ap_hook_handler(PythonHandler, NULL, NULL, APR_HOOK_MIDDLE);
1946
ap_hook_log_transaction(PythonLogHandler,
1947
NULL, NULL, APR_HOOK_MIDDLE);
1949
/* process initializer */
1950
ap_hook_child_init(PythonChildInitHandler,
1951
NULL, NULL, APR_HOOK_MIDDLE);
1956
command_rec python_commands[] =
1959
"PythonAccessHandler", directive_PythonAccessHandler, NULL, OR_ALL,
1960
"Python access by host address handlers."),
1962
"PythonAuthenHandler", directive_PythonAuthenHandler, NULL, OR_ALL,
1963
"Python authentication handlers."),
1965
"PythonAutoReload", directive_PythonAutoReload, NULL, OR_ALL,
1966
"Set to Off if you don't want changed modules to reload."),
1968
"PythonAuthzHandler", directive_PythonAuthzHandler, NULL, OR_ALL,
1969
"Python authorization handlers."),
1971
"PythonCleanupHandler", directive_PythonCleanupHandler, NULL, OR_ALL,
1972
"Python clean up handlers."),
1974
"PythonConnectionHandler", directive_PythonConnectionHandler, NULL, RSRC_CONF,
1975
"Python connection handlers."),
1977
"PythonDebug", directive_PythonDebug, NULL, OR_ALL,
1978
"Send (most) Python error output to the client rather than logfile."),
1980
"PythonEnablePdb", directive_PythonEnablePdb, NULL, OR_ALL,
1981
"Run handlers in PDB (Python Debugger). Use with -DONE_PROCESS."),
1983
"PythonFixupHandler", directive_PythonFixupHandler, NULL, OR_ALL,
1984
"Python fixups handlers."),
1986
"PythonHandler", directive_PythonHandler, NULL, OR_ALL,
1987
"Python request handlers."),
1989
"PythonHeaderParserHandler", directive_PythonHeaderParserHandler, NULL, OR_ALL,
1990
"Python header parser handlers."),
1992
"PythonImport", directive_PythonImport, NULL, RSRC_CONF,
1993
"Module and interpreter name to be imported at server/child init time."),
1995
"PythonInitHandler", directive_PythonInitHandler, NULL, OR_ALL,
1996
"Python request initialization handler."),
1998
"PythonInterpPerDirective", directive_PythonInterpPerDirective, NULL, OR_ALL,
1999
"Create subinterpreters per directive."),
2001
"PythonInterpPerDirectory", directive_PythonInterpPerDirectory, NULL, OR_ALL,
2002
"Create subinterpreters per directory."),
2004
"PythonInterpreter", directive_PythonInterpreter, NULL, OR_ALL,
2005
"Forces a specific Python interpreter name to be used here."),
2007
"PythonLogHandler", directive_PythonLogHandler, NULL, OR_ALL,
2008
"Python logger handlers."),
2010
"PythonHandlerModule", directive_PythonHandlerModule, NULL, OR_ALL,
2011
"A Python module containing handlers to be executed."),
2013
"PythonOptimize", directive_PythonOptimize, NULL, RSRC_CONF,
2014
"Set the equivalent of the -O command-line flag on the interpreter."),
2016
"PythonOption", directive_PythonOption, NULL, OR_ALL,
2017
"Useful to pass custom configuration information to scripts."),
2019
"PythonPath", directive_PythonPath, NULL, OR_ALL,
2020
"Python path, specified in Python list syntax."),
2022
"PythonPostReadRequestHandler", directive_PythonPostReadRequestHandler,
2024
"Python post read-request handlers."),
2026
"PythonTransHandler", directive_PythonTransHandler, NULL, RSRC_CONF,
2027
"Python filename to URI translation handlers."),
2029
"PythonTypeHandler", directive_PythonTypeHandler, NULL, OR_ALL,
2030
"Python MIME type checker/setter handlers."),
2032
"PythonInputFilter", directive_PythonInputFilter, NULL, RSRC_CONF|ACCESS_CONF,
2033
"Python input filter."),
2035
"PythonOutputFilter", directive_PythonOutputFilter, NULL, RSRC_CONF|ACCESS_CONF,
2036
"Python output filter."),
2041
module python_module =
2043
STANDARD20_MODULE_STUFF,
2044
python_create_dir_config, /* per-directory config creator */
2045
python_merge_config, /* dir config merger */
2046
python_create_srv_config, /* server config creator */
2047
python_merge_config, /* server config merger */
2048
python_commands, /* command table */
2049
python_register_hooks /* register hooks */