~ubuntu-branches/ubuntu/karmic/libapache2-mod-python/karmic-updates

« back to all changes in this revision

Viewing changes to src/mod_python.c

  • Committer: Bazaar Package Importer
  • Author(s): Piotr Ozarowski
  • Date: 2007-02-21 18:24:29 UTC
  • mfrom: (1.1.8 feisty)
  • Revision ID: james.westby@ubuntu.com-20070221182429-9okop7e0qpi24l85
Tags: 3.2.10-4
* Added XS-Vcs-Svn field
* Removed "db_purge" part from libapache2-mod-python.postrm
  (dh_installdebconf is generating a rule that will not fail if debconf is
  already removed)
* Added initial Spanish debconf translation from Manuel Porras Peralta.
  (closes: #411235)
* Added initial Portuguese debconf translation from Pedro Ribeiro.
  (closes: #411742)
* Added initial Galician debconf translation from Jacobo Tarrio.
  (closes: #411831)

Show diffs side-by-side

added added

removed removed

Lines of Context:
18
18
 *
19
19
 * mod_python.c 
20
20
 *
21
 
 * $Id: mod_python.c,v 1.113 2004/02/16 19:47:27 grisha Exp $
 
21
 * $Id: mod_python.c 397813 2006-04-28 09:06:55Z grahamd $
22
22
 *
23
23
 * See accompanying documentation and source code comments 
24
24
 * for details.
31
31
 * (In a Python dictionary) */
32
32
static PyObject * interpreters = NULL;
33
33
 
 
34
#if APR_HAS_THREADS
 
35
static apr_thread_mutex_t* interpreters_lock = 0;
 
36
#endif
 
37
 
34
38
apr_pool_t *child_init_pool = NULL;
35
39
 
36
40
/**
37
41
 ** make_interpreter
38
42
 **
39
 
 *      Creates a new Python interpeter.
 
43
 *      Creates a new Python interpreter.
40
44
 */
41
45
 
42
46
static PyInterpreterState *make_interpreter(const char *name, server_rec *srv)
73
77
 *      the reference to obCallBack.
74
78
 */
75
79
 
76
 
static PyObject * make_obcallback(server_rec *s)
 
80
static PyObject * make_obcallback(char *name, server_rec *s)
77
81
{
78
82
 
79
 
    PyObject *m;
 
83
    PyObject *m = NULL;
80
84
    PyObject *obCallBack = NULL;
81
85
 
82
86
    /* This makes _apache appear imported, and subsequent
93
97
     */
94
98
 
95
99
    if (! ((m = PyImport_ImportModule(MODULENAME)))) {
 
100
        PyObject *path;
 
101
 
96
102
        ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, 0, s,
97
 
                     "make_obcallback: could not import %s.\n", MODULENAME);
 
103
                     "make_obcallback: could not import %s.\n",
 
104
                     (!MODULENAME) ? "<null>" : MODULENAME);
 
105
 
98
106
        PyErr_Print();
 
107
        fflush(stderr); 
 
108
 
 
109
        path = PyObject_Repr(PySys_GetObject("path"));
 
110
 
 
111
        ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, 0, s,
 
112
                     "make_obcallback: Python path being used \"%s\".",
 
113
                     PyString_AsString(path));
 
114
 
 
115
        Py_DECREF(path);
 
116
 
 
117
        return NULL;
99
118
    }
100
119
    
101
 
    if (m && ! ((obCallBack = PyObject_CallMethod(m, INITFUNC, NULL)))) {
 
120
    if (m && ! ((obCallBack = PyObject_CallMethod(m,
 
121
                 INITFUNC, "sO", name, MpServer_FromServer(s))))) {
 
122
 
 
123
        const char *mp_compile_version = MPV_STRING;
 
124
        const char *mp_dynamic_version = "<unknown>";
 
125
        PyObject *o = NULL;
 
126
        PyObject *d = NULL;
 
127
        PyObject *f = NULL;
 
128
 
102
129
        ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, 0, s,
103
 
                     "make_obcallback: could not call %s.\n", INITFUNC);
 
130
                     "make_obcallback: could not call %s.\n",
 
131
                     (!INITFUNC) ? "<null>" : INITFUNC);
 
132
 
104
133
        PyErr_Print();
 
134
        fflush(stderr); 
 
135
 
 
136
        m = PyImport_ImportModule("mod_python");
 
137
        if (m) {
 
138
            d = PyModule_GetDict(m);
 
139
            o = PyDict_GetItemString(d, "version");
 
140
            f = PyDict_GetItemString(d, "__file__");
 
141
 
 
142
            if (o) {
 
143
                mp_dynamic_version = PyString_AsString(o);
 
144
            }
 
145
        }
 
146
 
 
147
        if (strcmp(mp_compile_version, mp_dynamic_version) != 0) {
 
148
            ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, 0, s,
 
149
                         "make_obcallback: mod_python version mismatch, expected '%s', found '%s'.",
 
150
                         mp_compile_version, mp_dynamic_version);
 
151
            ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, 0, s,
 
152
                         "make_obcallback: mod_python modules location '%s'.",
 
153
                         PyString_AsString(f));
 
154
        }
 
155
 
 
156
        Py_XDECREF(o);
 
157
        Py_XDECREF(f);
105
158
    }
 
159
 
 
160
      Py_XDECREF(m);
106
161
    
107
162
    return obCallBack;
108
163
}
109
164
 
110
165
/**
 
166
 ** save_interpreter
 
167
 **
 
168
 *      Save away the interpreter.
 
169
 */
 
170
 
 
171
static interpreterdata *save_interpreter(const char *name, PyInterpreterState *istate)
 
172
{
 
173
    PyObject *p;
 
174
    interpreterdata *idata = NULL;
 
175
 
 
176
    idata = (interpreterdata *)malloc(sizeof(interpreterdata));
 
177
    idata->istate = istate;
 
178
    /* obcallback will be created on first use */
 
179
    idata->obcallback = NULL; 
 
180
    p = PyCObject_FromVoidPtr((void *) idata, NULL);
 
181
    PyDict_SetItemString(interpreters, (char *)name, p);
 
182
    Py_DECREF(p);
 
183
 
 
184
    return idata;
 
185
}
 
186
 
 
187
/**
111
188
 ** get_interpreter
112
189
 **
113
190
 *      Get interpreter given its name. 
123
200
    if (! name)
124
201
        name = MAIN_INTERPRETER;
125
202
 
 
203
#if APR_HAS_THREADS
 
204
    apr_thread_mutex_lock(interpreters_lock);
 
205
#endif
126
206
#ifdef WITH_THREAD
127
207
    PyEval_AcquireLock();
128
208
#endif
129
209
 
130
 
    if (!interpreters)
 
210
    if (!interpreters) {
 
211
         ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, 0, srv,
 
212
                       "python_handler: interpreters dictionary not initialised.");
131
213
        return NULL;
 
214
    }
132
215
 
133
216
    p = PyDict_GetItemString(interpreters, (char *)name);
134
217
    if (!p)
135
218
    {
136
219
        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
 
        }
 
220
 
 
221
        if (istate)
 
222
            idata = save_interpreter(name, istate);
145
223
    }
146
224
    else {
147
225
        idata = (interpreterdata *)PyCObject_AsVoidPtr(p);
150
228
#ifdef WITH_THREAD
151
229
    PyEval_ReleaseLock();
152
230
#endif
 
231
#if APR_HAS_THREADS
 
232
    apr_thread_mutex_unlock(interpreters_lock);
 
233
#endif
153
234
 
154
235
    if (! idata) {
155
236
        ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, 0, srv,
167
248
 
168
249
    if (!idata->obcallback) {
169
250
 
170
 
        idata->obcallback = make_obcallback(srv);
 
251
        idata->obcallback = make_obcallback((char*)name,srv);
171
252
 
172
253
        if (!idata->obcallback) 
173
254
        {
174
255
#ifdef WITH_THREAD
175
256
            PyEval_ReleaseThread(tstate);
 
257
#else
 
258
            PyThreadState_Swap(NULL);
176
259
#endif
177
260
            PyThreadState_Delete(tstate);
 
261
            ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, 0, srv,
 
262
                      "python_handler: no interpreter callback found.");
178
263
            return NULL;
179
264
        }
180
265
    }
195
280
    PyThreadState *tstate = PyThreadState_Get();
196
281
#ifdef WITH_THREAD
197
282
    PyEval_ReleaseThread(tstate);
 
283
#else
 
284
    PyThreadState_Swap(NULL);
198
285
#endif
199
286
    PyThreadState_Delete(tstate);
200
287
}
223
310
    if (!idata) {
224
311
        Py_DECREF(ci->handler);
225
312
        Py_XDECREF(ci->data);
 
313
        free(ci->interpreter);
226
314
        free(ci);
227
315
        return APR_SUCCESS; /* this is ignored anyway */
