#ifndef PGS_PY_H #define PGS_PY_H #define PY_SSIZE_T_CLEAN 1 #include "pgs_api.h" #include #include PyObject *_pModule = NULL; bool python_initialized = false; PyObject *py_construct() { PyStatus status; PyConfig config; if (!python_initialized) { if (PyImport_AppendInittab("pgs", PyInit_mymodule) == -1) { fprintf(stderr, "Failed to add mymodule to the interpreter's table\n"); return NULL; } PyConfig_InitPythonConfig(&config); /* optional but recommended */ status = PyConfig_SetBytesString(&config, &config.program_name, "pgs"); if (PyStatus_Exception(status)) { goto exception; } status = Py_InitializeFromConfig(&config); if (PyStatus_Exception(status)) { goto exception; } PyConfig_Clear(&config); // Py_Initialize(); if (!Py_IsInitialized()) { fprintf(stderr, "Python initialization failed!\n"); return NULL; } PyGILState_STATE gstate = PyGILState_Ensure(); PyRun_SimpleString("import pgs"); // Py_InitModule("pgscript", NULL); python_initialized = true; PyObject *sysPath = PySys_GetObject("path"); PyList_Append(sysPath, PyUnicode_FromString(".")); // Py_DECREF(sysPath); PyObject *pName = PyUnicode_DecodeFSDefault("pgscript"); _pModule = PyImport_Import(pName); Py_DECREF(pName); PyGILState_Release(gstate); python_initialized = true; } return _pModule; exception: PyConfig_Clear(&config); Py_ExitStatusException(status); return NULL; } void py_destruct() { if (!python_initialized) return; Py_DECREF(_pModule); Py_Finalize(); python_initialized = false; } char py_on_headers(int downstream, char *headers) { PyObject *pModule = py_construct(); char *new_headers = NULL; if (pModule != NULL) { PyObject *pFunc = PyObject_GetAttrString(pModule, "on_headers"); if (PyCallable_Check(pFunc)) { PyObject *pArgs = PyTuple_Pack(2, PyLong_FromLong(downstream), PyUnicode_FromString(headers)); PyGILState_STATE gstate = PyGILState_Ensure(); new_headers = PyBytes_AsString(PyObject_CallObject(pFunc, pArgs)); PyGILState_Release(gstate); Py_DECREF(pArgs); } } return new_headers ? new_headers : headers; } char * py_http_intercept_headers(int sock, char * headers){ PyObject *pModule = py_construct(); char *new_headers = NULL; if (pModule != NULL) { PyObject *pFunc = PyObject_GetAttrString(pModule, "http_intercept_headers"); if (PyCallable_Check(pFunc)) { PyObject *pArgs = PyTuple_Pack(2, PyLong_FromLong(sock), PyUnicode_FromString(headers)); PyGILState_STATE gstate = PyGILState_Ensure(); new_headers = PyBytes_AsString(PyObject_CallObject(pFunc, pArgs)); PyGILState_Release(gstate); Py_DECREF(pArgs); } } return new_headers ? new_headers : headers; } int py_on_connect(int downstream) { PyObject *pModule = py_construct(); int upstream_fd = -1; if (pModule != NULL) { PyObject *pFunc = PyObject_GetAttrString(pModule, "on_connect"); if (PyCallable_Check(pFunc)) { PyObject *pArgs = PyTuple_Pack(1, PyLong_FromLong(downstream)); PyGILState_STATE gstate = PyGILState_Ensure(); PyObject *pValue = PyObject_CallObject(pFunc, pArgs); PyGILState_Release(gstate); Py_DECREF(pArgs); if (pValue != NULL) { upstream_fd = PyLong_AsLong(pValue); Py_DECREF(pValue); } else { PyErr_Print(); fprintf(stderr, "Call failed\n"); } } else { PyErr_Print(); fprintf(stderr, "Cannot find function 'route'\n"); } Py_XDECREF(pFunc); } else { PyErr_Print(); fprintf(stderr, "Failed to load 'script'\n"); } return upstream_fd; } #endif