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

« back to all changes in this revision

Viewing changes to src/mod_python.c

  • Committer: Bazaar Package Importer
  • Author(s): Martin Pitt
  • Date: 2006-07-07 13:18:35 UTC
  • mfrom: (1.2.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20060707131835-zfp1vupanjj2e77y
Tags: 3.2.8-1ubuntu1
* Merge to Debian unstable.
* Remaining Ubuntu change: debian/{control,rules}: Drop python 2.3 package.

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 102649 2004-02-16 19:47:28Z grisha $
 
21
 * $Id: mod_python.c 367835 2006-01-10 23:36:37Z jgallacher $
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
83
    PyObject *m;
94
98
 
95
99
    if (! ((m = PyImport_ImportModule(MODULENAME)))) {
96
100
        ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, 0, s,
97
 
                     "make_obcallback: could not import %s.\n", MODULENAME);
 
101
                     "make_obcallback: could not import %s.\n", (!MODULENAME) ? "<null>" : MODULENAME);
98
102
        PyErr_Print();
 
103
        fflush(stderr); 
99
104
    }
100
105
    
101
 
    if (m && ! ((obCallBack = PyObject_CallMethod(m, INITFUNC, NULL)))) {
 
106
    if (m && ! ((obCallBack = PyObject_CallMethod(m, INITFUNC, "sO", name, MpServer_FromServer(s))))) {
102
107
        ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, 0, s,
103
 
                     "make_obcallback: could not call %s.\n", INITFUNC);
 
108
                     "make_obcallback: could not call %s.\n", (!INITFUNC) ? "<null>" : INITFUNC);
104
109
        PyErr_Print();
 
110
        fflush(stderr); 
105
111
    }
106
112
    
107
113
    return obCallBack;
123
129
    if (! name)
124
130
        name = MAIN_INTERPRETER;
125
131
 
 
132
#if APR_HAS_THREADS
 
133
    apr_thread_mutex_lock(interpreters_lock);
 
134
#endif
126
135
#ifdef WITH_THREAD
127
136
    PyEval_AcquireLock();
128
137
#endif
129
138
 
130
 
    if (!interpreters)
 
139
    if (!interpreters) {
 
140
         ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, 0, srv,
 
141
                       "python_handler: interpreters dictionary not initialised.");
131
142
        return NULL;
 
143
    }
132
144
 
133
145
    p = PyDict_GetItemString(interpreters, (char *)name);
134
146
    if (!p)
141
153
            idata->obcallback = NULL; 
142
154
            p = PyCObject_FromVoidPtr((void *) idata, NULL);
143
155
            PyDict_SetItemString(interpreters, (char *)name, p);
 
156
            Py_DECREF(p);
144
157
        }
145
158
    }
146
159
    else {
150
163
#ifdef WITH_THREAD
151
164
    PyEval_ReleaseLock();
152
165
#endif
 
166
#if APR_HAS_THREADS
 
167
    apr_thread_mutex_unlock(interpreters_lock);
 
168
#endif
153
169
 
154
170
    if (! idata) {
155
171
        ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, 0, srv,
167
183
 
168
184
    if (!idata->obcallback) {
169
185
 
170
 
        idata->obcallback = make_obcallback(srv);
 
186
        idata->obcallback = make_obcallback((char*)name,srv);
171
187
 
172
188
        if (!idata->obcallback) 
173
189
        {
174
190
#ifdef WITH_THREAD
175
191
            PyEval_ReleaseThread(tstate);
 
192
#else
 
193
            PyThreadState_Swap(NULL);
176
194
#endif
177
195
            PyThreadState_Delete(tstate);
 
196
            ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, 0, srv,
 
197
                      "python_handler: no interpreter callback found.");
178
198
            return NULL;
179
199
        }
180
200
    }
195
215
    PyThreadState *tstate = PyThreadState_Get();
196
216
#ifdef WITH_THREAD
197
217
    PyEval_ReleaseThread(tstate);
 
218
#else
 
219
    PyThreadState_Swap(NULL);
198
220
#endif
199
221
    PyThreadState_Delete(tstate);
200
222
}
223
245
    if (!idata) {
224
246
        Py_DECREF(ci->handler);
225
247
        Py_XDECREF(ci->data);
 
248
        free(ci->interpreter);
226
249
        free(ci);
227
250
        return APR_SUCCESS; /* this is ignored anyway */
228
251
    }
