~ubuntu-branches/ubuntu/warty/libapache2-mod-python/warty

« back to all changes in this revision

Viewing changes to src/mod_python.c

  • Committer: Bazaar Package Importer
  • Author(s): Thom May
  • Date: 2004-09-06 20:27:57 UTC
  • Revision ID: james.westby@ubuntu.com-20040906202757-yzpyu1bcabgpjtiu
Tags: upstream-3.1.3
ImportĀ upstreamĀ versionĀ 3.1.3

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright 2004 Apache Software Foundation 
 
3
 * 
 
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
 
7
 *
 
8
 *      http://www.apache.org/licenses/LICENSE-2.0
 
9
 *
 
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.
 
15
 *
 
16
 * Originally developed by Gregory Trubetskoy.
 
17
 *
 
18
 *
 
19
 * mod_python.c 
 
20
 *
 
21
 * $Id: mod_python.c,v 1.113 2004/02/16 19:47:27 grisha Exp $
 
22
 *
 
23
 * See accompanying documentation and source code comments 
 
24
 * for details.
 
25
 *
 
26
 */
 
27
 
 
28
#include "mod_python.h"
 
29
 
 
30
/* List of available Python obCallBacks/Interpreters
 
31
 * (In a Python dictionary) */
 
32
static PyObject * interpreters = NULL;
 
33
 
 
34
apr_pool_t *child_init_pool = NULL;
 
35
 
 
36
/**
 
37
 ** make_interpreter
 
38
 **
 
39
 *      Creates a new Python interpeter.
 
40
 */
 
41
 
 
42
static PyInterpreterState *make_interpreter(const char *name, server_rec *srv)
 
43
{
 
44
    PyThreadState *tstate;
 
45
    
 
46
    /* create a new interpeter */
 
47
    tstate = Py_NewInterpreter();
 
48
 
 
49
    if (! tstate) {
 
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?");
 
53
        return NULL;
 
54
    }
 
55
 
 
56
    /* release the thread state */
 
57
    PyThreadState_Swap(NULL); 
 
58
 
 
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?)
 
63
     */
 
64
    return tstate->interp;
 
65
}
 
66
 
 
67
/**
 
68
 ** make_obcallback
 
69
 **
 
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.
 
74
 */
 
75
 
 
76
static PyObject * make_obcallback(server_rec *s)
 
77
{
 
78
 
 
79
    PyObject *m;
 
80
    PyObject *obCallBack = NULL;
 
81
 
 
82
    /* This makes _apache appear imported, and subsequent
 
83
     * >>> import _apache 
 
84
     * will not give an error.
 
85
     */
 
86
    /* Py_InitModule("_apache", _apache_module_methods); */
 
87
    init_apache();
 
88
 
 
89
    /* Now execute the equivalent of
 
90
     * >>> import <module>
 
91
     * >>> <initstring>
 
92
     * in the __main__ module to start up Python.
 
93
     */
 
94
 
 
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);
 
98
        PyErr_Print();
 
99
    }
 
100
    
 
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);
 
104
        PyErr_Print();
 
105
    }
 
106
    
 
107
    return obCallBack;
 
108
}
 
109
 
 
110
/**
 
111
 ** get_interpreter
 
112
 **
 
113
 *      Get interpreter given its name. 
 
114
 *      NOTE: This function will acquire lock
 
115
 */
 
116
 
 
117
static interpreterdata *get_interpreter(const char *name, server_rec *srv)
 
118
{
 
119
    PyObject *p;
 
120
    PyThreadState *tstate;
 
121
    interpreterdata *idata = NULL;
 
122
    
 
123
    if (! name)
 
124
        name = MAIN_INTERPRETER;
 
125
 
 
126
#ifdef WITH_THREAD
 
127
    PyEval_AcquireLock();
 
128
#endif
 
129
 
 
130
    if (!interpreters)
 
131
        return NULL;
 
132
 
 
133
    p = PyDict_GetItemString(interpreters, (char *)name);
 
134
    if (!p)
 
135
    {
 
136
        PyInterpreterState *istate = make_interpreter(name, srv);
 
137
        if (istate) {
 
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);
 
144
        }
 
145
    }
 
146
    else {
 
147
        idata = (interpreterdata *)PyCObject_AsVoidPtr(p);
 
148
    }
 
149
 
 
150
#ifdef WITH_THREAD
 
151
    PyEval_ReleaseLock();
 
152
#endif
 
153
 
 
154
    if (! idata) {
 
155
        ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, 0, srv,
 
156
                     "get_interpreter: cannot get interpreter data (no more memory?)");
 
157
        return NULL;
 
158
    }
 
159
 
 
160
    /* create thread state and acquire lock */
 
161
    tstate = PyThreadState_New(idata->istate);
 
162
#ifdef WITH_THREAD
 
163
    PyEval_AcquireThread(tstate);
 
164
#else
 
165
    PyThreadState_Swap(tstate);
 
166
#endif
 
167
 
 
168
    if (!idata->obcallback) {
 
169
 
 
170
        idata->obcallback = make_obcallback(srv);
 
171
 
 
172
        if (!idata->obcallback) 
 
173
        {
 
174
#ifdef WITH_THREAD
 
175
            PyEval_ReleaseThread(tstate);
 
176
#endif
 
177
            PyThreadState_Delete(tstate);
 
178
            return NULL;
 
179
        }
 
180
    }
 
181
 
 
182
    return idata;
 
183
}
 
184
 
 
185
 
 
186
/**
 
187
 ** release_interpreter
 
188
 **
 
189
 *      Release interpreter.
 
190
 *      NOTE: This function will release lock
 
191
 */
 
192
 
 
193
static void release_interpreter(void) 
 
194
{
 
195
    PyThreadState *tstate = PyThreadState_Get();
 
196
#ifdef WITH_THREAD
 
197
    PyEval_ReleaseThread(tstate);
 
198
#endif
 
199
    PyThreadState_Delete(tstate);
 
200
}
 
201
 
 
202
/**
 
203
 ** pytho_cleanup
 
204
 **
 
205
 *     This function gets called for clean ups registered
 
206
 *     with register_cleanup(). Clean ups registered via
 
207
 *     PythonCleanupHandler run in python_cleanup_handler()
 
208
 *     below.
 
209
 */
 
210
 
 
211
apr_status_t python_cleanup(void *data)
 
212
{
 
213
    interpreterdata *idata;
 
214
 
 
215
    cleanup_info *ci = (cleanup_info *)data;
 
216
 
 
217
    /* get/create interpreter */
 
218
    if (ci->request_rec)
 
219
        idata = get_interpreter(ci->interpreter, ci->request_rec->server);
 
220
    else
 
221
        idata = get_interpreter(ci->interpreter, ci->server_rec);
 
222
 
 
223
    if (!idata) {
 
224
        Py_DECREF(ci->handler);
 
225
        Py_XDECREF(ci->data);
 
226
        free(ci);
 
227
        return APR_SUCCESS; /* this is ignored anyway */
 
228
    }
 
229
    
 
230
    /* 
 
231
     * Call the cleanup function.
 
232
     */
 
233
    if (! PyObject_CallFunction(ci->handler, "O", ci->data)) {
 
234
        PyObject *ptype;
 
235
        PyObject *pvalue;
 
236
        PyObject *ptb;
 
237
        PyObject *handler;
 
238
        PyObject *stype;
 
239
        PyObject *svalue;
 
240
 
 
241
        PyErr_Fetch(&ptype, &pvalue, &ptb);
 
242
        handler = PyObject_Str(ci->handler);
 
243
        stype = PyObject_Str(ptype);
 
244
        svalue = PyObject_Str(pvalue);
 
245
 
 
246
        Py_XDECREF(ptype);
 
247
        Py_XDECREF(pvalue);
 
248
        Py_XDECREF(ptb);
 
249
 
 
250
        if (ci->request_rec) {
 
251
            ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, 0, 
 
252
                          ci->request_rec,
 
253
                          "python_cleanup: Error calling cleanup object %s", 
 
254
                          PyString_AsString(handler));
 
255
            ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, 0,
 
256
                          ci->request_rec,
 
257
                          "    %s: %s", PyString_AsString(stype), 
 
258
                          PyString_AsString(svalue));
 
259
        }
 
260
        else {
 
261
            ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, 0,
 
262
                         ci->server_rec,
 
263
                         "python_cleanup: Error calling cleanup object %s", 
 
264
                         PyString_AsString(handler));
 
265
            ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, 0,
 
266
                         ci->server_rec,
 
267
                         "    %s: %s", PyString_AsString(stype), 
 
268
                         PyString_AsString(svalue));
 
269
        }
 
270
 
 
271
        Py_DECREF(handler);
 
272
        Py_DECREF(stype);
 
273
        Py_DECREF(svalue);
 
274
    }
 
275
 
 
276
    Py_DECREF(ci->handler);
 
277
    Py_DECREF(ci->data);
 
278
    free(ci);
 
279
 
 
280
    release_interpreter();
 
281
 
 
282
    return APR_SUCCESS;
 
283
}
 
284
 
 
285
static apr_status_t init_mutexes(server_rec *s, apr_pool_t *p, py_global_config *glb)
 
286
{
 
287
    int max_threads = 0;
 
288
    int max_procs = 0;
 
289
    int is_threaded = 0;
 
290
    int is_forked = 0;
 
291
    int max_clients;
 
292
    int locks;
 
293
    int n;
 
294
 
 
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
 
298
    */
 
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);
 
302
    }
 
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);
 
311
        }
 
312
    }
 
313
    max_clients = (((max_threads <= 0) ? 1 : max_threads) *
 
314
                   ((max_procs <= 0) ? 1 : max_procs));
 
315
 
 
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
 
322
       solution.
 
323
 
 
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!
 
327
    */
 
328
    locks = (max_clients > MAX_LOCKS) ? MAX_LOCKS : max_clients; 
 
329
 
 
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);
 
334
 
 
335
    glb->g_locks = (apr_global_mutex_t **) 
 
336
        apr_palloc(p, locks * sizeof(apr_global_mutex_t *));
 
337
    glb->nlocks = locks;
 
338
    glb->parent_pid = getpid();
 
339
 
 
340
    for (n=0; n<locks; n++) {
 
341
        apr_status_t rc;
 
342
        apr_global_mutex_t **mutex = glb->g_locks;
 
343
 
 
344
#if !defined(OS2) && !defined(WIN32) && !defined(BEOS) && !defined(NETWARE)
 
345
        char fname[255];
 
346
 
 
347
        snprintf(fname, 255, "/tmp/mpmtx%d%d", glb->parent_pid, n);
 
348
#else
 
349
        char *fname = NULL;
 
350
#endif
 
351
        rc = apr_global_mutex_create(&mutex[n], fname, APR_LOCK_DEFAULT, 
 
352
                                     p);
 
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);
 
357
            if (n > 1) {
 
358
                /* we were able to crate at least two, so lets just print a 
 
359
                   warning/hint and proceed
 
360
                */
 
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]);
 
370
                glb->nlocks = n-1;
 
371
                if (n > 2) {
 
372
                  apr_global_mutex_destroy(mutex[n-2]);
 
373
                  glb->nlocks = n-2;
 
374
                }
 
375
                break;
 
376
                
 
377
            }
 
378
            else {
 
379
                return rc;
 
380
            }
 
381
        }
 
382
        else {
 
383
 
 
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 */
 
388
 
 
389
#if !defined(OS2) && !defined(WIN32) && !defined(BEOS) && !defined(NETWARE)
 
390
            if  (!geteuid()) {
 
391
                chown(fname, unixd_config.user_id, -1);
 
392
                unixd_set_global_mutex_perms(mutex[n]);
 
393
            }
 
394
#endif
 
395
        }
 
396
    }
 
397
    return APR_SUCCESS;
 
398
}
 
399
 
 
400
static apr_status_t reinit_mutexes(server_rec *s, apr_pool_t *p, py_global_config *glb)
 
401
{
 
402
    int n;
 
403
 
 
404
    for (n=0; n< glb->nlocks; n++) {
 
405
        apr_status_t rc;
 
406
        apr_global_mutex_t **mutex = glb->g_locks;
 
407
 
 
408
#if !defined(OS2) && !defined(WIN32) && !defined(BEOS) && !defined(NETWARE)
 
409
        char fname[255];
 
410
        snprintf(fname, 255, "/tmp/mpmtx%d%d", glb->parent_pid, n);
 
411
#else
 
412
        char *fname = NULL;
 
413
#endif
 
414
        rc = apr_global_mutex_child_init(&mutex[n], fname, p);
 
415
 
 
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);
 
420
            return rc;
 
421
        }
 
422
    }
 
423
    return APR_SUCCESS;
 
424
}
 
425
 
 
426
/**
 
427
 ** python_create_global_config
 
428
 **
 
429
 *      This creates the part of config that survives
 
430
 *  server restarts
 
431
 *
 
432
 */
 
433
 
 
434
static py_global_config *python_create_global_config(server_rec *s)
 
435
{
 
436
    apr_pool_t *pool = s->process->pool;
 
437
    py_global_config *glb;
 
438
 
 
439
    /* do we already have it in s->process->pool? */
 
440
    apr_pool_userdata_get((void **)&glb, MP_CONFIG_KEY, pool);
 
441
 
 
442
    if (glb) {
 
443
        return glb; 
 
444
    }
 
445
 
 
446
    /* otherwise, create it */
 
447
 
 
448
    glb = (py_global_config *)apr_palloc(pool, sizeof(*glb));
 
449
 
 
450
    apr_pool_userdata_set(glb, MP_CONFIG_KEY,
 
451
                          apr_pool_cleanup_null,
 
452
                          pool);
 
453
 
 
454
    return glb;
 
455
}
 
456
 
 
457
/**
 
458
 ** python_init()
 
459
 **
 
460
 *      Called by Apache at mod_python initialization time.
 
461
 */
 
462
 
 
463
static int python_init(apr_pool_t *p, apr_pool_t *ptemp, 
 
464
                       apr_pool_t *plog, server_rec *s)
 
465
{
 
466
    char buff[255];
 
467
    void *data;
 
468
    py_global_config *glb;
 
469
    const char *userdata_key = "python_init";
 
470
    apr_status_t rc;
 
471
 
 
472
    apr_pool_userdata_get(&data, userdata_key, s->process->pool);
 
473
    if (!data) {
 
474
        apr_pool_userdata_set((const void *)1, userdata_key,
 
475
                              apr_pool_cleanup_null, s->process->pool);
 
476
        return OK;
 
477
    }
 
478
 
 
479
    /* mod_python version */
 
480
    ap_add_version_component(p, VERSION_COMPONENT);
 
481
    
 
482
    /* Python version */
 
483
    sprintf(buff, "Python/%.200s", strtok((char *)Py_GetVersion(), " "));
 
484
    ap_add_version_component(p, buff);
 
485
 
 
486
    /* global config */
 
487
    glb = python_create_global_config(s);
 
488
    if ((rc = init_mutexes(s, p, glb)) != APR_SUCCESS) {
 
489
        return rc;
 
490
    }
 
491
 
 
492
    /* initialize global Python interpreter if necessary */
 
493
    if (! Py_IsInitialized()) 
 
494
    {
 
495
 
 
496
        /* initialze the interpreter */
 
497
        Py_Initialize();
 
498
 
 
499
#ifdef WITH_THREAD
 
500
        /* create and acquire the interpreter lock */
 
501
        PyEval_InitThreads();
 
502
#endif
 
503
        /* Release the thread state because we will never use 
 
504
         * the main interpreter, only sub interpreters created later. */
 
505
        PyThreadState_Swap(NULL); 
 
506
 
 
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?");
 
512
            exit(1);
 
513
        }
 
514
        
 
515
#ifdef WITH_THREAD
 
516
        /* release the lock; now other threads can run */
 
517
        PyEval_ReleaseLock();
 
518
#endif
 
519
 
 
520
    }
 
521
    return OK;
 
522
}
 
523
 
 
524
/**
 
525
 ** python_create_config
 
526
 **
 
527
 *      Called by create_dir_config and create_srv_config
 
528
 */
 
529
 
 
530
static py_config *python_create_config(apr_pool_t *p)
 
531
{
 
532
    py_config *conf = 
 
533
        (py_config *) apr_pcalloc(p, sizeof(py_config));
 
534
 
 
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);
 
541
 
 
542
    return conf;
 
543
}
 
544
 
 
545
 
 
546
/**
 
547
 ** python_create_dir_config
 
548
 **
 
549
 *      Allocate memory and initialize the strucure that will
 
550
 *      hold configuration parametes.
 
551
 *
 
552
 *      This function is called on every hit it seems.
 
553
 */
 
554
 
 
555
static void *python_create_dir_config(apr_pool_t *p, char *dir)
 
556
{
 
557
 
 
558
    py_config *conf = python_create_config(p);
 
559
 
 
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);
 
563
    else
 
564
        conf->config_dir = apr_pstrdup(p, dir);
 
565
 
 
566
    return conf;
 
567
}
 
568
 
 
569
/**
 
570
 ** python_create_srv_config
 
571
 **
 
572
 *      Allocate memory and initialize the strucure that will
 
573
 *      hold configuration parametes.
 
574
 */
 
575
 
 
576
static void *python_create_srv_config(apr_pool_t *p, server_rec *srv)
 
577
{
 
578
 
 
579
    py_config *conf = python_create_config(p);
 
580
 
 
581
    return conf;
 
582
}
 
583
 
 
584
/**
 
585
 ** python_merge_dir_config
 
586
 **
 
587
 */
 
588
 
 
589
static void *python_merge_config(apr_pool_t *p, void *current_conf, 
 
590
                                 void *new_conf)
 
591
{
 
592
 
 
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;
 
597
 
 
598
    apr_hash_index_t *hi;
 
599
    char *key;
 
600
    apr_ssize_t klen;
 
601
    hl_entry *hle;
 
602
 
 
603
    /* we basically allow the local configuration to override global,
 
604
     * by first copying current values and then new values on top
 
605
     */
 
606
 
 
607
    /** create **/
 
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);
 
613
 
 
614
    /** copy current **/
 
615
 
 
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);
 
622
 
 
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);
 
626
    }
 
627
 
 
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);
 
631
    }
 
632
 
 
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);
 
636
    }
 
637
 
 
638
    /** copy new **/
 
639
 
 
640
    if (nc->authoritative != merged_conf->authoritative)
 
641
        merged_conf->authoritative = nc->authoritative;
 
642
    if (nc->config_dir)
 
643
        merged_conf->config_dir = apr_pstrdup(p, nc->config_dir);
 
644
 
 
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);
 
649
 
 
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);
 
653
    }
 
654
 
 
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);
 
658
    }
 
659
 
 
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);
 
663
    }
 
664
 
 
665
    return (void *) merged_conf;
 
666
}
 
667
 
 
668
/**
 
669
 ** python_directive
 
670
 **
 
671
 *  Called by non-handler directives
 
672
 *
 
673
 */
 
674
 
 
675
static const char *python_directive(cmd_parms *cmd, void * mconfig, 
 
676
                                    char *key, const char *val)
 
677
{
 
678
    py_config *conf;
 
679
   
 
680
    conf = (py_config *) mconfig;
 
681
    apr_table_set(conf->directives, key, val);
 
682
    
 
683
    return NULL;
 
684
}
 
685
 
 
686
static void python_directive_hl_add(apr_pool_t *p,
 
687
                                    apr_hash_t *hlists, 
 
688
                                    const char *phase, const char *handler, 
 
689
                                    const char *directory, const int silent)
 
690
{
 
691
    hl_entry *head;
 
692
    char *h;
 
693
 
 
694
    head = (hl_entry *)apr_hash_get(hlists, phase, APR_HASH_KEY_STRING);
 
695
 
 
696
    /* it's possible that handler is multiple handlers separated
 
697
       by white space */
 
698
 
 
699
    while (*(h = ap_getword_white(p, &handler)) != '\0') {
 
700
        if (!head) {
 
701
            head = hlist_new(p, h, directory, silent);
 
702
            apr_hash_set(hlists, phase, APR_HASH_KEY_STRING, head);
 
703
        }
 
704
        else {
 
705
            hlist_append(p, head, h, directory, silent);
 
706
        }
 
707
    }
 
708
}
 
709
 
 
710
/**
 
711
 ** python_directive_handler
 
712
 **
 
713
 *  Called by Python*Handler directives.
 
714
 *
 
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.
 
718
 *
 
719
 */
 
720
 
 
721
static const char *python_directive_handler(cmd_parms *cmd, py_config* conf, 
 
722
                                            char *key, const char *val, int silent)
 
723
{
 
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
 
731
     */
 
732
 
 
733
    const char *exts = val;
 
734
    val = ap_getword(cmd->pool, &exts, '|');
 
735
 
 
736
    if (*exts == '\0') {
 
737
        python_directive_hl_add(cmd->pool, conf->hlists, key, val,
 
738
                                conf->config_dir, silent);
 
739
    }
 
740
    else {
 
741
 
 
742
        char *ext;
 
743
 
 
744
        /* skip blanks */
 
745
        while (apr_isspace(*exts)) exts++;
 
746
        
 
747
        /* repeat for every extension */
 
748
        while (*(ext = ap_getword_white(cmd->pool, &exts)) != '\0') {
 
749
            char *s;
 
750
 
 
751
            /* append extention to the directive name */
 
752
            s = apr_pstrcat(cmd->pool, key, ext, NULL);
 
753
 
 
754
            python_directive_hl_add(cmd->pool, conf->hlists, s, val,
 
755
                                    conf->config_dir, silent);
 
756
        }
 
757
    }
 
758
 
 
759
    return NULL;
 
760
}
 
761
 
 
762
/**
 
763
 ** python_directive_flag
 
764
 **
 
765
 *  Called for FLAG directives.
 
766
 *
 
767
 */
 
768
 
 
769
static const char *python_directive_flag(void * mconfig, 
 
770
                                         char *key, int val)
 
771
{
 
772
    py_config *conf;
 
773
 
 
774
    conf = (py_config *) mconfig;
 
775
 
 
776
    if (val) {
 
777
        apr_table_set(conf->directives, key, "1");
 
778
    }
 
779
    else {
 
780
        apr_table_unset(conf->directives, key);
 
781
    }
 
782
 
 
783
    return NULL;
 
784
}
 
785
 
 
786
static apr_status_t python_cleanup_handler(void *data);
 
787
 
 
788
/**
 
789
 ** get_request_object
 
790
 **
 
791
 *      This creates or retrieves a previously created request object.
 
792
 *      The pointer to request object is stored in req->request_config.
 
793
 */
 
794
 
 
795
static requestobject *get_request_object(request_rec *req, const char *interp_name, char *phase)
 
796
{
 
797
    py_req_config *req_config;
 
798
    requestobject *request_obj = NULL;
 
799
 
 
800
    /* see if there is a request object already */
 
801
    req_config = (py_req_config *) ap_get_module_config(req->request_config,
 
802
                                                        &python_module);
 
803
 
 
804
    if (req_config) {
 
805
        request_obj = req_config->request_obj;
 
806
    }
 
807
    else {
 
808
/*         if ((req->path_info) &&  */
 
809
/*             (req->path_info[strlen(req->path_info) - 1] == SLASH)) */
 
810
/*         { */
 
811
/*             int i; */
 
812
/*             i = strlen(req->path_info); */
 
813
/*             /\* take out the slash *\/ */
 
814
/*             req->path_info[i - 1] = 0; */
 
815
 
 
816
/*             Py_BEGIN_ALLOW_THREADS */
 
817
/*             ap_add_cgi_vars(req); */
 
818
/*             Py_END_ALLOW_THREADS */
 
819
 
 
820
/*             request_obj = (requestobject *)MpRequest_FromRequest(req); */
 
821
/*             if (!request_obj) return NULL; */
 
822
 
 
823
/*             /\* put the slash back in *\/ */
 
824
/*             req->path_info[i - 1] = SLASH;  */
 
825
/*             req->path_info[i] = 0; */
 
826
 
 
827
/*             /\* and also make PATH_INFO == req->subprocess_env *\/ */
 
828
/*             apr_table_set(req->subprocess_env, "PATH_INFO", req->path_info); */
 
829
/*         }  */
 
830
/*         else  */
 
831
/*         {  */
 
832
            Py_BEGIN_ALLOW_THREADS
 
833
            ap_add_cgi_vars(req);
 
834
            Py_END_ALLOW_THREADS
 
835
 
 
836
            request_obj = (requestobject *)MpRequest_FromRequest(req);
 
837
            if (!request_obj) return NULL;
 
838
/*         } */
 
839
 
 
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);
 
845
 
 
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);
 
850
    }
 
851
    /* make a note of which subinterpreter we're running under */
 
852
    if (interp_name)
 
853
        request_obj->interpreter = apr_pstrdup(req->pool, interp_name);
 
854
    else
 
855
        request_obj->interpreter = apr_pstrdup(req->pool, MAIN_INTERPRETER);
 
856
 
 
857
    /* make a note of which phase we are in right now */
 
858
    Py_XDECREF(request_obj->phase);
 
859
    if (phase)
 
860
        request_obj->phase = PyString_FromString(phase);
 
861
    else
 
862
        request_obj->phase = PyString_FromString("");
 
863
 
 
864
    return request_obj;
 
865
}
 
866
 
 
867
/**
 
868
 ** select_interpreter_name
 
869
 **
 
870
 *      (internal)
 
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.
 
875
 */
 
876
 
 
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)
 
879
{
 
880
    const char *s;
 
881
 
 
882
    if ((s = apr_table_get(conf->directives, "PythonInterpreter"))) {
 
883
        /* forced by configuration */
 
884
        return s;
 
885
    }
 
886
    else {
 
887
        if ((s = apr_table_get(conf->directives, "PythonInterpPerDirectory"))) {
 
888
            
 
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, 
 
893
                                                         SLASH_S, NULL ));
 
894
            else {
 
895
                if (req && req->filename)
 
896
                    return ap_make_dirstr_parent(req->pool, req->filename);
 
897
                else
 
898
                    /* 
 
899
                     * In early phases of the request, req->filename is not known,
 
900
                     * so this would have to run in the global interpreter.
 
901
                     */
 
902
                    return NULL;
 
903
            }
 
904
        }
 
