|
|
|
@ -64,6 +64,8 @@ typedef enum {
|
|
|
|
|
typedef struct {
|
|
|
|
|
array *extensions;
|
|
|
|
|
int debug;
|
|
|
|
|
|
|
|
|
|
proxy_balance_t balance;
|
|
|
|
|
} plugin_config;
|
|
|
|
|
|
|
|
|
|
typedef struct {
|
|
|
|
@ -190,6 +192,7 @@ SETDEFAULTS_FUNC(mod_proxy_set_defaults) {
|
|
|
|
|
config_values_t cv[] = {
|
|
|
|
|
{ "proxy.server", NULL, T_CONFIG_LOCAL, T_CONFIG_SCOPE_CONNECTION }, /* 0 */
|
|
|
|
|
{ "proxy.debug", NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION }, /* 1 */
|
|
|
|
|
{ "proxy.balance", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION }, /* 2 */
|
|
|
|
|
{ NULL, NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET }
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
@ -205,6 +208,9 @@ SETDEFAULTS_FUNC(mod_proxy_set_defaults) {
|
|
|
|
|
|
|
|
|
|
cv[0].destination = s->extensions;
|
|
|
|
|
cv[1].destination = &(s->debug);
|
|
|
|
|
cv[2].destination = p->balance_buf;
|
|
|
|
|
|
|
|
|
|
buffer_reset(p->balance_buf);
|
|
|
|
|
|
|
|
|
|
p->config_storage[i] = s;
|
|
|
|
|
ca = ((data_config *)srv->config_context->data[i])->value;
|
|
|
|
@ -213,6 +219,20 @@ SETDEFAULTS_FUNC(mod_proxy_set_defaults) {
|
|
|
|
|
return HANDLER_ERROR;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (buffer_is_empty(p->balance_buf)) {
|
|
|
|
|
s->balance = PROXY_BALANCE_FAIR;
|
|
|
|
|
} else if (buffer_is_equal_string(p->balance_buf, CONST_STR_LEN("fair"))) {
|
|
|
|
|
s->balance = PROXY_BALANCE_FAIR;
|
|
|
|
|
} else if (buffer_is_equal_string(p->balance_buf, CONST_STR_LEN("round-robin"))) {
|
|
|
|
|
s->balance = PROXY_BALANCE_RR;
|
|
|
|
|
} else if (buffer_is_equal_string(p->balance_buf, CONST_STR_LEN("hash"))) {
|
|
|
|
|
s->balance = PROXY_BALANCE_HASH;
|
|
|
|
|
} else {
|
|
|
|
|
log_error_write(srv, __FILE__, __LINE__, "sb",
|
|
|
|
|
"proxy.balance has to be one of: fair, round-robin, hash, but not:", p->balance_buf);
|
|
|
|
|
return HANDLER_ERROR;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (NULL != (du = array_get_element(ca, "proxy.server"))) {
|
|
|
|
|
size_t j;
|
|
|
|
|
data_array *da = (data_array *)du;
|
|
|
|
@ -277,9 +297,6 @@ SETDEFAULTS_FUNC(mod_proxy_set_defaults) {
|
|
|
|
|
|
|
|
|
|
pcv[0].destination = df->host;
|
|
|
|
|
pcv[1].destination = &(df->port);
|
|
|
|
|
pcv[2].destination = p->balance_buf;
|
|
|
|
|
|
|
|
|
|
buffer_reset(p->balance_buf);
|
|
|
|
|
|
|
|
|
|
if (0 != config_insert_values_internal(srv, da_host->value, pcv)) {
|
|
|
|
|
return HANDLER_ERROR;
|
|
|
|
@ -304,20 +321,7 @@ SETDEFAULTS_FUNC(mod_proxy_set_defaults) {
|
|
|
|
|
return HANDLER_ERROR;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (buffer_is_empty(p->balance_buf)) {
|
|
|
|
|
df->balance = PROXY_BALANCE_FAIR;
|
|
|
|
|
} else if (buffer_is_equal_string(p->balance_buf, CONST_STR_LEN("fair"))) {
|
|
|
|
|
df->balance = PROXY_BALANCE_FAIR;
|
|
|
|
|
} else if (buffer_is_equal_string(p->balance_buf, CONST_STR_LEN("round-robin"))) {
|
|
|
|
|
df->balance = PROXY_BALANCE_RR;
|
|
|
|
|
} else if (buffer_is_equal_string(p->balance_buf, CONST_STR_LEN("hash"))) {
|
|
|
|
|
df->balance = PROXY_BALANCE_HASH;
|
|
|
|
|
} else {
|
|
|
|
|
log_error_write(srv, __FILE__, __LINE__, "sb",
|
|
|
|
|
"proxy.server->balance has to be one of: fair, round-robin, hash, but not:", p->balance_buf);
|
|
|
|
|
return HANDLER_ERROR;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* if extension already exists, take it */
|
|
|
|
|
|
|
|
|
|
if (NULL == (dfa = (data_array *)array_get_element(s->extensions, da_ext->key->ptr))) {
|
|
|
|
@ -351,6 +355,7 @@ void proxy_connection_cleanup(server *srv, handler_ctx *hctx) {
|
|
|
|
|
|
|
|
|
|
fdevent_event_del(srv->ev, &(hctx->fde_ndx), hctx->fd);
|
|
|
|
|
fdevent_unregister(srv->ev, hctx->fd);
|
|
|
|
|
|
|
|
|
|
if (hctx->fd != -1) {
|
|
|
|
|
close(hctx->fd);
|
|
|
|
|
srv->cur_fds--;
|
|
|
|
@ -406,6 +411,7 @@ static int proxy_establish_connection(server *srv, handler_ctx *hctx) {
|
|
|
|
|
log_error_write(srv, __FILE__, __LINE__, "sd",
|
|
|
|
|
"connect succeeded: ", proxy_fd);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -585,6 +591,12 @@ static int proxy_demux_response(server *srv, handler_ctx *hctx) {
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (p->conf.debug) {
|
|
|
|
|
log_error_write(srv, __FILE__, __LINE__, "sd",
|
|
|
|
|
"proxy - have to read:", b);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (b > 0) {
|
|
|
|
|
if (hctx->response->used == 0) {
|
|
|
|
|
/* avoid too small buffer */
|
|
|
|
@ -668,6 +680,7 @@ static int proxy_demux_response(server *srv, handler_ctx *hctx) {
|
|
|
|
|
|
|
|
|
|
static handler_t proxy_write_request(server *srv, handler_ctx *hctx) {
|
|
|
|
|
data_proxy *host= hctx->host;
|
|
|
|
|
plugin_data *p = hctx->plugin_data;
|
|
|
|
|
|
|
|
|
|
int r;
|
|
|
|
|
|
|
|
|
@ -739,6 +752,9 @@ static handler_t proxy_write_request(server *srv, handler_ctx *hctx) {
|
|
|
|
|
|
|
|
|
|
return HANDLER_ERROR;
|
|
|
|
|
}
|
|
|
|
|
if (p->conf.debug) {
|
|
|
|
|
log_error_write(srv, __FILE__, __LINE__, "s", "proxy - connect - delayed success");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
proxy_set_state(srv, hctx, PROXY_STATE_PREPARE_WRITE);
|
|
|
|
@ -812,6 +828,8 @@ static int mod_proxy_patch_connection(server *srv, connection *con, plugin_data
|
|
|
|
|
PATCH(extensions);
|
|
|
|
|
} else if (buffer_is_equal_string(du->key, CONST_STR_LEN("proxy.debug"))) {
|
|
|
|
|
PATCH(debug);
|
|
|
|
|
} else if (buffer_is_equal_string(du->key, CONST_STR_LEN("proxy.balance"))) {
|
|
|
|
|
PATCH(balance);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
@ -826,11 +844,44 @@ static int mod_proxy_setup_connection(server *srv, connection *con, plugin_data
|
|
|
|
|
|
|
|
|
|
PATCH(extensions);
|
|
|
|
|
PATCH(debug);
|
|
|
|
|
PATCH(balance);
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
#undef PATCH
|
|
|
|
|
|
|
|
|
|
static int proxy_reconnect(server *srv, handler_ctx *hctx) {
|
|
|
|
|
plugin_data *p = hctx->plugin_data;
|
|
|
|
|
|
|
|
|
|
/* child died
|
|
|
|
|
*
|
|
|
|
|
* 1.
|
|
|
|
|
*
|
|
|
|
|
* connect was ok, connection was accepted
|
|
|
|
|
* but the php accept loop checks after the accept if it should die or not.
|
|
|
|
|
*
|
|
|
|
|
* if yes we can only detect it at a write()
|
|
|
|
|
*
|
|
|
|
|
* next step is resetting this attemp and setup a connection again
|
|
|
|
|
*
|
|
|
|
|
* if we have more then 5 reconnects for the same request, die
|
|
|
|
|
*
|
|
|
|
|
* 2.
|
|
|
|
|
*
|
|
|
|
|
* we have a connection but the child died by some other reason
|
|
|
|
|
*
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
fdevent_event_del(srv->ev, &(hctx->fde_ndx), hctx->fd);
|
|
|
|
|
fdevent_unregister(srv->ev, hctx->fd);
|
|
|
|
|
close(hctx->fd);
|
|
|
|
|
srv->cur_fds--;
|
|
|
|
|
|
|
|
|
|
proxy_set_state(srv, hctx, PROXY_STATE_INIT);
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
SUBREQUEST_FUNC(mod_proxy_handle_subrequest) {
|
|
|
|
|
plugin_data *p = p_d;
|
|
|
|
@ -840,7 +891,7 @@ SUBREQUEST_FUNC(mod_proxy_handle_subrequest) {
|
|
|
|
|
size_t i;
|
|
|
|
|
|
|
|
|
|
if (NULL == hctx) return HANDLER_GO_ON;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* select the right config */
|
|
|
|
|
mod_proxy_setup_connection(srv, con, p);
|
|
|
|
|
for (i = 0; i < srv->config_patches->used; i++) {
|
|
|
|
@ -863,14 +914,23 @@ SUBREQUEST_FUNC(mod_proxy_handle_subrequest) {
|
|
|
|
|
hctx->fd);
|
|
|
|
|
|
|
|
|
|
/* disable this server */
|
|
|
|
|
host->usage = -1;
|
|
|
|
|
host->is_disabled = 1;
|
|
|
|
|
host->disable_ts = srv->cur_ts;
|
|
|
|
|
|
|
|
|
|
proxy_connection_cleanup(srv, hctx);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* reset the enviroment and restart the sub-request */
|
|
|
|
|
buffer_reset(con->physical.path);
|
|
|
|
|
con->mode = DIRECT;
|
|
|
|
|
con->http_status = 503;
|
|
|
|
|
return HANDLER_FINISHED;
|
|
|
|
|
|
|
|
|
|
joblist_append(srv, con);
|
|
|
|
|
|
|
|
|
|
/* mis-using HANDLER_WAIT_FOR_FD to break out of the loop
|
|
|
|
|
* and hope that the childs will be restarted
|
|
|
|
|
*
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
return HANDLER_WAIT_FOR_FD;
|
|
|
|
|
case HANDLER_WAIT_FOR_EVENT:
|
|
|
|
|
return HANDLER_WAIT_FOR_EVENT;
|
|
|
|
|
case HANDLER_WAIT_FOR_FD:
|
|
|
|
@ -897,13 +957,6 @@ static handler_t proxy_connection_close(server *srv, handler_ctx *hctx) {
|
|
|
|
|
|
|
|
|
|
if (con->mode != p->id) return HANDLER_GO_ON;
|
|
|
|
|
|
|
|
|
|
log_error_write(srv, __FILE__, __LINE__, "ssdsd",
|
|
|
|
|
"emergency exit: proxy:",
|
|
|
|
|
"connection-fd:", con->fd,
|
|
|
|
|
"proxy-fd:", hctx->fd);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
proxy_connection_cleanup(srv, hctx);
|
|
|
|
|
|
|
|
|
|
return HANDLER_FINISHED;
|
|
|
|
@ -919,6 +972,12 @@ static handler_t proxy_handle_fdevent(void *s, void *ctx, int revents) {
|
|
|
|
|
|
|
|
|
|
if ((revents & FDEVENT_IN) &&
|
|
|
|
|
hctx->state == PROXY_STATE_READ) {
|
|
|
|
|
|
|
|
|
|
if (p->conf.debug) {
|
|
|
|
|
log_error_write(srv, __FILE__, __LINE__, "sd",
|
|
|
|
|
"proxy: fdevent-in", hctx->state);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
switch (proxy_demux_response(srv, hctx)) {
|
|
|
|
|
case 0:
|
|
|
|
|
break;
|
|
|
|
@ -926,11 +985,6 @@ static handler_t proxy_handle_fdevent(void *s, void *ctx, int revents) {
|
|
|
|
|
hctx->host->usage--;
|
|
|
|
|
|
|
|
|
|
/* we are done */
|
|
|
|
|
|
|
|
|
|
if (chunkqueue_is_empty(con->write_queue)) {
|
|
|
|
|
connection_set_state(srv, con, CON_STATE_RESPONSE_END);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
proxy_connection_cleanup(srv, hctx);
|
|
|
|
|
|
|
|
|
|
joblist_append(srv, con);
|
|
|
|
@ -952,6 +1006,11 @@ static handler_t proxy_handle_fdevent(void *s, void *ctx, int revents) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (revents & FDEVENT_OUT) {
|
|
|
|
|
if (p->conf.debug) {
|
|
|
|
|
log_error_write(srv, __FILE__, __LINE__, "sd",
|
|
|
|
|
"proxy: fdevent-out", hctx->state);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (hctx->state == PROXY_STATE_CONNECT ||
|
|
|
|
|
hctx->state == PROXY_STATE_WRITE) {
|
|
|
|
|
/* we are allowed to send something out
|
|
|
|
@ -961,38 +1020,30 @@ static handler_t proxy_handle_fdevent(void *s, void *ctx, int revents) {
|
|
|
|
|
*/
|
|
|
|
|
return mod_proxy_handle_subrequest(srv, con, p);
|
|
|
|
|
} else {
|
|
|
|
|
log_error_write(srv, __FILE__, __LINE__, "sd", "proxy: out", hctx->state);
|
|
|
|
|
log_error_write(srv, __FILE__, __LINE__, "sd",
|
|
|
|
|
"proxy: out", hctx->state);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* perhaps this issue is already handled */
|
|
|
|
|
if (revents & FDEVENT_HUP) {
|
|
|
|
|
log_error_write(srv, __FILE__, __LINE__, "sbSBSDS",
|
|
|
|
|
"error: unexpected close of proxy connection for",
|
|
|
|
|
con->uri.path,
|
|
|
|
|
"(no proxy process on host: ",
|
|
|
|
|
hctx->host->host,
|
|
|
|
|
", port: ",
|
|
|
|
|
hctx->host->port,
|
|
|
|
|
" ?)" );
|
|
|
|
|
|
|
|
|
|
#ifndef USE_LINUX_SIGIO
|
|
|
|
|
if (p->conf.debug) {
|
|
|
|
|
log_error_write(srv, __FILE__, __LINE__, "sd",
|
|
|
|
|
"proxy: fdevent-hup", hctx->state);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
con->file_finished = 1;
|
|
|
|
|
|
|
|
|
|
proxy_connection_close(srv, hctx);
|
|
|
|
|
# if 0
|
|
|
|
|
log_error_write(srv, __FILE__, __LINE__, "sd", "proxy-FDEVENT_HUP", con->fd);
|
|
|
|
|
# endif
|
|
|
|
|
joblist_append(srv, con);
|
|
|
|
|
return HANDLER_ERROR;
|
|
|
|
|
#endif
|
|
|
|
|
} else if (revents & FDEVENT_ERR) {
|
|
|
|
|
log_error_write(srv, __FILE__, __LINE__, "s", "proxy: err");
|
|
|
|
|
/* kill all connections to the proxy process */
|
|
|
|
|
|
|
|
|
|
proxy_connection_close(srv, hctx);
|
|
|
|
|
#if 1
|
|
|
|
|
log_error_write(srv, __FILE__, __LINE__, "s", "proxy-FDEVENT_ERR");
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
joblist_append(srv, con);
|
|
|
|
|
proxy_connection_close(srv, hctx);
|
|
|
|
|
|
|
|
|
|
return HANDLER_ERROR;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -1002,8 +1053,8 @@ static handler_t proxy_handle_fdevent(void *s, void *ctx, int revents) {
|
|
|
|
|
static handler_t mod_proxy_check_extension(server *srv, connection *con, void *p_d) {
|
|
|
|
|
plugin_data *p = p_d;
|
|
|
|
|
size_t s_len;
|
|
|
|
|
int last_max = -1;
|
|
|
|
|
int ndx;
|
|
|
|
|
unsigned long last_max = ~0L;
|
|
|
|
|
int ndx = -1;
|
|
|
|
|
size_t k, i;
|
|
|
|
|
buffer *fn;
|
|
|
|
|
data_array *extension = NULL;
|
|
|
|
@ -1030,7 +1081,11 @@ static handler_t mod_proxy_check_extension(server *srv, connection *con, void *p
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
path_info_offset = 0;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (p->conf.debug) {
|
|
|
|
|
log_error_write(srv, __FILE__, __LINE__, "s", "proxy - start");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* check if extension matches */
|
|
|
|
|
for (k = 0; k < p->conf.extensions->used; k++) {
|
|
|
|
|
size_t ct_len;
|
|
|
|
@ -1059,54 +1114,83 @@ static handler_t mod_proxy_check_extension(server *srv, connection *con, void *p
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* extension doesn't match */
|
|
|
|
|
if (k == p->conf.extensions->used) {
|
|
|
|
|
return HANDLER_GO_ON;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
switch(1) {
|
|
|
|
|
case 1:
|
|
|
|
|
if (p->conf.debug) {
|
|
|
|
|
log_error_write(srv, __FILE__, __LINE__, "s", "proxy - ext found");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
switch(p->conf.balance) {
|
|
|
|
|
case PROXY_BALANCE_HASH:
|
|
|
|
|
/* hash balancing */
|
|
|
|
|
for (k = 0, ndx = -1, last_max = -1; k < extension->value->used; k++) {
|
|
|
|
|
|
|
|
|
|
if (p->conf.debug) {
|
|
|
|
|
log_error_write(srv, __FILE__, __LINE__, "s", "proxy - used hash balancing");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (k = 0, ndx = -1, last_max = ~0L; k < extension->value->used; k++) {
|
|
|
|
|
data_proxy *host = (data_proxy *)extension->value->data[k];
|
|
|
|
|
int url_ndx, host_ndx;
|
|
|
|
|
unsigned long url_ndx, host_ndx, cur_max;
|
|
|
|
|
|
|
|
|
|
if (host->is_disabled) continue;
|
|
|
|
|
|
|
|
|
|
url_ndx = generate_crc32c(CONST_BUF_LEN(con->uri.path));
|
|
|
|
|
host_ndx = generate_crc32c(CONST_BUF_LEN(con->server_name));
|
|
|
|
|
host_ndx = generate_crc32c(CONST_BUF_LEN(host->host)); /* we can cache this */
|
|
|
|
|
|
|
|
|
|
if ((last_max == -1) ||
|
|
|
|
|
(url_ndx + host_ndx > last_max)) {
|
|
|
|
|
last_max = url_ndx + host_ndx;
|
|
|
|
|
cur_max = url_ndx % host_ndx;
|
|
|
|
|
|
|
|
|
|
if ((last_max == ~0L) || /* first round */
|
|
|
|
|
(cur_max > last_max)) {
|
|
|
|
|
last_max = cur_max;
|
|
|
|
|
|
|
|
|
|
ndx = k;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (p->conf.debug) {
|
|
|
|
|
log_error_write(srv, __FILE__, __LINE__, "sbdbddd",
|
|
|
|
|
"proxy - election:",
|
|
|
|
|
con->uri.path, url_ndx,
|
|
|
|
|
host->host, host_ndx,
|
|
|
|
|
last_max, cur_max);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
case 2:
|
|
|
|
|
case PROXY_BALANCE_FAIR:
|
|
|
|
|
/* fair balancing */
|
|
|
|
|
for (k = 0, ndx = -1, last_max = -1; k < extension->value->used; k++) {
|
|
|
|
|
if (p->conf.debug) {
|
|
|
|
|
log_error_write(srv, __FILE__, __LINE__, "s",
|
|
|
|
|
"proxy - used fair balancing");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (k = 0, ndx = -1, last_max = ~0L; k < extension->value->used; k++) {
|
|
|
|
|
data_proxy *host = (data_proxy *)extension->value->data[k];
|
|
|
|
|
|
|
|
|
|
if (host->is_disabled) continue;
|
|
|
|
|
|
|
|
|
|
if (last_max == -1 || host->usage < last_max) {
|
|
|
|
|
if (host->usage < last_max) {
|
|
|
|
|
last_max = host->usage;
|
|
|
|
|
|
|
|
|
|
ndx = k;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
case 3:
|
|
|
|
|
case PROXY_BALANCE_RR:
|
|
|
|
|
/* round robin */
|
|
|
|
|
for (k = 0, ndx = -1, last_max = -1; k < extension->value->used; k++) {
|
|
|
|
|
if (p->conf.debug) {
|
|
|
|
|
log_error_write(srv, __FILE__, __LINE__, "s",
|
|
|
|
|
"proxy - used round-robin balancing");
|
|
|
|
|
}
|
|
|
|
|
for (k = 0, ndx = -1, last_max = ~0L; k < extension->value->used; k++) {
|
|
|
|
|
data_proxy *host = (data_proxy *)extension->value->data[k];
|
|
|
|
|
|
|
|
|
|
if (host->is_disabled) continue;
|
|
|
|
|
|
|
|
|
|
/* first usable ndx */
|
|
|
|
|
if (last_max == -1) {
|
|
|
|
|
if (last_max == ~0L) {
|
|
|
|
|
last_max = k;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -1118,12 +1202,15 @@ static handler_t mod_proxy_check_extension(server *srv, connection *con, void *p
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
/* wrap to the start */
|
|
|
|
|
if (ndx != -1) {
|
|
|
|
|
|
|
|
|
|
/* didn't found a higher id, wrap to the start */
|
|
|
|
|
if (ndx != -1 && last_max != ~0L) {
|
|
|
|
|
ndx = last_max;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* found a server */
|
|
|
|
@ -1150,6 +1237,12 @@ static handler_t mod_proxy_check_extension(server *srv, connection *con, void *p
|
|
|
|
|
|
|
|
|
|
con->mode = p->id;
|
|
|
|
|
|
|
|
|
|
if (p->conf.debug) {
|
|
|
|
|
log_error_write(srv, __FILE__, __LINE__, "sbd",
|
|
|
|
|
"proxy - found a host",
|
|
|
|
|
host->host, host->port);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return HANDLER_GO_ON;
|
|
|
|
|
} else {
|
|
|
|
|
/* no handler found */
|
|
|
|
@ -1170,6 +1263,48 @@ static handler_t mod_proxy_connection_close_callback(server *srv, connection *co
|
|
|
|
|
return proxy_connection_close(srv, con->plugin_ctx[p->id]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
*
|
|
|
|
|
* the trigger re-enables the disabled connections after the timeout is over
|
|
|
|
|
*
|
|
|
|
|
* */
|
|
|
|
|
|
|
|
|
|
TRIGGER_FUNC(mod_proxy_trigger) {
|
|
|
|
|
plugin_data *p = p_d;
|
|
|
|
|
|
|
|
|
|
if (p->config_storage) {
|
|
|
|
|
size_t i, n, k;
|
|
|
|
|
for (i = 0; i < srv->config_context->used; i++) {
|
|
|
|
|
plugin_config *s = p->config_storage[i];
|
|
|
|
|
|
|
|
|
|
if (!s) continue;
|
|
|
|
|
|
|
|
|
|
/* get the extensions for all configs */
|
|
|
|
|
|
|
|
|
|
for (k = 0; k < s->extensions->used; k++) {
|
|
|
|
|
data_array *extension = (data_array *)s->extensions->data[k];
|
|
|
|
|
|
|
|
|
|
/* get all hosts */
|
|
|
|
|
for (n = 0; n < extension->value->used; n++) {
|
|
|
|
|
data_proxy *host = (data_proxy *)extension->value->data[n];
|
|
|
|
|
|
|
|
|
|
if (!host->is_disabled ||
|
|
|
|
|
srv->cur_ts - host->disable_ts < 5) continue;
|
|
|
|
|
|
|
|
|
|
log_error_write(srv, __FILE__, __LINE__, "sbd",
|
|
|
|
|
"proxy - re-enabled:",
|
|
|
|
|
host->host, host->port);
|
|
|
|
|
|
|
|
|
|
host->is_disabled = 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return HANDLER_GO_ON;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int mod_proxy_plugin_init(plugin *p) {
|
|
|
|
|
p->version = LIGHTTPD_VERSION_ID;
|
|
|
|
|
p->name = buffer_init_string("proxy");
|
|
|
|
@ -1181,6 +1316,7 @@ int mod_proxy_plugin_init(plugin *p) {
|
|
|
|
|
p->handle_connection_close = mod_proxy_connection_close_callback;
|
|
|
|
|
p->handle_uri_clean = mod_proxy_check_extension;
|
|
|
|
|
p->handle_subrequest = mod_proxy_handle_subrequest;
|
|
|
|
|
p->handle_trigger = mod_proxy_trigger;
|
|
|
|
|
|
|
|
|
|
p->data = NULL;
|
|
|
|
|
|
|
|
|
|