228
316
    }
291
379
    int max_clients;
292
380
    int locks;
293
381
    int n;
 
382
    char *val;
 
383
    char *mutex_dir;
 
384
    py_config *conf;
 
385
    
 
386
    conf = (py_config *) ap_get_module_config(s->module_config, 
 
387
                                           &python_module);
294
388
 
295
 
    /* figre out maximum possible concurrent connections */
 
389
    /* figure out maximum possible concurrent connections */
296
390
    /* MAX_DAEMON_USED seems to account for MaxClients, as opposed to
297
391
       MAX_DAEMONS, which is ServerLimit
298
392
    */
313
407
    max_clients = (((max_threads <= 0) ? 1 : max_threads) *
314
408
                   ((max_procs <= 0) ? 1 : max_procs));
315
409
 
316
 
    /* XXX On some systems the locking mechanism chosen uses valuable
 
410
    /* On some systems the locking mechanism chosen uses valuable
317
411
       system resources, notably on RH 8 it will use sysv ipc for
318
412
       which Linux by default provides only 128 semaphores
319
413
       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.
 
414
       results in a relatively large number of open files.
 
415
 
 
416
       The maximum number of locks can be specified at
 
417
       compile time using "./configure --with-max-locks value" or
 
418
       at run time with "PythonOption mod_python.mutex_locks value".
 
419
 
 
420
       If the PythonOption directive is used, it must be in a 
 
421
       server config context, otherwise it will be ignored.
323
422
 
324
423
       The optimal number of necessary locks is not clear, perhaps a
325
424
       small number is more than sufficient - if someone took the
326
425
       time to run some research on this, that'd be most welcome!
327
426
    */
328
 
    locks = (max_clients > MAX_LOCKS) ? MAX_LOCKS : max_clients; 
 
427
    val = apr_table_get(conf->options, "mod_python.mutex_locks");
 
428
    if (val) {
 
429
        locks = atoi(val);
 
430
    } else {
 
431
        locks = MAX_LOCKS;
 
432
    }
 
433
 
 
434
    locks = (max_clients > locks) ? locks : max_clients; 
329
435
 
330
436
    ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, s,
331
437
                 "mod_python: Creating %d session mutexes based "
337
443
    glb->nlocks = locks;
338
444
    glb->parent_pid = getpid();
339
445
 
 
446
#if !defined(OS2) && !defined(WIN32) && !defined(BEOS) && !defined(NETWARE)
 
447
    /* On some sytems a directory for the mutex lock files is required.
 
448
       This mutex directory can be specifed at compile time using
 
449
       "./configure --with-mutex-dir value" or at run time with
 
450
       "PythonOption mod_python.mutex_directory value".
 
451
     
 
452
       If the PythonOption directive is used, it must be in a 
 
453
       server config context, otherwise it will be ignored.
 
454
 
 
455
       XXX Should we check if mutex_dir exists and has the correct
 
456
       permissions?
 
457
    */
 
458
    mutex_dir = apr_table_get(conf->options, "mod_python.mutex_directory");
 
459
    if (!mutex_dir)
 
460
        mutex_dir = MUTEX_DIR;
 
461
    
 
462
    ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, s,
 
463
                 "mod_python: using mutex_directory %s ",
 
464
                 mutex_dir);
 
465
#endif
 
466
 
340
467
    for (n=0; n<locks; n++) {
341
468
        apr_status_t rc;
342
469
        apr_global_mutex_t **mutex = glb->g_locks;
343
470
 
344
471
#if !defined(OS2) && !defined(WIN32) && !defined(BEOS) && !defined(NETWARE)
345
472
        char fname[255];
346
 
 
347
 
        snprintf(fname, 255, "/tmp/mpmtx%d%d", glb->parent_pid, n);
 
473
        /* XXX What happens if len(mutex_dir) > 255 - len(mpmtx%d%d)? */   
 
474
        snprintf(fname, 255, "%s/mpmtx%d%d", mutex_dir, glb->parent_pid, n);
348
475
#else
349
476
        char *fname = NULL;
350
477
#endif
355
482
                         "mod_python: Failed to create global mutex %d of %d (%s).",
356
483
                         n, locks, (!fname) ? "<null>" : fname);
357
484
            if (n > 1) {
358
 
                /* we were able to crate at least two, so lets just print a 
 
485
                /* we were able to create at least two, so lets just print a 
359
486
                   warning/hint and proceed
360
487
                */
361
488
                ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
401
528
{
402
529
    int n;
403
530
 
 
531
#if !defined(OS2) && !defined(WIN32) && !defined(BEOS) && !defined(NETWARE)
 
532
    /* Determine the directory to use for mutex lock files. 
 
533
       See init_mutexes function for more details.
 
534
    */
 
535
    char *mutex_dir;
 
536
    py_config *conf;
 
537
 
 
538
    conf = (py_config *) ap_get_module_config(s->module_config, 
 
539
                                           &python_module);
 
540
    mutex_dir = apr_table_get(conf->options, "mod_python.mutex_directory");
 
541
    if (!mutex_dir)
 
542
        mutex_dir = MUTEX_DIR;
 
543
#endif
 
544
 
404
545
    for (n=0; n< glb->nlocks; n++) {
405
546
        apr_status_t rc;
406
547
        apr_global_mutex_t **mutex = glb->g_locks;
407
548
 
408
549
#if !defined(OS2) && !defined(WIN32) && !defined(BEOS) && !defined(NETWARE)
409
550
        char fname[255];
410
 
        snprintf(fname, 255, "/tmp/mpmtx%d%d", glb->parent_pid, n);
 
551
        snprintf(fname, 255, "%s/mpmtx%d%d", mutex_dir, glb->parent_pid, n);
411
552
#else
412
553
        char *fname = NULL;
413
554
#endif
469
610
    const char *userdata_key = "python_init";
470
611
    apr_status_t rc;
471
612
 
 
613
    const char *py_compile_version = PY_VERSION;
 
614
    const char *py_dynamic_version = 0;
 
615
 
 
616
    /* The "initialized" flag is a fudge for Mac OS X. It
 
617
     * addresses two issues. The first is that when an Apache
 
618
     * "restart" is performed, Apache will unload the mod_python
 
619
     * shared object, but not the Python framework. This means
 
620
     * that when "python_init()" is called after the restart,
 
621
     * the mod_python initialization will not run if only the
 
622
     * initialized state of Python is checked, because Python
 
623
     * is already initialized. The second problem is that for
 
624
     * some older revisions of Mac OS X, even on the initial
 
625
     * startup of Apache, the "Py_IsInitialized()" function
 
626
     * would return true and mod_python wouldn't initialize
 
627
     * itself correctly and would crash.
 
628
     */
 
629
    static int initialized = 0;
 
630
 
472
631
    apr_pool_userdata_get(&data, userdata_key, s->process->pool);
473
632
    if (!data) {
474
633
        apr_pool_userdata_set((const void *)1, userdata_key,
478
637
 
479
638
    /* mod_python version */
480
639
    ap_add_version_component(p, VERSION_COMPONENT);
481
 
    
 
640
 
 
641
    py_dynamic_version = strtok((char *)Py_GetVersion(), " ");
 
642
 
 
643
    if (strcmp(py_compile_version, py_dynamic_version) != 0) {
 
644
        ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, 0, s,
 
645
                     "python_init: Python version mismatch, expected '%s', found '%s'.",
 
646
                     py_compile_version, py_dynamic_version);
 
647
        ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, 0, s,
 
648
                     "python_init: Python executable found '%s'.",
 
649
                     Py_GetProgramFullPath());
 
650
        ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, 0, s,
 
651
                     "python_init: Python path being used '%s'.",
 
652
                     Py_GetPath());
 
653
    }
 
654
 
482
655
    /* Python version */
483
 
    sprintf(buff, "Python/%.200s", strtok((char *)Py_GetVersion(), " "));
 
656
    sprintf(buff, "Python/%.200s", py_dynamic_version);
484
657
    ap_add_version_component(p, buff);
485
658
 
486
659
    /* global config */
490
663
    }
491
664
 
492
665
    /* initialize global Python interpreter if necessary */
493
 
    if (! Py_IsInitialized()) 
 
666
    if (initialized == 0 || !Py_IsInitialized()) 
494
667
    {
495
 
 
 
668
        initialized = 1;
 
669
        
496
670
        /* initialze the interpreter */
497
671
        Py_Initialize();
498
672
 
 
673
#if APR_HAS_THREADS
 
674
        apr_thread_mutex_create(&interpreters_lock, APR_THREAD_MUTEX_UNNESTED, p);
 
675
#endif
499
676
#ifdef WITH_THREAD
500
677
        /* create and acquire the interpreter lock */
501
678
        PyEval_InitThreads();
502
679
#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
680
 
507
681
        /* create the obCallBack dictionary */
508
682
        interpreters = PyDict_New();
511
685
                         "python_init: PyDict_New() failed! No more memory?");
512
686
            exit(1);
513
687
        }
514
 
        
 
688
 
515
689
#ifdef WITH_THREAD
516
690
        /* release the lock; now other threads can run */
517
691
        PyEval_ReleaseLock();
518
692
#endif
519
 
 
520
693
    }
521
694
    return OK;
522
695
}
558
731
    py_config *conf = python_create_config(p);
559
732
 
560
733
    /* 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);
 
734
    if (dir && (dir[strlen(dir) - 1] != '/'))
 
735
        conf->config_dir = apr_pstrcat(p, dir, "/", NULL);
563
736
    else
564
737
        conf->config_dir = apr_pstrdup(p, dir);
565
738
 
581
754
    return conf;
582
755
}
583
756
 
 
757
/*
 
758
code begin
 
759
*/
 
760
/**
 
761
 ** modpython_table_overlap
 
762
 **
 
763
 * Replaces the apr_table_overlap() function using a specific pool
 
764
 * for the resulting table.
 
765
 */
 
766
 
 
767
static apr_table_t *modpython_table_overlap(apr_pool_t *p,
 
768
                                            apr_table_t *current_table,
 
769
                                            apr_table_t *new_table)
 
770
{
 
771
    apr_table_t *merge = apr_table_overlay(p, current_table, new_table);
 
772
    apr_table_compress(merge, APR_OVERLAP_TABLES_SET);
 
773
    return merge;
 
774
}
 
775
 
584
776
/**
585
777
 ** python_merge_dir_config
586
778
 **
587
779
 */
588
780
 
589
 
static void *python_merge_config(apr_pool_t *p, void *current_conf, 
 
781
static void *python_merge_config(apr_pool_t *p, void *current_conf,
590
782
                                 void *new_conf)
591
783
{
592
784
 
593
 
    py_config *merged_conf = 
 
785
    py_config *merged_conf =
594
786
        (py_config *) apr_pcalloc(p, sizeof(py_config));
595
787
    py_config *cc = (py_config *) current_conf;
596
788
    py_config *nc = (py_config *) new_conf;
605
797
     */
606
798
 
607
799
    /** create **/
608
 
    merged_conf->directives = apr_table_make(p, 4);
609
 
    merged_conf->options = apr_table_make(p, 4);
610
800
    merged_conf->hlists = apr_hash_make(p);
611
801
    merged_conf->in_filters = apr_hash_make(p);
612
802
    merged_conf->out_filters = apr_hash_make(p);
613
803
 
 
804
    /** merge directives and options **/
 
805
    merged_conf->directives = modpython_table_overlap(p, cc->directives,
 
806
                                                         nc->directives);
 
807
    merged_conf->options = modpython_table_overlap(p, cc->options,
 
808
                                                      nc->options);
 
809
 
614
810
    /** copy current **/
615
 
 
616
811
    merged_conf->authoritative = cc->authoritative;
617
812
    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
813
 
623
814
    for (hi = apr_hash_first(p, cc->hlists); hi; hi=apr_hash_next(hi)) {
624
815
        apr_hash_this(hi, (const void **)&key, &klen, (void **)&hle);
642
833
    if (nc->config_dir)
643
834
        merged_conf->config_dir = apr_pstrdup(p, nc->config_dir);
644
835
 
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
836
    for (hi = apr_hash_first(p, nc->hlists); hi; hi=apr_hash_next(hi)) {
651
837
        apr_hash_this(hi, (const void**)&key, &klen, (void **)&hle);
652
838
        apr_hash_set(merged_conf->hlists, key, klen, (void *)hle);
665
851
    return (void *) merged_conf;
666
852
}
667
853
 
 
854
/*
 
855
code end
 
856
*/
 
857
 
 
858
 
668
859
/**
669
860
 ** python_directive
670
861
 **
767
958
 */
768
959
 
769
960
static const char *python_directive_flag(void * mconfig, 
770
 
                                         char *key, int val)
 
961
                                         char *key, int val, int set)
771
962
{
772
963
    py_config *conf;
773
964
 
777
968
        apr_table_set(conf->directives, key, "1");
778
969
    }
779
970
    else {
780
 
        apr_table_unset(conf->directives, key);
 
971
        if (set) {
 
972
            apr_table_set(conf->directives, key, "0");
 
973
        }
 
974
        else {
 
975
            apr_table_unset(conf->directives, key);
 
976
        }
781
977
    }
782
978
 
783
979
    return NULL;
806
1002
    }
807
1003
    else {
808
1004
/*         if ((req->path_info) &&  */
809
 
/*             (req->path_info[strlen(req->path_info) - 1] == SLASH)) */
 
1005
/*             (req->path_info[strlen(req->path_info) - 1] == '/')) */
810
1006
/*         { */
811
1007
/*             int i; */
812
1008
/*             i = strlen(req->path_info); */
821
1017
/*             if (!request_obj) return NULL; */
822
1018
 
823
1019
/*             /\* put the slash back in *\/ */
824
 
/*             req->path_info[i - 1] = SLASH;  */
 
1020
/*             req->path_info[i - 1] = '/';  */
825
1021
/*             req->path_info[i] = 0; */
826
1022
 
827
1023
/*             /\* and also make PATH_INFO == req->subprocess_env *\/ */
887
1083
        if ((s = apr_table_get(conf->directives, "PythonInterpPerDirectory"))) {
888
1084
            
889
1085
            /* 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 ));
 
1086
            if (req && ap_is_directory(req->pool, req->filename)) {
 
1087
                /** XXX I suppose that if req->filename is a directory, there already
 
1088
                    is a trailing slash in req->filename. This is due to the fact
 
1089
                    that Apache redirect any request from /directory to /directory/.
 
1090
                    That's why the tests below are commented out, they should be useless.
 
1091
                **/
 
1092
                /* if (req->filename[strlen(req->filename)-1]=='/') { */
 
1093
                    return ap_make_dirstr_parent(req->pool, req->filename);
 
1094
                /* }
 
1095
                else {
 
1096
                    return ap_make_dirstr_parent(req->pool, 
 
1097
                                                apr_pstrcat(req->pool, req->filename, 
 
1098
                                                            "/", NULL ));
 
1099
                } */
 
1100
            }
894
1101
            else {
895
1102
                if (req && req->filename)
896
1103
                    return ap_make_dirstr_parent(req->pool, req->filename);
1015
1222
    /* get/create interpreter */
1016
1223
    idata = get_interpreter(interp_name, req->server);
1017
1224
 
1018
 
    if (!idata)
 
1225
    if (!idata) {
 
1226
        ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, 0, req,
 
1227
                      "python_handler: Can't get/create interpreter.");
1019
1228
        return HTTP_INTERNAL_SERVER_ERROR;
 
1229
    }
1020
1230
    
1021
1231
    /* create/acquire request object */
1022
1232
    request_obj = get_request_object(req, interp_name, phase);
1025
1235
    if (ext) 
1026
1236
        request_obj->extension = apr_pstrdup(req->pool, ext);
1027
1237
 
1028
 
    /* create a hahdler list object */
1029
 
    request_obj->hlo = (hlistobject *)MpHList_FromHLEntry(hle);
 
1238
    if (!hle) {
 
1239
        /* create a handler list object from dynamically registered handlers */
 
1240
        request_obj->hlo = (hlistobject *)MpHList_FromHLEntry(dynhle);
 
1241
    }
 
1242
    else {
 
1243
        /* create a handler list object */
 
1244
        request_obj->hlo = (hlistobject *)MpHList_FromHLEntry(hle);
1030
1245
 
1031
 
    /* add dynamically registered handlers, if any */
1032
 
    if (dynhle) {
1033
 
        MpHList_Append(request_obj->hlo, dynhle);
 
1246
        /* add dynamically registered handlers, if any */
 
1247
        if (dynhle) {
 
1248
            MpHList_Append(request_obj->hlo, dynhle);
 
1249
        }
1034
1250
    }
1035
1251
 
1036
1252
    /* 
1199
1415
    /* get/create interpreter */
1200
1416
    idata = get_interpreter(interp_name, con->base_server);
1201
1417
 
1202
 
    if (!idata)
 
1418
    if (!idata) {
 
1419
        ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, 0, con->base_server,
 
1420
                      "python_handler: Can't get/create interpreter.");
1203
1421
        return HTTP_INTERNAL_SERVER_ERROR;
 
1422
    }
1204
1423
    
1205
1424
    /* create connection object */
1206
1425
    conn_obj = (connobject*) MpConn_FromConn(con);
1296
1515
    /* get/create interpreter */
1297
1516
    idata = get_interpreter(interp_name, req->server);
1298
1517
   
1299
 
    if (!idata)
 
1518
    if (!idata) {
 
1519
        ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, 0, req,
 
1520
                      "python_handler: Can't get/create interpreter.");
1300
1521
        return HTTP_INTERNAL_SERVER_ERROR;
 
1522
    }
1301
1523
 
1302
1524
    /* create/acquire request object */
1303
1525
    request_obj = get_request_object(req, interp_name, 
1433
1655
 */
1434
1656
static const char *directive_PythonDebug(cmd_parms *cmd, void *mconfig,
1435
1657
                                         int val) {
1436
 
    const char *rc = python_directive_flag(mconfig, "PythonDebug", val);
 
1658
    const char *rc = python_directive_flag(mconfig, "PythonDebug", val, 0);
1437
1659
 
1438
1660
    if (!rc) {
1439
1661
        py_config *conf = ap_get_module_config(cmd->server->module_config,
1440
1662
                                               &python_module);
1441
1663
 
1442
 
        return python_directive_flag(conf, "PythonDebug", val);
 
1664
        return python_directive_flag(conf, "PythonDebug", val, 0);
1443
1665
    }
1444
1666
    return rc;
1445
1667
}
1452
1674
 */
1453
1675
static const char *directive_PythonEnablePdb(cmd_parms *cmd, void *mconfig,
1454
1676
                                             int val) {
1455
 
    const char *rc = python_directive_flag(mconfig, "PythonEnablePdb", val);
 
1677
    const char *rc = python_directive_flag(mconfig, "PythonEnablePdb", val, 0);
1456
1678
 
1457
1679
    if (!rc) {
1458
1680
        py_config *conf = ap_get_module_config(cmd->server->module_config,
1459
1681
                                               &python_module);
1460
 
        return python_directive_flag(conf, "PythonEnablePdb", val);
 
1682
        return python_directive_flag(conf, "PythonEnablePdb", val, 0);
1461
1683
    }
1462
1684
    return rc;
1463
1685
}
1471
1693
 
1472
1694
static const char *directive_PythonInterpPerDirective(cmd_parms *cmd, 
1473
1695
                                                      void *mconfig, int val) {
1474
 
    const char *rc = python_directive_flag(mconfig, "PythonInterpPerDirective", val);
 
1696
    const char *rc = python_directive_flag(mconfig, "PythonInterpPerDirective", val, 0);
1475
1697
 
1476
1698
    if (!rc) {
1477
1699
        py_config *conf = ap_get_module_config(cmd->server->module_config,
1478
1700
                                               &python_module);
1479
 
        return python_directive_flag(conf, "PythonInterpPerDirective", val);
 
1701
        return python_directive_flag(conf, "PythonInterpPerDirective", val, 0);
1480
1702
    }
1481
1703
    return rc;
1482
1704
}
1490
1712
 
1491
1713
static const char *directive_PythonInterpPerDirectory(cmd_parms *cmd, 
1492
1714
                                                      void *mconfig, int val) {
1493
 
    return python_directive_flag(mconfig, "PythonInterpPerDirectory", val);
 
1715
    return python_directive_flag(mconfig, "PythonInterpPerDirectory", val, 0);
1494
1716
}
1495
1717
 
1496
1718
/**
1502
1724
 
1503
1725
static const char *directive_PythonAutoReload(cmd_parms *cmd, 
1504
1726
                                              void *mconfig, int val) {
1505
 
    const char *rc = python_directive_flag(mconfig, "PythonAutoReload", val);
 
1727
    const char *rc = python_directive_flag(mconfig, "PythonAutoReload", val, 1);
1506
1728
 
1507
1729
    if (!rc) {
1508
1730
        py_config *conf = ap_get_module_config(cmd->server->module_config,
1509
1731
                                               &python_module);
1510
 
        return python_directive_flag(conf, "PythonAutoReload", val);
 
1732
        return python_directive_flag(conf, "PythonAutoReload", val, 1);
1511
1733
    }
1512
1734
    return rc;
1513
1735
}
1523
1745
static const char *directive_PythonOption(cmd_parms *cmd, void * mconfig, 
1524
1746
                                          const char *key, const char *val)
1525
1747
{
1526
 
 
1527
1748
    py_config *conf;
1528
1749
 
1529
1750
    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);
 
1751
 
 
1752
    if(val!=NULL) {
 
1753
        apr_table_set(conf->options, key, val);
 
1754
 
 
1755
        if (!cmd->path) {
 
1756
            conf = ap_get_module_config(cmd->server->module_config,
 
1757
                                        &python_module);
 
1758
            apr_table_set(conf->options, key, val);
 
1759
        }
 
1760
    }
 
1761
    else {
 
1762
        /** We don't remove the value, but set it
 
1763
            to an empty string. There is no possibility
 
1764
            of colliding with an actual value, since
 
1765
            an entry string precisely means 'remove the value' */
 
1766
        apr_table_set(conf->options, key, "");
 
1767
 
 
1768
        if (!cmd->path) {
 
1769
            conf = ap_get_module_config(cmd->server->module_config,
 
1770
                                        &python_module);
 
1771
            apr_table_set(conf->options, key, "");
 
1772
        }
 
1773
    }
1535
1774
 
1536
1775
    return NULL;
1537
1776
}
1614
1853
    python_directive_handler(cmd, mconfig, "PythonLogHandler", val, SILENT);
1615
1854
    python_directive_handler(cmd, mconfig, "PythonCleanupHandler", val, SILENT);
1616
1855
 
 
1856
    /*
 
1857
     * XXX There is a bug here with PythonConnectionHandler which can
 
1858
     * cause an infinite loop when the handler is added to the handler
 
1859
     * list. Cause is unknown so simply disable it for now. If someone
 
1860
     * really needs a connection handler, they can use the directive
 
1861
     * PythonConnectionHandler explicitly still and not rely on the
 
1862
     * PythonHandlerModule directive doing it automatically.
 
1863
     *
1617
1864
    python_directive_handler(cmd, srv_conf, "PythonConnectionHandler", val, SILENT);
 
1865
    */
1618
1866
 
1619
1867
    return NULL;
1620
1868
}
1739
1987
    PyEval_AcquireLock();
1740
1988
#endif
1741
1989
    PyOS_AfterFork();
 
1990
 
 
1991
    save_interpreter(MAIN_INTERPRETER, PyThreadState_Get()->interp);
 
1992
 
 
1993
    PyThreadState_Swap(NULL);
 
1994
 
1742
1995
#ifdef WITH_THREAD
1743
1996
    PyEval_ReleaseLock();
1744
1997
#endif
1811
2064
 
1812
2065
        err:
1813
2066
            PyErr_Print();
 
2067
            fflush(stderr); 
1814
2068
            release_interpreter();
1815
2069
            return;
1816
2070
        }
1818
2072
    success:
1819
2073
        /* now import the specified module */
1820
2074
        if (! PyImport_ImportModule((char *)module_name)) {
1821
 
            if (PyErr_Occurred())
 
2075
            if (PyErr_Occurred()) {
1822
2076
                PyErr_Print();
 
2077
                fflush(stderr); 
 
2078
            }
1823
2079
            ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, 0, s,
1824
 
                         "directive_PythonImport: error importing %s", module_name);
 
2080
                         "directive_PythonImport: error importing %s", (!module_name) ? "<null>" : module_name);
1825
2081
        }
1826
2082
 
1827
2083
        /* release interpreter */
2012
2268
    AP_INIT_FLAG(
2013
2269
        "PythonOptimize", directive_PythonOptimize, NULL, RSRC_CONF,
2014
2270
        "Set the equivalent of the -O command-line flag on the interpreter."),
2015
 
    AP_INIT_TAKE2(
 
2271
    AP_INIT_TAKE12(
2016
2272
        "PythonOption", directive_PythonOption, NULL, OR_ALL,
2017
2273
        "Useful to pass custom configuration information to scripts."),
2018
2274
    AP_INIT_TAKE1(