905
        else if (apr_table_get(conf->directives, "PythonInterpPerDirective")) {
 
906
 
 
907
            /* 
 
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.
 
911
             */
 
912
            
 
913
            py_handler *fh;
 
914
 
 
915
            if (fname) {
 
916
                if (is_input) {
 
917
                    fh = (py_handler *)apr_hash_get(conf->in_filters, fname,
 
918
                                                           APR_HASH_KEY_STRING);
 
919
                }
 
920
                else {
 
921
                    fh = (py_handler *)apr_hash_get(conf->out_filters, fname,
 
922
                                                           APR_HASH_KEY_STRING);
 
923
                }
 
924
                s = fh->dir;
 
925
            }
 
926
            else {
 
927
                s = hle->directory;
 
928
            }
 
929
 
 
930
            if (s && (s[0] == '\0'))
 
931
                return NULL;
 
932
            else
 
933
                return s;
 
934
        }
 
935
        else {
 
936
            /* - default: per server - */
 
937
            if (con)
 
938
                return con->base_server->server_hostname;
 
939
            else
 
940
                return req->server->server_hostname;
 
941
        }
 
942
    }
 
943
}
 
944
 
 
945
 
 
946
/**
 
947
 ** python_handler
 
948
 **
 
949
 *      A generic python handler. Most handlers should use this.
 
950
 */
 
951
 
 
952
static int python_handler(request_rec *req, char *phase)
 
953
{
 
954
 
 
955
    PyObject *resultobject = NULL;
 
956
    interpreterdata *idata;
 
957
    requestobject *request_obj;
 
958
    py_config * conf;
 
959
    int result;
 
960
    const char *interp_name = NULL;
 
961
    char *ext = NULL;
 
962
    hl_entry *hle = NULL;
 
963
    hl_entry *dynhle = NULL;
 
964
 
 
965
    py_req_config *req_conf;
 
966
 
 
967
    /* get configuration */
 
968
    conf = (py_config *) ap_get_module_config(req->per_dir_config, 
 
969
                                                  &python_module);
 
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)
 
974
            ext = req->filename;
 
975
        else 
 
976
            ++ext;
 
977
        /* get extension */
 
978
        ap_getword(req->pool, (const char **)&ext, '.');
 
979
        if (*ext != '\0')
 
980
            ext = apr_pstrcat(req->pool, ".", ext, NULL);
 
981
    }
 
982
 
 
983
    /* is there an hlist entry, i.e. a handler? */
 
984
    /* try with extension */
 
985
    if (ext) {
 
986
        hle = (hl_entry *)apr_hash_get(conf->hlists, 
 
987
                                       apr_pstrcat(req->pool, phase, ext, NULL),
 
988
                                       APR_HASH_KEY_STRING);
 
989
    }
 
990
 
 
991
    /* try without extension if we don't match */
 
992
    if (!hle) {
 
993
        hle = (hl_entry *)apr_hash_get(conf->hlists, phase, APR_HASH_KEY_STRING);
 
994
 
 
995
        /* also blank out ext since we didn't succeed with it. this is tested
 
996
           further below */
 
997
        ext = NULL;
 
998
    }
 
999
    
 
1000
    req_conf = (py_req_config *) ap_get_module_config(req->request_config,
 
1001
                                                      &python_module);
 
1002
    if (req_conf) {
 
1003
        dynhle = (hl_entry *)apr_hash_get(req_conf->dynhls, phase, 
 
1004
                                          APR_HASH_KEY_STRING);
 
1005
    }
 
1006
 
 
1007
    if (! (hle || dynhle)) {
 
1008
        /* nothing to do here */
 
1009
        return DECLINED;
 
1010
    }
 
1011
    
 
1012
    /* determine interpreter to use */
 
1013
    interp_name = select_interp_name(req, NULL, conf, hle, NULL, 0);
 
1014
 
 
1015
    /* get/create interpreter */
 
1016
    idata = get_interpreter(interp_name, req->server);
 
1017
 
 
1018
    if (!idata)
 
1019
        return HTTP_INTERNAL_SERVER_ERROR;
 
1020
    
 
1021
    /* create/acquire request object */
 
1022
    request_obj = get_request_object(req, interp_name, phase);
 
1023
 
 
1024
    /* remember the extension if any. used by publisher */
 
1025
    if (ext) 
 
1026
        request_obj->extension = apr_pstrdup(req->pool, ext);
 
1027
 
 
1028
    /* create a hahdler list object */
 
1029
    request_obj->hlo = (hlistobject *)MpHList_FromHLEntry(hle);
 
1030
 
 
1031
    /* add dynamically registered handlers, if any */
 
1032
    if (dynhle) {
 
1033
        MpHList_Append(request_obj->hlo, dynhle);
 
1034
    }
 
1035
 
 
1036
    /* 
 
1037
     * Here is where we call into Python!
 
1038
     * This is the C equivalent of
 
1039
     * >>> resultobject = obCallBack.Dispatch(request_object, phase)
 
1040
     */
 
1041
    resultobject = PyObject_CallMethod(idata->obcallback, "HandlerDispatch", "O", 
 
1042
                                       request_obj);
 
1043
     
 
1044
    /* release the lock and destroy tstate*/
 
1045
    release_interpreter();
 
1046
 
 
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;
 
1051
    }
 
1052
    else {
 
1053
        /* Attempt to analyze the result as a string indicating which
 
1054
           result to return */
 
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;
 
1059
        }
 
1060
        else {
 
1061
            result = PyInt_AsLong(resultobject);
 
1062
 
 
1063
            /* authen handlers need one more thing
 
1064
             * if authentication failed and this handler is not
 
1065
             * authoritative, let the others handle it
 
1066
             */
 
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
 
1071
                */
 
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;
 
1077
                }
 
1078
                if (result == HTTP_UNAUTHORIZED)
 
1079
                {
 
1080
                    if   (! conf->authoritative)
 
1081
                        result = DECLINED;
 
1082
                    else {
 
1083
                        /*
 
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.
 
1089
                         */
 
1090
                        ap_note_basic_auth_failure(req);
 
1091
                    }
 
1092
                }
 
1093
            }
 
1094
        }
 
1095
    } 
 
1096
 
 
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.
 
1104
     */
 
1105
 
 
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.
 
1117
     */
 
1118
 
 
1119
    /* clean up */
 
1120
    Py_XDECREF(resultobject);
 
1121
 
 
1122
    /* return the translated result (or default result) to the Server. */
 
1123
    return result;
 
1124
 
 
1125
}
 
1126
 
 
1127
/**
 
1128
 ** python_cleanup_handler
 
1129
 **
 
1130
 *    Runs handler registered via PythonCleanupHandler. Clean ups
 
1131
 *    registered via register_cleanup() run in python_cleanup() above.
 
1132
 */
 
1133
 
 
1134
static apr_status_t python_cleanup_handler(void *data)
 
1135
{
 
1136
 
 
1137
    apr_status_t rc;
 
1138
    py_req_config *req_config;
 
1139
    request_rec *req = (request_rec *)data;
 
1140
 
 
1141
    rc = python_handler((request_rec *)data, "PythonCleanupHandler");
 
1142
 
 
1143
    req_config = (py_req_config *) ap_get_module_config(req->request_config,
 
1144
                                                        &python_module);
 
1145
 
 
1146
    if (req_config && req_config->request_obj) {
 
1147
 
 
1148
        interpreterdata *idata;
 
1149
        requestobject *request_obj = req_config->request_obj;
 
1150
 
 
1151
        /* get interpreter */
 
1152
        idata = get_interpreter(NULL, req->server);
 
1153
        if (!idata)
 
1154
            return APR_SUCCESS; /* this return code is ignored by httpd anyway */
 
1155
 
 
1156
        Py_XDECREF(request_obj);
 
1157
 
 
1158
        /* release interpreter */
 
1159
        release_interpreter();
 
1160
    }
 
1161
 
 
1162
    return rc;
 
1163
}
 
1164
 
 
1165
 
 
1166
/**
 
1167
 ** python_connection
 
1168
 **
 
1169
 *    connection handler
 
1170
 */
 
1171
 
 
1172
static apr_status_t python_connection(conn_rec *con)
 
