mirror of https://git.kore.io/kore.git
Python HTTP improvements.
1) Add @kore.prerequest python decorator. Using this decorator on a function will cause that function to always be executed *before* any page handler is run. eg: @kore.prerequest def _check(req): if req.method == kore.HTTP_METHOD_POST: req.populate_post() 2) Allow attributes to be set on the pyhttp object.
This commit is contained in:
parent
89e58fa474
commit
9cc58d45c1
|
@ -45,6 +45,7 @@ static PyObject *python_kore_fatalx(PyObject *, PyObject *);
|
|||
static PyObject *python_kore_suspend(PyObject *, PyObject *);
|
||||
static PyObject *python_kore_shutdown(PyObject *, PyObject *);
|
||||
static PyObject *python_kore_bind_unix(PyObject *, PyObject *);
|
||||
static PyObject *python_kore_prerequest(PyObject *, PyObject *);
|
||||
static PyObject *python_kore_task_create(PyObject *, PyObject *);
|
||||
static PyObject *python_kore_socket_wrap(PyObject *, PyObject *);
|
||||
static PyObject *python_kore_gather(PyObject *, PyObject *, PyObject *);
|
||||
|
@ -80,6 +81,7 @@ static struct PyMethodDef pykore_methods[] = {
|
|||
METHOD("suspend", python_kore_suspend, METH_VARARGS),
|
||||
METHOD("shutdown", python_kore_shutdown, METH_NOARGS),
|
||||
METHOD("bind_unix", python_kore_bind_unix, METH_VARARGS),
|
||||
METHOD("prerequest", python_kore_prerequest, METH_VARARGS),
|
||||
METHOD("task_create", python_kore_task_create, METH_VARARGS),
|
||||
METHOD("socket_wrap", python_kore_socket_wrap, METH_VARARGS),
|
||||
METHOD("websocket_broadcast", python_websocket_broadcast, METH_VARARGS),
|
||||
|
@ -544,6 +546,7 @@ static PyTypeObject pyconnection_type = {
|
|||
struct pyhttp_request {
|
||||
PyObject_HEAD
|
||||
struct http_request *req;
|
||||
PyObject *dict;
|
||||
PyObject *data;
|
||||
};
|
||||
|
||||
|
@ -621,10 +624,13 @@ static PyTypeObject pyhttp_request_type = {
|
|||
PyVarObject_HEAD_INIT(NULL, 0)
|
||||
.tp_name = "kore.http_request",
|
||||
.tp_doc = "struct http_request",
|
||||
.tp_setattro = PyObject_GenericSetAttr,
|
||||
.tp_getattro = PyObject_GenericGetAttr,
|
||||
.tp_getset = pyhttp_request_getset,
|
||||
.tp_methods = pyhttp_request_methods,
|
||||
.tp_dealloc = (destructor)pyhttp_dealloc,
|
||||
.tp_basicsize = sizeof(struct pyhttp_request),
|
||||
.tp_dictoffset = offsetof(struct pyhttp_request, dict),
|
||||
.tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
|
||||
};
|
||||
|
||||
|
|
53
src/python.c
53
src/python.c
|
@ -40,6 +40,13 @@
|
|||
#include "python_api.h"
|
||||
#include "python_methods.h"
|
||||
|
||||
struct reqcall {
|
||||
PyObject *f;
|
||||
LIST_ENTRY(reqcall) list;
|
||||
};
|
||||
|
||||
LIST_HEAD(reqcall_list, reqcall);
|
||||
|
||||
static PyMODINIT_FUNC python_module_init(void);
|
||||
static PyObject *python_import(const char *);
|
||||
static PyObject *pyconnection_alloc(struct connection *);
|
||||
|
@ -177,6 +184,7 @@ static PyMemAllocatorEx allocator = {
|
|||
};
|
||||
|
||||
static TAILQ_HEAD(, pyproc) procs;
|
||||
static struct reqcall_list prereq;
|
||||
|
||||
static struct kore_pool coro_pool;
|
||||
static struct kore_pool iterobj_pool;
|
||||
|
@ -204,6 +212,8 @@ kore_python_init(void)
|
|||
coro_id = 0;
|
||||
coro_count = 0;
|
||||
|
||||
LIST_INIT(&prereq);
|
||||
|
||||
TAILQ_INIT(&procs);
|
||||
TAILQ_INIT(&coro_runnable);
|
||||
TAILQ_INIT(&coro_suspended);
|
||||
|
@ -620,6 +630,7 @@ pyconnection_dealloc(struct pyconnection *pyc)
|
|||
static void
|
||||
pyhttp_dealloc(struct pyhttp_request *pyreq)
|
||||
{
|
||||
Py_XDECREF(pyreq->dict);
|
||||
Py_XDECREF(pyreq->data);
|
||||
PyObject_Del((PyObject *)pyreq);
|
||||
}
|
||||
|
@ -633,7 +644,8 @@ pyhttp_file_dealloc(struct pyhttp_file *pyfile)
|
|||
static int
|
||||
python_runtime_http_request(void *addr, struct http_request *req)
|
||||
{
|
||||
PyObject *pyret, *pyreq, *args, *callable;
|
||||
struct reqcall *rq;
|
||||
PyObject *pyret, *pyreq, *args, *callable;
|
||||
|
||||
if (req->py_coro != NULL) {
|
||||
python_coro_wakeup(req->py_coro);
|
||||
|
@ -650,6 +662,26 @@ python_runtime_http_request(void *addr, struct http_request *req)
|
|||
if ((pyreq = pyhttp_request_alloc(req)) == NULL)
|
||||
fatal("python_runtime_http_request: pyreq alloc failed");
|
||||
|
||||
LIST_FOREACH(rq, &prereq, list) {
|
||||
PyErr_Clear();
|
||||
pyret = PyObject_CallFunctionObjArgs(rq->f, pyreq, NULL);
|
||||
|
||||
if (pyret == NULL) {
|
||||
Py_DECREF(pyreq);
|
||||
kore_python_log_error("prerequest");
|
||||
http_response(req, HTTP_STATUS_INTERNAL_ERROR, NULL, 0);
|
||||
return (KORE_RESULT_OK);
|
||||
}
|
||||
|
||||
if (pyret == Py_False) {
|
||||
Py_DECREF(pyreq);
|
||||
Py_DECREF(pyret);
|
||||
return (KORE_RESULT_OK);
|
||||
}
|
||||
|
||||
Py_DECREF(pyret);
|
||||
}
|
||||
|
||||
if ((args = PyTuple_New(1)) == NULL)
|
||||
fatal("python_runtime_http_request: PyTuple_New failed");
|
||||
|
||||
|
@ -1103,6 +1135,24 @@ python_kore_bind_unix(PyObject *self, PyObject *args)
|
|||
Py_RETURN_TRUE;
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
python_kore_prerequest(PyObject *self, PyObject *args)
|
||||
{
|
||||
PyObject *f;
|
||||
struct reqcall *rq;
|
||||
|
||||
if (!PyArg_ParseTuple(args, "O", &f))
|
||||
return (NULL);
|
||||
|
||||
rq = kore_calloc(1, sizeof(*rq));
|
||||
rq->f = f;
|
||||
|
||||
Py_INCREF(f);
|
||||
LIST_INSERT_HEAD(&prereq, rq, list);
|
||||
|
||||
return (f);
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
python_kore_task_create(PyObject *self, PyObject *args)
|
||||
{
|
||||
|
@ -3110,6 +3160,7 @@ pyhttp_request_alloc(const struct http_request *req)
|
|||
ptr.cp = req;
|
||||
pyreq->req = ptr.p;
|
||||
pyreq->data = NULL;
|
||||
pyreq->dict = NULL;
|
||||
|
||||
return ((PyObject *)pyreq);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue