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

« back to all changes in this revision

Viewing changes to src/serverobject.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
 * serverobject.c 
 
20
 *
 
21
 * $Id: serverobject.c,v 1.22 2004/02/16 19:47:27 grisha Exp $
 
22
 *
 
23
 */
 
24
 
 
25
#include "mod_python.h"
 
26
 
 
27
 
 
28
/**
 
29
 **     MpServer_FromServer
 
30
 **
 
31
 *      This routine creates a Python serverobject given an Apache
 
32
 *      server_rec pointer.
 
33
 *
 
34
 */
 
35
 
 
36
PyObject * MpServer_FromServer(server_rec *s)
 
37
{
 
38
    serverobject *result;
 
39
 
 
40
    result = PyObject_New(serverobject, &MpServer_Type);
 
41
    if (! result)
 
42
        return PyErr_NoMemory();
 
43
 
 
44
    result->dict = PyDict_New();
 
45
    if (!result->dict)
 
46
        return PyErr_NoMemory();
 
47
 
 
48
    result->server = s;
 
49
    result->next = NULL;
 
50
 
 
51
    return (PyObject *)result;
 
52
}
 
53
 
 
54
/**
 
55
 ** server.get_config(server self)
 
56
 **
 
57
 *     Returns the config directives set through Python* apache directives.
 
58
 *     unlike req.get_config, this one returns the per-server config
 
59
 */
 
60
 
 
61
static PyObject * server_get_config(serverobject *self)
 
62
{
 
63
    py_config *conf =
 
64
        (py_config *) ap_get_module_config(self->server->module_config, 
 
65
                                           &python_module);
 
66
    return MpTable_FromTable(conf->directives);
 
67
}
 
68
 
 
69
/**
 
70
 ** server.register_cleanup(req, handler, data)
 
71
 **
 
72
 *    same as request.register_cleanup, except the server pool is used.
 
73
 *    the server pool gets destroyed before the child dies or when the
 
74
 *    whole process dies in multithreaded situations.
 
75
 */
 
76
 
 
77
static PyObject *server_register_cleanup(serverobject *self, PyObject *args)
 
78
{
 
79
 
 
80
    cleanup_info *ci;
 
81
    PyObject *handler = NULL;
 
82
    PyObject *data = NULL;
 
83
    requestobject *req = NULL;
 
84
 
 
85
    if (! PyArg_ParseTuple(args, "OO|O", &req, &handler, &data))
 
86
        return NULL; 
 
87
 
 
88
    if (! MpRequest_Check(req)) {
 
89
        PyErr_SetString(PyExc_ValueError, 
 
90
                        "first argument must be a request object");
 
91
        return NULL;
 
92
    }
 
93
    else if(!PyCallable_Check(handler)) {
 
94
        PyErr_SetString(PyExc_ValueError, 
 
95
                        "second argument must be a callable object");
 
96
        return NULL;
 
97
    }
 
98
    
 
99
    ci = (cleanup_info *)malloc(sizeof(cleanup_info));
 
100
    ci->request_rec = NULL;
 
101
    ci->server_rec = self->server;
 
102
    Py_INCREF(handler);
 
103
    ci->handler = handler;
 
104
    ci->interpreter = req->interpreter;
 
105
    if (data) {
 
106
        Py_INCREF(data);
 
107
        ci->data = data;
 
108
    }
 
109
    else {
 
110
        Py_INCREF(Py_None);
 
111
        ci->data = Py_None;
 
112
    }
 
113
    
 
114
    apr_pool_cleanup_register(child_init_pool, ci, python_cleanup, 
 
115
                              apr_pool_cleanup_null);
 
116
    
 
117
    Py_INCREF(Py_None);
 
118
    return Py_None;
 
119
}
 
120
 
 
121
static PyMethodDef server_methods[] = {
 
122
    {"get_config",           (PyCFunction) server_get_config,        METH_NOARGS},
 
123
    {"register_cleanup",     (PyCFunction) server_register_cleanup,  METH_VARARGS},
 
124
    { NULL, NULL } /* sentinel */
 
125
};
 
126
 
 
127
 
 
128
/* 
 
129
   These are offsets into the Apache server_rec structure.
 
130
   They are accessed via getset functions. Note that the types
 
131
   specified here are irrelevant if a function other than
 
132
   getreq_recmbr() is used. E.g. bytes_sent is a long long,
 
133
   and is retrieved via getreq_recmbr_off() which ignores what's
 
134
   here.
 
135
*/
 
136
 
 
137
#define OFF(x) offsetof(server_rec, x)
 
138
 
 
139
static struct PyMemberDef server_rec_mbrs[] = {
 
140
    {"defn_name",          T_STRING,  OFF(defn_name)},
 
141
    {"defn_line_number",   T_INT,     OFF(defn_line_number)},
 
142
    {"server_admin",       T_STRING,  OFF(server_admin)},
 
143
    {"server_hostname",    T_STRING,  OFF(server_hostname)},
 
144
    {"port",               T_SHORT,   OFF(port)},
 
145
    {"error_fname",        T_STRING,  OFF(error_fname)},
 
146
    {"loglevel",           T_INT,     OFF(loglevel)},
 
147
    {"is_virtual",         T_INT,     OFF(is_virtual)},
 
148
    /* XXX implement module_config ? */
 
149
    /* XXX implement lookup_defaults ? */
 
150
    /* XXX implement server_addr_rec ? */
 
151
    {"timeout",            T_LONG,    OFF(timeout)},
 
152
    {"keep_alive_timeout", T_LONG,    OFF(keep_alive_timeout)},
 
153
    {"keep_alive_max",     T_INT,     OFF(keep_alive_max)},
 
154
    {"keep_alive",         T_INT,     OFF(keep_alive)},
 
155
    /* XXX send_buffer_size gone. where? document */
 
156
    /*{"send_buffer_size",   T_INT,       OFF(send_buffer_size),   RO},*/
 
157
    {"path",               T_STRING,  OFF(path)},
 
158
    {"pathlen",            T_INT,     OFF(pathlen)},
 
159
    {"names",              T_OBJECT,  OFF(names)},
 
160
    {"wild_names",         T_OBJECT,  OFF(wild_names)},
 
161
    /* XXX server_uid and server_gid seem gone. Where? Document. */
 
162
    /*{"server_uid",         T_INT,       OFF(server_uid),         RO},*/
 
163
    /*{"server_gid",         T_INT,       OFF(server_gid),         RO},*/
 
164
    /* XXX Document limit* below. Make RW? */
 
165
    {"limit_req_line",       T_INT,   OFF(limit_req_line)},
 
166
    {"limit_req_fieldsize",  T_INT,   OFF(limit_req_fieldsize)},
 
167
    {"limit_req_fields",     T_INT,   OFF(limit_req_fields)},
 
168
    {NULL}  /* Sentinel */
 
169
};
 
170
 
 
171
/**
 
172
 ** getsrv_recmbr
 
173
 **
 
174
 *    Retrieves server_rec structure members
 
175
 */
 
176
 
 
177
static PyObject *getsrv_recmbr(serverobject *self, void *name) 
 
178
{
 
179
    return PyMember_GetOne((char*)self->server,
 
180
                           find_memberdef(server_rec_mbrs, name));
 
181
}
 
182
 
 
183
/* we don't need setsrv_recmbr for now */
 
184
 
 
185
/**
 
186
 ** getsrv_recmbr_time
 
187
 **
 
188
 *    Retrieves apr_time_t server_rec members
 
189
 */
 
190
 
 
191
static PyObject *getsrv_recmbr_time(serverobject *self, void *name) 
 
