mirror of
http://git.haproxy.org/git/haproxy.git/
synced 2025-04-10 11:11:37 +00:00
Revert "[BUILD] backend.c and checks.c did not build without tproxy !"
This reverts commit 3c3c0122f8
.
This commit was buggy as it also removed previous tproxy changes !
This commit is contained in:
parent
3c3c0122f8
commit
21d2af3e9f
@ -3844,6 +3844,24 @@ port <port>
|
|||||||
inetd for instance. This parameter is ignored if the "check" parameter is not
|
inetd for instance. This parameter is ignored if the "check" parameter is not
|
||||||
set. See also the "addr" parameter.
|
set. See also the "addr" parameter.
|
||||||
|
|
||||||
|
redir <prefix>
|
||||||
|
The "redir" parameter enables the redirection mode for all GET and HEAD
|
||||||
|
requests addressing this server. This means that instead of having HAProxy
|
||||||
|
forward the request to the server, it will send an "HTTP 302" response with
|
||||||
|
the "Location" header composed of this prefix immediately followed by the
|
||||||
|
requested URI beginning at the leading '/' of the path component. That means
|
||||||
|
that no trailing slash should be used after <prefix>. All invalid requests
|
||||||
|
will be rejected, and all non-GET or HEAD requests will be normally served by
|
||||||
|
the server. Note that since the response is completely forged, no header
|
||||||
|
mangling nor cookie insertion is possible in the respose. However, cookies in
|
||||||
|
requests are still analysed, making this solution completely usable to direct
|
||||||
|
users to a remote location in case of local disaster. Main use consists in
|
||||||
|
increasing bandwidth for static servers by having the clients directly
|
||||||
|
connect to them. Note: never use a relative location here, it would cause a
|
||||||
|
loop between the client and HAProxy!
|
||||||
|
|
||||||
|
Example : server srv1 192.168.1.1:80 redir http://image1.mydomain.com check
|
||||||
|
|
||||||
rise <count>
|
rise <count>
|
||||||
The "rise" parameter states that a server will be considered as operational
|
The "rise" parameter states that a server will be considered as operational
|
||||||
after <count> consecutive successful health checks. This value defaults to 2
|
after <count> consecutive successful health checks. This value defaults to 2
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
include/types/server.h
|
include/types/server.h
|
||||||
This file defines everything related to servers.
|
This file defines everything related to servers.
|
||||||
|
|
||||||
Copyright (C) 2000-2007 Willy Tarreau - w@1wt.eu
|
Copyright (C) 2000-2008 Willy Tarreau - w@1wt.eu
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
This library is free software; you can redistribute it and/or
|
||||||
modify it under the terms of the GNU Lesser General Public
|
modify it under the terms of the GNU Lesser General Public
|
||||||
@ -73,7 +73,9 @@ struct server {
|
|||||||
int state; /* server state (SRV_*) */
|
int state; /* server state (SRV_*) */
|
||||||
int prev_state; /* server state before last change (SRV_*) */
|
int prev_state; /* server state before last change (SRV_*) */
|
||||||
int cklen; /* the len of the cookie, to speed up checks */
|
int cklen; /* the len of the cookie, to speed up checks */
|
||||||
|
int rdr_len; /* the length of the redirection prefix */
|
||||||
char *cookie; /* the id set in the cookie */
|
char *cookie; /* the id set in the cookie */
|
||||||
|
char *rdr_pfx; /* the redirection prefix */
|
||||||
|
|
||||||
struct proxy *proxy; /* the proxy this server belongs to */
|
struct proxy *proxy; /* the proxy this server belongs to */
|
||||||
int cur_sess, cur_sess_max; /* number of currently active sessions (including syn_sent) */
|
int cur_sess, cur_sess_max; /* number of currently active sessions (including syn_sent) */
|
||||||
|
@ -50,7 +50,7 @@
|
|||||||
#define SN_FRT_ADDR_SET 0x00000080 /* set if the frontend address has been filled */
|
#define SN_FRT_ADDR_SET 0x00000080 /* set if the frontend address has been filled */
|
||||||
#define SN_REDISP 0x00000100 /* set if this session was redispatched from one server to another */
|
#define SN_REDISP 0x00000100 /* set if this session was redispatched from one server to another */
|
||||||
#define SN_CONN_TAR 0x00000200 /* set if this session is turning around before reconnecting */
|
#define SN_CONN_TAR 0x00000200 /* set if this session is turning around before reconnecting */
|
||||||
/* unused: 0x00000400 */
|
#define SN_REDIRECTABLE 0x00000400 /* set if this session is redirectable (GET or HEAD) */
|
||||||
/* unused: 0x00000800 */
|
/* unused: 0x00000800 */
|
||||||
|
|
||||||
/* session termination conditions, bits values 0x1000 to 0x7000 (0-7 shift 12) */
|
/* session termination conditions, bits values 0x1000 to 0x7000 (0-7 shift 12) */
|
||||||
|
@ -1059,6 +1059,13 @@ int assign_server_and_queue(struct session *s)
|
|||||||
return SRV_STATUS_INTERNAL;
|
return SRV_STATUS_INTERNAL;
|
||||||
|
|
||||||
if (s->flags & SN_ASSIGNED) {
|
if (s->flags & SN_ASSIGNED) {
|
||||||
|
if ((s->flags & SN_REDIRECTABLE) && s->srv && s->srv->rdr_len) {
|
||||||
|
/* server scheduled for redirection, and already assigned. We
|
||||||
|
* don't want to go further nor check the queue.
|
||||||
|
*/
|
||||||
|
return SRV_STATUS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
if (s->srv && s->srv->maxqueue > 0 && s->srv->nbpend >= s->srv->maxqueue) {
|
if (s->srv && s->srv->maxqueue > 0 && s->srv->nbpend >= s->srv->maxqueue) {
|
||||||
s->flags &= ~(SN_DIRECT | SN_ASSIGNED | SN_ADDR_SET);
|
s->flags &= ~(SN_DIRECT | SN_ASSIGNED | SN_ADDR_SET);
|
||||||
s->srv = NULL;
|
s->srv = NULL;
|
||||||
@ -1084,6 +1091,13 @@ int assign_server_and_queue(struct session *s)
|
|||||||
err = assign_server(s);
|
err = assign_server(s);
|
||||||
switch (err) {
|
switch (err) {
|
||||||
case SRV_STATUS_OK:
|
case SRV_STATUS_OK:
|
||||||
|
if ((s->flags & SN_REDIRECTABLE) && s->srv && s->srv->rdr_len) {
|
||||||
|
/* server supporting redirection and it is possible.
|
||||||
|
* Let's report that and ignore maxconn !
|
||||||
|
*/
|
||||||
|
return SRV_STATUS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
/* in balance mode, we might have servers with connection limits */
|
/* in balance mode, we might have servers with connection limits */
|
||||||
if (s->srv &&
|
if (s->srv &&
|
||||||
s->srv->maxconn && s->srv->cur_sess >= srv_dynamic_maxconn(s->srv)) {
|
s->srv->maxconn && s->srv->cur_sess >= srv_dynamic_maxconn(s->srv)) {
|
||||||
@ -1189,7 +1203,6 @@ int connect_server(struct session *s)
|
|||||||
struct sockaddr_in *remote = NULL;
|
struct sockaddr_in *remote = NULL;
|
||||||
int ret, flags = 0;
|
int ret, flags = 0;
|
||||||
|
|
||||||
#if defined(CONFIG_HAP_CTTPROXY) || defined(CONFIG_HAP_LINUX_TPROXY)
|
|
||||||
switch (s->srv->state & SRV_TPROXY_MASK) {
|
switch (s->srv->state & SRV_TPROXY_MASK) {
|
||||||
case SRV_TPROXY_ADDR:
|
case SRV_TPROXY_ADDR:
|
||||||
remote = (struct sockaddr_in *)&s->srv->tproxy_addr;
|
remote = (struct sockaddr_in *)&s->srv->tproxy_addr;
|
||||||
@ -1204,7 +1217,6 @@ int connect_server(struct session *s)
|
|||||||
remote = (struct sockaddr_in *)&s->cli_addr;
|
remote = (struct sockaddr_in *)&s->cli_addr;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
ret = tcpv4_bind_socket(fd, flags, &s->srv->source_addr, remote);
|
ret = tcpv4_bind_socket(fd, flags, &s->srv->source_addr, remote);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
close(fd);
|
close(fd);
|
||||||
@ -1228,7 +1240,6 @@ int connect_server(struct session *s)
|
|||||||
struct sockaddr_in *remote = NULL;
|
struct sockaddr_in *remote = NULL;
|
||||||
int ret, flags = 0;
|
int ret, flags = 0;
|
||||||
|
|
||||||
#if defined(CONFIG_HAP_CTTPROXY) || defined(CONFIG_HAP_LINUX_TPROXY)
|
|
||||||
switch (s->be->options & PR_O_TPXY_MASK) {
|
switch (s->be->options & PR_O_TPXY_MASK) {
|
||||||
case PR_O_TPXY_ADDR:
|
case PR_O_TPXY_ADDR:
|
||||||
remote = (struct sockaddr_in *)&s->be->tproxy_addr;
|
remote = (struct sockaddr_in *)&s->be->tproxy_addr;
|
||||||
@ -1243,7 +1254,7 @@ int connect_server(struct session *s)
|
|||||||
remote = (struct sockaddr_in *)&s->cli_addr;
|
remote = (struct sockaddr_in *)&s->cli_addr;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
ret = tcpv4_bind_socket(fd, flags, &s->be->source_addr, remote);
|
ret = tcpv4_bind_socket(fd, flags, &s->be->source_addr, remote);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
close(fd);
|
close(fd);
|
||||||
|
@ -1547,6 +1547,11 @@ int cfg_parse_listen(const char *file, int linenum, char **args, int inv)
|
|||||||
newsrv->cklen = strlen(args[cur_arg + 1]);
|
newsrv->cklen = strlen(args[cur_arg + 1]);
|
||||||
cur_arg += 2;
|
cur_arg += 2;
|
||||||
}
|
}
|
||||||
|
else if (!strcmp(args[cur_arg], "redir")) {
|
||||||
|
newsrv->rdr_pfx = strdup(args[cur_arg + 1]);
|
||||||
|
newsrv->rdr_len = strlen(args[cur_arg + 1]);
|
||||||
|
cur_arg += 2;
|
||||||
|
}
|
||||||
else if (!strcmp(args[cur_arg], "rise")) {
|
else if (!strcmp(args[cur_arg], "rise")) {
|
||||||
newsrv->rise = atol(args[cur_arg + 1]);
|
newsrv->rise = atol(args[cur_arg + 1]);
|
||||||
newsrv->health = newsrv->rise;
|
newsrv->health = newsrv->rise;
|
||||||
@ -1691,7 +1696,7 @@ int cfg_parse_listen(const char *file, int linenum, char **args, int inv)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
Alert("parsing [%s:%d] : server %s only supports options 'backup', 'cookie', 'check', 'inter', 'fastinter', 'downinter', 'rise', 'fall', 'addr', 'port', 'source', 'minconn', 'maxconn', 'maxqueue', 'slowstart' and 'weight'.\n",
|
Alert("parsing [%s:%d] : server %s only supports options 'backup', 'cookie', 'redir', 'check', 'inter', 'fastinter', 'downinter', 'rise', 'fall', 'addr', 'port', 'source', 'minconn', 'maxconn', 'maxqueue', 'slowstart' and 'weight'.\n",
|
||||||
file, linenum, newsrv->id);
|
file, linenum, newsrv->id);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -2904,6 +2909,19 @@ int readcfgfile(const char *file)
|
|||||||
if (curproxy->options & PR_O_LOGASAP)
|
if (curproxy->options & PR_O_LOGASAP)
|
||||||
curproxy->to_log &= ~LW_BYTES;
|
curproxy->to_log &= ~LW_BYTES;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ensure that we're not cross-dressing a TCP server into HTTP.
|
||||||
|
*/
|
||||||
|
newsrv = curproxy->srv;
|
||||||
|
while (newsrv != NULL) {
|
||||||
|
if ((curproxy->mode != PR_MODE_HTTP) && (newsrv->rdr_len || newsrv->cklen)) {
|
||||||
|
Alert("parsing %s, %s '%s' : server cannot have cookie or redirect prefix in non-HTTP mode.\n",
|
||||||
|
file, proxy_type_str(curproxy), curproxy->id, linenum);
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
newsrv = newsrv->next;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If this server supports a maxconn parameter, it needs a dedicated
|
* If this server supports a maxconn parameter, it needs a dedicated
|
||||||
* tasks to fill the emptied slots when a connection leaves.
|
* tasks to fill the emptied slots when a connection leaves.
|
||||||
|
@ -422,12 +422,10 @@ void process_chk(struct task *t, struct timeval *next)
|
|||||||
struct sockaddr_in *remote = NULL;
|
struct sockaddr_in *remote = NULL;
|
||||||
int ret, flags = 0;
|
int ret, flags = 0;
|
||||||
|
|
||||||
#if defined(CONFIG_HAP_CTTPROXY) || defined(CONFIG_HAP_LINUX_TPROXY)
|
|
||||||
if ((s->state & SRV_TPROXY_MASK) == SRV_TPROXY_ADDR) {
|
if ((s->state & SRV_TPROXY_MASK) == SRV_TPROXY_ADDR) {
|
||||||
remote = (struct sockaddr_in *)&s->tproxy_addr;
|
remote = (struct sockaddr_in *)&s->tproxy_addr;
|
||||||
flags = 3;
|
flags = 3;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
ret = tcpv4_bind_socket(fd, flags, &s->source_addr, remote);
|
ret = tcpv4_bind_socket(fd, flags, &s->source_addr, remote);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
s->result |= SRV_CHK_ERROR;
|
s->result |= SRV_CHK_ERROR;
|
||||||
@ -447,12 +445,10 @@ void process_chk(struct task *t, struct timeval *next)
|
|||||||
struct sockaddr_in *remote = NULL;
|
struct sockaddr_in *remote = NULL;
|
||||||
int ret, flags = 0;
|
int ret, flags = 0;
|
||||||
|
|
||||||
#if defined(CONFIG_HAP_CTTPROXY) || defined(CONFIG_HAP_LINUX_TPROXY)
|
|
||||||
if ((s->proxy->options & PR_O_TPXY_MASK) == PR_O_TPXY_ADDR) {
|
if ((s->proxy->options & PR_O_TPXY_MASK) == PR_O_TPXY_ADDR) {
|
||||||
remote = (struct sockaddr_in *)&s->proxy->tproxy_addr;
|
remote = (struct sockaddr_in *)&s->proxy->tproxy_addr;
|
||||||
flags = 3;
|
flags = 3;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
ret = tcpv4_bind_socket(fd, flags, &s->proxy->source_addr, remote);
|
ret = tcpv4_bind_socket(fd, flags, &s->proxy->source_addr, remote);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
s->result |= SRV_CHK_ERROR;
|
s->result |= SRV_CHK_ERROR;
|
||||||
|
134
src/proto_http.c
134
src/proto_http.c
@ -592,6 +592,54 @@ static http_meth_t find_http_meth(const char *str, const int len)
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Parse the URI from the given transaction (which is assumed to be in request
|
||||||
|
* phase) and look for the "/" beginning the PATH. If not found, return NULL.
|
||||||
|
* It is returned otherwise.
|
||||||
|
*/
|
||||||
|
static char *
|
||||||
|
http_get_path(struct http_txn *txn)
|
||||||
|
{
|
||||||
|
char *ptr, *end;
|
||||||
|
|
||||||
|
ptr = txn->req.sol + txn->req.sl.rq.u;
|
||||||
|
end = ptr + txn->req.sl.rq.u_l;
|
||||||
|
|
||||||
|
if (ptr >= end)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
/* RFC2616, par. 5.1.2 :
|
||||||
|
* Request-URI = "*" | absuri | abspath | authority
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (*ptr == '*')
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (isalpha((unsigned char)*ptr)) {
|
||||||
|
/* this is a scheme as described by RFC3986, par. 3.1 */
|
||||||
|
ptr++;
|
||||||
|
while (ptr < end &&
|
||||||
|
(isalnum((unsigned char)*ptr) || *ptr == '+' || *ptr == '-' || *ptr == '.'))
|
||||||
|
ptr++;
|
||||||
|
/* skip '://' */
|
||||||
|
if (ptr == end || *ptr++ != ':')
|
||||||
|
return NULL;
|
||||||
|
if (ptr == end || *ptr++ != '/')
|
||||||
|
return NULL;
|
||||||
|
if (ptr == end || *ptr++ != '/')
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
/* skip [user[:passwd]@]host[:[port]] */
|
||||||
|
|
||||||
|
while (ptr < end && *ptr != '/')
|
||||||
|
ptr++;
|
||||||
|
|
||||||
|
if (ptr == end)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
/* OK, we got the '/' ! */
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
|
||||||
/* Processes the client and server jobs of a session task, then
|
/* Processes the client and server jobs of a session task, then
|
||||||
* puts it back to the wait queue in a clean state, or
|
* puts it back to the wait queue in a clean state, or
|
||||||
* cleans up its resources if it must be deleted. Returns
|
* cleans up its resources if it must be deleted. Returns
|
||||||
@ -2451,9 +2499,59 @@ int process_srv(struct session *t)
|
|||||||
|
|
||||||
do {
|
do {
|
||||||
/* first, get a connection */
|
/* first, get a connection */
|
||||||
|
if (txn->meth == HTTP_METH_GET || txn->meth == HTTP_METH_HEAD)
|
||||||
|
t->flags |= SN_REDIRECTABLE;
|
||||||
|
|
||||||
if (srv_redispatch_connect(t))
|
if (srv_redispatch_connect(t))
|
||||||
return t->srv_state != SV_STIDLE;
|
return t->srv_state != SV_STIDLE;
|
||||||
|
|
||||||
|
if ((t->flags & SN_REDIRECTABLE) && t->srv && t->srv->rdr_len) {
|
||||||
|
/* Server supporting redirection and it is possible.
|
||||||
|
* Invalid requests are reported as such. It concerns all
|
||||||
|
* the largest ones.
|
||||||
|
*/
|
||||||
|
struct chunk rdr;
|
||||||
|
char *path;
|
||||||
|
int len;
|
||||||
|
|
||||||
|
/* 1: create the response header */
|
||||||
|
rdr.len = strlen(HTTP_302);
|
||||||
|
rdr.str = trash;
|
||||||
|
memcpy(rdr.str, HTTP_302, rdr.len);
|
||||||
|
|
||||||
|
/* 2: add the server's prefix */
|
||||||
|
if (rdr.len + t->srv->rdr_len > sizeof(trash))
|
||||||
|
goto cancel_redir;
|
||||||
|
|
||||||
|
memcpy(rdr.str + rdr.len, t->srv->rdr_pfx, t->srv->rdr_len);
|
||||||
|
rdr.len += t->srv->rdr_len;
|
||||||
|
|
||||||
|
/* 3: add the request URI */
|
||||||
|
path = http_get_path(txn);
|
||||||
|
if (!path)
|
||||||
|
goto cancel_redir;
|
||||||
|
len = txn->req.sl.rq.u_l + (txn->req.sol+txn->req.sl.rq.u) - path;
|
||||||
|
if (rdr.len + len > sizeof(trash) - 4) /* 4 for CRLF-CRLF */
|
||||||
|
goto cancel_redir;
|
||||||
|
|
||||||
|
memcpy(rdr.str + rdr.len, path, len);
|
||||||
|
rdr.len += len;
|
||||||
|
memcpy(rdr.str + rdr.len, "\r\n\r\n", 4);
|
||||||
|
rdr.len += 4;
|
||||||
|
|
||||||
|
srv_close_with_err(t, SN_ERR_PRXCOND, SN_FINST_C, 302, &rdr);
|
||||||
|
/* FIXME: we should increase a counter of redirects per server and per backend. */
|
||||||
|
if (t->srv)
|
||||||
|
t->srv->cum_sess++;
|
||||||
|
return 1;
|
||||||
|
cancel_redir:
|
||||||
|
txn->status = 400;
|
||||||
|
t->fe->failed_req++;
|
||||||
|
srv_close_with_err(t, SN_ERR_PRXCOND, SN_FINST_C,
|
||||||
|
400, error_message(t, HTTP_ERR_400));
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
/* try to (re-)connect to the server, and fail if we expire the
|
/* try to (re-)connect to the server, and fail if we expire the
|
||||||
* number of retries.
|
* number of retries.
|
||||||
*/
|
*/
|
||||||
@ -5226,39 +5324,9 @@ acl_fetch_path(struct proxy *px, struct session *l4, void *l7, int dir,
|
|||||||
/* ensure the indexes are not affected */
|
/* ensure the indexes are not affected */
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
ptr = txn->req.sol + txn->req.sl.rq.u;
|
end = txn->req.sol + txn->req.sl.rq.u + txn->req.sl.rq.u_l;
|
||||||
end = ptr + txn->req.sl.rq.u_l;
|
ptr = http_get_path(txn);
|
||||||
|
if (!ptr)
|
||||||
if (ptr >= end)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
/* RFC2616, par. 5.1.2 :
|
|
||||||
* Request-URI = "*" | absuri | abspath | authority
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (*ptr == '*')
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
if (isalpha((unsigned char)*ptr)) {
|
|
||||||
/* this is a scheme as described by RFC3986, par. 3.1 */
|
|
||||||
ptr++;
|
|
||||||
while (ptr < end &&
|
|
||||||
(isalnum((unsigned char)*ptr) || *ptr == '+' || *ptr == '-' || *ptr == '.'))
|
|
||||||
ptr++;
|
|
||||||
/* skip '://' */
|
|
||||||
if (ptr == end || *ptr++ != ':')
|
|
||||||
return 0;
|
|
||||||
if (ptr == end || *ptr++ != '/')
|
|
||||||
return 0;
|
|
||||||
if (ptr == end || *ptr++ != '/')
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
/* skip [user[:passwd]@]host[:[port]] */
|
|
||||||
|
|
||||||
while (ptr < end && *ptr != '/')
|
|
||||||
ptr++;
|
|
||||||
|
|
||||||
if (ptr == end)
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/* OK, we got the '/' ! */
|
/* OK, we got the '/' ! */
|
||||||
|
35
tests/test-redir.cfg
Normal file
35
tests/test-redir.cfg
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
# This is a test configuration.
|
||||||
|
# It makes use of a farm built from 4 servers, 3 of which are remote and
|
||||||
|
# referenced only via an HTTP redirect (302), and the 4th one is normal.
|
||||||
|
# HTTP requests different from GET/HEAD should reach the servers directly
|
||||||
|
# while GET/HEAD should get redirected for the 3 first ones.
|
||||||
|
|
||||||
|
global
|
||||||
|
#log /dev/log local0
|
||||||
|
maxconn 1000
|
||||||
|
stats socket /tmp/sock1 mode 600
|
||||||
|
stats timeout 3000
|
||||||
|
stats maxconn 2000
|
||||||
|
|
||||||
|
listen sample1
|
||||||
|
#log global
|
||||||
|
#option httplog
|
||||||
|
mode http
|
||||||
|
retries 1
|
||||||
|
option redispatch
|
||||||
|
contimeout 1000
|
||||||
|
clitimeout 5000
|
||||||
|
srvtimeout 5000
|
||||||
|
maxconn 40000
|
||||||
|
bind :8080
|
||||||
|
#balance source
|
||||||
|
balance roundrobin
|
||||||
|
option allbackups
|
||||||
|
server rdr1 127.0.0.1:80 redir http://static1:80 weight 10 check inter 1000 fall 4
|
||||||
|
server rdr2 127.0.0.2:80 redir http://static2:80 weight 20 check inter 1000 fall 4
|
||||||
|
server rdr3 127.0.0.3:80 redir http://static3:80 weight 30 check inter 1000 fall 4
|
||||||
|
server dir4 127.0.0.4:80 redir weight 30 check inter 1000 fall 4
|
||||||
|
option httpclose
|
||||||
|
stats uri /stats
|
||||||
|
stats refresh 5
|
||||||
|
|
Loading…
Reference in New Issue
Block a user