/*
* Copyright (C) 2019 Weber Yann
*
* This file is part of PyFCGI.
*
* PyFCGI is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* PyFCGI is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with PyFCGI. If not, see .
*/
/**@defgroup libpyfcgi libpyfcgi python module
* @brief The libpyfcgi python module
*
* PyFCGI defines a python module : libpyfcgi for PEP333 implementation.
* This module contains 2 methods : start_response() and write_body()
*
* The first one is given as argument to the application function, and
* the second one is returned when start_method() is called.
*/
/**@file python_pyfcgi.h
* @ingroup libpyfcgi
*/
#ifndef _PYTHON_PYFCGI__H__
#define _PYTHON_PYFCGI__H__
#include "config.h"
#include
#include /* fcgi library; put it first*/
#define PY_SSIZE_T_CLEAN
#include
#include "structmember.h"
#include "logger.h"
#include "python_ioin.h"
#define LIBPYFCGI_TIMEOUT_HEADERS "Content-Type: text/plain\r\nStatus: 504 Gateway Timeout\r\n\r\n"
#define LIBPYFCGI_DEFAULT_HEADERS "Content-Type: text/html\r\nStatus: %s\r\n\r\n"
#define LIBPYFCGI_DEFAULT_STATUS "200 OK"
#define LIBPYFCGI_DEFAULT_CTYPE "Content-Type: text/html\r\n"
#define LIBPYFCGI_STATUS_SZ 128
struct libpyfcgi_context_s
{
/**@brief PEP333 handling python module reference
* @ingroup libpyfcgi */
PyObject *self;
/**@brief PEP333 status ref
* @ingroup libpyfcgi */
PyObject *status;
/**@brief PEP333 headers ref
* @ingroup libpyfcgi */
PyObject *headers;
/**@brief libpyfcgi.IoIn instance */
IoIn *ioin;
/**@brief Indicate if headers was sent in a PEP333 application
* @ingroup libpyfcgi */
short headers_sent;
/**@brief Stores the libFCGI stream for PEP333 application
* @ingroup libpyfcgi */
FCGX_Stream *out;
/**@brief Stores the libFCGI stream from wich HTTP request can be read
* @ingroup libpyfcgi */
FCGX_Stream *in;
/**@brief Persistent buffer (avoid malloc) for PEP333 headers */
char *heads_buf;
/**@brief Buffer size */
size_t heads_buf_sz;
/**@brief Persistent buffer for PEP333 status */
char status_buf[LIBPYFCGI_STATUS_SZ];
size_t rep_sz;
};
typedef struct libpyfcgi_context_s libpyfcgi_context_t;
/**@brief Stores python module context */
extern libpyfcgi_context_t libpyfcgi;
/**@brief libpyfcgi methods */
extern PyMethodDef pyfcgimodule_methods[];
/**@brief libpyfcgi module structure */
extern PyModuleDef pyfcgimodule;
/**@brief Clean response_status & response_headers globals */
inline void libpyfcgi_clean_response()
{
if(libpyfcgi.status) { Py_DECREF(libpyfcgi.status); }
libpyfcgi.status = NULL;
if(libpyfcgi.headers) { Py_DECREF(libpyfcgi.headers); }
libpyfcgi.headers = NULL;
libpyfcgi.headers_sent = 0;
libpyfcgi.rep_sz = 0;
libpyfcgi.ioin->eof=0;
libpyfcgi.ioin->closed=Py_False;
}
/**@brief Send headers stored in @ref libpyfcgi context
* @note Set python error if called from outside a valid context
*/
void libpyfcgi_send_headers();
/**@brief Send body to fcgi
* @param PyObject* the body data object (returned by PEP333 app)
* @return Python None
*/
PyObject* _pyfcgi_write_body(PyObject *body_data);
/**@brief Called by the SIGALRM sighandler @ref worker_sigalrmhandler()
*
* If no headers sent send a timeout header.
*
* Attempt to generate a python exception and to log exception before
* exiting.
*/
void libpyfcgi_timeout();
/* Defining Python module */
/**@brief Public module initialisation function
* @ingroup libpyfcgi
* @return A python module (PyObject*)
*/
PyMODINIT_FUNC PyInit_libpyfcgi(void);
/**@brief libpyfcgi.start_response() python callable
* @ingroup libpyfcgi
* @note This python callable is a fastcall C method of libpyfcgi module.
*
* The python function header is : start_response(status, response_headers, exc_info = None)
* @param PyObject* self
* @param PyObject* argv
* @param Py_ssize_t argc
* @return A PyObject* referencing a callable allowing to write data without
* cache : libpyfcgi.write_body()
*/
PyObject* pyfcgi_start_response(PyObject*, PyObject**, Py_ssize_t);
/**@brief libpyfcgi.write_body() python callable
* @ingroup libpyfcgi
* @note This python callable is a fastcall C method of libpyfcgi module.
*
* The python function header is : write_body(body_data)
* @param PyObject* self
* @param PyObject* argv
* @param Py_ssize_t argc
* @return ???
*/
PyObject* pyfcgi_write_body(PyObject*, PyObject**, Py_ssize_t);
#endif