forked from mirrors/kore
expose http_file interface to python.
This commit is contained in:
parent
0250c8ecba
commit
6578fc6589
|
@ -70,13 +70,21 @@ struct pyhttp_request {
|
|||
struct http_request *req;
|
||||
};
|
||||
|
||||
struct pyhttp_file {
|
||||
PyObject_HEAD
|
||||
struct http_file *file;
|
||||
};
|
||||
|
||||
static void pyhttp_dealloc(struct pyhttp_request *);
|
||||
static void pyhttp_file_dealloc(struct pyhttp_file *);
|
||||
|
||||
static PyObject *pyhttp_response(struct pyhttp_request *, PyObject *);
|
||||
static PyObject *pyhttp_argument(struct pyhttp_request *, PyObject *);
|
||||
static PyObject *pyhttp_body_read(struct pyhttp_request *, PyObject *);
|
||||
static PyObject *pyhttp_file_lookup(struct pyhttp_request *, PyObject *);
|
||||
static PyObject *pyhttp_populate_get(struct pyhttp_request *, PyObject *);
|
||||
static PyObject *pyhttp_populate_post(struct pyhttp_request *, PyObject *);
|
||||
static PyObject *pyhttp_populate_multi(struct pyhttp_request *, PyObject *);
|
||||
static PyObject *pyhttp_request_header(struct pyhttp_request *, PyObject *);
|
||||
static PyObject *pyhttp_response_header(struct pyhttp_request *, PyObject *);
|
||||
static PyObject *pyhttp_websocket_handshake(struct pyhttp_request *,
|
||||
|
@ -86,8 +94,10 @@ static PyMethodDef pyhttp_request_methods[] = {
|
|||
METHOD("response", pyhttp_response, METH_VARARGS),
|
||||
METHOD("argument", pyhttp_argument, METH_VARARGS),
|
||||
METHOD("body_read", pyhttp_body_read, METH_VARARGS),
|
||||
METHOD("file_lookup", pyhttp_file_lookup, METH_VARARGS),
|
||||
METHOD("populate_get", pyhttp_populate_get, METH_NOARGS),
|
||||
METHOD("populate_post", pyhttp_populate_post, METH_NOARGS),
|
||||
METHOD("populate_multi", pyhttp_populate_multi, METH_NOARGS),
|
||||
METHOD("request_header", pyhttp_request_header, METH_VARARGS),
|
||||
METHOD("response_header", pyhttp_response_header, METH_VARARGS),
|
||||
METHOD("websocket_handshake", pyhttp_websocket_handshake, METH_VARARGS),
|
||||
|
@ -125,4 +135,31 @@ static PyTypeObject pyhttp_request_type = {
|
|||
.tp_basicsize = sizeof(struct pyhttp_request),
|
||||
.tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
|
||||
};
|
||||
|
||||
static PyObject *pyhttp_file_read(struct pyhttp_file *, PyObject *);
|
||||
|
||||
static PyMethodDef pyhttp_file_methods[] = {
|
||||
METHOD("read", pyhttp_file_read, METH_VARARGS),
|
||||
METHOD(NULL, NULL, -1)
|
||||
};
|
||||
|
||||
static PyObject *pyhttp_file_get_name(struct pyhttp_file *, void *);
|
||||
static PyObject *pyhttp_file_get_filename(struct pyhttp_file *, void *);
|
||||
|
||||
static PyGetSetDef pyhttp_file_getset[] = {
|
||||
GETTER("name", pyhttp_file_get_name),
|
||||
GETTER("filename", pyhttp_file_get_filename),
|
||||
GETTER(NULL, NULL)
|
||||
};
|
||||
|
||||
static PyTypeObject pyhttp_file_type = {
|
||||
PyVarObject_HEAD_INIT(NULL, 0)
|
||||
.tp_name = "kore.http_file",
|
||||
.tp_doc = "struct http_file",
|
||||
.tp_getset = pyhttp_file_getset,
|
||||
.tp_methods = pyhttp_file_methods,
|
||||
.tp_dealloc = (destructor)pyhttp_file_dealloc,
|
||||
.tp_basicsize = sizeof(struct pyhttp_file),
|
||||
.tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
|
||||
};
|
||||
#endif
|
||||
|
|
111
src/python.c
111
src/python.c
|
@ -35,6 +35,7 @@ static PyObject *pyconnection_alloc(struct connection *);
|
|||
static PyObject *python_callable(PyObject *, const char *);
|
||||
|
||||
#if !defined(KORE_NO_HTTP)
|
||||
static PyObject *pyhttp_file_alloc(struct http_file *);
|
||||
static PyObject *pyhttp_request_alloc(struct http_request *);
|
||||
#endif
|
||||
|
||||
|
@ -247,6 +248,12 @@ pyhttp_dealloc(struct pyhttp_request *pyreq)
|
|||
PyObject_Del((PyObject *)pyreq);
|
||||
}
|
||||
|
||||
static void
|
||||
pyhttp_file_dealloc(struct pyhttp_file *pyfile)
|
||||
{
|
||||
PyObject_Del((PyObject *)pyfile);
|
||||
}
|
||||
|
||||
static int
|
||||
python_runtime_http_request(void *addr, struct http_request *req)
|
||||
{
|
||||
|
@ -469,6 +476,7 @@ python_module_init(void)
|
|||
}
|
||||
|
||||
#if !defined(KORE_NO_HTTP)
|
||||
python_push_type("pyhttp_file", pykore, &pyhttp_file_type);
|
||||
python_push_type("pyhttp_request", pykore, &pyhttp_request_type);
|
||||
#endif
|
||||
|
||||
|
@ -633,6 +641,20 @@ pyhttp_request_alloc(struct http_request *req)
|
|||
return ((PyObject *)pyreq);
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
pyhttp_file_alloc(struct http_file *file)
|
||||
{
|
||||
struct pyhttp_file *pyfile;
|
||||
|
||||
pyfile = PyObject_New(struct pyhttp_file, &pyhttp_file_type);
|
||||
if (pyfile == NULL)
|
||||
return (NULL);
|
||||
|
||||
pyfile->file = file;
|
||||
|
||||
return ((PyObject *)pyfile);
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
pyhttp_response(struct pyhttp_request *pyreq, PyObject *args)
|
||||
{
|
||||
|
@ -739,6 +761,13 @@ pyhttp_populate_post(struct pyhttp_request *pyreq, PyObject *args)
|
|||
Py_RETURN_TRUE;
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
pyhttp_populate_multi(struct pyhttp_request *pyreq, PyObject *args)
|
||||
{
|
||||
http_populate_multipart_form(pyreq->req);
|
||||
Py_RETURN_TRUE;
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
pyhttp_argument(struct pyhttp_request *pyreq, PyObject *args)
|
||||
{
|
||||
|
@ -761,6 +790,66 @@ pyhttp_argument(struct pyhttp_request *pyreq, PyObject *args)
|
|||
return (value);
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
pyhttp_file_lookup(struct pyhttp_request *pyreq, PyObject *args)
|
||||
{
|
||||
const char *name;
|
||||
struct http_file *file;
|
||||
PyObject *pyfile;
|
||||
|
||||
if (!PyArg_ParseTuple(args, "s", &name)) {
|
||||
PyErr_SetString(PyExc_TypeError, "invalid parameters");
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
if ((file = http_file_lookup(pyreq->req, name)) == NULL) {
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
if ((pyfile = pyhttp_file_alloc(file)) == NULL)
|
||||
return (PyErr_NoMemory());
|
||||
|
||||
return (pyfile);
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
pyhttp_file_read(struct pyhttp_file *pyfile, PyObject *args)
|
||||
{
|
||||
ssize_t ret;
|
||||
size_t len;
|
||||
Py_ssize_t pylen;
|
||||
PyObject *result;
|
||||
u_int8_t buf[1024];
|
||||
|
||||
if (!PyArg_ParseTuple(args, "n", &pylen) || pylen < 0) {
|
||||
PyErr_SetString(PyExc_TypeError, "invalid parameters");
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
len = (size_t)pylen;
|
||||
if (len > sizeof(buf)) {
|
||||
PyErr_SetString(PyExc_RuntimeError, "len > sizeof(buf)");
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
ret = http_file_read(pyfile->file, buf, len);
|
||||
if (ret == -1) {
|
||||
PyErr_SetString(PyExc_RuntimeError, "http_file_read() failed");
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
if (ret > INT_MAX) {
|
||||
PyErr_SetString(PyExc_RuntimeError, "ret > INT_MAX");
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
result = Py_BuildValue("ny#", ret, buf, (int)ret);
|
||||
if (result == NULL)
|
||||
return (PyErr_NoMemory());
|
||||
|
||||
return (result);
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
pyhttp_websocket_handshake(struct pyhttp_request *pyreq, PyObject *args)
|
||||
{
|
||||
|
@ -947,4 +1036,26 @@ pyhttp_get_connection(struct pyhttp_request *pyreq, void *closure)
|
|||
|
||||
return (pyc);
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
pyhttp_file_get_name(struct pyhttp_file *pyfile, void *closure)
|
||||
{
|
||||
PyObject *name;
|
||||
|
||||
if ((name = PyUnicode_FromString(pyfile->file->name)) == NULL)
|
||||
return (PyErr_NoMemory());
|
||||
|
||||
return (name);
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
pyhttp_file_get_filename(struct pyhttp_file *pyfile, void *closure)
|
||||
{
|
||||
PyObject *name;
|
||||
|
||||
if ((name = PyUnicode_FromString(pyfile->file->filename)) == NULL)
|
||||
return (PyErr_NoMemory());
|
||||
|
||||
return (name);
|
||||
}
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue