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_suspend(PyObject *, PyObject *);
|
||||||
static PyObject *python_kore_shutdown(PyObject *, PyObject *);
|
static PyObject *python_kore_shutdown(PyObject *, PyObject *);
|
||||||
static PyObject *python_kore_bind_unix(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_task_create(PyObject *, PyObject *);
|
||||||
static PyObject *python_kore_socket_wrap(PyObject *, PyObject *);
|
static PyObject *python_kore_socket_wrap(PyObject *, PyObject *);
|
||||||
static PyObject *python_kore_gather(PyObject *, 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("suspend", python_kore_suspend, METH_VARARGS),
|
||||||
METHOD("shutdown", python_kore_shutdown, METH_NOARGS),
|
METHOD("shutdown", python_kore_shutdown, METH_NOARGS),
|
||||||
METHOD("bind_unix", python_kore_bind_unix, METH_VARARGS),
|
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("task_create", python_kore_task_create, METH_VARARGS),
|
||||||
METHOD("socket_wrap", python_kore_socket_wrap, METH_VARARGS),
|
METHOD("socket_wrap", python_kore_socket_wrap, METH_VARARGS),
|
||||||
METHOD("websocket_broadcast", python_websocket_broadcast, METH_VARARGS),
|
METHOD("websocket_broadcast", python_websocket_broadcast, METH_VARARGS),
|
||||||
|
@ -544,6 +546,7 @@ static PyTypeObject pyconnection_type = {
|
||||||
struct pyhttp_request {
|
struct pyhttp_request {
|
||||||
PyObject_HEAD
|
PyObject_HEAD
|
||||||
struct http_request *req;
|
struct http_request *req;
|
||||||
|
PyObject *dict;
|
||||||
PyObject *data;
|
PyObject *data;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -621,10 +624,13 @@ static PyTypeObject pyhttp_request_type = {
|
||||||
PyVarObject_HEAD_INIT(NULL, 0)
|
PyVarObject_HEAD_INIT(NULL, 0)
|
||||||
.tp_name = "kore.http_request",
|
.tp_name = "kore.http_request",
|
||||||
.tp_doc = "struct http_request",
|
.tp_doc = "struct http_request",
|
||||||
|
.tp_setattro = PyObject_GenericSetAttr,
|
||||||
|
.tp_getattro = PyObject_GenericGetAttr,
|
||||||
.tp_getset = pyhttp_request_getset,
|
.tp_getset = pyhttp_request_getset,
|
||||||
.tp_methods = pyhttp_request_methods,
|
.tp_methods = pyhttp_request_methods,
|
||||||
.tp_dealloc = (destructor)pyhttp_dealloc,
|
.tp_dealloc = (destructor)pyhttp_dealloc,
|
||||||
.tp_basicsize = sizeof(struct pyhttp_request),
|
.tp_basicsize = sizeof(struct pyhttp_request),
|
||||||
|
.tp_dictoffset = offsetof(struct pyhttp_request, dict),
|
||||||
.tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
|
.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_api.h"
|
||||||
#include "python_methods.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 PyMODINIT_FUNC python_module_init(void);
|
||||||
static PyObject *python_import(const char *);
|
static PyObject *python_import(const char *);
|
||||||
static PyObject *pyconnection_alloc(struct connection *);
|
static PyObject *pyconnection_alloc(struct connection *);
|
||||||
|
@ -177,6 +184,7 @@ static PyMemAllocatorEx allocator = {
|
||||||
};
|
};
|
||||||
|
|
||||||
static TAILQ_HEAD(, pyproc) procs;
|
static TAILQ_HEAD(, pyproc) procs;
|
||||||
|
static struct reqcall_list prereq;
|
||||||
|
|
||||||
static struct kore_pool coro_pool;
|
static struct kore_pool coro_pool;
|
||||||
static struct kore_pool iterobj_pool;
|
static struct kore_pool iterobj_pool;
|
||||||
|
@ -204,6 +212,8 @@ kore_python_init(void)
|
||||||
coro_id = 0;
|
coro_id = 0;
|
||||||
coro_count = 0;
|
coro_count = 0;
|
||||||
|
|
||||||
|
LIST_INIT(&prereq);
|
||||||
|
|
||||||
TAILQ_INIT(&procs);
|
TAILQ_INIT(&procs);
|
||||||
TAILQ_INIT(&coro_runnable);
|
TAILQ_INIT(&coro_runnable);
|
||||||
TAILQ_INIT(&coro_suspended);
|
TAILQ_INIT(&coro_suspended);
|
||||||
|
@ -620,6 +630,7 @@ pyconnection_dealloc(struct pyconnection *pyc)
|
||||||
static void
|
static void
|
||||||
pyhttp_dealloc(struct pyhttp_request *pyreq)
|
pyhttp_dealloc(struct pyhttp_request *pyreq)
|
||||||
{
|
{
|
||||||
|
Py_XDECREF(pyreq->dict);
|
||||||
Py_XDECREF(pyreq->data);
|
Py_XDECREF(pyreq->data);
|
||||||
PyObject_Del((PyObject *)pyreq);
|
PyObject_Del((PyObject *)pyreq);
|
||||||
}
|
}
|
||||||
|
@ -633,7 +644,8 @@ pyhttp_file_dealloc(struct pyhttp_file *pyfile)
|
||||||
static int
|
static int
|
||||||
python_runtime_http_request(void *addr, struct http_request *req)
|
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) {
|
if (req->py_coro != NULL) {
|
||||||
python_coro_wakeup(req->py_coro);
|
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)
|
if ((pyreq = pyhttp_request_alloc(req)) == NULL)
|
||||||
fatal("python_runtime_http_request: pyreq alloc failed");
|
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)
|
if ((args = PyTuple_New(1)) == NULL)
|
||||||
fatal("python_runtime_http_request: PyTuple_New failed");
|
fatal("python_runtime_http_request: PyTuple_New failed");
|
||||||
|
|
||||||
|
@ -1103,6 +1135,24 @@ python_kore_bind_unix(PyObject *self, PyObject *args)
|
||||||
Py_RETURN_TRUE;
|
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 *
|
static PyObject *
|
||||||
python_kore_task_create(PyObject *self, PyObject *args)
|
python_kore_task_create(PyObject *self, PyObject *args)
|
||||||
{
|
{
|
||||||
|
@ -3110,6 +3160,7 @@ pyhttp_request_alloc(const struct http_request *req)
|
||||||
ptr.cp = req;
|
ptr.cp = req;
|
||||||
pyreq->req = ptr.p;
|
pyreq->req = ptr.p;
|
||||||
pyreq->data = NULL;
|
pyreq->data = NULL;
|
||||||
|
pyreq->dict = NULL;
|
||||||
|
|
||||||
return ((PyObject *)pyreq);
|
return ((PyObject *)pyreq);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue