~ubuntu-branches/ubuntu/oneiric/mod-wsgi/oneiric

« back to all changes in this revision

Viewing changes to mod_wsgi.c

  • Committer: Bazaar Package Importer
  • Author(s): Piotr Ożarowski, Sandro Tosi, Piotr Ożarowski
  • Date: 2009-04-18 22:06:03 UTC
  • mfrom: (1.1.4 upstream) (3.1.2 squeeze)
  • Revision ID: james.westby@ubuntu.com-20090418220603-re6oez0i1chj3wsh
Tags: 2.4-1
[ Sandro Tosi ]
* Switch Vcs-Browser field to viewsvn

[ Piotr Ożarowski ]
* New upstream release
* Don't ignore errors in postrm maintainer script
* Standards-Version bumped to 3.8.1
  + add debian/README.source file

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/* vim: set sw=4 expandtab : */
2
2
 
3
3
/*
4
 
 * Copyright 2007-2008 GRAHAM DUMPLETON
 
4
 * Copyright 2007-2009 GRAHAM DUMPLETON
5
5
 *
6
6
 * Licensed under the Apache License, Version 2.0 (the "License");
7
7
 * you may not use this file except in compliance with the License.
245
245
/* Version and module information. */
246
246
 
247
247
#define MOD_WSGI_MAJORVERSION_NUMBER 2
248
 
#define MOD_WSGI_MINORVERSION_NUMBER 2
249
 
#define MOD_WSGI_VERSION_STRING "2.3"
 
248
#define MOD_WSGI_MINORVERSION_NUMBER 4
 
249
#define MOD_WSGI_VERSION_STRING "2.4"
250
250
 
251
251
#if AP_SERVER_MAJORVERSION_NUMBER < 2
252
252
module MODULE_VAR_EXPORT wsgi_module;
1055
1055
    PyObject_Del(self);
1056
1056
}
1057
1057
 
 
1058
static PyObject *Log_close(LogObject *self, PyObject *args)
 
1059
{
 
1060
    if (self->expired) {
 
1061
        PyErr_SetString(PyExc_RuntimeError, "log object has expired");
 
1062
        return NULL;
 
1063
    }
 
1064
 
 
1065
    if (!PyArg_ParseTuple(args, ":close"))
 
1066
        return NULL;
 
1067
 
 
1068
    PyErr_SetString(PyExc_RuntimeError, "log object cannot be closed");
 
1069
    return NULL;
 
1070
}
 
1071
 
1058
1072
static PyObject *Log_flush(LogObject *self, PyObject *args)
1059
1073
{
1060
1074
    if (self->expired) {
1247
1261
    return Py_None;
1248
1262
}
1249
1263
 
 
1264
static PyObject *Log_closed(LogObject *self, void *closure)
 
1265
{
 
1266
    Py_INCREF(Py_False);
 
1267
    return Py_False;
 
1268
}
 
1269
 
 
1270
static PyObject *Log_isatty(LogObject *self, void *closure)
 
1271
{
 
1272
    Py_INCREF(Py_False);
 
1273
    return Py_False;
 
1274
}
 
1275
 
1250
1276
static PyMethodDef Log_methods[] = {
1251
 
    { "flush",      (PyCFunction)Log_flush,      METH_VARARGS, 0},
1252
 
    { "write",      (PyCFunction)Log_write,      METH_VARARGS, 0},
1253
 
    { "writelines", (PyCFunction)Log_writelines, METH_VARARGS, 0},
 
1277
    { "close",      (PyCFunction)Log_close,      METH_VARARGS, 0 },
 
1278
    { "flush",      (PyCFunction)Log_flush,      METH_VARARGS, 0 },
 
1279
    { "write",      (PyCFunction)Log_write,      METH_VARARGS, 0 },
 
1280
    { "writelines", (PyCFunction)Log_writelines, METH_VARARGS, 0 },
1254
1281
    { NULL, NULL}
1255
1282
};
1256
1283
 
 
1284
static PyGetSetDef Log_getset[] = {
 
1285
    { "closed", (getter)Log_closed, NULL, 0 },
 
1286
    { "isatty", (getter)Log_isatty, NULL, 0 },
 
1287
    { NULL },
 
1288
};
 
1289
 
1257
1290
static PyTypeObject Log_Type = {
1258
1291
    /* The ob_type field must be initialized in the module init function
1259
1292
     * to be portable to Windows without using C++. */
1288
1321
    0,                      /*tp_iternext*/
1289
1322
    Log_methods,            /*tp_methods*/
1290
1323
    0,                      /*tp_members*/
1291
 
    0,                      /*tp_getset*/
 
1324
    Log_getset,             /*tp_getset*/
1292
1325
    0,                      /*tp_base*/
1293
1326
    0,                      /*tp_dict*/
1294
1327
    0,                      /*tp_descr_get*/
1684
1717
         */
1685
1718
 
1686
1719
        while (!self->done) {
1687
 
            /* Increase the size of the string by 25%. */
1688
 
 
1689
 
            size = size + (size >> 2);
1690
 
 
1691
 
            if (_PyString_Resize(&result, size))
1692
 
                return NULL;
1693
 
 
1694
 
            buffer = PyString_AS_STRING((PyStringObject *)result);
 
1720
            if (length == size) {
 
1721
                /* Increase the size of the string by 25%. */
 
1722
 
 
1723
                size = size + (size >> 2);
 
1724
 
 
1725
                if (_PyString_Resize(&result, size))
 
1726
                    return NULL;
 
1727
 
 
1728
                buffer = PyString_AS_STRING((PyStringObject *)result);
 
1729
            }
1695
1730
 
1696
1731
            /* Now make succesive attempt at reading data. */
1697
1732
 
1992
2027
                    memcpy(self->buffer, p, self->size);
1993
2028
                }
1994
2029
 
1995
 
                if (buffer[length-1] != '\n') {
 
2030
                if (buffer[length-1] != '\n' && length == size) {
1996
2031
                    /* Increase size of string and keep going. */
1997
2032
 
1998
2033
                    size = size + (size >> 2);
2082
2117
}
2083
2118
 
2084
2119
static PyMethodDef Input_methods[] = {
2085
 
    { "close",     (PyCFunction)Input_close,     METH_VARARGS, 0},
2086
 
    { "read",      (PyCFunction)Input_read,      METH_VARARGS, 0},
2087
 
    { "readline",  (PyCFunction)Input_readline,  METH_VARARGS, 0},
2088
 
    { "readlines", (PyCFunction)Input_readlines, METH_VARARGS, 0},
 
2120
    { "close",     (PyCFunction)Input_close,     METH_VARARGS, 0 },
 
2121
    { "read",      (PyCFunction)Input_read,      METH_VARARGS, 0 },
 
2122
    { "readline",  (PyCFunction)Input_readline,  METH_VARARGS, 0 },
 
2123
    { "readlines", (PyCFunction)Input_readlines, METH_VARARGS, 0 },
2089
2124
    { NULL, NULL}
2090
2125
};
2091
2126
 
2422
2457
                return 0;
2423
2458
            }
2424
2459
 
 
2460
            if (strchr(name, '\n') != 0 || strchr(value, '\n') != 0) {
 
2461
                PyErr_Format(PyExc_ValueError, "embedded newline in "
 
2462
                             "response header with name '%s' and value '%s'",
 
2463
                             name, value);
 
2464
                return 0;
 
2465
            }
 
2466
 
2425
2467
            if (!strcasecmp(name, "Content-Type")) {
2426
2468
#if AP_SERVER_MAJORVERSION_NUMBER < 2
2427
2469
                r->content_type = apr_pstrdup(r->pool, value);
2685
2727
 
2686
2728
    APR_BRIGADE_INSERT_TAIL(bb, b);
2687
2729
 
 
2730
    b = apr_bucket_flush_create(r->connection->bucket_alloc);
 
2731
    APR_BRIGADE_INSERT_TAIL(bb, b);
 
2732
 
2688
2733
    b = apr_bucket_eos_create(r->connection->bucket_alloc);
2689
2734
    APR_BRIGADE_INSERT_TAIL(bb, b);
2690
2735
 
2801
2846
    PyDict_SetItemString(vars, "wsgi.file_wrapper", object);
2802
2847
    Py_DECREF(object);
2803
2848
 
 
2849
    /* Add mod_wsgi version information. */
 
2850
 
 
2851
    object = Py_BuildValue("(ii)", MOD_WSGI_MAJORVERSION_NUMBER,
 
2852
                           MOD_WSGI_MINORVERSION_NUMBER);
 
2853
    PyDict_SetItemString(vars, "mod_wsgi.version", object);
 
2854
    Py_DECREF(object);
 
2855
 
2804
2856
    /*
2805
2857
     * If Apache extensions are enabled and running in embedded
2806
2858
     * mode add a CObject reference to the Apache request_rec
3205
3257
}
3206
3258
 
3207
3259
static PyMethodDef Adapter_methods[] = {
3208
 
    { "start_response", (PyCFunction)Adapter_start_response, METH_VARARGS, 0},
3209
 
    { "write",          (PyCFunction)Adapter_write, METH_VARARGS, 0},
3210
 
    { "file_wrapper",   (PyCFunction)Adapter_file_wrapper, METH_VARARGS, 0},
 
3260
    { "start_response", (PyCFunction)Adapter_start_response, METH_VARARGS, 0 },
 
3261
    { "write",          (PyCFunction)Adapter_write, METH_VARARGS, 0 },
 
3262
    { "file_wrapper",   (PyCFunction)Adapter_file_wrapper, METH_VARARGS, 0 },
3211
3263
    { NULL, NULL}
3212
3264
};
3213
3265
 
3366
3418
}
3367
3419
 
3368
3420
static PyMethodDef Stream_methods[] = {
3369
 
    { "close",      (PyCFunction)Stream_close,      METH_VARARGS, 0},
 
3421
    { "close",      (PyCFunction)Stream_close,      METH_VARARGS, 0 },
3370
3422
    { NULL, NULL}
3371
3423
};
3372
3424
 
3538
3590
        }
3539
3591
    }
3540
3592
 
3541
 
    Py_INCREF(m);
 
3593
    Py_XDECREF(m);
3542
3594
 
3543
3595
    Py_INCREF(h);
3544
3596
 
3698
3750
    }
3699
3751
 
3700
3752
    /*
 
3753
     * If running in daemon process, override as appropriate
 
3754
     * the USER, USERNAME or LOGNAME environment  variables
 
3755
     * so that they match the user that the process is running
 
3756
     * as. Need to do this else we inherit the value from the
 
3757
     * Apache parent process which is likely wrong as will be
 
3758
     * root or the user than ran sudo when Apache started.
 
3759
     * Can't update these for normal Apache child processes
 
3760
     * as that would change the expected environment of other
 
3761
     * Apache modules.
 
3762
     */
 
3763
 
 
3764
#ifndef WIN32
 
3765
    if (wsgi_daemon_pool) {
 
3766
        module = PyImport_ImportModule("os");
 
3767
 
 
3768
        if (module) {
 
3769
            PyObject *dict = NULL;
 
3770
            PyObject *key = NULL;
 
3771
            PyObject *value = NULL;
 
3772
 
 
3773
            dict = PyModule_GetDict(module);
 
3774
            object = PyDict_GetItemString(dict, "environ");
 
3775
 
 
3776
            if (object) {
 
3777
                struct passwd *pwent;
 
3778
 
 
3779
                pwent = getpwuid(geteuid());
 
3780
 
 
3781
                if (getenv("USER")) {
 
3782
                    key = PyString_FromString("USER");
 
3783
                    value = PyString_FromString(pwent->pw_name);
 
3784
 
 
3785
                    PyObject_SetItem(object, key, value);
 
3786
 
 
3787
                    Py_DECREF(key);
 
3788
                    Py_DECREF(value);
 
3789
                }
 
3790
 
 
3791
                if (getenv("USERNAME")) {
 
3792
                    key = PyString_FromString("USERNAME");
 
3793
                    value = PyString_FromString(pwent->pw_name);
 
3794
 
 
3795
                    PyObject_SetItem(object, key, value);
 
3796
 
 
3797
                    Py_DECREF(key);
 
3798
                    Py_DECREF(value);
 
3799
                }
 
3800
 
 
3801
                if (getenv("LOGNAME")) {
 
3802
                    key = PyString_FromString("LOGNAME");
 
3803
                    value = PyString_FromString(pwent->pw_name);
 
3804
 
 
3805
                    PyObject_SetItem(object, key, value);
 
3806
 
 
3807
                    Py_DECREF(key);
 
3808
                    Py_DECREF(value);
 
3809
                }
 
3810
            }
 
3811
 
 
3812
            Py_DECREF(module);
 
3813
        }
 
3814
    }
 
3815
#endif
 
3816
 
 
3817
    /*
3701
3818
     * If running in daemon process, override HOME environment
3702
3819
     * variable so that is matches the home directory of the
3703
3820
     * user that the process is running as. Need to do this as
3779
3896
     * added using site.addsitedir() so that any Python .pth
3780
3897
     * files are opened and additional directories so defined
3781
3898
     * are added to default Python search path as well. This
3782
 
     * allows virtual Python environments to work.
 
3899
     * allows virtual Python environments to work. Note that
 
3900
     * site.addsitedir() adds new directories at the end of
 
3901
     * sys.path when they really need to be added in order at
 
3902
     * the start. We therefore need to do a fiddle and shift
 
3903
     * any newly added directories to the start of sys.path.
3783
3904
     */
3784
3905
 
3785
3906
    if (!wsgi_daemon_pool)
3786
3907
        wsgi_python_path = wsgi_server_config->python_path;
3787
3908
 
3788
3909
    if (wsgi_python_path) {
 
3910
        PyObject *path = NULL;
 
3911
 
3789
3912
        module = PyImport_ImportModule("site");
 
3913
        path = PySys_GetObject("path");
3790
3914
 
3791
 
        if (module) {
 
3915
        if (module && path) {
3792
3916
            PyObject *dict = NULL;
3793
3917
 
 
3918
            PyObject *old = NULL;
 
3919
            PyObject *new = NULL;
 
3920
            PyObject *tmp = NULL;
 
3921
 
 
3922
            PyObject *item = NULL;
 
3923
 
 
3924
            int i = 0;
 
3925
 
 
3926
            old = PyList_New(0);
 
3927
            new = PyList_New(0);
 
3928
            tmp = PyList_New(0);
 
3929
 
 
3930
            for (i=0; i<PyList_Size(path); i++)
 
3931
                PyList_Append(old, PyList_GetItem(path, i));
 
3932
 
3794
3933
            dict = PyModule_GetDict(module);
3795
3934
            object = PyDict_GetItemString(dict, "addsitedir");
3796
3935
 
3903
4042
                Py_END_ALLOW_THREADS
3904
4043
            }
3905
4044
 
 
4045
            for (i=0; i<PyList_Size(path); i++)
 
4046
                PyList_Append(tmp, PyList_GetItem(path, i));
 
4047
 
 
4048
            for (i=0; i<PyList_Size(tmp); i++) {
 
4049
                item = PyList_GetItem(tmp, i);
 
4050
                if (!PySequence_Contains(old, item)) {
 
4051
                    int index = PySequence_Index(path, item);
 
4052
                    PyList_Append(new, item);
 
4053
                    if (index != -1)
 
4054
                        PySequence_DelItem(path, index); 
 
4055
                }
 
4056
            }
 
4057
 
 
4058
            PyList_SetSlice(path, 0, 0, new);
 
4059
 
 
4060
            Py_DECREF(old);
 
4061
            Py_DECREF(new);
 
4062
            Py_DECREF(tmp);
 
4063
 
3906
4064
            Py_DECREF(module);
3907
4065
        }
3908
4066
        else {
3909
 
            Py_BEGIN_ALLOW_THREADS
3910
 
            ap_log_error(APLOG_MARK, WSGI_LOG_ERR(0), wsgi_server,
3911
 
                         "mod_wsgi (pid=%d): Unable to import 'site' "
3912
 
                         "module.", getpid());
3913
 
            Py_END_ALLOW_THREADS
 
4067
            if (!module) {
 
4068
                Py_BEGIN_ALLOW_THREADS
 
4069
                ap_log_error(APLOG_MARK, WSGI_LOG_ERR(0), wsgi_server,
 
4070
                             "mod_wsgi (pid=%d): Unable to import 'site' "
 
4071
                             "module.", getpid());
 
4072
                Py_END_ALLOW_THREADS
 
4073
            }
 
4074
 
 
4075
            if (!path) {
 
4076
                Py_BEGIN_ALLOW_THREADS
 
4077
                ap_log_error(APLOG_MARK, WSGI_LOG_ERR(0), wsgi_server,
 
4078
                             "mod_wsgi (pid=%d): Lookup for 'sys.path' "
 
4079
                             "failed.", getpid());
 
4080
                Py_END_ALLOW_THREADS
 
4081
            }
3914
4082
        }
3915
4083
    }
3916
4084
 
3962
4130
                       MOD_WSGI_MAJORVERSION_NUMBER,
3963
4131
                       MOD_WSGI_MINORVERSION_NUMBER));
3964
4132
 
 
4133
    /*
 
4134
     * Add information about process group and application
 
4135
     * group to the Python 'mod_wsgi' module.
 
4136
     */
 
4137
 
 
4138
    PyModule_AddObject(module, "process_group",
 
4139
                       PyString_FromString(wsgi_daemon_group));
 
4140
    PyModule_AddObject(module, "application_group",
 
4141
                       PyString_FromString(name));
 
4142
 
3965
4143
    Py_DECREF(module);
3966
4144
 
3967
4145
    /*
4204
4382
 
4205
4383
                Py_XDECREF(result);
4206
4384
 
4207
 
                Py_DECREF(m);
 
4385
                Py_XDECREF(m);
4208
4386
            }
4209
4387
 
4210
4388
            Py_XDECREF(res);
4313
4491
 
4314
4492
            Py_XDECREF(result);
4315
4493
 
4316
 
            Py_DECREF(m);
 
4494
            Py_XDECREF(m);
4317
4495
        }
4318
4496
 
4319
4497
        Py_XDECREF(res);
4420
4598
    }
4421
4599
}
4422
4600
 
4423
 
static apr_status_t wsgi_python_term(void *data)
 
4601
static apr_status_t wsgi_python_term()
4424
4602
{
4425
4603
    PyInterpreterState *interp = NULL;
4426
4604
    PyThreadState *tstate = NULL;
4448
4626
    return APR_SUCCESS;
4449
4627
}
4450
4628
 
 
4629
#if AP_SERVER_MAJORVERSION_NUMBER < 2
 
4630
static void wsgi_python_parent_cleanup(void *data)
 
4631
#else
 
4632
static apr_status_t wsgi_python_parent_cleanup(void *data)
 
4633
#endif
 
4634
{
 
4635
    if (wsgi_parent_pid == getpid()) {
 
4636
        /*
 
4637
         * Destroy Python itself including the main
 
4638
         * interpreter. If mod_python is being loaded it
 
4639
         * is left to mod_python to destroy Python,
 
4640
         * although it currently doesn't do so.
 
4641
         */
 
4642
 
 
4643
        if (wsgi_python_initialized)
 
4644
            wsgi_python_term();
 
4645
    }
 
4646
 
 
4647
#if AP_SERVER_MAJORVERSION_NUMBER >= 2
 
4648
    return APR_SUCCESS;
 
4649
#endif
 
4650
}
 
4651
 
 
4652
 
4451
4653
static void wsgi_python_init(apr_pool_t *p)
4452
4654
{
4453
4655
#if defined(DARWIN) && (AP_SERVER_MAJORVERSION_NUMBER < 2)
4483
4685
        /* Initialise Python. */
4484
4686
 
4485
4687
        ap_log_error(APLOG_MARK, WSGI_LOG_INFO(0), wsgi_server,
4486
 
                     "mod_wsgi: Initializing Python.");
 
4688
                     "mod_wsgi (pid=%d): Initializing Python.", getpid());
4487
4689
 
4488
4690
        initialized = 1;
4489
4691
 
4513
4715
        PyEval_ReleaseLock();
4514
4716
 
4515
4717
        wsgi_python_initialized = 1;
 
4718
 
 
4719
    /*
 
4720
     * Register cleanups to be performed on parent restart
 
4721
     * or shutdown. This will destroy Python itself.
 
4722
     */
 
4723
 
 
4724
#if AP_SERVER_MAJORVERSION_NUMBER < 2
 
4725
        ap_register_cleanup(p, NULL, wsgi_python_parent_cleanup,
 
4726
                            ap_null_cleanup);
 
4727
#else
 
4728
        apr_pool_cleanup_register(p, NULL, wsgi_python_parent_cleanup,
 
4729
                                  apr_pool_cleanup_null);
 
4730
#endif
4516
4731
    }
4517
4732
}
4518
4733
 
4753
4968
            }
4754
4969
#else
4755
4970
            apr_finfo_t finfo;
4756
 
            if (apr_stat(&finfo, filename, APR_FINFO_SIZE,
 
4971
            if (apr_stat(&finfo, filename, APR_FINFO_NORM,
4757
4972
                         pool) != APR_SUCCESS) {
4758
4973
                object = PyLong_FromLongLong(0);
4759
4974
            }
4819
5034
            }
4820
5035
#else
4821
5036
            apr_finfo_t finfo;
4822
 
            if (apr_stat(&finfo, filename, APR_FINFO_SIZE,
 
5037
            if (apr_stat(&finfo, filename, APR_FINFO_NORM,
4823
5038
                         pool) != APR_SUCCESS) {
4824
5039
                return 1;
4825
5040
            }
5164
5379
}
5165
5380
 
5166
5381
/*
5167
 
 * Apache child process initialision and cleanup. Initialise
 
5382
 * Apache child process initialisation and cleanup. Initialise
5168
5383
 * global table containing Python interpreter instances and
5169
5384
 * cache reference to main interpreter. Also register cleanup
5170
5385
 * function to delete interpreter on process shutdown.
5224
5439
    /*
5225
5440
     * Destroy Python itself including the main interpreter.
5226
5441
     * If mod_python is being loaded it is left to mod_python to
5227
 
     * destroy mod_python, although it currently doesn't do so.
 
5442
     * destroy Python, although it currently doesn't do so.
5228
5443
     */
5229
5444
 
5230
5445
    if (wsgi_python_initialized)
5231
 
        wsgi_python_term(0);
 
5446
        wsgi_python_term();
5232
5447
 
5233
5448
#if AP_SERVER_MAJORVERSION_NUMBER >= 2
5234
5449
    return APR_SUCCESS;
5412
5627
                                              entry->handler_script,
5413
5628
                                              entry->process_group,
5414
5629
                                              entry->application_group);
 
5630
 
 
5631
                    if (PyErr_Occurred()) 
 
5632
                        PyErr_Clear(); 
5415
5633
                }
5416
5634
 
5417
5635
                /* Safe now to release the module lock. */
5655
5873
    while (*args) {
5656
5874
        char const *option;
5657
5875
 
5658
 
        option = ap_getword_conf(cmd->temp_pool, &args);
 
5876
        option = ap_getword_conf(cmd->pool, &args);
5659
5877
 
5660
5878
        if (!strcmp(option, "%{GLOBAL}"))
5661
5879
            option = "";
5744
5962
 
5745
5963
    object = (WSGIScriptFile *)apr_array_push(sconfig->import_list);
5746
5964
 
5747
 
    object->handler_script = ap_getword_conf(cmd->temp_pool, &args);
 
5965
    object->handler_script = ap_getword_conf(cmd->pool, &args);
5748
5966
    object->process_group = NULL;
5749
5967
    object->application_group = NULL;
5750
5968
 
5752
5970
        return "Location of import script not supplied.";
5753
5971
 
5754
5972
    while (*args) {
5755
 
        option = ap_getword_conf(cmd->temp_pool, &args);
 
5973
        option = ap_getword_conf(cmd->pool, &args);
5756
5974
 
5757
5975
        if (strstr(option, "application-group=") == option) {
5758
5976
            value = option + 18;
5803
6021
 
5804
6022
    object = newWSGIScriptFile(cmd->pool);
5805
6023
 
5806
 
    object->handler_script = ap_getword_conf(cmd->temp_pool, &args);
 
6024
    object->handler_script = ap_getword_conf(cmd->pool, &args);
5807
6025
 
5808
6026
    if (!object->handler_script || !*object->handler_script)
5809
6027
        return "Location of dispatch script not supplied.";
5810
6028
 
5811
6029
    while (*args) {
5812
 
        option = ap_getword_conf(cmd->temp_pool, &args);
 
6030
        option = ap_getword_conf(cmd->pool, &args);
5813
6031
 
5814
6032
        if (strstr(option, "application-group=") == option) {
5815
6033
            value = option + 18;
5972
6190
 
5973
6191
    object = newWSGIScriptFile(cmd->pool);
5974
6192
 
5975
 
    object->handler_script = ap_getword_conf(cmd->temp_pool, &args);
 
6193
    object->handler_script = ap_getword_conf(cmd->pool, &args);
5976
6194
 
5977
6195
    if (!object->handler_script || !*object->handler_script)
5978
6196
        return "Location of access script not supplied.";
5979
6197
 
5980
6198
    while (*args) {
5981
 
        option = ap_getword_conf(cmd->temp_pool, &args);
 
6199
        option = ap_getword_conf(cmd->pool, &args);
5982
6200
 
5983
6201
        if (strstr(option, "application-group=") == option) {
5984
6202
            value = option + 18;
6008
6226
 
6009
6227
    object = newWSGIScriptFile(cmd->pool);
6010
6228
 
6011
 
    object->handler_script = ap_getword_conf(cmd->temp_pool, &args);
 
6229
    object->handler_script = ap_getword_conf(cmd->pool, &args);
6012
6230
 
6013
6231
    if (!object->handler_script || !*object->handler_script)
6014
6232
        return "Location of auth user script not supplied.";
6015
6233
 
6016
6234
    while (*args) {
6017
 
        option = ap_getword_conf(cmd->temp_pool, &args);
 
6235
        option = ap_getword_conf(cmd->pool, &args);
6018
6236
 
6019
6237
        if (strstr(option, "application-group=") == option) {
6020
6238
            value = option + 18;
6044
6262
 
6045
6263
    object = newWSGIScriptFile(cmd->pool);
6046
6264
 
6047
 
    object->handler_script = ap_getword_conf(cmd->temp_pool, &args);
 
6265
    object->handler_script = ap_getword_conf(cmd->pool, &args);
6048
6266
 
6049
6267
    if (!object->handler_script || !*object->handler_script)
6050
6268
        return "Location of auth group script not supplied.";
6051
6269
 
6052
6270
    while (*args) {
6053
 
        option = ap_getword_conf(cmd->temp_pool, &args);
 
6271
        option = ap_getword_conf(cmd->pool, &args);
6054
6272
 
6055
6273
        if (strstr(option, "application-group=") == option) {
6056
6274
            value = option + 18;
6226
6444
        n = r->filename;
6227
6445
 
6228
6446
    message = apr_psprintf(r->pool, "%s: %s", e, n);
6229
 
    apr_table_set(r->notes, "error-notes", message);
6230
6447
 
6231
 
    ap_log_rerror(APLOG_MARK, WSGI_LOG_ERR(0), r, message);
 
6448
    ap_log_rerror(APLOG_MARK, WSGI_LOG_ERR(0), r, "%s", message);
6232
6449
}
6233
6450
 
6234
6451
static void wsgi_build_environment(request_rec *r)
7308
7525
 
7309
7526
    /* Now parse options for directive. */
7310
7527
 
7311
 
    name = ap_getword_conf(cmd->temp_pool, &args);
 
7528
    name = ap_getword_conf(cmd->pool, &args);
7312
7529
 
7313
7530
    if (!name || !*name)
7314
7531
        return "Name of WSGI daemon process not supplied.";
7315
7532
 
7316
7533
    while (*args) {
7317
 
        option = ap_getword_conf(cmd->temp_pool, &args);
 
7534
        option = ap_getword_conf(cmd->pool, &args);
7318
7535
 
7319
7536
        if (strstr(option, "user=") == option) {
7320
7537
            value = option + 5;
7617
7834
    return NULL;
7618
7835
}
7619
7836
 
 
7837
static apr_file_t *wsgi_signal_pipe_in = NULL;
 
7838
static apr_file_t *wsgi_signal_pipe_out = NULL;
 
7839
 
7620
7840
static void wsgi_signal_handler(int signum)
7621
7841
{
 
7842
    apr_size_t nbytes = 1;
 
7843
 
 
7844
    apr_file_write(wsgi_signal_pipe_out, "X", &nbytes);
 
7845
    apr_file_flush(wsgi_signal_pipe_out);
 
7846
 
7622
7847
    wsgi_daemon_shutdown++;
7623
7848
}
7624
7849
 
7625
 
static int wsgi_check_signal(int signum)
7626
 
{
7627
 
    if (signum == SIGINT || signum == SIGTERM) {
7628
 
        wsgi_daemon_shutdown++;
7629
 
 
7630
 
        return 1;
7631
 
    }
7632
 
 
7633
 
    return 0;
7634
 
}
7635
 
 
7636
7850
static int wsgi_start_process(apr_pool_t *p, WSGIDaemonProcess *daemon);
7637
7851
 
7638
7852
static void wsgi_manage_process(int reason, void *data, apr_wait_t status)
8380
8594
    apr_status_t rv;
8381
8595
    apr_status_t thread_rv;
8382
8596
 
8383
 
    /* Block all signals from being received. */
8384
 
 
8385
 
    rv = apr_setup_signal_thread();
 
8597
    apr_pollfd_t poll_fd;
 
8598
    apr_int32_t poll_count = 0;
 
8599
 
 
8600
    /*
 
8601
     * Create pipe by which signal handler can notify the main
 
8602
     * thread that signal has arrived indicating that process
 
8603
     * needs to shutdown.
 
8604
     */
 
8605
 
 
8606
    rv = apr_file_pipe_create(&wsgi_signal_pipe_in, &wsgi_signal_pipe_out, p);
 
8607
 
8386
8608
    if (rv != APR_SUCCESS) {
8387
8609
        ap_log_error(APLOG_MARK, WSGI_LOG_EMERG(rv), wsgi_server,
8388
8610
                     "mod_wsgi (pid=%d): Couldn't initialise signal "
8389
 
                     "thread in daemon process '%s'.", getpid(),
 
8611
                     "pipe in daemon process '%s'.", getpid(),
8390
8612
                     daemon->group->name);
8391
8613
        sleep(20);
8392
8614
 
8393
8615
        return;
8394
8616
    }
8395
8617
 
 
8618
    poll_fd.desc_type = APR_POLL_FILE;
 
8619
    poll_fd.reqevents = APR_POLLIN;
 
8620
    poll_fd.desc.f = wsgi_signal_pipe_in;
 
8621
 
8396
8622
    /* Initialise maximum request count for daemon. */
8397
8623
 
8398
8624
    if (daemon->group->maximum_requests)
8480
8706
 
8481
8707
    /* Block until we get a process shutdown signal. */
8482
8708
 
8483
 
    apr_signal_thread(wsgi_check_signal);
 
8709
    do {
 
8710
        rv = apr_poll(&poll_fd, 1, &poll_count, -1);
 
8711
    } while (APR_STATUS_IS_EINTR(rv));
8484
8712
 
8485
8713
    ap_log_error(APLOG_MARK, WSGI_LOG_INFO(0), wsgi_server,
8486
8714
                 "mod_wsgi (pid=%d): Shutdown requested '%s'.",
8665
8893
        ap_close_listeners();
8666
8894
 
8667
8895
        /*
 
8896
         * Cleanup the Apache scoreboard to ensure that any
 
8897
         * shared memory segments or memory mapped files not
 
8898
         * available to code in daemon processes.
 
8899
         */
 
8900
 
 
8901
        ap_cleanup_scoreboard(0);
 
8902
 
 
8903
        /*
8668
8904
         * Wipe out random value used in magic token so that not
8669
8905
         * possible for user code running in daemon process to
8670
8906
         * discover this value for other daemon process groups.
8704
8940
 
8705
8941
        wsgi_daemon_shutdown = 0;
8706
8942
 
8707
 
        if (daemon->group->threads == 1) {
8708
 
            apr_signal(SIGINT, wsgi_signal_handler);
8709
 
            apr_signal(SIGTERM, wsgi_signal_handler);
8710
 
        }
 
8943
        apr_signal(SIGINT, wsgi_signal_handler);
 
8944
        apr_signal(SIGTERM, wsgi_signal_handler);
8711
8945
 
8712
8946
        /*
8713
8947
         * Flag whether multiple daemon processes or denoted
8854
9088
        entry = &entries[i];
8855
9089
 
8856
9090
        /*
 
9091
         * Check for whether the daemon process user and
 
9092
         * group are the default Apache values. If they are
 
9093
         * then reset them to the current values configured for
 
9094
         * Apache. This is to work around where the User/Group
 
9095
         * directives had not been set before the WSGIDaemonProcess
 
9096
         * directive was used in configuration file. In this case,
 
9097
         * where no 'user' and 'group' options were provided,
 
9098
         * the default values would have been used, but these
 
9099
         * were later overridden thus why we need to update it.
 
9100
         */
 
9101
 
 
9102
        if (entry->uid == ap_uname2id(DEFAULT_USER)) {
 
9103
            entry->uid = unixd_config.user_id;
 
9104
            entry->user = unixd_config.user_name;
 
9105
 
 
9106
            ap_log_error(APLOG_MARK, WSGI_LOG_DEBUG(0), wsgi_server,
 
9107
                         "mod_wsgi (pid=%d): Reset default user for "
 
9108
                         "daemon process group '%s' to uid=%ld.",
 
9109
                         getpid(), entry->name, (long)entry->uid);
 
9110
        }
 
9111
 
 
9112
        if (entry->gid == ap_gname2id(DEFAULT_GROUP)) {
 
9113
            entry->gid = unixd_config.group_id;
 
9114
 
 
9115
            ap_log_error(APLOG_MARK, WSGI_LOG_DEBUG(0), wsgi_server,
 
9116
                         "mod_wsgi (pid=%d): Reset default group for "
 
9117
                         "daemon process group '%s' to gid=%ld.",
 
9118
                         getpid(), entry->name, (long)entry->gid);
 
9119
        }
 
9120
 
 
9121
        /*
8857
9122
         * Calculate path for socket to accept requests on and
8858
9123
         * create the socket.
8859
9124
         */
9380
9645
        }
9381
9646
    }
9382
9647
 
 
9648
    /*
 
9649
     * Need to reset request status value to HTTP_OK else it
 
9650
     * screws up HTTP input filter when processing a POST
 
9651
     * request with 100-continue requirement.
 
9652
     */
 
9653
 
 
9654
    r->status = HTTP_OK;
 
9655
 
9383
9656
    /* Transfer any request content which was provided. */
9384
9657
 
9385
9658
    seen_eos = 0;
9805
10078
 
9806
10079
    r->filename = (char *)apr_table_get(r->subprocess_env, "SCRIPT_FILENAME");
9807
10080
 
9808
 
    if ((rv = apr_stat(&r->finfo, r->filename, APR_FINFO_SIZE,
 
10081
    if ((rv = apr_stat(&r->finfo, r->filename, APR_FINFO_NORM,
9809
10082
                       r->pool)) != APR_SUCCESS) {
9810
10083
        /*
9811
10084
         * Don't fail at this point. Allow the lack of file to
10036
10309
 
10037
10310
static void wsgi_hook_child_init(apr_pool_t *p, server_rec *s)
10038
10311
{
 
10312
#if defined(MOD_WSGI_WITH_DAEMONS)
10039
10313
    WSGIProcessGroup *entries = NULL;
10040
10314
    WSGIProcessGroup *entry = NULL;
10041
10315
 
10053
10327
            entry->listener_fd = -1;
10054
10328
        }
10055
10329
    }
 
10330
#endif
10056
10331
 
10057
10332
    /* Setup Python in Apache worker processes. */
10058
10333