1173
{
 
1174
 
 
1175
    PyObject *resultobject = NULL;
 
1176
    interpreterdata *idata;
 
1177
    connobject *conn_obj;
 
1178
    py_config * conf;
 
1179
    int result;
 
1180
    const char *interp_name = NULL;
 
1181
    hl_entry *hle = NULL;
 
1182
 
 
1183
    /* get configuration */
 
1184
    conf = (py_config *) ap_get_module_config(con->base_server->module_config, 
 
1185
                                                  &python_module);
 
1186
 
 
1187
    /* is there a handler? */
 
1188
    hle = (hl_entry *)apr_hash_get(conf->hlists, "PythonConnectionHandler", 
 
1189
                                   APR_HASH_KEY_STRING);
 
1190
 
 
1191
    if (! hle) {
 
1192
        /* nothing to do here */
 
1193
        return DECLINED;
 
1194
    }
 
1195
    
 
1196
    /* determine interpreter to use */
 
1197
    interp_name = select_interp_name(NULL, con, conf, hle, NULL, 0);
 
1198
 
 
1199
    /* get/create interpreter */
 
1200
    idata = get_interpreter(interp_name, con->base_server);
 
1201
 
 
1202
    if (!idata)
 
1203
        return HTTP_INTERNAL_SERVER_ERROR;
 
1204
    
 
1205
    /* create connection object */
 
1206
    conn_obj = (connobject*) MpConn_FromConn(con);
 
1207
 
 
1208
    /* create a hahdler list object */
 
1209
    conn_obj->hlo = (hlistobject *)MpHList_FromHLEntry(hle);
 
1210
 
 
1211
    /* 
 
1212
     * Here is where we call into Python!
 
1213
     * This is the C equivalent of
 
1214
     * >>> resultobject = obCallBack.Dispatch(request_object, phase)
 
1215
     */
 
1216
    resultobject = PyObject_CallMethod(idata->obcallback, "ConnectionDispatch", "O", 
 
1217
                                       conn_obj);
 
1218
     
 
1219
    /* release the lock and destroy tstate*/
 
1220
    release_interpreter();
 
1221
 
 
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;
 
1226
    }
 
1227
    else {
 
1228
        /* Attempt to analyze the result as a string indicating which
 
1229
           result to return */
 
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;
 
1234
        }
 
1235
        else 
 
1236
            result = PyInt_AsLong(resultobject);
 
1237
    } 
 
1238
 
 
1239
    /* clean up */
 
1240
    Py_XDECREF(resultobject);
 
1241
 
 
1242
    /* return the translated result (or default result) to the Server. */
 
1243
    return result;
 
1244
}
 
1245
 
 
1246
/**
 
1247
 ** python_filter
 
1248
 **
 
1249
 *    filter
 
1250
 */
 
1251
 
 
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) {
 
1257
 
 
1258
    PyObject *resultobject = NULL;
 
1259
    interpreterdata *idata;
 
1260
    requestobject *request_obj;
 
1261
    py_config * conf;
 
1262
    const char * interp_name = NULL;
 
1263
    request_rec *req;
 
1264
    filterobject *filter;
 
1265
    python_filter_ctx *ctx;
 
1266
    py_handler *fh;
 
1267
 
 
1268
    /* we only allow request level filters so far */
 
1269
    req = f->r;
 
1270
 
 
1271
    /* create ctx if not there yet */
 
1272
    if (!f->ctx) {
 
1273
        ctx = (python_filter_ctx *) apr_pcalloc(req->pool, sizeof(python_filter_ctx));
 
1274
        f->ctx = (void *)ctx;
 
1275
    }
 
1276
    else {
 
1277
        ctx = (python_filter_ctx *) f->ctx;
 
1278
    }
 
1279
        
 
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) {
 
1283
        if (is_input) 
 
1284
            return ap_get_brigade(f->next, bb, mode, block, readbytes);
 
1285
        else
 
1286
            return ap_pass_brigade(f->next, bb);
 
1287
    }
 
1288
        
 
1289
    /* get configuration */
 
1290
    conf = (py_config *) ap_get_module_config(req->per_dir_config, 
 
1291
                                                  &python_module);
 
1292
 
 
1293
    /* determine interpreter to use */
 
1294
    interp_name = select_interp_name(req, NULL, conf, NULL, f->frec->name, is_input);
 
1295
 
 
1296
    /* get/create interpreter */
 
1297
    idata = get_interpreter(interp_name, req->server);
 
1298
   
 
1299
    if (!idata)
 
1300
        return HTTP_INTERNAL_SERVER_ERROR;
 
1301
 
 
1302
    /* create/acquire request object */
 
1303
    request_obj = get_request_object(req, interp_name, 
 
1304
                                     is_input?"PythonInputFilter":"PythonOutputFilter");
 
1305
    
 
1306
    /* the name of python function to call */
 
1307
    if (is_input)
 
1308
        fh = apr_hash_get(conf->in_filters, f->frec->name, APR_HASH_KEY_STRING);
 
1309
    else
 
1310
        fh = apr_hash_get(conf->out_filters, f->frec->name, APR_HASH_KEY_STRING);
 
1311
 
 
1312
    /* create filter */
 
1313
    filter = (filterobject *)MpFilter_FromFilter(f, bb, is_input, mode, readbytes,
 
1314
                                                 fh->handler, fh->dir);
 
1315
 
 
1316
    Py_INCREF(request_obj);
 
1317
    filter->request_obj = request_obj;
 
1318
 
 
1319
    /* 
 
1320
     * Here is where we call into Python!
 
1321
     * This is the C equivalent of
 
1322
     * >>> resultobject = obCallBack.FilterDispatch(filter_object)
 
1323
     */
 
1324
    resultobject = PyObject_CallMethod(idata->obcallback, "FilterDispatch", "O", 
 
1325
                                       filter);
 
1326
 
 
1327
    /* clean up */
 
1328
    Py_XDECREF(resultobject);
 
1329
 
 
1330
    /* release interpreter */
 
1331
    release_interpreter();
 
1332
    
 
1333
    return filter->rc;
 
1334
}
 
1335
 
 
1336
/**
 
1337
 ** python_input_filter
 
1338
 **
 
1339
 *    input filter
 
1340
 */
 
1341
 
 
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)
 
1347
{
 
1348
    return python_filter(1, f, bb, mode, block, readbytes);
 
1349
}
 
1350
 
 
1351
 
 
1352
/**
 
1353
 ** python_output_filter
 
1354
 **
 
1355
 *    output filter
 
1356
 */
 
1357
 
 
1358
static apr_status_t python_output_filter(ap_filter_t *f, 
 
1359
                                         apr_bucket_brigade *bb)
 
1360
{
 
1361
    return python_filter(0, f, bb, 0, 0, 0);
 
1362
}
 
1363
 
 
1364
 
 
1365
/**
 
1366
 ** directive_PythonImport
 
1367
 **
 
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.
 
1374
 *
 
1375
 */
 
1376
static const char *directive_PythonImport(cmd_parms *cmd, void *mconfig, 
 
1377
                                          const char *module, const char *interp_name) 
 
1378
{
 
1379
    py_config *conf = ap_get_module_config(cmd->server->module_config,
 
1380
                                           &python_module);
 
1381
 
 
1382
    if (!conf->imports)
 
1383
        conf->imports = hlist_new(cmd->pool, module, interp_name, 0);
 
1384
    else 
 
1385
        hlist_append(cmd->pool, conf->imports, module, interp_name, 0);
 
1386
 
 
1387
    return NULL;
 
1388
 
 
1389
}
 
1390
 
 
1391
/**
 
1392
 ** directive_PythonPath
 
1393
 **
 
1394
 *      This function called whenever PythonPath directive
 
1395
 *      is encountered.
 
1396
 */
 
1397
static const char *directive_PythonPath(cmd_parms *cmd, void *mconfig, 
 
1398
                                        const char *val) {
 
1399
 
 
1400
    const char *rc = python_directive(cmd, mconfig, "PythonPath", val);
 
1401
 
 
1402
    if (!rc) {
 
1403
        py_config *conf = ap_get_module_config(cmd->server->module_config,
 
1404
                                               &python_module);
 
1405
        return python_directive(cmd, conf, "PythonPath", val);
 
1406
    }
 
1407
    return rc;
 
1408
}
 
1409
 
 
1410
/**
 
1411
 ** directive_PythonInterpreter
 
1412
 **
 
1413
 *      This function called whenever PythonInterpreter directive
 
1414
 *      is encountered.
 
1415
 */
 
1416
static const char *directive_PythonInterpreter(cmd_parms *cmd, void *mconfig, 
 
1417
                                               const char *val) {
 
1418
    const char *rc = python_directive(cmd, mconfig, "PythonInterpreter", val);
 
1419
 
 
1420
    if (!rc) {
 
1421
        py_config *conf = ap_get_module_config(cmd->server->module_config,
 
1422
                                               &python_module);
 
1423
        return python_directive(cmd, conf, "PythonInterpreter", val);
 
1424
    }
 
1425
    return rc;
 
1426
}
 
1427
 
 
1428
/**
 
1429
 ** directive_PythonDebug
 
1430
 **
 
1431
 *      This function called whenever PythonDebug directive
 
1432
 *      is encountered.
 
1433
 */
 
1434
static const char *directive_PythonDebug(cmd_parms *cmd, void *mconfig,
 
1435
                                         int val) {
 
1436
    const char *rc = python_directive_flag(mconfig, "PythonDebug", val);
 
1437
 
 
1438
    if (!rc) {
 
1439
        py_config *conf = ap_get_module_config(cmd->server->module_config,
 
1440
                                               &python_module);
 
1441
 
 
1442
        return python_directive_flag(conf, "PythonDebug", val);
 
1443
    }
 
1444
    return rc;
 
1445
}
 
