kore

An easy to use, scalable and secure web application framework for writing web APIs in C.
Commits | Files | Refs | README | LICENSE | git clone https://git.kore.io/kore.git

commit 620cc231dcdd4534f59bda7d27a50e3a7f3b9311
parent 7c74a0824bc2ca3643f87827459b56e741de56de
Author: Joris Vink <joris@coders.se>
Date:   Wed, 25 Jan 2017 21:17:12 +0100

validators now work in python.

Diffstat:
includes/http.h | 2++
src/auth.c | 8+++++++-
src/python.c | 61+++++++++++++++++++++++++++++++++++++++++++++++++++++++++----
3 files changed, 66 insertions(+), 5 deletions(-)

diff --git a/includes/http.h b/includes/http.h @@ -162,6 +162,8 @@ struct http_file { #define HTTP_REQUEST_NO_CONTENT_LENGTH 0x0080 #define HTTP_REQUEST_AUTHED 0x0100 +#define HTTP_VALIDATOR_IS_REQUEST 0x8000 + struct kore_task; struct http_request { diff --git a/src/auth.c b/src/auth.c @@ -157,7 +157,13 @@ kore_auth_header(struct http_request *req, struct kore_auth *auth) static int kore_auth_request(struct http_request *req, struct kore_auth *auth) { - return (kore_validator_check(req, auth->validator, req)); + int ret; + + req->flags |= HTTP_VALIDATOR_IS_REQUEST; + ret = kore_validator_check(req, auth->validator, req); + req->flags &= ~HTTP_VALIDATOR_IS_REQUEST; + + return (ret); } struct kore_auth * diff --git a/src/python.c b/src/python.c @@ -125,8 +125,10 @@ python_log_error(const char *function) PyErr_Fetch(&type, &value, &traceback); - if (type == NULL || value == NULL || traceback == NULL) - fatal("python_log_error(): exception but no error trace?"); + if (type == NULL || value == NULL || traceback == NULL) { + kore_log(LOG_ERR, "unknown python exception in '%s'", function); + return; + } kore_log(LOG_ERR, "python exception in '%s' - type:%s - value:%s - trace:%s", @@ -237,8 +239,57 @@ python_runtime_http_request(void *addr, struct http_request *req) static int python_runtime_validator(void *addr, struct http_request *req, void *data) { - printf("python_runtime_validator: XXX %s\n", req->path); - return (KORE_RESULT_OK); + int ret; + PyObject *pyret, *pyreq, *args, *callable, *arg; + + callable = (PyObject *)addr; + + if ((pyreq = pyhttp_request_alloc(req)) == NULL) { + kore_log(LOG_ERR, "cannot create new pyhttp_request"); + http_response(req, HTTP_STATUS_INTERNAL_ERROR, NULL, 0); + return (KORE_RESULT_OK); + } + + if (req->flags & HTTP_VALIDATOR_IS_REQUEST) { + if ((arg = pyhttp_request_alloc(data)) == NULL) { + Py_DECREF(pyreq); + kore_log(LOG_ERR, "cannot create new pyhttp_request"); + http_response(req, HTTP_STATUS_INTERNAL_ERROR, NULL, 0); + return (KORE_RESULT_OK); + } + } else { + if ((arg = PyUnicode_FromString(data)) == NULL) { + Py_DECREF(pyreq); + kore_log(LOG_ERR, "cannot create new pyhttp_request"); + http_response(req, HTTP_STATUS_INTERNAL_ERROR, NULL, 0); + return (KORE_RESULT_OK); + } + } + + if ((args = PyTuple_New(2)) == NULL) + fatal("python_runtime_validator: PyTuple_New failed"); + + if (PyTuple_SetItem(args, 0, pyreq) != 0 || + PyTuple_SetItem(args, 1, arg) != 0) + fatal("python_runtime_vaildator: PyTuple_SetItem failed"); + + PyErr_Clear(); + pyret = PyObject_Call(callable, args, NULL); + Py_DECREF(args); + + if (pyret == NULL) { + python_log_error("python_runtime_validator"); + http_response(req, HTTP_STATUS_INTERNAL_ERROR, NULL, 0); + return (KORE_RESULT_OK); + } + + if (!PyLong_Check(pyret)) + fatal("python_runtime_validator: unexpected return type"); + + ret = (int)PyLong_AsLong(pyret); + Py_DECREF(pyret); + + return (ret); } #endif @@ -259,6 +310,7 @@ python_runtime_onload(void *addr, int action) if (PyTuple_SetItem(args, 0, pyact) != 0) fatal("python_runtime_onload: PyTuple_SetItem failed"); + PyErr_Clear(); pyret = PyObject_Call(callable, args, NULL); Py_DECREF(args); @@ -295,6 +347,7 @@ python_runtime_connect(void *addr, struct connection *c) if (PyTuple_SetItem(args, 0, pyc) != 0) fatal("python_runtime_connect: PyTuple_SetItem failed"); + PyErr_Clear(); pyret = PyObject_Call(callable, args, NULL); Py_DECREF(args);