docs: add Doxygen comments to mod_reqin_log.c
- File header: French multi-line description block - 7 section banners in French (/* ====== Section ====== */ format): Configuration du serveur, Buffer dynamique, Sérialisation JSON, Gestionnaires de directives, Socket Unix, Journalisation, Hooks Apache - 26 @brief/@param/@return blocks on every function: server config, dynbuf_*, JSON helpers, cmd_set_* handlers, socket helpers (try_connect/ensure_connected/write_to_socket), log_request, Apache hooks (post_read_request, child_init, etc.) - No logic changes (1033 → 1268 lines, comments only) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
@ -1,5 +1,9 @@
|
|||||||
/*
|
/* mod_reqin_log.c — Module Apache HTTPD pour la journalisation des requêtes HTTP
|
||||||
* mod_reqin_log.c - Apache HTTPD module for logging HTTP requests as JSON to Unix socket
|
* entrantes au format JSON vers un socket de domaine Unix.
|
||||||
|
*
|
||||||
|
* Fonctionnalités : capture des requêtes en phase post-read, sérialisation JSON,
|
||||||
|
* envoi non-bloquant vers un socket Unix, reconnexion automatique et filtrage
|
||||||
|
* des en-têtes sensibles.
|
||||||
*
|
*
|
||||||
* Copyright (c) 2026. All rights reserved.
|
* Copyright (c) 2026. All rights reserved.
|
||||||
*/
|
*/
|
||||||
@ -161,13 +165,26 @@ module AP_MODULE_DECLARE_DATA reqin_log_module = {
|
|||||||
0 /* flags */
|
0 /* flags */
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Get module configuration */
|
/* ====== Configuration du serveur ====== */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Retourne la configuration du module pour un serveur virtuel donné.
|
||||||
|
*
|
||||||
|
* @param s Enregistrement du serveur Apache.
|
||||||
|
* @return Pointeur vers la configuration du serveur, ou NULL.
|
||||||
|
*/
|
||||||
static reqin_log_server_conf_t *get_server_conf(server_rec *s)
|
static reqin_log_server_conf_t *get_server_conf(server_rec *s)
|
||||||
{
|
{
|
||||||
return (reqin_log_server_conf_t *)ap_get_module_config(s->module_config, &reqin_log_module);
|
return (reqin_log_server_conf_t *)ap_get_module_config(s->module_config, &reqin_log_module);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Create server configuration */
|
/**
|
||||||
|
* @brief Crée et initialise la configuration du serveur avec les valeurs par défaut.
|
||||||
|
*
|
||||||
|
* @param pool Pool APR pour les allocations mémoire.
|
||||||
|
* @param s Enregistrement du serveur (non utilisé).
|
||||||
|
* @return Pointeur opaque vers la configuration initialisée.
|
||||||
|
*/
|
||||||
static void *reqin_log_create_server_conf(apr_pool_t *pool, server_rec *s)
|
static void *reqin_log_create_server_conf(apr_pool_t *pool, server_rec *s)
|
||||||
{
|
{
|
||||||
(void)s;
|
(void)s;
|
||||||
@ -191,8 +208,15 @@ static void *reqin_log_create_server_conf(apr_pool_t *pool, server_rec *s)
|
|||||||
return srv_conf;
|
return srv_conf;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ============== Dynamic Buffer Functions ============== */
|
/* ====== Fonctions de buffer dynamique ====== */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Initialise le buffer dynamique avec la capacité initiale spécifiée.
|
||||||
|
*
|
||||||
|
* @param db Pointeur vers le buffer dynamique à initialiser.
|
||||||
|
* @param pool Pool APR utilisé pour toutes les allocations mémoire.
|
||||||
|
* @param initial_capacity Capacité initiale en octets.
|
||||||
|
*/
|
||||||
static void dynbuf_init(dynbuf_t *db, apr_pool_t *pool, apr_size_t initial_capacity)
|
static void dynbuf_init(dynbuf_t *db, apr_pool_t *pool, apr_size_t initial_capacity)
|
||||||
{
|
{
|
||||||
db->pool = pool;
|
db->pool = pool;
|
||||||
@ -202,6 +226,13 @@ static void dynbuf_init(dynbuf_t *db, apr_pool_t *pool, apr_size_t initial_capac
|
|||||||
db->data[0] = '\0';
|
db->data[0] = '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Ajoute une chaîne au buffer dynamique, en le redimensionnant si nécessaire.
|
||||||
|
*
|
||||||
|
* @param db Pointeur vers le buffer dynamique.
|
||||||
|
* @param str Chaîne à ajouter (ignorée si NULL).
|
||||||
|
* @param len Nombre d'octets à copier, ou (apr_size_t)-1 pour utiliser strlen(str).
|
||||||
|
*/
|
||||||
static void dynbuf_append(dynbuf_t *db, const char *str, apr_size_t len)
|
static void dynbuf_append(dynbuf_t *db, const char *str, apr_size_t len)
|
||||||
{
|
{
|
||||||
if (str == NULL) return;
|
if (str == NULL) return;
|
||||||
@ -223,6 +254,12 @@ static void dynbuf_append(dynbuf_t *db, const char *str, apr_size_t len)
|
|||||||
db->data[db->len] = '\0';
|
db->data[db->len] = '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Ajoute un seul caractère au buffer dynamique, en le redimensionnant si nécessaire.
|
||||||
|
*
|
||||||
|
* @param db Pointeur vers le buffer dynamique.
|
||||||
|
* @param c Caractère à ajouter.
|
||||||
|
*/
|
||||||
static void dynbuf_append_char(dynbuf_t *db, char c)
|
static void dynbuf_append_char(dynbuf_t *db, char c)
|
||||||
{
|
{
|
||||||
if (db->len + 1 >= db->capacity) {
|
if (db->len + 1 >= db->capacity) {
|
||||||
@ -236,8 +273,17 @@ static void dynbuf_append_char(dynbuf_t *db, char c)
|
|||||||
db->data[db->len] = '\0';
|
db->data[db->len] = '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ============== JSON Helper Functions ============== */
|
/* ====== Sérialisation JSON ====== */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Échappe et ajoute une chaîne C dans le buffer au format JSON (RFC 7159).
|
||||||
|
*
|
||||||
|
* Les caractères spéciaux (guillemets, antislash, retours chariot, etc.) sont encodés.
|
||||||
|
* Les caractères de contrôle inférieurs à 0x20 sont produits sous la forme \\uXXXX.
|
||||||
|
*
|
||||||
|
* @param db Pointeur vers le buffer dynamique de destination.
|
||||||
|
* @param str Chaîne source à sérialiser (ignorée si NULL).
|
||||||
|
*/
|
||||||
static void append_json_string(dynbuf_t *db, const char *str)
|
static void append_json_string(dynbuf_t *db, const char *str)
|
||||||
{
|
{
|
||||||
if (str == NULL) {
|
if (str == NULL) {
|
||||||
@ -267,6 +313,15 @@ static void append_json_string(dynbuf_t *db, const char *str)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Formate un horodatage APR en chaîne ISO 8601 UTC et l'ajoute au buffer.
|
||||||
|
*
|
||||||
|
* Le format produit est YYYY-MM-DDTHH:MM:SSZ (20 caractères).
|
||||||
|
* Les composantes hors plage sont écrêtées pour éviter tout dépassement de tampon.
|
||||||
|
*
|
||||||
|
* @param db Pointeur vers le buffer dynamique de destination.
|
||||||
|
* @param t Horodatage APR en microsecondes depuis l'époque Unix.
|
||||||
|
*/
|
||||||
static void format_iso8601(dynbuf_t *db, apr_time_t t)
|
static void format_iso8601(dynbuf_t *db, apr_time_t t)
|
||||||
{
|
{
|
||||||
apr_time_exp_t tm;
|
apr_time_exp_t tm;
|
||||||
@ -302,6 +357,16 @@ static void format_iso8601(dynbuf_t *db, apr_time_t t)
|
|||||||
dynbuf_append(db, time_str, -1);
|
dynbuf_append(db, time_str, -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Analyse strictement un entier décimal depuis une chaîne de caractères.
|
||||||
|
*
|
||||||
|
* Rejette toute chaîne contenant des espaces en tête, des caractères non numériques
|
||||||
|
* ou des valeurs hors de la plage [INT_MIN, INT_MAX].
|
||||||
|
*
|
||||||
|
* @param arg Chaîne à analyser.
|
||||||
|
* @param out Pointeur vers l'entier résultat (renseigné en cas de succès).
|
||||||
|
* @return 0 en cas de succès, -1 en cas d'erreur.
|
||||||
|
*/
|
||||||
static int parse_int_strict(const char *arg, int *out)
|
static int parse_int_strict(const char *arg, int *out)
|
||||||
{
|
{
|
||||||
char *end = NULL;
|
char *end = NULL;
|
||||||
@ -318,8 +383,16 @@ static int parse_int_strict(const char *arg, int *out)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ============== Configuration Command Handlers ============== */
|
/* ====== Gestionnaires de directives de configuration ====== */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Gestionnaire de la directive JsonSockLogEnabled — active ou désactive le module.
|
||||||
|
*
|
||||||
|
* @param cmd Contexte de la directive Apache.
|
||||||
|
* @param dummy Contexte de répertoire (non utilisé).
|
||||||
|
* @param flag 1 pour activer le module, 0 pour le désactiver.
|
||||||
|
* @return NULL en cas de succès, message d'erreur statique sinon.
|
||||||
|
*/
|
||||||
static const char *cmd_set_enabled(cmd_parms *cmd, void *dummy, int flag)
|
static const char *cmd_set_enabled(cmd_parms *cmd, void *dummy, int flag)
|
||||||
{
|
{
|
||||||
(void)dummy;
|
(void)dummy;
|
||||||
@ -331,6 +404,14 @@ static const char *cmd_set_enabled(cmd_parms *cmd, void *dummy, int flag)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Gestionnaire de la directive JsonSockLogSocket — définit le chemin du socket Unix.
|
||||||
|
*
|
||||||
|
* @param cmd Contexte de la directive Apache.
|
||||||
|
* @param dummy Contexte de répertoire (non utilisé).
|
||||||
|
* @param arg Chemin absolu vers le socket de domaine Unix.
|
||||||
|
* @return NULL en cas de succès, message d'erreur statique sinon.
|
||||||
|
*/
|
||||||
static const char *cmd_set_socket(cmd_parms *cmd, void *dummy, const char *arg)
|
static const char *cmd_set_socket(cmd_parms *cmd, void *dummy, const char *arg)
|
||||||
{
|
{
|
||||||
(void)dummy;
|
(void)dummy;
|
||||||
@ -348,6 +429,17 @@ static const char *cmd_set_socket(cmd_parms *cmd, void *dummy, const char *arg)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Gestionnaire de la directive JsonSockLogHeaders — ajoute un en-tête à journaliser.
|
||||||
|
*
|
||||||
|
* Peut être appelé plusieurs fois (directive ITERATE) pour constituer la liste
|
||||||
|
* des en-têtes HTTP à inclure dans le JSON produit.
|
||||||
|
*
|
||||||
|
* @param cmd Contexte de la directive Apache.
|
||||||
|
* @param dummy Contexte de répertoire (non utilisé).
|
||||||
|
* @param arg Nom de l'en-tête HTTP à ajouter à la liste.
|
||||||
|
* @return NULL en cas de succès, message d'erreur statique sinon.
|
||||||
|
*/
|
||||||
static const char *cmd_set_headers(cmd_parms *cmd, void *dummy, const char *arg)
|
static const char *cmd_set_headers(cmd_parms *cmd, void *dummy, const char *arg)
|
||||||
{
|
{
|
||||||
(void)dummy;
|
(void)dummy;
|
||||||
@ -359,6 +451,14 @@ static const char *cmd_set_headers(cmd_parms *cmd, void *dummy, const char *arg)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Gestionnaire de la directive JsonSockLogMaxHeaders — limite le nombre d'en-têtes journalisés.
|
||||||
|
*
|
||||||
|
* @param cmd Contexte de la directive Apache.
|
||||||
|
* @param dummy Contexte de répertoire (non utilisé).
|
||||||
|
* @param arg Nombre entier maximal d'en-têtes à journaliser (>= 0).
|
||||||
|
* @return NULL en cas de succès, message d'erreur statique sinon.
|
||||||
|
*/
|
||||||
static const char *cmd_set_max_headers(cmd_parms *cmd, void *dummy, const char *arg)
|
static const char *cmd_set_max_headers(cmd_parms *cmd, void *dummy, const char *arg)
|
||||||
{
|
{
|
||||||
int val;
|
int val;
|
||||||
@ -377,6 +477,14 @@ static const char *cmd_set_max_headers(cmd_parms *cmd, void *dummy, const char *
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Gestionnaire de la directive JsonSockLogMaxHeaderValueLen — limite la longueur des valeurs d'en-têtes.
|
||||||
|
*
|
||||||
|
* @param cmd Contexte de la directive Apache.
|
||||||
|
* @param dummy Contexte de répertoire (non utilisé).
|
||||||
|
* @param arg Longueur maximale en octets d'une valeur d'en-tête (>= 1).
|
||||||
|
* @return NULL en cas de succès, message d'erreur statique sinon.
|
||||||
|
*/
|
||||||
static const char *cmd_set_max_header_value_len(cmd_parms *cmd, void *dummy, const char *arg)
|
static const char *cmd_set_max_header_value_len(cmd_parms *cmd, void *dummy, const char *arg)
|
||||||
{
|
{
|
||||||
int val;
|
int val;
|
||||||
@ -395,6 +503,14 @@ static const char *cmd_set_max_header_value_len(cmd_parms *cmd, void *dummy, con
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Gestionnaire de la directive JsonSockLogReconnectInterval — intervalle de reconnexion au socket.
|
||||||
|
*
|
||||||
|
* @param cmd Contexte de la directive Apache.
|
||||||
|
* @param dummy Contexte de répertoire (non utilisé).
|
||||||
|
* @param arg Intervalle en secondes entre deux tentatives de reconnexion (>= 0).
|
||||||
|
* @return NULL en cas de succès, message d'erreur statique sinon.
|
||||||
|
*/
|
||||||
static const char *cmd_set_reconnect_interval(cmd_parms *cmd, void *dummy, const char *arg)
|
static const char *cmd_set_reconnect_interval(cmd_parms *cmd, void *dummy, const char *arg)
|
||||||
{
|
{
|
||||||
int val;
|
int val;
|
||||||
@ -413,6 +529,14 @@ static const char *cmd_set_reconnect_interval(cmd_parms *cmd, void *dummy, const
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Gestionnaire de la directive JsonSockLogErrorReportInterval — fréquence des erreurs dans error_log.
|
||||||
|
*
|
||||||
|
* @param cmd Contexte de la directive Apache.
|
||||||
|
* @param dummy Contexte de répertoire (non utilisé).
|
||||||
|
* @param arg Intervalle minimal en secondes entre deux entrées d'erreur (>= 0).
|
||||||
|
* @return NULL en cas de succès, message d'erreur statique sinon.
|
||||||
|
*/
|
||||||
static const char *cmd_set_error_report_interval(cmd_parms *cmd, void *dummy, const char *arg)
|
static const char *cmd_set_error_report_interval(cmd_parms *cmd, void *dummy, const char *arg)
|
||||||
{
|
{
|
||||||
int val;
|
int val;
|
||||||
@ -431,6 +555,16 @@ static const char *cmd_set_error_report_interval(cmd_parms *cmd, void *dummy, co
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Gestionnaire de la directive JsonSockLogLevel — définit le niveau de verbosité interne.
|
||||||
|
*
|
||||||
|
* Valeurs acceptées : DEBUG, INFO, WARNING, ERROR, EMERG (insensible à la casse).
|
||||||
|
*
|
||||||
|
* @param cmd Contexte de la directive Apache.
|
||||||
|
* @param dummy Contexte de répertoire (non utilisé).
|
||||||
|
* @param arg Chaîne représentant le niveau de log souhaité.
|
||||||
|
* @return NULL en cas de succès, message d'erreur statique sinon.
|
||||||
|
*/
|
||||||
static const char *cmd_set_log_level(cmd_parms *cmd, void *dummy, const char *arg)
|
static const char *cmd_set_log_level(cmd_parms *cmd, void *dummy, const char *arg)
|
||||||
{
|
{
|
||||||
(void)dummy;
|
(void)dummy;
|
||||||
@ -457,11 +591,16 @@ static const char *cmd_set_log_level(cmd_parms *cmd, void *dummy, const char *ar
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ============== Socket Functions ============== */
|
/* ====== Gestion du socket Unix ====== */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if a header name is in the sensitive headers blacklist.
|
* @brief Vérifie si un nom d'en-tête figure dans la liste noire des en-têtes sensibles.
|
||||||
* Returns 1 if header should be excluded, 0 otherwise.
|
*
|
||||||
|
* La comparaison est insensible à la casse. Les en-têtes sensibles (Authorization,
|
||||||
|
* Cookie, etc.) ne sont jamais journalisés pour éviter les fuites d'identifiants.
|
||||||
|
*
|
||||||
|
* @param name Nom de l'en-tête HTTP à vérifier.
|
||||||
|
* @return 1 si l'en-tête est sensible et doit être exclu, 0 sinon.
|
||||||
*/
|
*/
|
||||||
static int is_sensitive_header(const char *name)
|
static int is_sensitive_header(const char *name)
|
||||||
{
|
{
|
||||||
@ -490,6 +629,18 @@ static int is_sensitive_header(const char *name)
|
|||||||
} \
|
} \
|
||||||
} while(0)
|
} while(0)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Tente d'établir (ou de rétablir) la connexion au socket Unix configuré.
|
||||||
|
*
|
||||||
|
* Respecte l'intervalle de reconnexion pour éviter de saturer les tentatives.
|
||||||
|
* Le socket est créé en mode non-bloquant (O_NONBLOCK). La fonction est protégée
|
||||||
|
* par le mutex interne pour la sécurité des threads.
|
||||||
|
*
|
||||||
|
* @param cfg Configuration du module (chemin du socket, intervalle de reconnexion).
|
||||||
|
* @param state État de la connexion du processus enfant courant.
|
||||||
|
* @param s Enregistrement du serveur Apache pour la journalisation des erreurs.
|
||||||
|
* @return 0 en cas de succès ou connexion déjà en cours, -1 en cas d'échec.
|
||||||
|
*/
|
||||||
static int try_connect(reqin_log_config_t *cfg, reqin_log_child_state_t *state, server_rec *s)
|
static int try_connect(reqin_log_config_t *cfg, reqin_log_child_state_t *state, server_rec *s)
|
||||||
{
|
{
|
||||||
apr_time_t now;
|
apr_time_t now;
|
||||||
@ -569,6 +720,17 @@ static int try_connect(reqin_log_config_t *cfg, reqin_log_child_state_t *state,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Vérifie l'état de la connexion et tente de se reconnecter si nécessaire.
|
||||||
|
*
|
||||||
|
* Utilise un double-check sous verrou pour éviter les tentatives superflues
|
||||||
|
* en contexte haute concurrence.
|
||||||
|
*
|
||||||
|
* @param cfg Configuration du module.
|
||||||
|
* @param state État de la connexion du processus enfant courant.
|
||||||
|
* @param s Enregistrement du serveur Apache pour la journalisation des erreurs.
|
||||||
|
* @return 0 si le socket est prêt, -1 si la connexion n'est pas disponible.
|
||||||
|
*/
|
||||||
static int ensure_connected(reqin_log_config_t *cfg, reqin_log_child_state_t *state, server_rec *s)
|
static int ensure_connected(reqin_log_config_t *cfg, reqin_log_child_state_t *state, server_rec *s)
|
||||||
{
|
{
|
||||||
int connected;
|
int connected;
|
||||||
@ -587,6 +749,20 @@ static int ensure_connected(reqin_log_config_t *cfg, reqin_log_child_state_t *st
|
|||||||
return try_connect(cfg, state, s);
|
return try_connect(cfg, state, s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Envoie un bloc de données vers le socket Unix en mode non-bloquant.
|
||||||
|
*
|
||||||
|
* En cas d'erreur de connexion (EPIPE, ECONNRESET, ENOTCONN), le socket est fermé
|
||||||
|
* et marqué pour reconnexion lors du prochain appel. L'envoi partiel est traité
|
||||||
|
* comme une erreur fatale.
|
||||||
|
*
|
||||||
|
* @param data Pointeur vers les données à envoyer.
|
||||||
|
* @param len Taille des données en octets.
|
||||||
|
* @param s Enregistrement du serveur Apache pour la journalisation des erreurs.
|
||||||
|
* @param cfg Configuration du module.
|
||||||
|
* @param state État de la connexion du processus enfant courant.
|
||||||
|
* @return 0 en cas de succès, -1 en cas d'erreur.
|
||||||
|
*/
|
||||||
static int write_to_socket(const char *data, apr_size_t len, server_rec *s,
|
static int write_to_socket(const char *data, apr_size_t len, server_rec *s,
|
||||||
reqin_log_config_t *cfg, reqin_log_child_state_t *state)
|
reqin_log_config_t *cfg, reqin_log_child_state_t *state)
|
||||||
{
|
{
|
||||||
@ -639,8 +815,15 @@ static int write_to_socket(const char *data, apr_size_t len, server_rec *s,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ============== Request Logging Functions ============== */
|
/* ====== Journalisation des requêtes ====== */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Récupère la valeur d'un en-tête HTTP entrant par son nom (insensible à la casse).
|
||||||
|
*
|
||||||
|
* @param r Enregistrement de la requête Apache.
|
||||||
|
* @param name Nom de l'en-tête à rechercher.
|
||||||
|
* @return Valeur de l'en-tête, ou NULL s'il est absent.
|
||||||
|
*/
|
||||||
static const char *get_header(request_rec *r, const char *name)
|
static const char *get_header(request_rec *r, const char *name)
|
||||||
{
|
{
|
||||||
const apr_table_t *headers = r->headers_in;
|
const apr_table_t *headers = r->headers_in;
|
||||||
@ -656,6 +839,18 @@ static const char *get_header(request_rec *r, const char *name)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Sérialise une requête HTTP entrante en JSON et l'envoie vers le socket Unix.
|
||||||
|
*
|
||||||
|
* Construit un objet JSON contenant les métadonnées de la requête (adresses, méthode,
|
||||||
|
* chemin, version HTTP, en-têtes demandés), en respectant les limites de taille et
|
||||||
|
* en filtrant les en-têtes sensibles. La ligne JSON est terminée par un saut de ligne.
|
||||||
|
*
|
||||||
|
* @param r Enregistrement de la requête Apache.
|
||||||
|
* @param cfg Configuration du module (liste d'en-têtes, limites, chemin socket).
|
||||||
|
* @param state État de la connexion du processus enfant courant.
|
||||||
|
* @param srv_conf Configuration complète du serveur (inclut le niveau de log).
|
||||||
|
*/
|
||||||
static void log_request(request_rec *r, reqin_log_config_t *cfg, reqin_log_child_state_t *state, reqin_log_server_conf_t *srv_conf)
|
static void log_request(request_rec *r, reqin_log_config_t *cfg, reqin_log_child_state_t *state, reqin_log_server_conf_t *srv_conf)
|
||||||
{
|
{
|
||||||
apr_pool_t *pool;
|
apr_pool_t *pool;
|
||||||
@ -917,8 +1112,17 @@ static void log_request(request_rec *r, reqin_log_config_t *cfg, reqin_log_child
|
|||||||
write_to_socket(buf.data, buf.len, s, cfg, state);
|
write_to_socket(buf.data, buf.len, s, cfg, state);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ============== Apache Hooks ============== */
|
/* ====== Hooks Apache ====== */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Hook post_read_request — journalise la requête entrante dès sa réception.
|
||||||
|
*
|
||||||
|
* Les sous-requêtes et les redirections internes sont ignorées afin de ne
|
||||||
|
* journaliser que la requête originale du client.
|
||||||
|
*
|
||||||
|
* @param r Enregistrement de la requête Apache.
|
||||||
|
* @return DECLINED dans tous les cas (traitement non exclusif).
|
||||||
|
*/
|
||||||
static int reqin_log_post_read_request(request_rec *r)
|
static int reqin_log_post_read_request(request_rec *r)
|
||||||
{
|
{
|
||||||
reqin_log_server_conf_t *srv_conf = get_server_conf(r->server);
|
reqin_log_server_conf_t *srv_conf = get_server_conf(r->server);
|
||||||
@ -937,6 +1141,16 @@ static int reqin_log_post_read_request(request_rec *r)
|
|||||||
return DECLINED;
|
return DECLINED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Hook child_init — initialise l'état du processus enfant et établit la connexion socket.
|
||||||
|
*
|
||||||
|
* Réinitialise le descripteur de socket, crée le mutex de protection du FD et
|
||||||
|
* tente une première connexion au socket Unix. En MPM threadé, l'absence de mutex
|
||||||
|
* entraîne la désactivation du module pour garantir la sécurité des threads.
|
||||||
|
*
|
||||||
|
* @param p Pool APR du processus enfant.
|
||||||
|
* @param s Enregistrement du serveur Apache.
|
||||||
|
*/
|
||||||
static void reqin_log_child_init(apr_pool_t *p, server_rec *s)
|
static void reqin_log_child_init(apr_pool_t *p, server_rec *s)
|
||||||
{
|
{
|
||||||
reqin_log_server_conf_t *srv_conf = get_server_conf(s);
|
reqin_log_server_conf_t *srv_conf = get_server_conf(s);
|
||||||
@ -987,6 +1201,19 @@ static void reqin_log_child_init(apr_pool_t *p, server_rec *s)
|
|||||||
try_connect(srv_conf->config, &srv_conf->child_state, s);
|
try_connect(srv_conf->config, &srv_conf->child_state, s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Hook post_config — valide la configuration de tous les serveurs virtuels.
|
||||||
|
*
|
||||||
|
* Vérifie que chaque serveur ayant le module activé dispose d'un chemin de socket
|
||||||
|
* valide et non vide. Retourne une erreur HTTP en cas de configuration invalide,
|
||||||
|
* ce qui interrompt le démarrage d'Apache.
|
||||||
|
*
|
||||||
|
* @param pconf Pool de configuration Apache (non utilisé).
|
||||||
|
* @param plog Pool de journalisation Apache (non utilisé).
|
||||||
|
* @param ptemp Pool temporaire (non utilisé).
|
||||||
|
* @param s Premier enregistrement de serveur de la chaîne.
|
||||||
|
* @return OK en cas de succès, HTTP_INTERNAL_SERVER_ERROR sinon.
|
||||||
|
*/
|
||||||
static int reqin_log_post_config(apr_pool_t *pconf, apr_pool_t *plog, apr_pool_t *ptemp, server_rec *s)
|
static int reqin_log_post_config(apr_pool_t *pconf, apr_pool_t *plog, apr_pool_t *ptemp, server_rec *s)
|
||||||
{
|
{
|
||||||
server_rec *cur;
|
server_rec *cur;
|
||||||
@ -1024,6 +1251,14 @@ static int reqin_log_post_config(apr_pool_t *pconf, apr_pool_t *plog, apr_pool_t
|
|||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Enregistre tous les hooks Apache utilisés par le module.
|
||||||
|
*
|
||||||
|
* Enregistre les hooks post_config, post_read_request et child_init
|
||||||
|
* avec une priorité APR_HOOK_MIDDLE.
|
||||||
|
*
|
||||||
|
* @param p Pool APR (non utilisé).
|
||||||
|
*/
|
||||||
static void reqin_log_register_hooks(apr_pool_t *p)
|
static void reqin_log_register_hooks(apr_pool_t *p)
|
||||||
{
|
{
|
||||||
(void)p;
|
(void)p;
|
||||||
|
|||||||
Reference in New Issue
Block a user