Browse Source

[multiple] reduce direct use of srv->errh

personal/stbuehler/ci-build
Glenn Strauss 2 years ago
parent
commit
b5775b9951
  1. 55
      src/connections.c
  2. 2
      src/connections.h
  3. 142
      src/gw_backend.c
  4. 38
      src/mod_accesslog.c
  5. 42
      src/mod_auth.c
  6. 100
      src/mod_cgi.c
  7. 6
      src/mod_mysql_vhost.c
  8. 10
      src/mod_openssl.c
  9. 9
      src/mod_rrdtool.c
  10. 8
      src/mod_secdownload.c
  11. 2
      src/network.c
  12. 6
      src/server.c

55
src/connections.c

@ -75,17 +75,15 @@ static int connection_del(server *srv, connection *con) {
/* not last element */
if (i != conns->used - 1) {
if (i != --conns->used) {
connection * const temp = conns->ptr[i];
conns->ptr[i] = conns->ptr[conns->used - 1];
conns->ptr[conns->used - 1] = temp;
conns->ptr[i] = conns->ptr[conns->used];
conns->ptr[conns->used] = temp;
conns->ptr[i]->ndx = i;
conns->ptr[conns->used - 1]->ndx = -1;
conns->ptr[conns->used]->ndx = -1;
}
conns->used--;
con->ndx = -1;
#if 0
fprintf(stderr, "%s.%d: del: (%d)", __FILE__, __LINE__, conns->used);
@ -110,7 +108,7 @@ static void connection_plugin_ctx_check(server *srv, connection *con) {
}
}
static int connection_close(server *srv, connection *con) {
static int connection_close(connection *con) {
if (con->fd < 0) con->fd = -con->fd;
plugins_call_handle_connection_close(con);
@ -118,6 +116,7 @@ static int connection_close(server *srv, connection *con) {
con->request_count = 0;
chunkqueue_reset(con->read_queue);
server * const srv = con->srv;
fdevent_fdnode_event_del(srv->ev, con->fdn);
fdevent_unregister(srv->ev, con->fd);
con->fdn = NULL;
@ -187,11 +186,11 @@ static void connection_read_for_eos(connection * const con) {
: connection_read_for_eos_ssl(con);
}
static void connection_handle_close_state(server *srv, connection *con) {
static void connection_handle_close_state(connection *con) {
connection_read_for_eos(con);
if (log_epoch_secs - con->close_timeout_ts > HTTP_LINGER_TIMEOUT) {
connection_close(srv, con);
connection_close(con);
}
}
@ -199,8 +198,7 @@ static void connection_handle_shutdown(connection *con) {
plugins_call_handle_connection_shut_wr(con);
connection_reset(con);
server * const srv = con->srv;
++srv->con_closed;
++con->srv->con_closed;
/* close the connection */
if (con->fd >= 0
@ -208,12 +206,12 @@ static void connection_handle_shutdown(connection *con) {
con->close_timeout_ts = log_epoch_secs;
connection_set_state(con, CON_STATE_CLOSE);
if (srv->srvconf.log_state_handling) {
if (con->srv->srvconf.log_state_handling) {
log_error(con->conf.errh, __FILE__, __LINE__,
"shutdown for fd %d", con->fd);
}
} else {
connection_close(srv, con);
connection_close(con);
}
}
@ -757,7 +755,7 @@ static uint32_t connection_read_header_hoff(const char *n, const uint32_t clen,
*
* we get called by the state-engine and by the fdevent-handler
*/
static int connection_handle_read_state(server * const srv, connection * const con) {
static int connection_handle_read_state(connection * const con) {
int keepalive_request_start = 0;
int pipelined_request_start = 0;
@ -797,7 +795,7 @@ static int connection_handle_read_state(server * const srv, connection * const c
* addition might overflow, but max_request_field_size is USHRT_MAX,
* so failure will be detected below */
const unsigned int max_request_field_size =
srv->srvconf.max_request_field_size;
con->srv->srvconf.max_request_field_size;
if ((con->header_len ? con->header_len : clen) > max_request_field_size
|| hoff[0] >= sizeof(hoff)/sizeof(hoff[0])-1) {
log_error(con->conf.errh, __FILE__, __LINE__, "%s",
@ -855,7 +853,7 @@ static int connection_handle_read_state(server * const srv, connection * const c
con->keep_alive = 0;
con->request.content_length = 0;
if (srv->srvconf.log_request_header_on_error) {
if (con->srv->srvconf.log_request_header_on_error) {
/*(http_request_parse() modifies hdrs only to
* undo line-wrapping in-place using spaces)*/
log_error(con->conf.errh, __FILE__, __LINE__, "request-header:\n%.*s",
@ -891,7 +889,7 @@ static handler_t connection_handle_fdevent(server *srv, void *context, int reven
if (con->state == CON_STATE_READ) {
connection_handle_read_state(srv, con);
connection_handle_read_state(con);
}
if (con->state == CON_STATE_WRITE &&
@ -1091,8 +1089,7 @@ static int connection_read_cq(connection *con, chunkqueue *cq, off_t max_bytes)
static int connection_write_cq(connection *con, chunkqueue *cq, off_t max_bytes) {
server * const srv = con->srv;
return srv->network_backend_write(con->fd, cq, max_bytes, con->conf.errh);
return con->srv->network_backend_write(con->fd,cq,max_bytes,con->conf.errh);
}
@ -1129,7 +1126,7 @@ connection *connection_accepted(server *srv, server_socket *srv_socket, sock_add
buffer_copy_string_len(con->proto, CONST_STR_LEN("http"));
if (HANDLER_GO_ON != plugins_call_handle_connection_accept(con)) {
connection_reset(con);
connection_close(srv, con);
connection_close(con);
return NULL;
}
if (con->http_status < 0) connection_set_state(con, CON_STATE_WRITE);
@ -1245,10 +1242,10 @@ static int connection_handle_request(connection *con) {
}
int connection_state_machine(server *srv, connection *con) {
int connection_state_machine(connection *con) {
connection_state_t ostate;
int r;
const int log_state_handling = srv->srvconf.log_state_handling;
const int log_state_handling = con->srv->srvconf.log_state_handling;
if (log_state_handling) {
log_error(con->conf.errh, __FILE__, __LINE__,
@ -1273,7 +1270,7 @@ int connection_state_machine(server *srv, connection *con) {
connection_set_state(con, CON_STATE_READ);
/* fall through */
case CON_STATE_READ:
if (!connection_handle_read_state(srv, con)) break;
if (!connection_handle_read_state(con)) break;
/*if (con->state != CON_STATE_REQUEST_END) break;*/
/* fall through */
case CON_STATE_REQUEST_END: /* transient */
@ -1313,7 +1310,7 @@ int connection_state_machine(server *srv, connection *con) {
connection_handle_response_end_state(con);
break;
case CON_STATE_CLOSE:
connection_handle_close_state(srv, con);
connection_handle_close_state(con);
break;
case CON_STATE_CONNECT:
break;
@ -1377,14 +1374,14 @@ int connection_state_machine(server *srv, connection *con) {
if ((r & FDEVENT_OUT) && !(events & FDEVENT_OUT)) {
con->write_request_ts = log_epoch_secs;
}
fdevent_fdnode_event_set(srv->ev, con->fdn, r);
fdevent_fdnode_event_set(con->srv->ev, con->fdn, r);
}
}
return 0;
}
static void connection_check_timeout (server * const srv, const time_t cur_ts, connection * const con) {
static void connection_check_timeout (connection * const con, const time_t cur_ts) {
const int waitevents = fdevent_fdnode_interest(con->fdn);
int changed = 0;
int t_diff;
@ -1466,7 +1463,7 @@ static void connection_check_timeout (server * const srv, const time_t cur_ts, c
con->bytes_written_cur_second = 0;
if (changed) {
connection_state_machine(srv, con);
connection_state_machine(con);
}
}
@ -1474,7 +1471,7 @@ void connection_periodic_maint (server * const srv, const time_t cur_ts) {
/* check all connections for timeouts */
connections * const conns = &srv->conns;
for (size_t ndx = 0; ndx < conns->used; ++ndx) {
connection_check_timeout(srv, cur_ts, conns->ptr[ndx]);
connection_check_timeout(conns->ptr[ndx], cur_ts);
}
}
@ -1509,7 +1506,7 @@ void connection_graceful_shutdown_maint (server *srv) {
}
if (changed) {
connection_state_machine(srv, con);
connection_state_machine(con);
}
}
}

2
src/connections.h

@ -17,7 +17,7 @@ connection * connection_accepted(server *srv, server_socket *srv_socket, sock_ad
const char * connection_get_state(connection_state_t state);
const char * connection_get_short_state(connection_state_t state);
int connection_state_machine(server *srv, connection *con);
int connection_state_machine(connection *con);
handler_t connection_handle_read_post_state(connection *con);
handler_t connection_handle_read_post_error(connection *con, int http_status);
int connection_write_chunkqueue(connection *con, chunkqueue *c, off_t max_bytes);

142
src/gw_backend.c

@ -297,39 +297,38 @@ static void gw_proc_release(gw_host *host, gw_proc *proc, int debug, log_error_s
}
}
static void gw_proc_check_enable(server *srv, gw_host *host, gw_proc *proc) {
static void gw_proc_check_enable(gw_host * const host, gw_proc * const proc, log_error_st * const errh) {
if (log_epoch_secs <= proc->disabled_until) return;
if (proc->state != PROC_STATE_OVERLOADED) return;
gw_proc_set_state(host, proc, PROC_STATE_RUNNING);
log_error(srv->errh, __FILE__, __LINE__,
log_error(errh, __FILE__, __LINE__,
"gw-server re-enabled: %s %s %hu %s",
proc->connection_name->ptr, host->host->ptr, host->port,
host->unixsocket->ptr ? host->unixsocket->ptr : "");
}
static void gw_proc_waitpid_log(server *srv, gw_host *host, gw_proc *proc, int status) {
UNUSED(host);
static void gw_proc_waitpid_log(const gw_host * const host, const gw_proc * const proc, log_error_st * const errh, const int status) {
if (WIFEXITED(status)) {
if (proc->state != PROC_STATE_KILLED) {
log_error(srv->errh, __FILE__, __LINE__,
log_error(errh, __FILE__, __LINE__,
"child exited: %d %s",
WEXITSTATUS(status), proc->connection_name->ptr);
}
} else if (WIFSIGNALED(status)) {
if (WTERMSIG(status) != SIGTERM && WTERMSIG(status) != SIGINT
&& WTERMSIG(status) != host->kill_signal) {
log_error(srv->errh, __FILE__, __LINE__,
log_error(errh, __FILE__, __LINE__,
"child signalled: %d", WTERMSIG(status));
}
} else {
log_error(srv->errh, __FILE__, __LINE__,
log_error(errh, __FILE__, __LINE__,
"child died somehow: %d", status);
}
}
static int gw_proc_waitpid(server *srv, gw_host *host, gw_proc *proc) {
static int gw_proc_waitpid(gw_host *host, gw_proc *proc, log_error_st *errh) {
int rc, status;
if (!proc->is_local) return 0;
@ -344,11 +343,11 @@ static int gw_proc_waitpid(server *srv, gw_host *host, gw_proc *proc) {
if (-1 == rc) {
/* EINVAL or ECHILD no child processes */
/* should not happen; someone else has cleaned up for us */
log_perror(srv->errh, __FILE__, __LINE__,
log_perror(errh, __FILE__, __LINE__,
"pid %d %d not found", proc->pid, proc->state);
}
else {
gw_proc_waitpid_log(srv, host, proc, status);
gw_proc_waitpid_log(host, proc, errh, status);
}
proc->pid = 0;
@ -358,13 +357,13 @@ static int gw_proc_waitpid(server *srv, gw_host *host, gw_proc *proc) {
return 1;
}
static int gw_proc_sockaddr_init(server *srv, gw_host *host, gw_proc *proc) {
static int gw_proc_sockaddr_init(gw_host * const host, gw_proc * const proc, log_error_st * const errh) {
sock_addr addr;
socklen_t addrlen;
if (!buffer_string_is_empty(proc->unixsocket)) {
if (1 != sock_addr_from_str_hints(&addr,&addrlen,proc->unixsocket->ptr,
AF_UNIX, 0, srv->errh)) {
AF_UNIX, 0, errh)) {
errno = EINVAL;
return -1;
}
@ -374,7 +373,7 @@ static int gw_proc_sockaddr_init(server *srv, gw_host *host, gw_proc *proc) {
else {
/*(note: name resolution here is *blocking* if IP string not supplied)*/
if (1 != sock_addr_from_str_hints(&addr, &addrlen, host->host->ptr,
0, proc->port, srv->errh)) {
0, proc->port, errh)) {
errno = EINVAL;
return -1;
}
@ -435,20 +434,20 @@ static int env_add(char_array *env, const char *key, size_t key_len, const char
return 0;
}
static int gw_spawn_connection(server *srv, gw_host *host, gw_proc *proc, int debug) {
static int gw_spawn_connection(gw_host * const host, gw_proc * const proc, log_error_st * const errh, int debug) {
int gw_fd;
int status;
struct timeval tv = { 0, 10 * 1000 };
if (debug) {
log_error(srv->errh, __FILE__, __LINE__,
log_error(errh, __FILE__, __LINE__,
"new proc, socket: %hu %s",
proc->port, proc->unixsocket->ptr ? proc->unixsocket->ptr : "");
}
gw_fd = fdevent_socket_cloexec(proc->saddr->sa_family, SOCK_STREAM, 0);
if (-1 == gw_fd) {
log_perror(srv->errh, __FILE__, __LINE__, "socket()");
log_perror(errh, __FILE__, __LINE__, "socket()");
return -1;
}
@ -458,7 +457,7 @@ static int gw_spawn_connection(server *srv, gw_host *host, gw_proc *proc, int de
if (-1 == status && errno != ENOENT
&& !buffer_string_is_empty(proc->unixsocket)) {
log_perror(srv->errh, __FILE__, __LINE__,
log_perror(errh, __FILE__, __LINE__,
"unlink %s after connect failed", proc->unixsocket->ptr);
unlink(proc->unixsocket->ptr);
}
@ -474,26 +473,26 @@ static int gw_spawn_connection(server *srv, gw_host *host, gw_proc *proc, int de
/* reopen socket */
gw_fd = fdevent_socket_cloexec(proc->saddr->sa_family, SOCK_STREAM, 0);
if (-1 == gw_fd) {
log_perror(srv->errh, __FILE__, __LINE__, "socket()");
log_perror(errh, __FILE__, __LINE__, "socket()");
return -1;
}
if (fdevent_set_so_reuseaddr(gw_fd, 1) < 0) {
log_perror(srv->errh, __FILE__, __LINE__, "socketsockopt()");
log_perror(errh, __FILE__, __LINE__, "socketsockopt()");
close(gw_fd);
return -1;
}
/* create socket */
if (-1 == bind(gw_fd, proc->saddr, proc->saddrlen)) {
log_perror(srv->errh, __FILE__, __LINE__,
log_perror(errh, __FILE__, __LINE__,
"bind failed for: %s", proc->connection_name->ptr);
close(gw_fd);
return -1;
}
if (-1 == listen(gw_fd, host->listen_backlog)) {
log_perror(srv->errh, __FILE__, __LINE__, "listen()");
log_perror(errh, __FILE__, __LINE__, "listen()");
close(gw_fd);
return -1;
}
@ -553,7 +552,7 @@ static int gw_spawn_connection(server *srv, gw_host *host, gw_proc *proc, int de
dfd = fdevent_open_dirname(host->args.ptr[0], 1); /* permit symlinks */
if (-1 == dfd) {
log_perror(srv->errh, __FILE__, __LINE__,
log_perror(errh, __FILE__, __LINE__,
"open dirname failed: %s", host->args.ptr[0]);
}
@ -569,7 +568,7 @@ static int gw_spawn_connection(server *srv, gw_host *host, gw_proc *proc, int de
close(gw_fd);
if (-1 == proc->pid) {
log_error(srv->errh, __FILE__, __LINE__,
log_error(errh, __FILE__, __LINE__,
"gw-backend failed to start: %s", host->bin_path->ptr);
proc->pid = 0;
proc->disabled_until = log_epoch_secs;
@ -583,10 +582,10 @@ static int gw_spawn_connection(server *srv, gw_host *host, gw_proc *proc, int de
/* wait */
select(0, NULL, NULL, NULL, &tv);
if (0 != gw_proc_waitpid(srv, host, proc)) {
log_error(srv->errh, __FILE__, __LINE__,
if (0 != gw_proc_waitpid(host, proc, errh)) {
log_error(errh, __FILE__, __LINE__,
"gw-backend failed to start: %s", host->bin_path->ptr);
log_error(srv->errh, __FILE__, __LINE__,
log_error(errh, __FILE__, __LINE__,
"If you're trying to run your app as a FastCGI backend, make "
"sure you're using the FastCGI-enabled version. If this is PHP "
"on Gentoo, add 'fastcgi' to the USE flags. If this is PHP, try "
@ -598,7 +597,7 @@ static int gw_spawn_connection(server *srv, gw_host *host, gw_proc *proc, int de
proc->pid = 0;
if (debug) {
log_error(srv->errh, __FILE__, __LINE__,
log_error(errh, __FILE__, __LINE__,
"(debug) socket is already used; won't spawn: %s",
proc->connection_name->ptr);
}
@ -608,7 +607,7 @@ static int gw_spawn_connection(server *srv, gw_host *host, gw_proc *proc, int de
return 0;
}
static void gw_proc_spawn(server *srv, gw_host *host, int debug) {
static void gw_proc_spawn(gw_host * const host, log_error_st * const errh, const int debug) {
gw_proc *proc;
for (proc = host->unused_procs; proc; proc = proc->next) {
/* (proc->pid <= 0 indicates PROC_STATE_DIED, not PROC_STATE_KILLED) */
@ -644,16 +643,16 @@ static void gw_proc_spawn(server *srv, gw_host *host, int debug) {
buffer_append_int(proc->unixsocket, proc->id);
}
if (0 != gw_proc_sockaddr_init(srv, host, proc)) {
if (0 != gw_proc_sockaddr_init(host, proc, errh)) {
/*(should not happen if host->host validated at startup,
* and translated from name to IP address at startup)*/
log_error(srv->errh, __FILE__, __LINE__,
log_error(errh, __FILE__, __LINE__,
"ERROR: spawning backend failed.");
--host->num_procs;
if (proc->id == host->max_id-1) --host->max_id;
gw_proc_free(proc);
} else if (gw_spawn_connection(srv, host, proc, debug)) {
log_error(srv->errh, __FILE__, __LINE__,
} else if (gw_spawn_connection(host, proc, errh, debug)) {
log_error(errh, __FILE__, __LINE__,
"ERROR: spawning backend failed.");
proc->next = host->unused_procs;
if (host->unused_procs)
@ -922,7 +921,7 @@ static gw_host * gw_host_get(connection *con, gw_extension *extension, int balan
host = extension->hosts[k];
if (0 == host->min_procs && 0 == host->num_procs
&& !buffer_string_is_empty(host->bin_path)) {
gw_proc_spawn(con->srv, host, debug);
gw_proc_spawn(host, con->srv->errh, debug);
if (host->num_procs) return host;
}
}
@ -969,10 +968,10 @@ static int gw_establish_connection(connection *con, gw_host *host, gw_proc *proc
return 0;
}
static void gw_restart_dead_procs(server *srv, gw_host *host, int debug, int trigger) {
static void gw_restart_dead_procs(gw_host * const host, log_error_st * const errh, const int debug, const int trigger) {
for (gw_proc *proc = host->first; proc; proc = proc->next) {
if (debug > 2) {
log_error(srv->errh, __FILE__, __LINE__,
log_error(errh, __FILE__, __LINE__,
"proc: %s %d %d %d %d", proc->connection_name->ptr,
proc->state, proc->is_local, proc->load, proc->pid);
}
@ -981,7 +980,7 @@ static void gw_restart_dead_procs(server *srv, gw_host *host, int debug, int tri
case PROC_STATE_RUNNING:
break;
case PROC_STATE_OVERLOADED:
gw_proc_check_enable(srv, host, proc);
gw_proc_check_enable(host, proc, errh);
break;
case PROC_STATE_KILLED:
if (trigger && ++proc->disabled_until > 4) {
@ -997,8 +996,8 @@ static void gw_restart_dead_procs(server *srv, gw_host *host, int debug, int tri
* to save proc->disabled_until before gw_proc_waitpid() since
* gw_proc_waitpid will set proc->disabled_until to log_epoch_secs,
* and so process will not be restarted below until one sec later)*/
if (0 == gw_proc_waitpid(srv, host, proc)) {
gw_proc_check_enable(srv, host, proc);
if (0 == gw_proc_waitpid(host, proc, errh)) {
gw_proc_check_enable(host, proc, errh);
}
if (proc->state != PROC_STATE_DIED) break;
@ -1019,19 +1018,19 @@ static void gw_restart_dead_procs(server *srv, gw_host *host, int debug, int tri
/* restart the child */
if (debug) {
log_error(srv->errh, __FILE__, __LINE__,
log_error(errh, __FILE__, __LINE__,
"--- gw spawning"
"\n\tsocket %s"
"\n\tcurrent: 1 / %u",
proc->connection_name->ptr, host->max_procs);
}
if (gw_spawn_connection(srv, host, proc, debug)) {
log_error(srv->errh, __FILE__, __LINE__,
if (gw_spawn_connection(host, proc, errh, debug)) {
log_error(errh, __FILE__, __LINE__,
"ERROR: spawning gw failed.");
}
} else {
gw_proc_check_enable(srv, host, proc);
gw_proc_check_enable(host, proc, errh);
}
break;
}
@ -1622,13 +1621,13 @@ int gw_set_defaults_backend(server *srv, gw_plugin_data *p, const array *a, gw_p
pno, host->max_procs);
}
if (0 != gw_proc_sockaddr_init(srv, host, proc)) {
if (0 != gw_proc_sockaddr_init(host, proc, srv->errh)) {
gw_proc_free(proc);
goto error;
}
if (!srv->srvconf.preflight_check
&& gw_spawn_connection(srv, host, proc, s->debug)) {
&& gw_spawn_connection(host, proc, srv->errh, s->debug)) {
log_error(srv->errh, __FILE__, __LINE__,
"[ERROR]: spawning gw failed.");
gw_proc_free(proc);
@ -1663,7 +1662,7 @@ int gw_set_defaults_backend(server *srv, gw_plugin_data *p, const array *a, gw_p
host->min_procs = 1;
host->max_procs = 1;
if (0 != gw_proc_sockaddr_init(srv, host, proc)) goto error;
if (0 != gw_proc_sockaddr_init(host, proc, srv->errh)) goto error;
}
/* s->exts is list of exts -> hosts
@ -1992,7 +1991,7 @@ static handler_t gw_write_error(gw_handler_ctx *hctx, connection *con) {
/* (optimization to detect backend process exit while processing a
* large number of ready events; (this block could be removed)) */
if (0 == con->srv->srvconf.max_worker)
gw_restart_dead_procs(con->srv, hctx->host, hctx->conf.debug, 0);
gw_restart_dead_procs(hctx->host,con->srv->errh,hctx->conf.debug,0);
/* cleanup this request and let request handler start request again */
if (hctx->reconnects++ < 5) return gw_reconnect(hctx, con);
@ -2115,7 +2114,6 @@ static handler_t gw_recv_response(gw_handler_ctx *hctx, connection *con) {
buffer *b = hctx->opts.backend == BACKEND_FASTCGI
? chunk_buffer_acquire()
: hctx->response;
log_error_st *errh;
handler_t rc =
http_response_read(hctx->remote_conn, &hctx->opts, b, hctx->fdn);
@ -2150,7 +2148,7 @@ static handler_t gw_recv_response(gw_handler_ctx *hctx, connection *con) {
/* don't do more than 6 loops here; normally shouldn't happen */
if (++con->loops_per_request > 5) {
log_error(hctx->remote_conn->conf.errh, __FILE__, __LINE__,
log_error(con->conf.errh, __FILE__, __LINE__,
"too many loops while processing request: %s",
con->request.orig_uri->ptr);
con->http_status = 500; /* Internal Server Error */
@ -2180,20 +2178,20 @@ static handler_t gw_recv_response(gw_handler_ctx *hctx, connection *con) {
case HANDLER_ERROR:
/* (optimization to detect backend process exit while processing a
* large number of ready events; (this block could be removed)) */
errh = con->conf.errh;
if (proc->is_local && 1 == proc->load && proc->pid == hctx->pid
&& proc->state != PROC_STATE_DIED
&& 0 == con->srv->srvconf.max_worker) {
/* intentionally check proc->disabed_until before gw_proc_waitpid */
log_error_st * const errh = con->srv->errh;
if (proc->disabled_until < log_epoch_secs
&& 0 != gw_proc_waitpid(con->srv, host, proc)) {
&& 0 != gw_proc_waitpid(host, proc, errh)) {
if (hctx->conf.debug) {
log_error(errh, __FILE__, __LINE__,
"--- gw spawning\n\tsocket %s\n\tcurrent: 1/%d",
proc->connection_name->ptr, host->num_procs);
}
if (gw_spawn_connection(con->srv,host,proc,hctx->conf.debug)) {
if (gw_spawn_connection(host, proc, errh, hctx->conf.debug)) {
log_error(errh, __FILE__, __LINE__,
"respawning failed, will retry later");
}
@ -2206,7 +2204,7 @@ static handler_t gw_recv_response(gw_handler_ctx *hctx, connection *con) {
if (hctx->wb->bytes_out == 0 &&
hctx->reconnects++ < 5) {
log_error(errh, __FILE__, __LINE__,
log_error(con->conf.errh, __FILE__, __LINE__,
"response not received, request not sent on "
"socket: %s for %s?%.*s, reconnecting",
proc->connection_name->ptr,
@ -2215,13 +2213,13 @@ static handler_t gw_recv_response(gw_handler_ctx *hctx, connection *con) {
return gw_reconnect(hctx, con);
}
log_error(errh, __FILE__, __LINE__,
log_error(con->conf.errh, __FILE__, __LINE__,
"response not received, request sent: %lld on "
"socket: %s for %s?%.*s, closing connection",
(long long)hctx->wb->bytes_out, proc->connection_name->ptr,
con->uri.path->ptr, BUFFER_INTLEN_PTR(con->uri.query));
} else {
log_error(errh, __FILE__, __LINE__,
log_error(con->conf.errh, __FILE__, __LINE__,
"response already sent out, but backend returned error on "
"socket: %s for %s?%.*s, terminating connection",
proc->connection_name->ptr,
@ -2515,7 +2513,7 @@ handler_t gw_check_extension(connection *con, gw_plugin_data *p, int uri_path_ha
return HANDLER_GO_ON;
}
static void gw_handle_trigger_host(server *srv, gw_host *host, int debug) {
static void gw_handle_trigger_host(gw_host * const host, log_error_st * const errh, const int debug) {
/*
* TODO:
*
@ -2534,10 +2532,10 @@ static void gw_handle_trigger_host(server *srv, gw_host *host, int debug) {
int overload = 1;
for (proc = host->first; proc; proc = proc->next) {
gw_proc_waitpid(srv, host, proc);
gw_proc_waitpid(host, proc, errh);
}
gw_restart_dead_procs(srv, host, debug, 1);
gw_restart_dead_procs(host, errh, debug, 1);
/* check if adaptive spawning enabled */
if (host->min_procs == host->max_procs) return;
@ -2553,11 +2551,11 @@ static void gw_handle_trigger_host(server *srv, gw_host *host, int debug) {
if (overload && host->num_procs && host->num_procs < host->max_procs) {
/* overload, spawn new child */
if (debug) {
log_error(srv->errh, __FILE__, __LINE__,
log_error(errh, __FILE__, __LINE__,
"overload detected, spawning a new child");
}
gw_proc_spawn(srv, host, debug);
gw_proc_spawn(host, errh, debug);
}
idle_timestamp = log_epoch_secs - host->idle_timeout;
@ -2569,7 +2567,7 @@ static void gw_handle_trigger_host(server *srv, gw_host *host, int debug) {
/* terminate proc that has been idling for a long time */
if (debug) {
log_error(srv->errh, __FILE__, __LINE__,
log_error(errh, __FILE__, __LINE__,
"idle-timeout reached, terminating child: socket: %s pid %d",
proc->unixsocket->ptr, proc->pid);
}
@ -2581,27 +2579,27 @@ static void gw_handle_trigger_host(server *srv, gw_host *host, int debug) {
}
for (proc = host->unused_procs; proc; proc = proc->next) {
gw_proc_waitpid(srv, host, proc);
gw_proc_waitpid(host, proc, errh);
}
}
static void gw_handle_trigger_exts(server *srv, gw_exts *exts, int debug) {
static void gw_handle_trigger_exts(gw_exts * const exts, log_error_st * const errh, const int debug) {
for (uint32_t j = 0; j < exts->used; ++j) {
gw_extension *ex = exts->exts+j;
for (uint32_t n = 0; n < ex->used; ++n) {
gw_handle_trigger_host(srv, ex->hosts[n], debug);
gw_handle_trigger_host(ex->hosts[n], errh, debug);
}
}
}
static void gw_handle_trigger_exts_wkr(server *srv, gw_exts *exts) {
static void gw_handle_trigger_exts_wkr(gw_exts *exts, log_error_st *errh) {
for (uint32_t j = 0; j < exts->used; ++j) {
gw_extension * const ex = exts->exts+j;
for (uint32_t n = 0; n < ex->used; ++n) {
gw_host * const host = ex->hosts[n];
for (gw_proc *proc = host->first; proc; proc = proc->next) {
if (proc->state == PROC_STATE_OVERLOADED)
gw_proc_check_enable(srv, host, proc);
gw_proc_check_enable(host, proc, errh);
}
}
}
@ -2610,6 +2608,7 @@ static void gw_handle_trigger_exts_wkr(server *srv, gw_exts *exts) {
handler_t gw_handle_trigger(server *srv, void *p_d) {
gw_plugin_data * const p = p_d;
int wkr = (0 != srv->srvconf.max_worker && p->srv_pid != srv->pid);
log_error_st * const errh = srv->errh;
int global_debug = 0;
if (NULL == p->cvlist) return HANDLER_GO_ON;
@ -2638,8 +2637,8 @@ handler_t gw_handle_trigger(server *srv, void *p_d) {
* (unable to use p->defaults.debug since gw_plugin_config
* might be part of a larger plugin_config) */
wkr
? gw_handle_trigger_exts_wkr(srv, conf->exts)
: gw_handle_trigger_exts(srv, conf->exts, debug);
? gw_handle_trigger_exts_wkr(conf->exts, errh)
: gw_handle_trigger_exts(conf->exts, errh, debug);
}
return HANDLER_GO_ON;
@ -2649,6 +2648,7 @@ handler_t gw_handle_waitpid_cb(server *srv, void *p_d, pid_t pid, int status) {
gw_plugin_data * const p = p_d;
if (0 != srv->srvconf.max_worker && p->srv_pid != srv->pid)
return HANDLER_GO_ON;
log_error_st * const errh = srv->errh;
int global_debug = 0;
if (NULL == p->cvlist) return HANDLER_GO_ON;
@ -2686,7 +2686,7 @@ handler_t gw_handle_waitpid_cb(server *srv, void *p_d, pid_t pid, int status) {
for (proc = host->first; proc; proc = proc->next) {
if (!proc->is_local || proc->pid != pid) continue;
gw_proc_waitpid_log(srv, host, proc, status);
gw_proc_waitpid_log(host, proc, errh, status);
gw_proc_set_state(host, proc, PROC_STATE_DIED);
proc->pid = 0;
@ -2694,8 +2694,8 @@ handler_t gw_handle_waitpid_cb(server *srv, void *p_d, pid_t pid, int status) {
if (proc->disabled_until < cur_ts) {
if (proc->state != PROC_STATE_KILLED)
proc->disabled_until = cur_ts;
if (gw_spawn_connection(srv, host, proc, debug)) {
log_error(srv->errh, __FILE__, __LINE__,
if (gw_spawn_connection(host, proc, errh, debug)) {
log_error(errh, __FILE__, __LINE__,
"ERROR: spawning gw failed.");
}
}
@ -2705,7 +2705,7 @@ handler_t gw_handle_waitpid_cb(server *srv, void *p_d, pid_t pid, int status) {
for (proc = host->unused_procs; proc; proc = proc->next) {
if (!proc->is_local || proc->pid != pid) continue;
gw_proc_waitpid_log(srv, host, proc, status);
gw_proc_waitpid_log(host, proc, errh, status);
if (proc->state != PROC_STATE_KILLED)
proc->disabled_until = cur_ts;
gw_proc_set_state(host, proc, PROC_STATE_DIED);

38
src/mod_accesslog.c

@ -248,13 +248,13 @@ static void accesslog_append_escaped(buffer *dest, const buffer *str) {
}
__attribute_cold__
static format_fields * accesslog_parse_format_err(server *srv, const char *file, unsigned int line, format_field *f, const char *msg) {
log_error(srv->errh, file, line, "%s", msg);
static format_fields * accesslog_parse_format_err(log_error_st *errh, const char *file, unsigned int line, format_field *f, const char *msg) {
log_error(errh, file, line, "%s", msg);
for (; f->type != FIELD_UNSET; ++f) free(f->string.ptr);
return NULL;
}
static format_fields * accesslog_parse_format(server *srv, const char *format, const size_t flen) {
static format_fields * accesslog_parse_format(const char * const format, const size_t flen, log_error_st * const errh) {
/* common log format (the default) results in 18 elements,
* so 127 should be enough except for obscene custom usage */
size_t i, j, k = 0, start = 0;
@ -273,7 +273,7 @@ static format_fields * accesslog_parse_format(server *srv, const char *format, c
if (i > 0 && start != i) {
/* copy the string before this % */
if (used == sz)
return accesslog_parse_format_err(srv, __FILE__, __LINE__, fptr,
return accesslog_parse_format_err(errh, __FILE__, __LINE__, fptr,
"too many fields (>= 127) in accesslog.format");
f = fptr+used;
@ -286,7 +286,7 @@ static format_fields * accesslog_parse_format(server *srv, const char *format, c
/* we need a new field */
if (used == sz)
return accesslog_parse_format_err(srv, __FILE__, __LINE__, fptr,
return accesslog_parse_format_err(errh, __FILE__, __LINE__, fptr,
"too many fields (>= 127) in accesslog.format");
/* search for the terminating command */
@ -295,7 +295,7 @@ static format_fields * accesslog_parse_format(server *srv, const char *format, c
case '<':
/* after the } has to be a character */
if (format[i+2] == '\0') {
return accesslog_parse_format_err(srv, __FILE__, __LINE__, fptr,
return accesslog_parse_format_err(errh, __FILE__, __LINE__, fptr,
"%< and %> have to be followed by a format-specifier");
}
@ -317,7 +317,7 @@ static format_fields * accesslog_parse_format(server *srv, const char *format, c
}
if (fmap[j].key == '\0') {
return accesslog_parse_format_err(srv, __FILE__, __LINE__, fptr,
return accesslog_parse_format_err(errh, __FILE__, __LINE__, fptr,
"%< and %> have to be followed by a valid format-specifier");
}
@ -333,18 +333,18 @@ static format_fields * accesslog_parse_format(server *srv, const char *format, c
}
if (k == flen) {
return accesslog_parse_format_err(srv, __FILE__, __LINE__, fptr,
return accesslog_parse_format_err(errh, __FILE__, __LINE__, fptr,
"%{ has to be terminated by a }");
}
/* after the } has to be a character */
if (format[k+1] == '\0') {
return accesslog_parse_format_err(srv, __FILE__, __LINE__, fptr,
return accesslog_parse_format_err(errh, __FILE__, __LINE__, fptr,
"%{...} has to be followed by a format-specifier");
}
if (k == i + 2) {
return accesslog_parse_format_err(srv, __FILE__, __LINE__, fptr,
return accesslog_parse_format_err(errh, __FILE__, __LINE__, fptr,
"%{...} has to contain a string");
}
@ -366,7 +366,7 @@ static format_fields * accesslog_parse_format(server *srv, const char *format, c
}
if (fmap[j].key == '\0') {
return accesslog_parse_format_err(srv, __FILE__, __LINE__, fptr,
return accesslog_parse_format_err(errh, __FILE__, __LINE__, fptr,
"%{...} has to be followed by a valid format-specifier");
}
@ -377,7 +377,7 @@ static format_fields * accesslog_parse_format(server *srv, const char *format, c
default:
/* after the % has to be a character */
if (format[i+1] == '\0') {
return accesslog_parse_format_err(srv, __FILE__, __LINE__, fptr,
return accesslog_parse_format_err(errh, __FILE__, __LINE__, fptr,
"% has to be followed by a format-specifier");
}
@ -398,7 +398,7 @@ static format_fields * accesslog_parse_format(server *srv, const char *format, c
}
if (fmap[j].key == '\0') {
return accesslog_parse_format_err(srv, __FILE__, __LINE__, fptr,
return accesslog_parse_format_err(errh, __FILE__, __LINE__, fptr,
"% has to be followed by a valid format-specifier");
}
@ -412,7 +412,7 @@ static format_fields * accesslog_parse_format(server *srv, const char *format, c
if (start < i) {
/* copy the string */
if (used == sz)
return accesslog_parse_format_err(srv, __FILE__, __LINE__, fptr,
return accesslog_parse_format_err(errh, __FILE__, __LINE__, fptr,
"too many fields (>= 127) in accesslog.format");
f = fptr+used;
@ -518,7 +518,7 @@ static void mod_accesslog_patch_config(connection * const con, plugin_data * con
}
}
static format_fields * mod_accesslog_process_format(server * const srv, const char * const format, const size_t flen);
static format_fields * mod_accesslog_process_format(const char * const format, const size_t flen, server * const srv);
SETDEFAULTS_FUNC(mod_accesslog_set_defaults) {
static const config_plugin_keys_t cpk[] = {
@ -563,7 +563,7 @@ SETDEFAULTS_FUNC(mod_accesslog_set_defaults) {
break;
case 1: /* accesslog.format */
cpv->v.v =
mod_accesslog_process_format(srv, CONST_BUF_LEN(cpv->v.b));
mod_accesslog_process_format(CONST_BUF_LEN(cpv->v.b), srv);
if (NULL == cpv->v.v) return HANDLER_ERROR;
cpv->vtype = T_CONFIG_LOCAL;
break;
@ -606,16 +606,16 @@ SETDEFAULTS_FUNC(mod_accesslog_set_defaults) {
static const char fmt[] =
"%h %V %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"";
p->defaults.parsed_format = p->default_format =
mod_accesslog_process_format(srv, CONST_STR_LEN(fmt));
mod_accesslog_process_format(CONST_STR_LEN(fmt), srv);
if (NULL == p->default_format) return HANDLER_ERROR;
}
return HANDLER_GO_ON;
}
static format_fields * mod_accesslog_process_format(server * const srv, const char * const format, const size_t flen) {
static format_fields * mod_accesslog_process_format(const char * const format, const size_t flen, server * const srv) {
format_fields * const parsed_format =
accesslog_parse_format(srv, format, flen);
accesslog_parse_format(format, flen, srv->errh);
if (NULL == parsed_format) {
log_error(srv->errh, __FILE__, __LINE__,
"parsing accesslog-definition failed: %s", format);

42
src/mod_auth.c

@ -169,7 +169,7 @@ static int mod_auth_algorithms_parse(int *algorithm, buffer *algos) {
return 1;
}
static int mod_auth_require_parse (server *srv, http_auth_require_t * const require, const buffer *b)
static int mod_auth_require_parse (http_auth_require_t * const require, const buffer *b, log_error_st *errh)
{
/* user=name1|user=name2|group=name3|host=name4 */
@ -188,14 +188,14 @@ static int mod_auth_require_parse (server *srv, http_auth_require_t * const requ
len = NULL != p ? (size_t)(p - str) : strlen(str);
eq = memchr(str, '=', len);
if (NULL == eq) {
log_error(srv->errh, __FILE__, __LINE__,
log_error(errh, __FILE__, __LINE__,
"error parsing auth.require 'require' field: missing '=' "
"(expecting \"valid-user\" or \"user=a|user=b|group=g|host=h\"). "
"error value: %s error near: %s", b->ptr, str);
return 0;
}
if (eq[1] == '|' || eq[1] == '\0') {
log_error(srv->errh, __FILE__, __LINE__,
log_error(errh, __FILE__, __LINE__,
"error parsing auth.require 'require' field: "
"missing token after '=' "
"(expecting \"valid-user\" or \"user=a|user=b|group=g|host=h\"). "
@ -213,7 +213,7 @@ static int mod_auth_require_parse (server *srv, http_auth_require_t * const requ
else if (0 == memcmp(str, CONST_STR_LEN("host"))) {
/*("host=" is 5)*/
array_set_key_value(&require->host, str+5, len-5, CONST_STR_LEN(""));
log_error(srv->errh, __FILE__, __LINE__,
log_error(errh, __FILE__, __LINE__,
"warning parsing auth.require 'require' field: "
"'host' not implemented; field value: %s", b->ptr);
continue;
@ -224,7 +224,7 @@ static int mod_auth_require_parse (server *srv, http_auth_require_t * const requ
/*("group=" is 6)*/
array_set_key_value(&require->group, str+6, len-6, CONST_STR_LEN(""));
#if 0/*(supported by mod_authn_ldap, but not all other backends)*/
log_error(srv->errh, __FILE__, __LINE__,
log_error(errh, __FILE__, __LINE__,
"warning parsing auth.require 'require' field: "
"'group' not implemented; field value: %s", b->ptr);
#endif
@ -233,7 +233,7 @@ static int mod_auth_require_parse (server *srv, http_auth_require_t * const requ
break; /* to error */
case 10:
if (0 == memcmp(str, CONST_STR_LEN("valid-user"))) {
log_error(srv->errh, __FILE__, __LINE__,
log_error(errh, __FILE__, __LINE__,
"error parsing auth.require 'require' field: "
"valid user can not be combined with other require rules "
"(expecting \"valid-user\" or "
@ -245,7 +245,7 @@ static int mod_auth_require_parse (server *srv, http_auth_require_t * const requ
break; /* to error */
}
log_error(srv->errh, __FILE__, __LINE__,
log_error(errh, __FILE__, __LINE__,
"error parsing auth.require 'require' field: "
"invalid/unsupported token "
"(expecting \"valid-user\" or \"user=a|user=b|group=g|host=h\"). "
@ -257,7 +257,7 @@ static int mod_auth_require_parse (server *srv, http_auth_require_t * const requ
return 1; /* success */
}
static handler_t mod_auth_require_parse_array(server *srv, const array *value, array * const auth_require)
static handler_t mod_auth_require_parse_array(const array *value, array * const auth_require, log_error_st *errh)
{
for (uint32_t n = 0; n < value->used; ++n) {
size_t m;
@ -268,7 +268,7 @@ static handler_t mod_auth_require_parse_array(server *srv, const array *value, a
int algorithm = HTTP_AUTH_DIGEST_SESS;
if (!array_is_kvstring(&da_file->value)) {
log_error(srv->errh, __FILE__, __LINE__,
log_error(errh, __FILE__, __LINE__,
"unexpected value for auth.require; expected "
"auth.require = ( \"urlpath\" => ( \"option\" => \"value\" ) )");
@ -287,7 +287,7 @@ static handler_t mod_auth_require_parse_array(server *srv, const array *value, a
} else if (buffer_is_equal_string(&ds->key, CONST_STR_LEN("algorithm"))) {
algos = &ds->value;
} else {
log_error(srv->errh, __FILE__, __LINE__,
log_error(errh, __FILE__, __LINE__,
"the field is unknown in: "
"auth.require = ( \"...\" => ( ..., -> \"%s\" <- => \"...\" ) )",
da_file->value.data[m]->key.ptr);
@ -295,7 +295,7 @@ static handler_t mod_auth_require_parse_array(server *srv, const array *value, a
return HANDLER_ERROR;
}
} else {
log_error(srv->errh, __FILE__, __LINE__,
log_error(errh, __FILE__, __LINE__,
"a string was expected for: "
"auth.require = ( \"...\" => ( ..., -> \"%s\" <- => \"...\" ) )",
da_file->value.data[m]->key.ptr);
@ -305,14 +305,14 @@ static handler_t mod_auth_require_parse_array(server *srv, const array *value, a
}
if (buffer_string_is_empty(method)) {
log_error(srv->errh, __FILE__, __LINE__,
log_error(errh, __FILE__, __LINE__,
"the method field is missing or blank in: "
"auth.require = ( \"...\" => ( ..., \"method\" => \"...\" ) )");
return HANDLER_ERROR;
} else {
auth_scheme = http_auth_scheme_get(method);
if (NULL == auth_scheme) {
log_error(srv->errh, __FILE__, __LINE__,
log_error(errh, __FILE__, __LINE__,
"unknown method %s (e.g. \"basic\", \"digest\" or \"extern\") in "
"auth.require = ( \"...\" => ( ..., \"method\" => \"...\") )", method->ptr);
return HANDLER_ERROR;
@ -320,14 +320,14 @@ static handler_t mod_auth_require_parse_array(server *srv, const array *value, a
}
if (buffer_is_empty(realm)) {
log_error(srv->errh, __FILE__, __LINE__,
log_error(errh, __FILE__, __LINE__,
"the realm field is missing in: "
"auth.require = ( \"...\" => ( ..., \"realm\" => \"...\" ) )");
return HANDLER_ERROR;
}
if (buffer_string_is_empty(require)) {
log_error(srv->errh, __FILE__, __LINE__,
log_error(errh, __FILE__, __LINE__,
"the require field is missing or blank in: "
"auth.require = ( \"...\" => ( ..., \"require\" => \"...\" ) )");
return HANDLER_ERROR;
@ -336,7 +336,7 @@ static handler_t mod_auth_require_parse_array(server *srv, const array *value, a
if (buffer_string_is_empty(algos)) {
algorithm |= HTTP_AUTH_DIGEST_MD5;
} else if (!mod_auth_algorithms_parse(&algorithm, algos)) {
log_error(srv->errh, __FILE__, __LINE__,
log_error(errh, __FILE__, __LINE__,
"invalid algorithm in: "
"auth.require = ( \"...\" => ( ..., \"algorithm\" => \"...\" ) )");
return HANDLER_ERROR;
@ -348,7 +348,7 @@ static handler_t mod_auth_require_parse_array(server *srv, const array *value, a
dauth->require->scheme = auth_scheme;
dauth->require->algorithm = algorithm;
dauth->require->realm = realm;
if (!mod_auth_require_parse(srv, dauth->require, require)) {
if (!mod_auth_require_parse(dauth->require, require, errh)) {
dauth->fn->free((data_unset *)dauth);
return HANDLER_ERROR;
}
@ -433,7 +433,7 @@ SETDEFAULTS_FUNC(mod_auth_set_defaults) {
if (array_is_kvarray(cpv->v.a)) {
array * const a = array_init(4);
if (HANDLER_GO_ON !=
mod_auth_require_parse_array(srv, cpv->v.a, a)) {
mod_auth_require_parse_array(cpv->v.a, a, srv->errh)) {
array_free(a);
return HANDLER_ERROR;
}
@ -1196,9 +1196,9 @@ static handler_t mod_auth_check_digest(connection *con, void *p_d, const struct
}
static handler_t mod_auth_send_401_unauthorized_digest(connection *con, const struct http_auth_require_t *require, int nonce_stale) {
server *srv = con->srv;
mod_auth_digest_www_authenticate(srv->tmp_buf, log_epoch_secs, require, nonce_stale);
http_header_response_set(con, HTTP_HEADER_OTHER, CONST_STR_LEN("WWW-Authenticate"), CONST_BUF_LEN(srv->tmp_buf));
buffer * const tb = con->srv->tmp_buf;
mod_auth_digest_www_authenticate(tb, log_epoch_secs, require, nonce_stale);
http_header_response_set(con, HTTP_HEADER_OTHER, CONST_STR_LEN("WWW-Authenticate"), CONST_BUF_LEN(tb));
con->http_status = 401;
con->mode = DIRECT;

100
src/mod_cgi.c

@ -308,18 +308,18 @@ static void cgi_pid_del(plugin_data *p, size_t i) {
}
static void cgi_connection_close_fdtocgi(server *srv, handler_ctx *hctx) {
static void cgi_connection_close_fdtocgi(connection *con, handler_ctx *hctx) {
/*(closes only hctx->fdtocgi)*/
fdevent_fdnode_event_del(srv->ev, hctx->fdntocgi);
/*fdevent_unregister(srv->ev, hctx->fdtocgi);*//*(handled below)*/
fdevent_sched_close(srv->ev, hctx->fdtocgi, 0);
struct fdevents * const ev = con->srv->ev;
fdevent_fdnode_event_del(ev, hctx->fdntocgi);
/*fdevent_unregister(ev, hctx->fdtocgi);*//*(handled below)*/
fdevent_sched_close(ev, hctx->fdtocgi, 0);
hctx->fdntocgi = NULL;
hctx->fdtocgi = -1;
}
static void cgi_connection_close(server *srv, handler_ctx *hctx) {
static void cgi_connection_close(connection *con, handler_ctx *hctx) {
plugin_data *p = hctx->plugin_data;
connection *con = hctx->remote_conn;
/* the connection to the browser went away, but we still have a connection
* to the CGI script
@ -328,15 +328,16 @@ static void cgi_connection_close(server *srv, handler_ctx *hctx) {
*/
if (hctx->fd != -1) {
struct fdevents * const ev = con->srv->ev;
/* close connection to the cgi-script */
fdevent_fdnode_event_del(srv->ev, hctx->fdn);
/*fdevent_unregister(srv->ev, hctx->fd);*//*(handled below)*/
fdevent_sched_close(srv->ev, hctx->fd, 0);
fdevent_fdnode_event_del(ev, hctx->fdn);
/*fdevent_unregister(ev, hctx->fd);*//*(handled below)*/
fdevent_sched_close(ev, hctx->fd, 0);
hctx->fdn = NULL;
}
if (hctx->fdtocgi != -1) {
cgi_connection_close_fdtocgi(srv, hctx); /*(closes only hctx->fdtocgi)*/
cgi_connection_close_fdtocgi(con, hctx); /*(closes only hctx->fdtocgi)*/
}
if (hctx->pid > 0) {
@ -356,7 +357,7 @@ static void cgi_connection_close(server *srv, handler_ctx *hctx) {
static handler_t cgi_connection_close_callback(connection *con, void *p_d) {
plugin_data *p = p_d;
handler_ctx *hctx = con->plugin_ctx[p->id];
if (hctx) cgi_connection_close(con->srv, hctx);
if (hctx) cgi_connection_close(con, hctx);
return HANDLER_GO_ON;
}
@ -374,7 +375,7 @@ static handler_t cgi_handle_fdevent_send (server *srv, void *ctx, int revents) {
if (revents & FDEVENT_OUT) {
if (0 != cgi_write_request(hctx, hctx->fdtocgi)) {
cgi_connection_close(srv, hctx);
cgi_connection_close(con, hctx);
return HANDLER_ERROR;
}
/* more request body to be sent to CGI */
@ -390,13 +391,13 @@ static handler_t cgi_handle_fdevent_send (server *srv, void *ctx, int revents) {
}
}
cgi_connection_close_fdtocgi(srv, hctx); /*(closes only hctx->fdtocgi)*/
cgi_connection_close_fdtocgi(con, hctx); /*(closes only hctx->fdtocgi)*/
} else if (revents & FDEVENT_ERR) {
/* kill all connections to the cgi process */
#if 1
log_error(con->conf.errh, __FILE__, __LINE__, "cgi-FDEVENT_ERR");
#endif
cgi_connection_close(srv, hctx);
cgi_connection_close(con, hctx);
return HANDLER_ERROR;
}
@ -429,7 +430,7 @@ static handler_t cgi_response_headers(connection *con, struct http_response_opts
chunkqueue *cq = con->request_content_queue;
hctx->conf.upgrade = 0;
if (cq->bytes_out == (off_t)con->request.content_length) {
cgi_connection_close_fdtocgi(con->srv, hctx); /*(closes hctx->fdtocgi)*/
cgi_connection_close_fdtocgi(con, hctx); /*(closes hctx->fdtocgi)*/
}
}
@ -437,23 +438,23 @@ static handler_t cgi_response_headers(connection *con, struct http_response_opts
}
static int cgi_recv_response(server *srv, handler_ctx *hctx) {
switch (http_response_read(hctx->remote_conn, &hctx->opts,
static int cgi_recv_response(connection *con, handler_ctx *hctx) {
switch (http_response_read(con, &hctx->opts,
hctx->response, hctx->fdn)) {
default:
return HANDLER_GO_ON;
case HANDLER_ERROR:
http_response_backend_error(hctx->remote_conn);
http_response_backend_error(con);
/* fall through */
case HANDLER_FINISHED:
cgi_connection_close(srv, hctx);
cgi_connection_close(con, hctx);
return HANDLER_FINISHED;
case HANDLER_COMEBACK:
/* hctx->conf.local_redir */
buffer_clear(hctx->response);
connection_response_reset(hctx->remote_conn); /*(includes con->http_status = 0)*/
plugins_call_connection_reset(hctx->remote_conn);
/*cgi_connection_close(srv, hctx);*//*(already cleaned up and hctx is now invalid)*/
connection_response_reset(con); /*(includes con->http_status = 0)*/
plugins_call_connection_reset(con);
/*cgi_connection_close(con, hctx);*//*(already cleaned up and hctx is now invalid)*/
return HANDLER_COMEBACK;
}
}
@ -466,7 +467,7 @@ static handler_t cgi_handle_fdevent(server *srv, void *ctx, int revents) {
joblist_append(srv, con);
if (revents & FDEVENT_IN) {
handler_t rc = cgi_recv_response(srv, hctx);/*(might invalidate hctx)*/
handler_t rc = cgi_recv_response(con, hctx);/*(might invalidate hctx)*/
if (rc != HANDLER_GO_ON) return rc; /*(unless HANDLER_GO_ON)*/
}
@ -483,7 +484,7 @@ static handler_t cgi_handle_fdevent(server *srv, void *ctx, int revents) {
con->conf.stream_response_body &= ~FDEVENT_STREAM_RESPONSE_BUFMIN;
con->conf.stream_response_body |= FDEVENT_STREAM_RESPONSE_POLLRDHUP;
do {
rc = cgi_recv_response(srv,hctx);/*(might invalidate hctx)*/
rc = cgi_recv_response(con,hctx);/*(might invalidate hctx)*/
} while (rc == HANDLER_GO_ON); /*(unless HANDLER_GO_ON)*/
con->conf.stream_response_body = flags;
return rc; /* HANDLER_FINISHED or HANDLER_COMEBACK or HANDLER_ERROR */
@ -491,15 +492,15 @@ static handler_t cgi_handle_fdevent(server *srv, void *ctx, int revents) {
/* unfinished header package which is a body in reality */
con->file_started = 1;
if (0 != http_chunk_append_buffer(con, hctx->response)) {
cgi_connection_close(srv, hctx);
cgi_connection_close(con, hctx);
return HANDLER_ERROR;
}
if (0 == con->http_status) con->http_status = 200; /* OK */
}
cgi_connection_close(srv, hctx);
cgi_connection_close(con, hctx);
} else if (revents & FDEVENT_ERR) {
/* kill all connections to the cgi process */
cgi_connection_close(srv, hctx);
cgi_connection_close(con, hctx);
return HANDLER_ERROR;
}
@ -712,18 +713,16 @@ static int cgi_write_request(handler_ctx *hctx, int fd) {
}
}
server * const srv = con->srv;
if (cq->bytes_out == (off_t)con->request.content_length && !hctx->conf.upgrade) {
/* sent all request body input */