99 lines
2.8 KiB
C
Raw Normal View History

2024-12-31 14:26:13 +00:00
#define PY_SSIZE_T_CLEAN 1
#include <Python.h>
#include <arpa/inet.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
static PyObject *pgs_api_is_http(PyObject *self, PyObject *args) {
const char *py_bytes;
if (!PyArg_ParseTuple(args, "y", &py_bytes)) {
return NULL;
}
bool is_http = strstr(py_bytes, "HTTP/") != NULL;
return is_http ? Py_True : Py_False;
}
static PyObject *pgs_api_is_ssh(PyObject *self, PyObject *args) {
const char *py_bytes;
if (!PyArg_ParseTuple(args, "y", &py_bytes)) {
return NULL;
}
bool is_ssh = strstr(py_bytes, "SSH") != NULL;
return is_ssh ? Py_True : Py_False;
}
static PyObject *pgs_api_read(PyObject *self, PyObject *args) {
int fd, length;
if (!PyArg_ParseTuple(args, "ii", &fd, &length)) {
return NULL;
}
char buffer[length + 1];
ssize_t bytes_read = read(fd, buffer, length);
buffer[bytes_read] = 0;
Py_buffer *pybuffer = (Py_buffer *)malloc(bytes_read);
PyBuffer_FillInfo(pybuffer, 0, &buffer, bytes_read, false, PyBUF_CONTIG);
return PyMemoryView_FromBuffer(pybuffer);
}
static PyObject *pgs_api_write(PyObject *self, PyObject *args) {
int fd, length;
const char *input_data;
Py_ssize_t input_length;
if (!PyArg_ParseTuple(args, "is", &fd, &input_data, &input_length)) {
return NULL;
}
ssize_t bytes_sent_total = 0;
input_length = strlen(input_data);
while (true) {
ssize_t bytes_sent =
send(fd, input_data + bytes_sent_total, input_length, 0);
if (bytes_sent < 1) {
return PyLong_FromSsize_t(bytes_sent);
}
bytes_sent_total += bytes_sent;
if (bytes_sent_total == input_length) {
break;
}
}
return PyLong_FromSsize_t(input_length);
}
// A simple function: add two numbers
static PyObject *mymodule_add(PyObject *self, PyObject *args) {
double a, b, result;
if (!PyArg_ParseTuple(args, "dd", &a, &b)) {
return NULL;
}
result = a + b;
return PyFloat_FromDouble(result);
}
// Method table for the module
static PyMethodDef MyModuleMethods[] = {
{"add", mymodule_add, METH_VARARGS, "Add two numbers"},
{"read", pgs_api_read, METH_VARARGS, "Read fd"},
{"write", pgs_api_write, METH_VARARGS, "Write fd"},
{"is_ssh", pgs_api_is_ssh, METH_VARARGS,
"Check if header contains SSH data."},
{"is_http", pgs_api_is_http, METH_VARARGS,
"Check if header contains HTTP data."},
{NULL, NULL, 0, NULL} // Sentinel
};
// Module definition structure
static struct PyModuleDef mymodule = {
PyModuleDef_HEAD_INIT,
"pgs", // Module name
"Pretty Good Server API.", // Module docstring
-1, // Size of per-interpreter state of the module
MyModuleMethods // Methods
};
// Module initialization function
PyMODINIT_FUNC PyInit_mymodule(void) { return PyModule_Create(&mymodule); }