469
492
    const char *userdata_key = "python_init";
470
493
    apr_status_t rc;
471
494
 
 
495
    /* fudge for Mac OS X with Apache 1.3 where Py_IsInitialized() broke */
 
496
    static int initialized = 0;
 
497
 
472
498
    apr_pool_userdata_get(&data, userdata_key, s->process->pool);
473
499
    if (!data) {
474
500
        apr_pool_userdata_set((const void *)1, userdata_key,
490
516
    }
491
517
 
492
518
    /* initialize global Python interpreter if necessary */
493
 
    if (! Py_IsInitialized()) 
 
519
    if (initialized == 0 || !Py_IsInitialized()) 
494
520
    {
495
 
 
 
521
        initialized = 1;
 
522
        
496
523
        /* initialze the interpreter */
497
524
        Py_Initialize();
498
525
 
 
526
#if APR_HAS_THREADS
 
527
        apr_thread_mutex_create(&interpreters_lock, APR_THREAD_MUTEX_UNNESTED, p);
 
528
#endif
499
529
#ifdef WITH_THREAD
500
530
        /* create and acquire the interpreter lock */
501
531
        PyEval_InitThreads();
558
588
    py_config *conf = python_create_config(p);
559
589
 
560
590
    /* 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);
 
591
    if (dir && (dir[strlen(dir) - 1] != '/'))
 
592
        conf->config_dir = apr_pstrcat(p, dir, "/", NULL);
563
593
    else
564
594
        conf->config_dir = apr_pstrdup(p, dir);
565
595
 
581
611
    return conf;
582
612
}
583
613
 
 
614
/*
 
615
code begin
 
616
*/
 
617
/**
 
618
 ** modpython_table_overlap
 
619
 **
 
620
 * Replaces the apr_table_overlap() function using a specific pool
 
621
 * for the resulting table.
 
622
 */
 
623
 
 
624
static apr_table_t *modpython_table_overlap(apr_pool_t *p,
 
625
                                            apr_table_t *current_table,
 
626
                                            apr_table_t *new_table)
 
627
{
 
628
    apr_table_t *merge = apr_table_overlay(p, current_table, new_table);
 
629
    apr_table_compress(merge, APR_OVERLAP_TABLES_SET);
 
630
    return merge;
 
631
}
 
632
 
584
633
/**
585
634
 ** python_merge_dir_config
586
635
 **
587
636
 */
588
637
 
589
 
static void *python_merge_config(apr_pool_t *p, void *current_conf, 
 
638
static void *python_merge_config(apr_pool_t *p, void *current_conf,
590
639
                                 void *new_conf)
591
640
{
592
641
 
593
 
    py_config *merged_conf = 
 
642
    py_config *merged_conf =
594
643
        (py_config *) apr_pcalloc(p, sizeof(py_config));
595
644
    py_config *cc = (py_config *) current_conf;
596
645
    py_config *nc = (py_config *) new_conf;
605
654
     */
606
655
 
607
656
    /** create **/
608
 
    merged_conf->directives = apr_table_make(p, 4);
609
 
    merged_conf->options = apr_table_make(p, 4);
610
657
    merged_conf->hlists = apr_hash_make(p);
611
658
    merged_conf->in_filters = apr_hash_make(p);
612
659
    merged_conf->out_filters = apr_hash_make(p);
613
660
 
 
661
    /** merge directives and options **/
 
662
    merged_conf->directives = modpython_table_overlap(p, cc->directives,
 
663
                                                         nc->directives);
 
664
    merged_conf->options = modpython_table_overlap(p, cc->options,
 
665
                                                      nc->options);
 
666
 
614
667
    /** copy current **/
615
 
 
616
668
    merged_conf->authoritative = cc->authoritative;
617
669
    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
670
 
623
671
    for (hi = apr_hash_first(p, cc->hlists); hi; hi=apr_hash_next(hi)) {
624
672
        apr_hash_this(hi, (const void **)&key, &klen, (void **)&hle);
642
690
    if (nc->config_dir)
643
691
        merged_conf->config_dir = apr_pstrdup(p, nc->config_dir);
644
692
 
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
693
    for (hi = apr_hash_first(p, nc->hlists); hi; hi=apr_hash_next(hi)) {
651
694
        apr_hash_this(hi, (const void**)&key, &klen, (void **)&hle);
652
695
        apr_hash_set(merged_conf->hlists, key, klen, (void *)hle);
665
708
    return (void *) merged_conf;
666
709
}
667
710
 
 
711
/*
 
712
code end
 
713
*/
 
714
 
 
715
 
668
716
/**
669
717
 ** python_directive
670
718
 **
767
815
 */
768
816
 
769
817
static const char *python_directive_flag(void * mconfig, 
770
 
                                         char *key, int val)
 
818
                                         char *key, int val, int set)
771
819
{
772
820
    py_config *conf;
773
821
 
777
825
        apr_table_set(conf->directives, key, "1");
778
826
    }
779
827
    else {
780
 
        apr_table_unset(conf->directives, key);
 
828
        if (set) {
 
829
            apr_table_set(conf->directives, key, "0");
 
830
        }
 
831
        else {
 
832
            apr_table_unset(conf->directives, key);
 
833
        }
781
834
    }
782
835
 
783
836
    return NULL;
806
859
    }
807
860
    else {
808
861
/*         if ((req->path_info) &&  */
809
 
/*             (req->path_info[strlen(req->path_info) - 1] == SLASH)) */
 
862
/*             (req->path_info[strlen(req->path_info) - 1] == '/')) */
810
863
/*         { */
811
864
/*             int i; */
812
865
/*             i = strlen(req->path_info); */
821
874
/*             if (!request_obj) return NULL; */
822
875
 
823
876
/*             /\* put the slash back in *\/ */
824
 
/*             req->path_info[i - 1] = SLASH;  */
 
877
/*             req->path_info[i - 1] = '/';  */
825
878
/*             req->path_info[i] = 0; */
826
879
 
827
880
/*             /\* and also make PATH_INFO == req->subprocess_env *\/ */
887
940
        if ((s = apr_table_get(conf->directives, "PythonInterpPerDirectory"))) {
888
941
            
889
942
            /* 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 ));
 
943
            if (req && ap_is_directory(req->pool, req->filename)) {
 
944
                /** XXX I suppose that if req->filename is a directory, there already
 
945
                    is a trailing slash in req->filename. This is due to the fact
 
946
                    that Apache redirect any request from /directory to /directory/.
 
947
                    That's why the tests below are commented out, they should be useless.
 
948
                **/
 
949
                /* if (req->filename[strlen(req->filename)-1]=='/') { */
 
950
                    return ap_make_dirstr_parent(req->pool, req->filename);
 
951
                /* }
 
952
                else {
 
953
                    return ap_make_dirstr_parent(req->pool, 
 
954
                                                apr_pstrcat(req->pool, req->filename, 
 
955
                                                            "/", NULL ));
 
956
                } */
 
957
            }
894
958
            else {
895
959
                if (req && req->filename)
896
960
                    return ap_make_dirstr_parent(req->pool, req->filename);
1015
1079
    /* get/create interpreter */
1016
1080
    idata = get_interpreter(interp_name, req->server);
1017
1081
 
1018
 
    if (!idata)
 
1082
    if (!idata) {
 
1083
        ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, 0, req,
 
1084
                      "python_handler: Can't get/create interpreter.");
1019
1085
        return HTTP_INTERNAL_SERVER_ERROR;
 
1086
    }
1020
1087
    
1021
1088
    /* create/acquire request object */
1022
1089
    request_obj = get_request_object(req, interp_name, phase);
1025
1092
    if (ext) 
1026
1093
        request_obj->extension = apr_pstrdup(req->pool, ext);
1027
1094
 
1028
 
    /* create a hahdler list object */
1029
 
    request_obj->hlo = (hlistobject *)MpHList_FromHLEntry(hle);
 
1095
    if (!hle) {
 
1096
        /* create a handler list object from dynamically registered handlers */
 
1097
        request_obj->hlo = (hlistobject *)MpHList_FromHLEntry(dynhle);
 
1098
    }
 
1099
    else {
 
1100
        /* create a handler list object */
 
1101
        request_obj->hlo = (hlistobject *)MpHList_FromHLEntry(hle);
1030
1102
 
1031
 
    /* add dynamically registered handlers, if any */
1032
 
    if (dynhle) {
1033
 
        MpHList_Append(request_obj->hlo, dynhle);
 
1103
        /* add dynamically registered handlers, if any */
 
1104
        if (dynhle) {
 
1105
            MpHList_Append(request_obj->hlo, dynhle);
 
1106
        }
1034
1107
    }
1035
1108
 
1036
1109
    /* 
1199
1272
    /* get/create interpreter */
1200
1273
    idata = get_interpreter(interp_name, con->base_server);
1201
1274
 
1202
 
    if (!idata)
 
1275
    if (!idata) {
 
1276
        ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, 0, con->base_server,
 
1277
                      "python_handler: Can't get/create interpreter.");
1203
1278
        return HTTP_INTERNAL_SERVER_ERROR;
 
1279
    }
1204
1280
    
1205
1281
    /* create connection object */
1206
1282
    conn_obj = (connobject*) MpConn_FromConn(con);
1296
1372
    /* get/create interpreter */
1297
1373
    idata = get_interpreter(interp_name, req->server);
1298
1374
   
1299
 
    if (!idata)
 
1375
    if (!idata) {
 
1376
        ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, 0, req,
 
1377
                      "python_handler: Can't get/create interpreter.");
1300
1378
        return HTTP_INTERNAL_SERVER_ERROR;
 
1379
    }
1301
1380
 
1302
1381
    /* create/acquire request object */
1303
1382
    request_obj = get_request_object(req, interp_name, 
1433
1512
 */
1434
1513
static const char *directive_PythonDebug(cmd_parms *cmd, void *mconfig,
1435
1514
                                         int val) {
1436
 
    const char *rc = python_directive_flag(mconfig, "PythonDebug", val);
 
1515
    const char *rc = python_directive_flag(mconfig, "PythonDebug", val, 0);
1437
1516
 
1438
1517
    if (!rc) {
1439
1518
        py_config *conf = ap_get_module_config(cmd->server->module_config,
1440
1519
                                               &python_module);
1441
1520
 
1442
 
        return python_directive_flag(conf, "PythonDebug", val);
 
1521
        return python_directive_flag(conf, "PythonDebug", val, 0);
1443
1522
    }
1444
1523
    return rc;
1445
1524
}
1452
1531
 */
1453
1532
static const char *directive_PythonEnablePdb(cmd_parms *cmd, void *mconfig,
1454
1533
                                             int val) {
1455
 
    const char *rc = python_directive_flag(mconfig, "PythonEnablePdb", val);
 
1534
    const char *rc = python_directive_flag(mconfig, "PythonEnablePdb", val, 0);
1456
1535
 
1457
1536
    if (!rc) {
1458
1537
        py_config *conf = ap_get_module_config(cmd->server->module_config,
1459
1538
                                               &python_module);
1460
 
        return python_directive_flag(conf, "PythonEnablePdb", val);
 
1539
        return python_directive_flag(conf, "PythonEnablePdb", val, 0);
1461
1540
    }
1462
1541
    return rc;
1463
1542
}
1471
1550
 
1472
1551
static const char *directive_PythonInterpPerDirective(cmd_parms *cmd, 
1473
1552
                                                      void *mconfig, int val) {
1474
 
    const char *rc = python_directive_flag(mconfig, "PythonInterpPerDirective", val);
 
1553
    const char *rc = python_directive_flag(mconfig, "PythonInterpPerDirective", val, 0);
1475
1554
 
1476
1555
    if (!rc) {
1477
1556
        py_config *conf = ap_get_module_config(cmd->server->module_config,
1478
1557
                                               &python_module);
1479
 
        return python_directive_flag(conf, "PythonInterpPerDirective", val);
 
1558
        return python_directive_flag(conf, "PythonInterpPerDirective", val, 0);
1480
1559
    }
1481
1560
    return rc;
1482
1561
}
1490
1569
 
1491
1570
static const char *directive_PythonInterpPerDirectory(cmd_parms *cmd, 
1492
1571
                                                      void *mconfig, int val) {
1493
 
    return python_directive_flag(mconfig, "PythonInterpPerDirectory", val);
 
1572
    return python_directive_flag(mconfig, "PythonInterpPerDirectory", val, 0);
1494
1573
}
1495
1574
 
1496
1575
/**
1502
1581
 
1503
1582
static const char *directive_PythonAutoReload(cmd_parms *cmd, 
1504
1583
                                              void *mconfig, int val) {
1505
 
    const char *rc = python_directive_flag(mconfig, "PythonAutoReload", val);
 
1584
    const char *rc = python_directive_flag(mconfig, "PythonAutoReload", val, 1);
1506
1585
 
1507
1586
    if (!rc) {
1508
1587
        py_config *conf = ap_get_module_config(cmd->server->module_config,
1509
1588
                                               &python_module);
1510
 
        return python_directive_flag(conf, "PythonAutoReload", val);
 
1589
        return python_directive_flag(conf, "PythonAutoReload", val, 1);
1511
1590
    }
1512
1591
    return rc;
1513
1592
}
1523
1602
static const char *directive_PythonOption(cmd_parms *cmd, void * mconfig, 
1524
1603
                                          const char *key, const char *val)
1525
1604
{
1526
 
 
1527
1605
    py_config *conf;
1528
1606
 
1529
1607
    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);
 
1608
 
 
1609
    if(val!=NULL) {
 
1610
        apr_table_set(conf->options, key, val);
 
1611
 
 
1612
        conf = ap_get_module_config(cmd->server->module_config,
 
1613
                                    &python_module);
 
1614
        apr_table_set(conf->options, key, val);
 
1615
    }
 
1616
    else {
 
1617
        /** We don't remove the value, but set it
 
1618
            to an empty string. There is no possibility
 
1619
            of colliding with an actual value, since
 
1620
            an entry string precisely means 'remove the value' */
 
1621
        apr_table_set(conf->options, key, "");
 
1622
 
 
1623
        conf = ap_get_module_config(cmd->server->module_config,
 
1624
                                    &python_module);
 
1625
        apr_table_set(conf->options, key, "");
 
1626
    }
1535
1627
 
1536
1628
    return NULL;
1537
1629
}
1614
1706
    python_directive_handler(cmd, mconfig, "PythonLogHandler", val, SILENT);
1615
1707
    python_directive_handler(cmd, mconfig, "PythonCleanupHandler", val, SILENT);
1616
1708
 
 
1709
    /*
 
1710
     * XXX There is a bug here with PythonConnectionHandler which can
 
1711
     * cause an infinite loop when the handler is added to the handler
 
1712
     * list. Cause is unknown so simply disable it for now. If someone
 
1713
     * really needs a connection handler, they can use the directive
 
1714
     * PythonConnectionHandler explicitly still and not rely on the
 
1715
     * PythonHandlerModule directive doing it automatically.
 
1716
     *
1617
1717
    python_directive_handler(cmd, srv_conf, "PythonConnectionHandler", val, SILENT);
 
1718
    */
1618
1719
 
1619
1720
    return NULL;
1620
1721
}
1811
1912
 
1812
1913
        err:
1813
1914
            PyErr_Print();
 
1915
            fflush(stderr); 
1814
1916
            release_interpreter();
1815
1917
            return;
1816
1918
        }
1818
1920
    success:
1819
1921
        /* now import the specified module */
1820
1922
        if (! PyImport_ImportModule((char *)module_name)) {
1821
 
            if (PyErr_Occurred())
 
1923
            if (PyErr_Occurred()) {
1822
1924
                PyErr_Print();
 
1925
                fflush(stderr); 
 
1926
            }
1823
1927
            ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, 0, s,
1824
 
                         "directive_PythonImport: error importing %s", module_name);
 
1928
                         "directive_PythonImport: error importing %s", (!module_name) ? "<null>" : module_name);
1825
1929
        }
1826
1930
 
1827
1931
        /* release interpreter */
2012
2116
    AP_INIT_FLAG(
2013
2117
        "PythonOptimize", directive_PythonOptimize, NULL, RSRC_CONF,
2014
2118
        "Set the equivalent of the -O command-line flag on the interpreter."),
2015
 
    AP_INIT_TAKE2(
 
2119
    AP_INIT_TAKE12(
2016
2120
        "PythonOption", directive_PythonOption, NULL, OR_ALL,
2017
2121
        "Useful to pass custom configuration information to scripts."),
2018
2122
    AP_INIT_TAKE1(