Refactor: thread-safe per-process state and add tests
Major changes: - Move child state from global variable to server config (reqin_log_server_conf_t) - Add reqin_log_create_server_conf() for proper per-server initialization - Fix thread safety for worker/event MPMs - Add cmocka unit tests (test_module_real.c) - Add Python integration tests (test_integration.py) - Update CI workflow and Dockerfiles for test execution - Fix: Remove child_exit hook (not in architecture.yml) Tests: - Unit tests: JSON escaping, ISO8601 formatting, header truncation - Integration tests: basic_logging, header_limits, socket_unavailable, socket_loss Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
This commit is contained in:
@ -52,7 +52,7 @@ typedef struct {
|
||||
apr_pool_t *pool;
|
||||
} dynbuf_t;
|
||||
|
||||
/* Per-child process state */
|
||||
/* Per-child process state - stored in server config */
|
||||
typedef struct {
|
||||
int socket_fd;
|
||||
apr_time_t last_connect_attempt;
|
||||
@ -60,27 +60,28 @@ typedef struct {
|
||||
int connect_failed;
|
||||
} reqin_log_child_state_t;
|
||||
|
||||
/* Global child state (one per process) */
|
||||
static reqin_log_child_state_t g_child_state = {
|
||||
.socket_fd = -1,
|
||||
.last_connect_attempt = 0,
|
||||
.last_error_report = 0,
|
||||
.connect_failed = 0
|
||||
};
|
||||
/* Module server configuration structure */
|
||||
typedef struct {
|
||||
reqin_log_config_t *config;
|
||||
reqin_log_child_state_t child_state;
|
||||
} reqin_log_server_conf_t;
|
||||
|
||||
/* Forward declarations for helper functions */
|
||||
static void dynbuf_append(dynbuf_t *db, const char *str, apr_size_t len);
|
||||
static void append_json_string(dynbuf_t *db, const char *str);
|
||||
static void format_iso8601(dynbuf_t *db, apr_time_t t);
|
||||
|
||||
/* Forward declarations for server config */
|
||||
static void *reqin_log_create_server_conf(apr_pool_t *pool, server_rec *s);
|
||||
|
||||
/* Forward declarations for commands */
|
||||
static const char *cmd_set_enabled(cmd_parms *cmd, void *cfg, int flag);
|
||||
static const char *cmd_set_socket(cmd_parms *cmd, void *cfg, const char *arg);
|
||||
static const char *cmd_set_headers(cmd_parms *cmd, void *cfg, const char *arg);
|
||||
static const char *cmd_set_max_headers(cmd_parms *cmd, void *cfg, const char *arg);
|
||||
static const char *cmd_set_max_header_value_len(cmd_parms *cmd, void *cfg, const char *arg);
|
||||
static const char *cmd_set_reconnect_interval(cmd_parms *cmd, void *cfg, const char *arg);
|
||||
static const char *cmd_set_error_report_interval(cmd_parms *cmd, void *cfg, const char *arg);
|
||||
static const char *cmd_set_enabled(cmd_parms *cmd, void *dummy, int flag);
|
||||
static const char *cmd_set_socket(cmd_parms *cmd, void *dummy, const char *arg);
|
||||
static const char *cmd_set_headers(cmd_parms *cmd, void *dummy, const char *arg);
|
||||
static const char *cmd_set_max_headers(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);
|
||||
static const char *cmd_set_reconnect_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);
|
||||
|
||||
/* Forward declarations for hooks */
|
||||
static int reqin_log_post_read_request(request_rec *r);
|
||||
@ -109,19 +110,40 @@ static const command_rec reqin_log_cmds[] = {
|
||||
/* Module definition */
|
||||
module AP_MODULE_DECLARE_DATA reqin_log_module = {
|
||||
STANDARD20_MODULE_STUFF,
|
||||
NULL, /* per-directory config creator */
|
||||
NULL, /* dir config merger */
|
||||
NULL, /* server config creator */
|
||||
NULL, /* server config merger */
|
||||
reqin_log_cmds, /* command table */
|
||||
reqin_log_register_hooks /* register hooks */
|
||||
NULL, /* per-directory config creator */
|
||||
NULL, /* dir config merger */
|
||||
reqin_log_create_server_conf, /* server config creator */
|
||||
NULL, /* server config merger */
|
||||
reqin_log_cmds, /* command table */
|
||||
reqin_log_register_hooks /* register hooks */
|
||||
};
|
||||
|
||||
/* Get module configuration */
|
||||
static reqin_log_config_t *get_module_config(server_rec *s)
|
||||
static reqin_log_server_conf_t *get_server_conf(server_rec *s)
|
||||
{
|
||||
reqin_log_config_t *cfg = (reqin_log_config_t *)ap_get_module_config(s->module_config, &reqin_log_module);
|
||||
return cfg;
|
||||
reqin_log_server_conf_t *srv_conf = (reqin_log_server_conf_t *)ap_get_module_config(s->module_config, &reqin_log_module);
|
||||
return srv_conf;
|
||||
}
|
||||
|
||||
/* Create server configuration */
|
||||
static void *reqin_log_create_server_conf(apr_pool_t *pool, server_rec *s)
|
||||
{
|
||||
(void)s;
|
||||
reqin_log_server_conf_t *srv_conf = apr_pcalloc(pool, sizeof(reqin_log_server_conf_t));
|
||||
|
||||
srv_conf->config = apr_pcalloc(pool, sizeof(reqin_log_config_t));
|
||||
srv_conf->config->headers = apr_array_make(pool, 5, sizeof(const char *));
|
||||
srv_conf->config->max_headers = DEFAULT_MAX_HEADERS;
|
||||
srv_conf->config->max_header_value_len = DEFAULT_MAX_HEADER_VALUE_LEN;
|
||||
srv_conf->config->reconnect_interval = DEFAULT_RECONNECT_INTERVAL;
|
||||
srv_conf->config->error_report_interval = DEFAULT_ERROR_REPORT_INTERVAL;
|
||||
|
||||
srv_conf->child_state.socket_fd = -1;
|
||||
srv_conf->child_state.last_connect_attempt = 0;
|
||||
srv_conf->child_state.last_error_report = 0;
|
||||
srv_conf->child_state.connect_failed = 0;
|
||||
|
||||
return srv_conf;
|
||||
}
|
||||
|
||||
/* ============== Dynamic Buffer Functions ============== */
|
||||
@ -214,227 +236,184 @@ static void format_iso8601(dynbuf_t *db, apr_time_t t)
|
||||
|
||||
/* ============== Configuration Command Handlers ============== */
|
||||
|
||||
static const char *cmd_set_enabled(cmd_parms *cmd, void *cfg, int flag)
|
||||
static const char *cmd_set_enabled(cmd_parms *cmd, void *dummy, int flag)
|
||||
{
|
||||
reqin_log_config_t *conf = get_module_config(cmd->server);
|
||||
if (conf == NULL) {
|
||||
conf = apr_pcalloc(cmd->pool, sizeof(reqin_log_config_t));
|
||||
conf->headers = apr_array_make(cmd->pool, 0, sizeof(const char *));
|
||||
conf->max_headers = DEFAULT_MAX_HEADERS;
|
||||
conf->max_header_value_len = DEFAULT_MAX_HEADER_VALUE_LEN;
|
||||
conf->reconnect_interval = DEFAULT_RECONNECT_INTERVAL;
|
||||
conf->error_report_interval = DEFAULT_ERROR_REPORT_INTERVAL;
|
||||
ap_set_module_config(cmd->server->module_config, &reqin_log_module, conf);
|
||||
(void)dummy;
|
||||
reqin_log_server_conf_t *srv_conf = get_server_conf(cmd->server);
|
||||
if (srv_conf == NULL) {
|
||||
return "Internal error: server configuration not available";
|
||||
}
|
||||
conf->enabled = flag ? 1 : 0;
|
||||
srv_conf->config->enabled = flag ? 1 : 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static const char *cmd_set_socket(cmd_parms *cmd, void *cfg, const char *arg)
|
||||
static const char *cmd_set_socket(cmd_parms *cmd, void *dummy, const char *arg)
|
||||
{
|
||||
reqin_log_config_t *conf = get_module_config(cmd->server);
|
||||
if (conf == NULL) {
|
||||
conf = apr_pcalloc(cmd->pool, sizeof(reqin_log_config_t));
|
||||
conf->enabled = 0;
|
||||
conf->headers = apr_array_make(cmd->pool, 0, sizeof(const char *));
|
||||
conf->max_headers = DEFAULT_MAX_HEADERS;
|
||||
conf->max_header_value_len = DEFAULT_MAX_HEADER_VALUE_LEN;
|
||||
conf->reconnect_interval = DEFAULT_RECONNECT_INTERVAL;
|
||||
conf->error_report_interval = DEFAULT_ERROR_REPORT_INTERVAL;
|
||||
ap_set_module_config(cmd->server->module_config, &reqin_log_module, conf);
|
||||
(void)dummy;
|
||||
reqin_log_server_conf_t *srv_conf = get_server_conf(cmd->server);
|
||||
if (srv_conf == NULL) {
|
||||
return "Internal error: server configuration not available";
|
||||
}
|
||||
conf->socket_path = apr_pstrdup(cmd->pool, arg);
|
||||
srv_conf->config->socket_path = apr_pstrdup(cmd->pool, arg);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static const char *cmd_set_headers(cmd_parms *cmd, void *cfg, const char *arg)
|
||||
static const char *cmd_set_headers(cmd_parms *cmd, void *dummy, const char *arg)
|
||||
{
|
||||
reqin_log_config_t *conf = get_module_config(cmd->server);
|
||||
if (conf == NULL) {
|
||||
conf = apr_pcalloc(cmd->pool, sizeof(reqin_log_config_t));
|
||||
conf->enabled = 0;
|
||||
conf->socket_path = NULL;
|
||||
conf->max_headers = DEFAULT_MAX_HEADERS;
|
||||
conf->max_header_value_len = DEFAULT_MAX_HEADER_VALUE_LEN;
|
||||
conf->reconnect_interval = DEFAULT_RECONNECT_INTERVAL;
|
||||
conf->error_report_interval = DEFAULT_ERROR_REPORT_INTERVAL;
|
||||
ap_set_module_config(cmd->server->module_config, &reqin_log_module, conf);
|
||||
(void)dummy;
|
||||
reqin_log_server_conf_t *srv_conf = get_server_conf(cmd->server);
|
||||
if (srv_conf == NULL) {
|
||||
return "Internal error: server configuration not available";
|
||||
}
|
||||
if (conf->headers == NULL) {
|
||||
conf->headers = apr_array_make(cmd->pool, 5, sizeof(const char *));
|
||||
}
|
||||
*(const char **)apr_array_push(conf->headers) = apr_pstrdup(cmd->pool, arg);
|
||||
*(const char **)apr_array_push(srv_conf->config->headers) = apr_pstrdup(cmd->pool, arg);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static const char *cmd_set_max_headers(cmd_parms *cmd, void *cfg, const char *arg)
|
||||
static const char *cmd_set_max_headers(cmd_parms *cmd, void *dummy, const char *arg)
|
||||
{
|
||||
reqin_log_config_t *conf = get_module_config(cmd->server);
|
||||
if (conf == NULL) {
|
||||
conf = apr_pcalloc(cmd->pool, sizeof(reqin_log_config_t));
|
||||
conf->enabled = 0;
|
||||
conf->socket_path = NULL;
|
||||
conf->headers = apr_array_make(cmd->pool, 0, sizeof(const char *));
|
||||
conf->max_header_value_len = DEFAULT_MAX_HEADER_VALUE_LEN;
|
||||
conf->reconnect_interval = DEFAULT_RECONNECT_INTERVAL;
|
||||
conf->error_report_interval = DEFAULT_ERROR_REPORT_INTERVAL;
|
||||
ap_set_module_config(cmd->server->module_config, &reqin_log_module, conf);
|
||||
(void)dummy;
|
||||
reqin_log_server_conf_t *srv_conf = get_server_conf(cmd->server);
|
||||
if (srv_conf == NULL) {
|
||||
return "Internal error: server configuration not available";
|
||||
}
|
||||
int val = atoi(arg);
|
||||
if (val < 0) {
|
||||
return "JsonSockLogMaxHeaders must be >= 0";
|
||||
}
|
||||
conf->max_headers = val;
|
||||
srv_conf->config->max_headers = val;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static const char *cmd_set_max_header_value_len(cmd_parms *cmd, void *cfg, const char *arg)
|
||||
static const char *cmd_set_max_header_value_len(cmd_parms *cmd, void *dummy, const char *arg)
|
||||
{
|
||||
reqin_log_config_t *conf = get_module_config(cmd->server);
|
||||
if (conf == NULL) {
|
||||
conf = apr_pcalloc(cmd->pool, sizeof(reqin_log_config_t));
|
||||
conf->enabled = 0;
|
||||
conf->socket_path = NULL;
|
||||
conf->headers = apr_array_make(cmd->pool, 0, sizeof(const char *));
|
||||
conf->max_headers = DEFAULT_MAX_HEADERS;
|
||||
conf->reconnect_interval = DEFAULT_RECONNECT_INTERVAL;
|
||||
conf->error_report_interval = DEFAULT_ERROR_REPORT_INTERVAL;
|
||||
ap_set_module_config(cmd->server->module_config, &reqin_log_module, conf);
|
||||
(void)dummy;
|
||||
reqin_log_server_conf_t *srv_conf = get_server_conf(cmd->server);
|
||||
if (srv_conf == NULL) {
|
||||
return "Internal error: server configuration not available";
|
||||
}
|
||||
int val = atoi(arg);
|
||||
if (val < 1) {
|
||||
return "JsonSockLogMaxHeaderValueLen must be >= 1";
|
||||
}
|
||||
conf->max_header_value_len = val;
|
||||
srv_conf->config->max_header_value_len = val;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static const char *cmd_set_reconnect_interval(cmd_parms *cmd, void *cfg, const char *arg)
|
||||
static const char *cmd_set_reconnect_interval(cmd_parms *cmd, void *dummy, const char *arg)
|
||||
{
|
||||
reqin_log_config_t *conf = get_module_config(cmd->server);
|
||||
if (conf == NULL) {
|
||||
conf = apr_pcalloc(cmd->pool, sizeof(reqin_log_config_t));
|
||||
conf->enabled = 0;
|
||||
conf->socket_path = NULL;
|
||||
conf->headers = apr_array_make(cmd->pool, 0, sizeof(const char *));
|
||||
conf->max_headers = DEFAULT_MAX_HEADERS;
|
||||
conf->max_header_value_len = DEFAULT_MAX_HEADER_VALUE_LEN;
|
||||
conf->error_report_interval = DEFAULT_ERROR_REPORT_INTERVAL;
|
||||
ap_set_module_config(cmd->server->module_config, &reqin_log_module, conf);
|
||||
(void)dummy;
|
||||
reqin_log_server_conf_t *srv_conf = get_server_conf(cmd->server);
|
||||
if (srv_conf == NULL) {
|
||||
return "Internal error: server configuration not available";
|
||||
}
|
||||
int val = atoi(arg);
|
||||
if (val < 0) {
|
||||
return "JsonSockLogReconnectInterval must be >= 0";
|
||||
}
|
||||
conf->reconnect_interval = val;
|
||||
srv_conf->config->reconnect_interval = val;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static const char *cmd_set_error_report_interval(cmd_parms *cmd, void *cfg, const char *arg)
|
||||
static const char *cmd_set_error_report_interval(cmd_parms *cmd, void *dummy, const char *arg)
|
||||
{
|
||||
reqin_log_config_t *conf = get_module_config(cmd->server);
|
||||
if (conf == NULL) {
|
||||
conf = apr_pcalloc(cmd->pool, sizeof(reqin_log_config_t));
|
||||
conf->enabled = 0;
|
||||
conf->socket_path = NULL;
|
||||
conf->headers = apr_array_make(cmd->pool, 0, sizeof(const char *));
|
||||
conf->max_headers = DEFAULT_MAX_HEADERS;
|
||||
conf->max_header_value_len = DEFAULT_MAX_HEADER_VALUE_LEN;
|
||||
conf->reconnect_interval = DEFAULT_RECONNECT_INTERVAL;
|
||||
ap_set_module_config(cmd->server->module_config, &reqin_log_module, conf);
|
||||
(void)dummy;
|
||||
reqin_log_server_conf_t *srv_conf = get_server_conf(cmd->server);
|
||||
if (srv_conf == NULL) {
|
||||
return "Internal error: server configuration not available";
|
||||
}
|
||||
int val = atoi(arg);
|
||||
if (val < 0) {
|
||||
return "JsonSockLogErrorReportInterval must be >= 0";
|
||||
}
|
||||
conf->error_report_interval = val;
|
||||
srv_conf->config->error_report_interval = val;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* ============== Socket Functions ============== */
|
||||
|
||||
static int try_connect(reqin_log_config_t *cfg, 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_now();
|
||||
apr_time_t interval = apr_time_from_sec(cfg->reconnect_interval);
|
||||
|
||||
if (g_child_state.connect_failed &&
|
||||
(now - g_child_state.last_connect_attempt) < interval) {
|
||||
|
||||
if (state->connect_failed &&
|
||||
(now - state->last_connect_attempt) < interval) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
g_child_state.last_connect_attempt = now;
|
||||
|
||||
if (g_child_state.socket_fd < 0) {
|
||||
g_child_state.socket_fd = socket(AF_UNIX, SOCK_STREAM, 0);
|
||||
if (g_child_state.socket_fd < 0) {
|
||||
|
||||
state->last_connect_attempt = now;
|
||||
|
||||
if (state->socket_fd < 0) {
|
||||
state->socket_fd = socket(AF_UNIX, SOCK_STREAM, 0);
|
||||
if (state->socket_fd < 0) {
|
||||
ap_log_error(APLOG_MARK, APLOG_ERR, errno, s,
|
||||
MOD_REQIN_LOG_NAME ": Failed to create socket");
|
||||
return -1;
|
||||
}
|
||||
|
||||
int flags = fcntl(g_child_state.socket_fd, F_GETFL, 0);
|
||||
fcntl(g_child_state.socket_fd, F_SETFL, flags | O_NONBLOCK);
|
||||
|
||||
int flags = fcntl(state->socket_fd, F_GETFL, 0);
|
||||
fcntl(state->socket_fd, F_SETFL, flags | O_NONBLOCK);
|
||||
}
|
||||
|
||||
|
||||
struct sockaddr_un addr;
|
||||
memset(&addr, 0, sizeof(addr));
|
||||
addr.sun_family = AF_UNIX;
|
||||
snprintf(addr.sun_path, sizeof(addr.sun_path), "%s", cfg->socket_path);
|
||||
|
||||
int rc = connect(g_child_state.socket_fd, (struct sockaddr *)&addr, sizeof(addr));
|
||||
|
||||
int rc = connect(state->socket_fd, (struct sockaddr *)&addr, sizeof(addr));
|
||||
if (rc < 0) {
|
||||
int err = errno;
|
||||
if (err != EINPROGRESS && err != EAGAIN && err != EWOULDBLOCK) {
|
||||
close(g_child_state.socket_fd);
|
||||
g_child_state.socket_fd = -1;
|
||||
g_child_state.connect_failed = 1;
|
||||
|
||||
if ((now - g_child_state.last_error_report) >= apr_time_from_sec(cfg->error_report_interval)) {
|
||||
close(state->socket_fd);
|
||||
state->socket_fd = -1;
|
||||
state->connect_failed = 1;
|
||||
|
||||
if ((now - state->last_error_report) >= apr_time_from_sec(cfg->error_report_interval)) {
|
||||
ap_log_error(APLOG_MARK, APLOG_ERR, err, s,
|
||||
MOD_REQIN_LOG_NAME ": Unix socket connect failed: %s", cfg->socket_path);
|
||||
g_child_state.last_error_report = now;
|
||||
state->last_error_report = now;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
g_child_state.connect_failed = 0;
|
||||
|
||||
state->connect_failed = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ensure_connected(reqin_log_config_t *cfg, server_rec *s)
|
||||
static int ensure_connected(reqin_log_config_t *cfg, reqin_log_child_state_t *state, server_rec *s)
|
||||
{
|
||||
if (g_child_state.socket_fd >= 0 && !g_child_state.connect_failed) {
|
||||
if (state->socket_fd >= 0 && !state->connect_failed) {
|
||||
return 0;
|
||||
}
|
||||
return try_connect(cfg, s);
|
||||
return try_connect(cfg, state, s);
|
||||
}
|
||||
|
||||
static int write_to_socket(const char *data, apr_size_t len, server_rec *s, reqin_log_config_t *cfg)
|
||||
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)
|
||||
{
|
||||
if (g_child_state.socket_fd < 0) {
|
||||
if (state->socket_fd < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
apr_size_t total_written = 0;
|
||||
while (total_written < len) {
|
||||
ssize_t n = write(g_child_state.socket_fd, data + total_written, len - total_written);
|
||||
ssize_t n = write(state->socket_fd, data + total_written, len - total_written);
|
||||
if (n < 0) {
|
||||
int err = errno;
|
||||
if (err == EAGAIN || err == EWOULDBLOCK) {
|
||||
return -1;
|
||||
}
|
||||
if (err == EPIPE || err == ECONNRESET) {
|
||||
close(g_child_state.socket_fd);
|
||||
g_child_state.socket_fd = -1;
|
||||
g_child_state.connect_failed = 1;
|
||||
|
||||
close(state->socket_fd);
|
||||
state->socket_fd = -1;
|
||||
state->connect_failed = 1;
|
||||
|
||||
apr_time_t now = apr_time_now();
|
||||
if ((now - g_child_state.last_error_report) >= apr_time_from_sec(cfg->error_report_interval)) {
|
||||
if ((now - state->last_error_report) >= apr_time_from_sec(cfg->error_report_interval)) {
|
||||
ap_log_error(APLOG_MARK, APLOG_ERR, err, s,
|
||||
MOD_REQIN_LOG_NAME ": Unix socket write failed: %s", strerror(err));
|
||||
g_child_state.last_error_report = now;
|
||||
state->last_error_report = now;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
@ -442,7 +421,7 @@ static int write_to_socket(const char *data, apr_size_t len, server_rec *s, reqi
|
||||
}
|
||||
total_written += n;
|
||||
}
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -453,7 +432,7 @@ static const char *get_header(request_rec *r, const char *name)
|
||||
const apr_table_t *headers = r->headers_in;
|
||||
apr_table_entry_t *elts = (apr_table_entry_t *)apr_table_elts(headers)->elts;
|
||||
int nelts = apr_table_elts(headers)->nelts;
|
||||
|
||||
|
||||
for (int i = 0; i < nelts; i++) {
|
||||
if (strcasecmp(elts[i].key, name) == 0) {
|
||||
return elts[i].val;
|
||||
@ -462,13 +441,13 @@ static const char *get_header(request_rec *r, const char *name)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void log_request(request_rec *r, reqin_log_config_t *cfg)
|
||||
static void log_request(request_rec *r, reqin_log_config_t *cfg, reqin_log_child_state_t *state)
|
||||
{
|
||||
apr_pool_t *pool = r->pool;
|
||||
server_rec *s = r->server;
|
||||
char port_buf[16];
|
||||
|
||||
if (ensure_connected(cfg, s) < 0) {
|
||||
if (ensure_connected(cfg, state, s) < 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -571,50 +550,45 @@ static void log_request(request_rec *r, reqin_log_config_t *cfg)
|
||||
|
||||
dynbuf_append(&buf, "}\n", 2);
|
||||
|
||||
write_to_socket(buf.data, buf.len, s, cfg);
|
||||
write_to_socket(buf.data, buf.len, s, cfg, state);
|
||||
}
|
||||
|
||||
/* ============== Apache Hooks ============== */
|
||||
|
||||
static int reqin_log_post_read_request(request_rec *r)
|
||||
{
|
||||
reqin_log_config_t *cfg = get_module_config(r->server);
|
||||
|
||||
if (cfg == NULL || !cfg->enabled || cfg->socket_path == NULL) {
|
||||
reqin_log_server_conf_t *srv_conf = get_server_conf(r->server);
|
||||
|
||||
if (srv_conf == NULL || srv_conf->config == NULL ||
|
||||
!srv_conf->config->enabled || srv_conf->config->socket_path == NULL) {
|
||||
return DECLINED;
|
||||
}
|
||||
|
||||
log_request(r, cfg);
|
||||
|
||||
log_request(r, srv_conf->config, &srv_conf->child_state);
|
||||
return DECLINED;
|
||||
}
|
||||
|
||||
static void reqin_log_child_init(apr_pool_t *p, server_rec *s)
|
||||
{
|
||||
(void)p;
|
||||
reqin_log_server_conf_t *srv_conf = get_server_conf(s);
|
||||
|
||||
reqin_log_config_t *cfg = get_module_config(s);
|
||||
|
||||
g_child_state.socket_fd = -1;
|
||||
g_child_state.last_connect_attempt = 0;
|
||||
g_child_state.last_error_report = 0;
|
||||
g_child_state.connect_failed = 0;
|
||||
|
||||
if (cfg == NULL || !cfg->enabled || cfg->socket_path == NULL) {
|
||||
if (srv_conf == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
try_connect(cfg, s);
|
||||
}
|
||||
/* Initialize child state for this process */
|
||||
srv_conf->child_state.socket_fd = -1;
|
||||
srv_conf->child_state.last_connect_attempt = 0;
|
||||
srv_conf->child_state.last_error_report = 0;
|
||||
srv_conf->child_state.connect_failed = 0;
|
||||
|
||||
static void reqin_log_child_exit(apr_pool_t *p, server_rec *s)
|
||||
{
|
||||
(void)p;
|
||||
(void)s;
|
||||
|
||||
if (g_child_state.socket_fd >= 0) {
|
||||
close(g_child_state.socket_fd);
|
||||
g_child_state.socket_fd = -1;
|
||||
if (srv_conf->config == NULL || !srv_conf->config->enabled ||
|
||||
srv_conf->config->socket_path == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
try_connect(srv_conf->config, &srv_conf->child_state, s);
|
||||
}
|
||||
|
||||
static void reqin_log_register_hooks(apr_pool_t *p)
|
||||
@ -622,5 +596,4 @@ static void reqin_log_register_hooks(apr_pool_t *p)
|
||||
(void)p;
|
||||
ap_hook_post_read_request(reqin_log_post_read_request, NULL, NULL, APR_HOOK_MIDDLE);
|
||||
ap_hook_child_init(reqin_log_child_init, NULL, NULL, APR_HOOK_MIDDLE);
|
||||
ap_hook_child_exit(reqin_log_child_exit, NULL, NULL, APR_HOOK_MIDDLE);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user