diff options
author | Toni Uhlig <matzeton@googlemail.com> | 2020-05-24 16:48:22 +0200 |
---|---|---|
committer | Toni Uhlig <matzeton@googlemail.com> | 2020-05-25 21:57:14 +0200 |
commit | 31c69b6ca1b91e7fd9fd8e14082fd2584c5f538c (patch) | |
tree | 16e789c7d68608831b498f41f54d9482b82a711a /source/tools/host/old/pyhttp.c |
first public release
Signed-off-by: Toni Uhlig <matzeton@googlemail.com>
Diffstat (limited to 'source/tools/host/old/pyhttp.c')
-rw-r--r-- | source/tools/host/old/pyhttp.c | 188 |
1 files changed, 188 insertions, 0 deletions
diff --git a/source/tools/host/old/pyhttp.c b/source/tools/host/old/pyhttp.c new file mode 100644 index 0000000..b66576f --- /dev/null +++ b/source/tools/host/old/pyhttp.c @@ -0,0 +1,188 @@ +/* + * Module: pyhttp.c + * Author: Toni Uhlig <matzeton@googlemail.com> + * Purpose: Python loadable module for http codes/flags + */ + +#include "helper.h" /* must be the first include if compiling a python module */ + +#include <stdio.h> +#include <stdlib.h> + +#include "compat.h" +#include "http.h" +#include "xor_strings.h" /* DLLSECTION */ + + +static const char pname[] = "pyhttp"; + + +static PyObject* info(PyObject* self, PyObject* args) +{ + printf("%s: http codes/flags\n", pname); + Py_RETURN_NONE; +} + +#define PYDICT_SET_CMACRO(name, obj) PyDict_SetItemString( dict, name, obj ); +#define PYDICT_SETI_CMACRO(mname) { PyObject* pyval = Py_BuildValue("I", mname); if (pyval) { PYDICT_SET_CMACRO( #mname, pyval ); Py_DECREF(pyval); } } +#define PYDICT_SETS_CMACRO(mname) { PyObject* pyval = Py_BuildValue("s", mname); if (pyval) { PYDICT_SET_CMACRO( #mname, pyval ); Py_DECREF(pyval); } } +static PyObject* __http_getCodes(PyObject* self, PyObject* args) +{ + PyObject* dict = PyDict_New(); + PYDICT_SETI_CMACRO(RC_INFO); + PYDICT_SETI_CMACRO(RC_REGISTER); + PYDICT_SETI_CMACRO(RC_PING); + return dict; +} + +static PyObject* __http_getCodeSiz(PyObject* self, PyObject* args) +{ + return Py_BuildValue("I", sizeof(rrcode)); +} + +static PyObject* __http_getFlags(PyObject* self, PyObject* args) +{ + PyObject* dict = PyDict_New(); + PYDICT_SETI_CMACRO(RF_AGAIN); + PYDICT_SETI_CMACRO(RF_ERROR); + PYDICT_SETI_CMACRO(RF_OK); + + return dict; +} + +static PyObject* __http_getFlagSiz(PyObject* self, PyObject* args) +{ + return Py_BuildValue("I", sizeof(rflags)); +} + +static PyObject* __http_getConsts(PyObject* self, PyObject* args) +{ + PyObject* dict = PyDict_New(); + PYDICT_SETS_CMACRO(DLLSECTION); + PYDICT_SETI_CMACRO(SID_LEN); + PYDICT_SETI_CMACRO(SID_ZEROES0); + PYDICT_SETI_CMACRO(SID_ZEROES1); + PYDICT_SETI_CMACRO(MARKER_SIZ); + PYDICT_SETI_CMACRO(RND_LEN); + PYDICT_SETI_CMACRO(AESKEY_SIZ); + + return dict; +} + +static PyObject* __http_parseResponse(PyObject* self, PyObject* args) +{ + PyObject* ctxRecvBuffer = NULL; + PyObject* ctxStartMarker = NULL; + Py_buffer recvBuffer = {0}, startMarker = {0}; + PyObject* rList = Py_BuildValue("[]"); + + if (! PyArg_ParseTuple(args, "O|O:parseResponse", &ctxRecvBuffer, &ctxStartMarker) || + ! ctxRecvBuffer || ! ctxStartMarker) { + PyErr_SetString(PyExc_TypeError, "Invalid arguments"); + PyErr_Print(); + return NULL; + } + + if (PyObject_GetBuffer(ctxRecvBuffer, &recvBuffer, PyBUF_SIMPLE) < 0 || + PyObject_GetBuffer(ctxStartMarker, &startMarker, PyBUF_SIMPLE) < 0) { + PyErr_SetString(PyExc_TypeError, "Argument types are not buffer objects"); + PyErr_Print(); + goto finalize; + } + if (recvBuffer.len <= 0) { + PyErr_Format(PyExc_RuntimeError, "Invalid buffer length: %u", (unsigned)recvBuffer.len); + PyErr_Print(); + goto finalize; + } + if (startMarker.len != MARKER_SIZ) { + PyErr_Format(PyExc_TypeError, "Marker size is not exactly %u bytes: %u bytes", MARKER_SIZ, (unsigned)startMarker.len); + PyErr_Print(); + goto finalize; + } + + off_t bufOff = 0; + http_resp* hResp = NULL; + while (parseResponse(recvBuffer.buf, recvBuffer.len, &hResp, &bufOff, startMarker.buf) == RSP_OK && + hResp) { + PyObject* tuple = Py_BuildValue("(s#BHIs#)", hResp->startMarker, MARKER_SIZ, + hResp->respFlags, hResp->respCode, hResp->pkgsiz, &hResp->pkgbuf[0], hResp->pkgsiz); + PyList_Append(rList, tuple); + Py_DECREF(tuple); + } + +finalize: + if (recvBuffer.buf != NULL) + PyBuffer_Release(&recvBuffer); + if (startMarker.buf != NULL) + PyBuffer_Release(&startMarker); + return rList; +} + +static PyObject* __http_addRequest(PyObject* self, PyObject* args) +{ + struct http_resp* hResp = NULL; + PyObject* ctxBuf; + PyObject* ctxResp; + Py_buffer pkgBuf = {0}, httpResp = {0}; + PyObject* retBuf = NULL; + + if (! PyArg_ParseTuple(args, "O|O:addRequest", &ctxBuf, &ctxResp) || + ! ctxBuf || ! ctxResp) { + PyErr_SetString(PyExc_TypeError, "Invalid arguments"); + return NULL; + } + + if (PyObject_GetBuffer(ctxBuf, &pkgBuf, PyBUF_SIMPLE) < 0 || + PyObject_GetBuffer(ctxResp, &httpResp, PyBUF_SIMPLE) < 0) { + PyErr_SetString(PyExc_TypeError, "Argument types are not buffer objects"); + PyErr_Print(); + goto finalize; + } + + hResp = (struct http_resp*)httpResp.buf; + if (httpResp.len != sizeof(struct http_resp) + hResp->pkgsiz) { + PyErr_Format(PyExc_RuntimeError, "Invalid http_resp size: %lu (required: %lu + %u)", httpResp.len, sizeof(struct http_resp), hResp->pkgsiz); + PyErr_Print(); + goto finalize; + } + + rrsize send_siz = pkgBuf.len; + rrbuff send_buf = COMPAT(calloc)(send_siz, sizeof(*send_buf)); + if (! send_buf) + goto finalize; + COMPAT(memcpy)(send_buf, pkgBuf.buf, send_siz); + if (addRequest(&send_buf, &send_siz, hResp) == RSP_OK) + retBuf = PyByteArray_FromStringAndSize((const char*)send_buf, send_siz); + COMPAT(free)(send_buf); +finalize: + if (pkgBuf.buf != NULL) + PyBuffer_Release(&pkgBuf); + if (httpResp.buf != NULL) + PyBuffer_Release(&httpResp); + if (retBuf) + return retBuf; + else + Py_RETURN_NONE; +} + + +/* define module methods */ +static PyMethodDef pycryptMethods[] = { + {"info", info, METH_NOARGS, "print module info"}, + {"getCodes", __http_getCodes, METH_NOARGS, "get http request/response codes"}, + {"getCodeSiz", __http_getCodeSiz, METH_NOARGS, "get code size"}, + {"getFlags", __http_getFlags, METH_NOARGS, "get http response flags"}, + {"getFlagSiz", __http_getFlagSiz, METH_NOARGS, "get flag size"}, + {"getConsts", __http_getConsts, METH_NOARGS, "get const data/macros"}, + {"parseResponse", __http_parseResponse, METH_VARARGS, "buf,startMarker -> parse http request/response"}, + {"addRequest", __http_addRequest, METH_VARARGS, "buf,struct http_resp -> add a http request to an pkgbuffer"}, + {NULL, NULL, 0, NULL} +}; + +/* module initialization */ +PyMODINIT_FUNC +initpyhttp(void) +{ + printf("ENABLED %s\n", pname); + (void) Py_InitModule(pname, pycryptMethods); +} |