192
{
 
193
    PyMemberDef *md = find_memberdef(server_rec_mbrs, name);
 
194
    char *addr = (char *)self->server + md->offset;
 
195
    apr_time_t time = *(apr_time_t*)addr;
 
196
    return PyFloat_FromDouble(time*0.000001);
 
197
}
 
198
 
 
199
/**
 
200
 ** getsrv_rec_ah
 
201
 **
 
202
 *    For array headers that will get converted to tuple
 
203
 */
 
204
 
 
205
static PyObject *getsrv_recmbr_ah(serverobject *self, void *name) 
 
206
{
 
207
    const PyMemberDef *md = find_memberdef(server_rec_mbrs, name);
 
208
    apr_array_header_t *ah = 
 
209
        (apr_array_header_t *)((char *)self->server + md->offset);
 
210
 
 
211
    return tuple_from_array_header(ah);
 
212
}
 
213
 
 
214
/**
 
215
 ** getmakeobj
 
216
 **
 
217
 *    A getter func that creates an object as needed.
 
218
 */
 
219
 
 
220
static PyObject *getmakeobj(serverobject* self, void *objname) 
 
221
{
 
222
    char *name = (char *)objname;
 
223
    PyObject *result = NULL;
 
224
 
 
225
    if (strcmp(name, "next") == 0) {
 
226
        if (!self->next && self->server->next)
 
227
            self->next = MpServer_FromServer(self->server->next);
 
228
        result = self->next;
 
229
    }
 
230
 
 
231
    if (!result)
 
232
        result = Py_None;
 
233
 
 
234
    Py_INCREF(result);
 
235
    return result;
 
236
}
 
237
 
 
238
static PyObject *my_generation(serverobject *self, void *objname)
 
239
{
 
240
    return PyInt_FromLong((long)ap_my_generation);
 
241
}
 
242
 
 
243
static PyObject *restart_time(serverobject *self, void *objname)
 
244
{
 
245
    return PyFloat_FromDouble(ap_scoreboard_image->global->restart_time*0.000001);
 
246
}
 
247
 
 
248
static PyGetSetDef server_getsets[] = {
 
249
    /* XXX process */
 
250
    {"next",         (getter)getmakeobj,    NULL, "The next server in the list", "next"},
 
251
    {"defn_name",    (getter)getsrv_recmbr, NULL, "The name of the server", "defn_name"},
 
252
    {"defn_line_number",    (getter)getsrv_recmbr, NULL, 
 
253
          "The line of the config file that the server was defined on", "defn_line_number"},
 
254
    {"server_admin", (getter)getsrv_recmbr, NULL, "The admin's contact information", "server_admin"},
 
255
    {"server_hostname",    (getter)getsrv_recmbr, NULL, "The server hostname", "server_hostname"},
 
256
    {"port",    (getter)getsrv_recmbr, NULL, " for redirects, etc.", "port"},
 
257
    {"error_fname",    (getter)getsrv_recmbr, NULL, "The name of the error log", "error_fname"},
 
258
    /* XXX error_log apr_file_t */
 
259
    {"loglevel",    (getter)getsrv_recmbr, NULL, "The log level for this server", "loglevel"},
 
260
    {"is_virtual",    (getter)getsrv_recmbr, NULL, "true if this is the virtual server", "is_virtual"},
 
261
    {"timeout",    (getter)getsrv_recmbr_time, NULL, "Timeout, as interval, before we give up", "timeout"},
 
262
    {"keep_alive_timeout",    (getter)getsrv_recmbr_time, NULL, "The apr interval we will wait for another request", "keep_alive_timeout"},
 
263
    {"keep_alive_max",    (getter)getsrv_recmbr, NULL, "Maximum requests per connection", "keep_alive_max"},
 
264
    {"keep_alive",    (getter)getsrv_recmbr, NULL, "Use persistent connections?", "keep_alive"},
 
265
    {"path",    (getter)getsrv_recmbr, NULL, "Pathname for ServerPath", "path"},
 
266
    {"pathlen",    (getter)getsrv_recmbr, NULL, "Length of path", "pathlen"},
 
267
    {"names",    (getter)getsrv_recmbr_ah, NULL, "Normal names for ServerAlias servers", "names"},
 
268
    {"wild_names",    (getter)getsrv_recmbr_ah, NULL, "Wildcarded names for ServerAlias servers", "wild_names"},
 
269
    {"limit_req_line",    (getter)getsrv_recmbr, NULL, "limit on size of the HTTP request line", "limit_req_line"},
 
270
    {"limit_req_fieldsize",    (getter)getsrv_recmbr, NULL, "limit on size of any request header field", "limit_req_fieldsize"},
 
271
    {"limit_req_fields",    (getter)getsrv_recmbr, NULL, "limit on number of request header fields", "limit_req_fields"},
 
272
    {"my_generation",    (getter)my_generation, NULL, "Generation of this child", "my_generation"},
 
273
    {"restart_time",    (getter)restart_time, NULL, "Server restart time", "restart_time"},
 
274
    {NULL}  /* Sentinel */
 
275
};
 
276
 
 
277
 
 
278
/**
 
279
 ** server_dealloc
 
280
 **
 
281
 *
 
282
 */
 
283
 
 
284
static void server_dealloc(serverobject *self)
 
285
{  
 
286
    Py_XDECREF(self->dict);
 
287
    Py_XDECREF(self->next);
 
288
    PyObject_Del(self);
 
289
}
 
290
 
 
291
static char server_doc[] =
 
292
"Apache server_rec structure\n";
 
293
 
 
294
PyTypeObject MpServer_Type = {
 
295
    PyObject_HEAD_INIT(NULL)
 
296
    0,
 
297
    "mp_server",
 
298
    sizeof(serverobject),
 
299
    0,
 
300
    (destructor) server_dealloc,     /*tp_dealloc*/
 
301
    0,                               /*tp_print*/
 
302
    0,                               /*tp_getattr*/
 
303
    0,                               /*tp_setattr*/
 
304
    0,                               /*tp_compare*/
 
305
    0,                               /*tp_repr*/
 
306
    0,                               /*tp_as_number*/
 
307
    0,                               /*tp_as_sequence*/
 
308
    0,                               /*tp_as_mapping*/
 
309
    0,                               /*tp_hash*/
 
310
    0,                               /* tp_call */
 
311
    0,                               /* tp_str */
 
312
    PyObject_GenericGetAttr,         /* tp_getattro */
 
313
    PyObject_GenericSetAttr,         /* tp_setattro */
 
314
    0,                               /* tp_as_buffer */
 
315
    Py_TPFLAGS_DEFAULT |
 
316
    Py_TPFLAGS_BASETYPE,             /* tp_flags */
 
317
    server_doc,                      /* tp_doc */
 
318
    0,                               /* tp_traverse */
 
319
    0,                               /* tp_clear */
 
320
    0,                               /* tp_richcompare */
 
321
    0,                               /* tp_weaklistoffset */
 
322
    0,                               /* tp_iter */
 
323
    0,                               /* tp_iternext */
 
324
    server_methods,                  /* tp_methods */
 
325
    0,                               /* tp_members */
 
326
    server_getsets,                  /* tp_getset */
 
327
    0,                               /* tp_base */
 
328
    0,                               /* tp_dict */
 
329
    0,                               /* tp_descr_get */
 
330
    0,                               /* tp_descr_set */
 
331
    offsetof(serverobject, dict),    /* tp_dictoffset */
 
332
    0,                               /* tp_init */
 
333
    0,                               /* tp_alloc */
 
334
    0,                               /* tp_new */
 
335
    (destructor)server_dealloc,      /* tp_free */
 
336
};
 
337
 
 
338
 
 
339
 
 
340
 
 
341