1446
 
 
1447
/**
 
1448
 ** directive_PythonEnablePdb
 
1449
 **
 
1450
 *      This function called whenever PythonEnablePdb directive
 
1451
 *      is encountered.
 
1452
 */
 
1453
static const char *directive_PythonEnablePdb(cmd_parms *cmd, void *mconfig,
 
1454
                                             int val) {
 
1455
    const char *rc = python_directive_flag(mconfig, "PythonEnablePdb", val);
 
1456
 
 
1457
    if (!rc) {
 
1458
        py_config *conf = ap_get_module_config(cmd->server->module_config,
 
1459
                                               &python_module);
 
1460
        return python_directive_flag(conf, "PythonEnablePdb", val);
 
1461
    }
 
1462
    return rc;
 
1463
}
 
1464
 
 
1465
/**
 
1466
 ** directive_PythonInterpPerDirective
 
1467
 **
 
1468
 *      This function called whenever PythonInterpPerDirective directive
 
1469
 *      is encountered.
 
1470
 */
 
1471
 
 
1472
static const char *directive_PythonInterpPerDirective(cmd_parms *cmd, 
 
1473
                                                      void *mconfig, int val) {
 
1474
    const char *rc = python_directive_flag(mconfig, "PythonInterpPerDirective", val);
 
1475
 
 
1476
    if (!rc) {
 
1477
        py_config *conf = ap_get_module_config(cmd->server->module_config,
 
1478
                                               &python_module);
 
1479
        return python_directive_flag(conf, "PythonInterpPerDirective", val);
 
1480
    }
 
1481
    return rc;
 
1482
}
 
1483
 
 
1484
/**
 
1485
 ** directive_PythonInterpPerDirectory
 
1486
 **
 
1487
 *      This function called whenever PythonInterpPerDirectory directive
 
1488
 *      is encountered.
 
1489
 */
 
1490
 
 
1491
static const char *directive_PythonInterpPerDirectory(cmd_parms *cmd, 
 
1492
                                                      void *mconfig, int val) {
 
1493
    return python_directive_flag(mconfig, "PythonInterpPerDirectory", val);
 
1494
}
 
1495
 
 
1496
/**
 
1497
 ** directive_PythonAutoReload
 
1498
 **
 
1499
 *      This function called whenever PythonAutoReload directive
 
1500
 *      is encountered.
 
1501
 */
 
1502
 
 
1503
static const char *directive_PythonAutoReload(cmd_parms *cmd, 
 
1504
                                              void *mconfig, int val) {
 
1505
    const char *rc = python_directive_flag(mconfig, "PythonAutoReload", val);
 
1506
 
 
1507
    if (!rc) {
 
1508
        py_config *conf = ap_get_module_config(cmd->server->module_config,
 
1509
                                               &python_module);
 
1510
        return python_directive_flag(conf, "PythonAutoReload", val);
 
1511
    }
 
1512
    return rc;
 
1513
}
 
1514
 
 
1515
/**
 
1516
 ** directive_PythonOption
 
1517
 **
 
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.
 
1521
 */
 
1522
 
 
1523
static const char *directive_PythonOption(cmd_parms *cmd, void * mconfig, 
 
1524
                                          const char *key, const char *val)
 
1525
{
 
1526
 
 
1527
    py_config *conf;
 
1528
 
 
1529
    conf = (py_config *) mconfig;
 
1530
    apr_table_set(conf->options, key, val);
 
1531
 
 
1532
    conf = ap_get_module_config(cmd->server->module_config,
 
1533
                                &python_module);
 
1534
    apr_table_set(conf->options, key, val);
 
1535
 
 
1536
    return NULL;
 
1537
}
 
1538
 
 
1539
/**
 
1540
 ** directive_PythonOptimize
 
1541
 **
 
1542
 *      This function called whenever PythonOptimize directive
 
1543
 *      is encountered.
 
1544
 */
 
1545
 
 
1546
static const char *directive_PythonOptimize(cmd_parms *cmd, void *mconfig,
 
1547
                                            int val) {
 
1548
    if ((val) && (Py_OptimizeFlag != 2))
 
1549
        Py_OptimizeFlag = 2;
 
1550
    return NULL;
 
1551
}
 
1552
 
 
1553
/**
 
1554
 ** Python*Handler directives
 
1555
 **
 
1556
 */
 
1557
 
 
1558
static const char *directive_PythonAccessHandler(cmd_parms *cmd, void *mconfig, 
 
1559
                                                 const char *val) {
 
1560
    return python_directive_handler(cmd, mconfig, "PythonAccessHandler", val, NOTSILENT);
 
1561
}
 
1562
static const char *directive_PythonAuthenHandler(cmd_parms *cmd, void *mconfig, 
 
1563
                                                 const char *val) {
 
1564
    return python_directive_handler(cmd, mconfig, "PythonAuthenHandler", val, NOTSILENT);
 
1565
}
 
1566
static const char *directive_PythonAuthzHandler(cmd_parms *cmd, void *mconfig, 
 
1567
                                                const char *val) {
 
1568
    return python_directive_handler(cmd, mconfig, "PythonAuthzHandler", val, NOTSILENT);
 
1569
}
 
1570
static const char *directive_PythonCleanupHandler(cmd_parms *cmd, void *mconfig, 
 
1571
                                                  const char *val) {
 
1572
    return python_directive_handler(cmd, mconfig, "PythonCleanupHandler", val, NOTSILENT);
 
1573
}
 
1574
static const char *directive_PythonConnectionHandler(cmd_parms *cmd, void *mconfig, 
 
1575
                                                     const char *val) {
 
1576
    py_config *conf = ap_get_module_config(cmd->server->module_config,
 
1577
                                           &python_module);
 
1578
    return python_directive_handler(cmd, conf, "PythonConnectionHandler", val, NOTSILENT);
 
1579
}
 
1580
static const char *directive_PythonFixupHandler(cmd_parms *cmd, void *mconfig, 
 
1581
                                                const char *val) {
 
1582
    return python_directive_handler(cmd, mconfig, "PythonFixupHandler", val, NOTSILENT);
 
1583
}
 
1584
static const char *directive_PythonHandler(cmd_parms *cmd, void *mconfig, 
 
1585
                                           const char *val) {
 
1586
    return python_directive_handler(cmd, mconfig, "PythonHandler", val, NOTSILENT);
 
1587
}
 
1588
static const char *directive_PythonHeaderParserHandler(cmd_parms *cmd, void *mconfig, 
 
1589
                                                       const char *val) {
 
1590
    return python_directive_handler(cmd, mconfig, "PythonHeaderParserHandler", val, NOTSILENT);
 
1591
}
 
1592
static const char *directive_PythonInitHandler(cmd_parms *cmd, void *mconfig,
 
1593
                                               const char *val) {
 
1594
    return python_directive_handler(cmd, mconfig, "PythonInitHandler", val, NOTSILENT);
 
1595
}
 
1596
static const char *directive_PythonHandlerModule(cmd_parms *cmd, void *mconfig,
 
1597
                                                 const char *val) {
 
1598
 
 
1599
    /* 
 
1600
     * This handler explodes into all other handlers, but their absense will be
 
1601
     * silently ignored.
 
1602
     */
 
1603
    py_config *srv_conf = ap_get_module_config(cmd->server->module_config,
 
1604
                                               &python_module);
 
1605
 
 
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);
 
1616
 
 
1617
    python_directive_handler(cmd, srv_conf, "PythonConnectionHandler", val, SILENT);
 
1618
 
 
1619
    return NULL;
 
1620
}
 
1621
static const char *directive_PythonPostReadRequestHandler(cmd_parms *cmd, 
 
1622
                                                          void * mconfig, 
 
1623
                                                          const char *val) {
 
1624
 
 
1625
    if (strchr((char *)val, '|'))
 
1626
        return "PythonPostReadRequestHandler does not accept \"| .ext\" syntax.";
 
1627
 
 
1628
    return python_directive_handler(cmd, mconfig, "PythonPostReadRequestHandler", val,NOTSILENT);
 
1629
}
 
1630
 
 
1631
static const char *directive_PythonTransHandler(cmd_parms *cmd, void *mconfig, 
 
1632
                                                const char *val) {
 
1633
    if (strchr((char *)val, '|'))
 
1634
        return "PythonTransHandler does not accept \"| .ext\" syntax.";
 
1635
 
 
1636
    return python_directive_handler(cmd, mconfig, "PythonTransHandler", val, NOTSILENT);
 
1637
}
 
1638
static const char *directive_PythonTypeHandler(cmd_parms *cmd, void *mconfig, 
 
1639
                                               const char *val) {
 
1640
    return python_directive_handler(cmd, mconfig, "PythonTypeHandler", val, NOTSILENT);
 
1641
}
 
1642
static const char *directive_PythonLogHandler(cmd_parms *cmd, void *mconfig, 
 
1643
                                              const char *val) {
 
1644
    return python_directive_handler(cmd, mconfig, "PythonLogHandler", val, NOTSILENT);
 
1645
}
 
1646
static const char *directive_PythonInputFilter(cmd_parms *cmd, void *mconfig, 
 
1647
                                               const char *handler, const char *name) {
 
1648
 
 
1649
    py_config *conf;
 
1650
    py_handler *fh;
 
1651
    ap_filter_rec_t *frec;
 
1652
 
 
1653
    if (!name)
 
1654
        name = apr_pstrdup(cmd->pool, handler);
 
1655
 
 
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);
 
1660
 
 
1661
    conf = (py_config *) mconfig;
 
1662
 
 
1663
    fh = (py_handler *) apr_pcalloc(cmd->pool, sizeof(py_handler));
 
1664
    fh->handler = (char *)handler;
 
1665
    fh->dir = conf->config_dir;
 
1666
 
 
1667
    apr_hash_set(conf->in_filters, frec->name, APR_HASH_KEY_STRING, fh);
 
1668
 
 
1669
    return NULL;
 
1670
}
 
1671
 
 
1672
static const char *directive_PythonOutputFilter(cmd_parms *cmd, void *mconfig, 
 
1673
                                                const char *handler, const char *name) {
 
1674
    py_config *conf;
 
1675
    py_handler *fh;
 
1676
    ap_filter_rec_t *frec;
 
1677
 
 
1678
    if (!name)
 
1679
        name = apr_pstrdup(cmd->pool, handler);
 
1680
 
 
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);
 
1685
 
 
1686
    conf = (py_config *) mconfig;
 
1687
    
 
1688
    fh = (py_handler *) apr_pcalloc(cmd->pool, sizeof(py_handler));
 
1689
    fh->handler = (char *)handler;
 
1690
    fh->dir = conf->config_dir;
 
1691
 
 
1692
    apr_hash_set(conf->out_filters, frec->name, APR_HASH_KEY_STRING, fh);
 
1693
 
 
1694
    return NULL;
 
1695
}
 
1696
 
 
1697
/**
 
1698
 ** python_finalize
 
1699
 **
 
1700
 *  We create a thread state just so we can run Py_Finalize()
 
1701
 */
 
1702
 
 
1703
static apr_status_t python_finalize(void *data)
 
1704
{
 
1705
    interpreterdata *idata;
 
1706
 
 
1707
    idata = get_interpreter(NULL, NULL);
 
1708
 
 
1709
    if (idata) {
 
1710
 
 
1711
        Py_Finalize();
 
1712
 
 
1713
#ifdef WITH_THREAD
 
1714
        PyEval_ReleaseLock();
 
1715
#endif
 
1716
 
 
1717
    }
 
1718
 
 
1719
    return APR_SUCCESS;
 
1720
 
 
1721
}
 
1722
 
 
1723
/**
 
1724
 ** Handlers
 
1725
 **
 
1726
 */
 
1727
 
 
1728
static void PythonChildInitHandler(apr_pool_t *p, server_rec *s)
 
1729
{
 
1730
 
 
1731
 
 
1732
    hl_entry *hle;
 
1733
    py_config *conf = ap_get_module_config(s->module_config, &python_module);
 
1734
    py_global_config *glb;
 
1735
 
 
1736
    /* accordig Py C Docs we must do this after forking */
 
1737
 
 
1738
#ifdef WITH_THREAD
 
1739
    PyEval_AcquireLock();
 
1740
#endif
 
1741
    PyOS_AfterFork();
 
1742
#ifdef WITH_THREAD
 
1743
    PyEval_ReleaseLock();
 
1744
#endif
 
1745
 
 
1746
    /*
 
1747
     * Cleanups registered first will be called last. This will
 
1748
     * end the Python interpreter *after* all other cleanups.
 
1749
     */
 
1750
 
 
1751
    apr_pool_cleanup_register(p, NULL, python_finalize, apr_pool_cleanup_null);
 
1752
 
 
1753
    /*
 
1754
     * Reinit mutexes
 
1755
     */
 
1756
 
 
1757
    /* this will return it if it already exists */
 
1758
    glb = python_create_global_config(s);
 
1759
 
 
1760
    reinit_mutexes(s, p, glb);
 
1761
 
 
1762
    /*
 
1763
     * remember the pool in a global var. we may use it
 
1764
     * later in server.register_cleanup()
 
1765
     */
 
1766
    child_init_pool = p;
 
1767
 
 
1768
    /*
 
1769
     * Now run PythonImports
 
1770
     */
 
1771
 
 
1772
    hle = conf->imports;
 
1773
    while(hle) {
 
1774
 
 
1775
        interpreterdata *idata;
 
1776
        const char *module_name = hle->handler;
 
1777
        const char *interp_name = hle->directory;
 
1778
        const char *ppath;
 
1779
 
 
1780
        /* get interpreter */
 
1781
        idata = get_interpreter(interp_name, s);
 
1782
        if (!idata)
 
1783
            return;
 
1784
 
 
1785
        /* set up PythonPath */
 
1786
        ppath = apr_table_get(conf->directives, "PythonPath");
 
1787
        if (ppath) {
 
1788
 
 
1789
            PyObject *globals, *locals, *newpath, *sys;
 
1790
            
 
1791
            globals = PyDict_New();
 
1792
            locals = PyDict_New();
 
1793
            
 
1794
            sys = PyImport_ImportModuleEx("sys", globals, locals, NULL);
 
1795
            if (!sys)
 
1796
                goto err;
 
1797
 
 
1798
            PyDict_SetItemString(globals, "sys", sys);
 
1799
            newpath = PyRun_String((char *)ppath, Py_eval_input, globals, locals);
 
1800
            if (!newpath)
 
1801
                goto err;
 
1802
 
 
1803
            if (PyObject_SetAttrString(sys, "path", newpath) == -1)
 
1804
                goto err;
 
1805
 
 
1806
            Py_XDECREF(sys);
 
1807
            Py_XDECREF(newpath);
 
1808
            Py_XDECREF(globals);
 
1809
            Py_XDECREF(locals);
 
1810
            goto success;
 
1811
 
 
1812
        err:
 
1813
            PyErr_Print();
 
1814
            release_interpreter();
 
1815
            return;
 
1816
        }
 
1817
 
 
1818
    success:
 
1819
        /* now import the specified module */
 
1820
        if (! PyImport_ImportModule((char *)module_name)) {
 
1821
            if (PyErr_Occurred())
 
1822
                PyErr_Print();
 
1823
            ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, 0, s,
 
1824
                         "directive_PythonImport: error importing %s", module_name);
 
1825
        }
 
1826
 
 
1827
        /* release interpreter */
 
1828
        release_interpreter();
 
1829
 
 
1830
        /* next module */
 
1831
        hle = hle->next;
 
1832
    }
 
1833
}
 
1834
 
 
1835
static int PythonConnectionHandler(conn_rec *con) {
 
1836
    return python_connection(con);
 
1837
}
 
1838
static int PythonAccessHandler(request_rec *req) {
 
1839
    return python_handler(req, "PythonAccessHandler");
 
1840
}
 
1841
static int PythonAuthenHandler(request_rec *req) {
 
1842
    return python_handler(req, "PythonAuthenHandler");
 
1843
}
 
1844
static int PythonAuthzHandler(request_rec *req) {
 
1845
    return python_handler(req, "PythonAuthzHandler");
 
1846
}
 
1847
static int PythonFixupHandler(request_rec *req) {
 
1848
    return python_handler(req, "PythonFixupHandler");
 
1849
}
 
1850
static int PythonHandler(request_rec *req) {
 
1851
    /*
 
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 
 
1855
     * above).
 
1856
     */
 
1857
    if (!req->handler || (strcmp(req->handler, "mod_python") &&
 
1858
                          strcmp(req->handler, "python-program")))
 
1859
        return DECLINED;
 
1860
 
 
1861
    return python_handler(req, "PythonHandler");
 
1862
}
 
1863
static int PythonHeaderParserHandler(request_rec *req) {
 
1864
    int rc;
 
1865
    
 
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))
 
1870
            return rc;
 
1871
    }
 
1872
    return python_handler(req, "PythonHeaderParserHandler");
 
1873
}
 
1874
static int PythonLogHandler(request_rec *req) {
 
1875
    return python_handler(req, "PythonLogHandler");
 
1876
}
 
1877
static int PythonPostReadRequestHandler(request_rec *req) {
 
1878
    int rc;
 
1879
 
 
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))
 
1884
        return rc;
 
1885
 
 
1886
    return python_handler(req, "PythonPostReadRequestHandler");
 
1887
}
 
1888
static int PythonTransHandler(request_rec *req) {
 
1889
    return python_handler(req, "PythonTransHandler");
 
1890
}
 
1891
static int PythonTypeHandler(request_rec *req) {
 
1892
    return python_handler(req, "PythonTypeHandler");
 
1893
}
 
1894
 
 
1895
static void python_register_hooks(apr_pool_t *p)
 
1896
{
 
1897
 
 
1898
    /* module initializer */ 
 
1899
    ap_hook_post_config(python_init, 
 
1900
                        NULL, NULL, APR_HOOK_MIDDLE);
 
1901
 
 
1902
    /* [0] raw connection handling */ 
 
1903
    ap_hook_process_connection(PythonConnectionHandler, 
 
1904
                               NULL, NULL, APR_HOOK_MIDDLE);
 
1905
 
 
1906
    /* [1] post read_request handling */ 
 
1907
    ap_hook_post_read_request(PythonPostReadRequestHandler, 
 
1908
                              NULL, NULL, APR_HOOK_MIDDLE);
 
1909
 
 
1910
    /* [2] filename-to-URI translation */ 
 
1911
    ap_hook_translate_name(PythonTransHandler,
 
1912
                           NULL, NULL, APR_HOOK_MIDDLE);
 
1913
 
 
1914
    /* [3] header parser */ 
 
1915
    ap_hook_header_parser(PythonHeaderParserHandler,
 
1916
                          NULL, NULL, APR_HOOK_MIDDLE); 
 
1917
 
 
1918
    /* [4] check access by host address */ 
 
1919
    ap_hook_access_checker(PythonAccessHandler,
 
1920
                           NULL, NULL, APR_HOOK_MIDDLE);
 
1921
 
 
1922
    /* [5] check/validate user_id */ 
 
1923
    ap_hook_check_user_id(PythonAuthenHandler,
 
1924
                          NULL, NULL, APR_HOOK_MIDDLE);
 
1925
 
 
1926
    /* [6] check user_id is valid *here* */ 
 
1927
    ap_hook_auth_checker(PythonAuthzHandler,
 
1928
                         NULL, NULL, APR_HOOK_MIDDLE); 
 
1929
 
 
1930
    /* [7] MIME type checker/setter */ 
 
1931
    ap_hook_type_checker(PythonTypeHandler,
 
1932
                         NULL, NULL, APR_HOOK_MIDDLE);
 
1933
 
 
1934
    /* [8] fixups */ 
 
1935
    ap_hook_fixups(PythonFixupHandler,
 
1936
                   NULL, NULL, APR_HOOK_MIDDLE);
 
1937
 
 
1938
    /* [9] filter insert opportunity */
 
1939
    /* ap_hook_insert_filter(PythonInsertFilter,
 
1940
       NULL, NULL, APR_HOOK_MIDDLE); */
 
1941
 
 
1942
    /* [10] is for the handlers; see below */
 
1943
    ap_hook_handler(PythonHandler, NULL, NULL, APR_HOOK_MIDDLE);
 
1944
 
 
1945
    /* [11] logger */ 
 
1946
    ap_hook_log_transaction(PythonLogHandler,
 
1947
                            NULL, NULL, APR_HOOK_MIDDLE);
 
1948
 
 
1949
    /* process initializer */ 
 
1950
    ap_hook_child_init(PythonChildInitHandler,
 
1951
                       NULL, NULL, APR_HOOK_MIDDLE);
 
1952
 
 
1953
}
 
1954
 
 
1955
/* command table */
 
1956
command_rec python_commands[] =
 
1957
{
 
1958
    AP_INIT_RAW_ARGS(
 
1959
        "PythonAccessHandler", directive_PythonAccessHandler, NULL, OR_ALL,
 
1960
        "Python access by host address handlers."),
 
1961
    AP_INIT_RAW_ARGS(
 
1962
        "PythonAuthenHandler", directive_PythonAuthenHandler, NULL, OR_ALL,
 
1963
        "Python authentication handlers."),
 
1964
    AP_INIT_FLAG(
 
1965
        "PythonAutoReload", directive_PythonAutoReload, NULL, OR_ALL,
 
1966
        "Set to Off if you don't want changed modules to reload."),
 
1967
    AP_INIT_RAW_ARGS(
 
1968
        "PythonAuthzHandler", directive_PythonAuthzHandler, NULL, OR_ALL,
 
1969
        "Python authorization handlers."),
 
1970
    AP_INIT_RAW_ARGS(
 
1971
        "PythonCleanupHandler", directive_PythonCleanupHandler, NULL, OR_ALL,
 
1972
        "Python clean up handlers."),
 
1973
    AP_INIT_RAW_ARGS(
 
1974
        "PythonConnectionHandler", directive_PythonConnectionHandler, NULL, RSRC_CONF,
 
1975
        "Python connection handlers."),
 
1976
    AP_INIT_FLAG(
 
1977
        "PythonDebug", directive_PythonDebug, NULL, OR_ALL,
 
1978
        "Send (most) Python error output to the client rather than logfile."),
 
1979
    AP_INIT_FLAG(
 
1980
        "PythonEnablePdb", directive_PythonEnablePdb, NULL, OR_ALL,
 
1981
        "Run handlers in PDB (Python Debugger). Use with -DONE_PROCESS."),
 
1982
    AP_INIT_RAW_ARGS(
 
1983
        "PythonFixupHandler", directive_PythonFixupHandler, NULL, OR_ALL,
 
1984
        "Python fixups handlers."),
 
1985
    AP_INIT_RAW_ARGS(
 
1986
        "PythonHandler", directive_PythonHandler, NULL, OR_ALL,
 
1987
        "Python request handlers."),
 
1988
    AP_INIT_RAW_ARGS(
 
1989
        "PythonHeaderParserHandler", directive_PythonHeaderParserHandler, NULL, OR_ALL,
 
1990
        "Python header parser handlers."),
 
1991
    AP_INIT_TAKE2(
 
1992
        "PythonImport", directive_PythonImport, NULL, RSRC_CONF,
 
1993
        "Module and interpreter name to be imported at server/child init time."),
 
1994
    AP_INIT_RAW_ARGS(
 
1995
        "PythonInitHandler", directive_PythonInitHandler, NULL, OR_ALL,
 
1996
        "Python request initialization handler."),
 
1997
    AP_INIT_FLAG(
 
1998
        "PythonInterpPerDirective", directive_PythonInterpPerDirective, NULL, OR_ALL,
 
1999
        "Create subinterpreters per directive."),
 
2000
    AP_INIT_FLAG(
 
2001
        "PythonInterpPerDirectory", directive_PythonInterpPerDirectory, NULL, OR_ALL,
 
2002
        "Create subinterpreters per directory."),
 
2003
    AP_INIT_TAKE1(
 
2004
        "PythonInterpreter", directive_PythonInterpreter, NULL, OR_ALL,
 
2005
        "Forces a specific Python interpreter name to be used here."),
 
2006
    AP_INIT_RAW_ARGS(
 
2007
        "PythonLogHandler", directive_PythonLogHandler, NULL, OR_ALL,
 
2008
        "Python logger handlers."),
 
2009
    AP_INIT_RAW_ARGS(
 
2010
        "PythonHandlerModule", directive_PythonHandlerModule, NULL, OR_ALL,
 
2011
        "A Python module containing handlers to be executed."),
 
2012
    AP_INIT_FLAG(
 
2013
        "PythonOptimize", directive_PythonOptimize, NULL, RSRC_CONF,
 
2014
        "Set the equivalent of the -O command-line flag on the interpreter."),
 
2015
    AP_INIT_TAKE2(
 
2016
        "PythonOption", directive_PythonOption, NULL, OR_ALL,
 
2017
        "Useful to pass custom configuration information to scripts."),
 
2018
    AP_INIT_TAKE1(
 
2019
        "PythonPath", directive_PythonPath, NULL, OR_ALL,
 
2020
        "Python path, specified in Python list syntax."),
 
2021
    AP_INIT_RAW_ARGS(
 
2022
        "PythonPostReadRequestHandler", directive_PythonPostReadRequestHandler, 
 
2023
        NULL, RSRC_CONF,
 
2024
        "Python post read-request handlers."),
 
2025
    AP_INIT_RAW_ARGS(
 
2026
        "PythonTransHandler", directive_PythonTransHandler, NULL, RSRC_CONF,
 
2027
        "Python filename to URI translation handlers."),
 
2028
    AP_INIT_RAW_ARGS(
 
2029
        "PythonTypeHandler", directive_PythonTypeHandler, NULL, OR_ALL,
 
2030
        "Python MIME type checker/setter handlers."),
 
2031
    AP_INIT_TAKE12(
 
2032
        "PythonInputFilter", directive_PythonInputFilter, NULL, RSRC_CONF|ACCESS_CONF,
 
2033
        "Python input filter."),
 
2034
    AP_INIT_TAKE12(
 
2035
        "PythonOutputFilter", directive_PythonOutputFilter, NULL, RSRC_CONF|ACCESS_CONF,
 
2036
        "Python output filter."),
 
2037
    {NULL}
 
2038
};
 
2039
 
 
2040
 
 
2041
module python_module =
 
2042
{
 
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 */
 
2050
};
 
2051
    
 
2052
 
 
2053
 
 
2054
 
 
2055
 
 
2056
 
 
2057
 
 
2058