[-]
[+]
|
Changed |
haproxy.spec
|
|
[-]
[+]
|
Changed |
haproxy-1.4.8.tar.gz/CHANGELOG
^
|
@@ -1,6 +1,29 @@
ChangeLog :
===========
+2010/06/16 : 1.4.8
+ - [DOC] mention 'option http-server-close' effect in Tq section
+ - [DOC] summarize and highlight persistent connections behaviour
+ - [DOC] add configuration samples
+ - [BUG] stick_table: the fix for the memory leak caused a regression
+ - [BUG] client: don't add a new session to the list too early
+
+2010/06/07 : 1.4.7
+ - [BUG] http: dispatch and http_proxy modes were broken for a long time
+ - [BUG] http: the transaction must be initialized even in TCP mode
+ - [BUG] tcp: dropped connections must be counted as "denied" not "failed"
+ - [BUG] consistent hash: balance on all servers, not only 2 !
+ - [CONTRIB] halog: report per-server status codes, errors and response times
+ - [BUG] http: the transaction must be initialized even in TCP mode (part 2)
+ - [BUG] stick_table: fix possible memory leak in case of connection error
+ - [BUG] proxy: connection rate limiting was eating lots of CPU
+ - [BUG] frontend: always ensure to zero rep->analysers
+ - [BUG] http: report correct flags in case of client aborts during body
+ - [TESTS] refine non-regression tests and add 4 new tests
+ - [BUG] debug: wrong pointer was used to report a status line
+ - [BUG] debug: correctly report truncated messages
+ - [DOC] document the "dispatch" keyword
+
2010/05/16 : 1.4.6
- [BUILD] ebtree: update to v6.0.1 to remove references to dprintf()
- [CLEANUP] acl: make use of eb_is_empty() instead of open coding the tree's emptiness test
|
[-]
[+]
|
Changed |
haproxy-1.4.8.tar.gz/VERDATE
^
|
@@ -1 +1 @@
-2010/05/16
+2010/06/16
|
[-]
[+]
|
Changed |
haproxy-1.4.8.tar.gz/VERSION
^
|
@@ -1 +1 @@
-1.4.6
+1.4.8
|
[-]
[+]
|
Changed |
haproxy-1.4.8.tar.gz/contrib/halog/Makefile
^
|
@@ -5,10 +5,10 @@
OBJS = halog halog64
halog: halog.c fgets2.c
- $(CC) $(OPTIMIZE) -o $@ $(INCLUDE) $(EBTREE_DIR)/ebtree.c $(EBTREE_DIR)/eb32tree.c $^
+ $(CC) $(OPTIMIZE) -o $@ $(INCLUDE) $(EBTREE_DIR)/ebtree.c $(EBTREE_DIR)/eb32tree.c $(EBTREE_DIR)/ebmbtree.c $(EBTREE_DIR)/ebsttree.c $^
halog64: halog.c fgets2-64.c
- $(CC) $(OPTIMIZE) -o $@ $(INCLUDE) $(EBTREE_DIR)/ebtree.c $(EBTREE_DIR)/eb32tree.c $^
+ $(CC) $(OPTIMIZE) -o $@ $(INCLUDE) $(EBTREE_DIR)/ebtree.c $(EBTREE_DIR)/eb32tree.c $(EBTREE_DIR)/ebmbtree.c $(EBTREE_DIR)/ebsttree.c $^
clean:
rm -vf $(OBJS)
|
[-]
[+]
|
Changed |
haproxy-1.4.8.tar.gz/contrib/halog/halog.c
^
|
@@ -1,7 +1,7 @@
/*
* haproxy log time reporter
*
- * Copyright 2000-2009 Willy Tarreau <w@1wt.eu>
+ * Copyright 2000-2010 Willy Tarreau <w@1wt.eu>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -28,8 +28,11 @@
#include <ctype.h>
#include <eb32tree.h>
+#include <ebsttree.h>
+#define SOURCE_FIELD 5
#define ACCEPT_FIELD 6
+#define SERVER_FIELD 8
#define TIME_FIELD 9
#define STATUS_FIELD 10
#define CONN_FIELD 15
@@ -49,6 +52,13 @@
unsigned int count;
};
+struct srv_st {
+ unsigned int st_cnt[6]; /* 0xx to 5xx */
+ unsigned int nb_ct, nb_rt, nb_ok;
+ unsigned long long cum_ct, cum_rt;
+ struct ebmb_node node;
+ /* don't put anything else here, the server name will be there */
+};
#define FILT_COUNT_ONLY 0x01
#define FILT_INVERT 0x02
@@ -64,6 +74,7 @@
#define FILT_INVERT_TIME_RESP 0x400
#define FILT_COUNT_STATUS 0x800
+#define FILT_COUNT_SRV_STATUS 0x1000
unsigned int filter = 0;
unsigned int filter_invert = 0;
@@ -75,7 +86,7 @@
{
fprintf(stderr,
"%s"
- "Usage: halog [-c] [-v] [-gt] [-pct] [-st] [-s <skip>] [-e|-E] [-rt|-RT <time>] [-ad <delay>] [-ac <count>] < file.log\n"
+ "Usage: halog [-q] [-c] [-v] [-gt] [-pct] [-st] [-srv] [-s <skip>] [-e|-E] [-rt|-RT <time>] [-ad <delay>] [-ac <count>] < file.log\n"
"\n",
msg ? msg : ""
);
@@ -412,6 +423,8 @@
filter |= FILT_PERCENTILE;
else if (strcmp(argv[0], "-st") == 0)
filter |= FILT_COUNT_STATUS;
+ else if (strcmp(argv[0], "-srv") == 0)
+ filter |= FILT_COUNT_SRV_STATUS;
else if (strcmp(argv[0], "-o") == 0) {
if (output_file)
die("Fatal: output file name already specified.\n");
@@ -606,6 +619,104 @@
continue;
}
+ if (unlikely(filter & FILT_COUNT_SRV_STATUS)) {
+ char *srv_name;
+ struct ebmb_node *srv_node;
+ struct srv_st *srv;
+
+ /* first, let's ensure that the line is a traffic line (beginning
+ * with an IP address)
+ */
+ b = field_start(line, SOURCE_FIELD + skip_fields);
+ if (*b < '0' || *b > '9') {
+ parse_err++;
+ continue;
+ }
+
+ /* the server field is before the status field, so let's
+ * parse them in the proper order.
+ */
+ b = field_start(b, SERVER_FIELD - SOURCE_FIELD + 1);
+ if (!*b) {
+ truncated_line(linenum, line);
+ continue;
+ }
+
+ e = field_stop(b + 1); /* we have the server name in [b]..[e-1] */
+
+ /* the chance that a server name already exists is extremely high,
+ * so let's perform a normal lookup first.
+ */
+ srv_node = ebst_lookup_len(&timers[0], b, e - b);
+ srv = container_of(srv_node, struct srv_st, node);
+
+ if (!srv_node) {
+ /* server not yet in the tree, let's create it */
+ srv = (void *)calloc(1, sizeof(struct srv_st) + e - b + 1);
+ srv_node = &srv->node;
+ memcpy(&srv_node->key, b, e - b);
+ srv_node->key[e - b] = '\0';
+ ebst_insert(&timers[0], srv_node);
+ }
+
+ /* let's collect the connect and response times */
+ b = field_start(e, TIME_FIELD - SERVER_FIELD);
+ if (!*b) {
+ truncated_line(linenum, line);
+ continue;
+ }
+
+ e = field_stop(b + 1);
+ /* we have field TIME_FIELD in [b]..[e-1] */
+
+ p = b;
+ err = 0;
+ for (f = 0; f < 5 && *p; f++) {
+ array[f] = str2ic(p);
+ if (array[f] < 0) {
+ array[f] = -1;
+ err = 1;
+ }
+
+ SKIP_CHAR(p, '/');
+ }
+
+ if (f < 5) {
+ parse_err++;
+ continue;
+ }
+
+ /* OK we have our timers in array[2,3] */
+ if (!err)
+ srv->nb_ok++;
+
+ if (array[2] >= 0) {
+ srv->cum_ct += array[2];
+ srv->nb_ct++;
+ }
+
+ if (array[3] >= 0) {
+ srv->cum_rt += array[3];
+ srv->nb_rt++;
+ }
+
+ /* we're interested in the 5 HTTP status classes (1xx ... 5xx), and
+ * the invalid ones which will be reported as 0.
+ */
+ b = field_start(e, STATUS_FIELD - TIME_FIELD);
+ if (!*b) {
+ truncated_line(linenum, line);
+ continue;
+ }
+
+ val = 0;
+ if (*b >= '1' && *b <= '5')
+ val = *b - '0';
+
+ srv->st_cnt[val]++;
+ continue;
+ }
+
/* all other cases mean we just want to count lines */
tot++;
if (unlikely(!(filter & FILT_COUNT_ONLY)))
@@ -732,6 +843,34 @@
n = eb32_next(n);
}
}
+ else if (unlikely(filter & FILT_COUNT_SRV_STATUS)) {
+ char *srv_name;
+ struct ebmb_node *srv_node;
+ struct srv_st *srv;
+
+ printf("#srv_name 1xx 2xx 3xx 4xx 5xx other tot_req req_ok pct_ok avg_ct avg_rt\n");
+
+ srv_node = ebmb_first(&timers[0]);
+ while (srv_node) {
+ int tot_rq;
+
+ srv = container_of(srv_node, struct srv_st, node);
+
+ tot_rq = 0;
+ for (f = 0; f <= 5; f++)
+ tot_rq += srv->st_cnt[f];
+
+ printf("%s %d %d %d %d %d %d %d %d %.1f %d %d\n",
+ srv_node->key, srv->st_cnt[1], srv->st_cnt[2],
+ srv->st_cnt[3], srv->st_cnt[4], srv->st_cnt[5], srv->st_cnt[0],
+ tot_rq,
+ srv->nb_ok, (double)srv->nb_ok * 100.0 / (tot_rq?tot_rq:1),
+ (int)(srv->cum_ct / (srv->nb_ct?srv->nb_ct:1)), (int)(srv->cum_rt / (srv->nb_rt?srv->nb_rt:1)));
+ srv_node = ebmb_next(srv_node);
+ tot++;
+ }
+ }
+
empty:
if (!(filter & FILT_QUIET))
fprintf(stderr, "%d lines in, %d lines out, %d parsing errors\n",
|
[-]
[+]
|
Changed |
haproxy-1.4.8.tar.gz/doc/configuration.txt
^
|
@@ -2,9 +2,9 @@
HAProxy
Configuration Manual
----------------------
- version 1.4.6
+ version 1.4.8
willy tarreau
- 2010/05/16
+ 2010/06/16
This document covers the configuration language as implemented in the version
@@ -37,6 +37,7 @@
2. Configuring HAProxy
2.1. Configuration file format
2.2. Time format
+2.3. Examples
3. Global parameters
3.1. Process management and security
@@ -127,8 +128,7 @@
Its advantages are a reduced latency between transactions, and less processing
power required on the server side. It is generally better than the close mode,
but not always because the clients often limit their concurrent connections to
-a smaller value. HAProxy currently only supports the HTTP keep-alive mode on
-the client side, and transforms it to a close mode on the server side.
+a smaller value.
A last improvement in the communications is the pipelining mode. It still uses
keep-alive, but the client does not wait for the first response to send the
@@ -142,8 +142,17 @@
correctly support pipelining since there is no way to associate a response with
the corresponding request in HTTP. For this reason, it is mandatory for the
server to reply in the exact same order as the requests were received.
-HAProxy supports pipelined requests on the client side and processes them one
-at a time.
+
+By default HAProxy operates in a tunnel-like mode with regards to persistent
+connections: for each connection it processes the first request and forwards
+everything else (including additional requests) to selected server. Once
+established, the connection is persisted both on the client and server
+sides. Use "option http-server-close" to preserve client persistent connections
+while handling every incoming request individually, dispatching them one after
+another to servers, in HTTP close mode. Use "option httpclose" to switch both
+sides to HTTP close mode. "option forceclose" and "option
+http-pretend-keepalive" help working around servers misbehaving in HTTP close
+mode.
1.2. HTTP request
@@ -362,6 +371,52 @@
- d : days. 1d = 24h = 1440m = 86400s = 86400000ms
+2.3. Examples
+-------------
+
+ # Simple configuration for an HTTP proxy listening on port 80 on all
+ # interfaces and forwarding requests to a single backend "servers" with a
+ # single server "server1" listening on 127.0.0.1:8000
+ global
+ daemon
+ maxconn 256
+
+ defaults
+ mode http
+ timeout connect 5000ms
+ timeout client 50000ms
+ timeout server 50000ms
+
+ frontend http-in
+ bind *:80
+ default_backend servers
+
+ backend servers
+ server server1 127.0.0.1:8000 maxconn 32
+
+
+ # The same configuration defined with a single listen block. Shorter but
+ # less expressive, especially in HTTP mode.
+ global
+ daemon
+ maxconn 256
+
+ defaults
+ mode http
+ timeout connect 5000ms
+ timeout client 50000ms
+ timeout server 50000ms
+
+ listen http-in
+ bind *:80
+ server server1 127.0.0.1:8000 maxconn 32
+
+
+Assuming haproxy is in $PATH, test these configurations in a shell with:
+
+ $ sudo haproxy -f configuration.conf -d
+
+
3. Global parameters
--------------------
@@ -1761,6 +1816,29 @@
See also : "enabled"
+dispatch <address>:<port>
+ Set a default server address
+ May be used in sections : defaults | frontend | listen | backend
+ no | no | yes | yes
+ Arguments : none
+
+ <address> is the IPv4 address of the default server. Alternatively, a
+ resolvable hostname is supported, but this name will be resolved
+ during start-up.
+
+ <ports> is a mandatory port specification. All connections will be sent
+ to this port, and it is not permitted to use port offsets as is
+ possible with normal servers.
+
+ The "disabled" keyword designates a default server for use when no other
+ server can take the connection. In the past it was used to forward non
+ persistent connections to an auxiliary load balancer. Due to its simple
+ syntax, it has also been used for simple TCP relays. It is recommended not to
+ use it for more clarity, and to use the "server" directive instead.
+
+ See also : "server"
+
+
enabled
Enable a proxy, frontend or backend.
May be used in sections : defaults | frontend | listen | backend
@@ -2768,16 +2846,18 @@
yes | yes | yes | yes
Arguments : none
- This mode enables HTTP connection-close mode on the server side while keeping
- the ability to support HTTP keep-alive and pipelining on the client side.
- This provides the lowest latency on the client side (slow network) and the
- fastest session reuse on the server side to save server resources, similarly
- to "option forceclose". It also permits non-keepalive capable servers to be
- served in keep-alive mode to the clients if they conform to the requirements
- of RFC2616. Please note that some servers do not always conform to those
- requirements when they see "Connection: close" in the request. The effect
- will be that keep-alive will never be used. A workaround consists in enabling
- "option http-pretend-keepalive".
+ By default, when a client communicates with a server, HAProxy will only
+ analyze, log, and process the first request of each connection. Setting
+ "option http-server-close" enables HTTP connection-close mode on the server
+ side while keeping the ability to support HTTP keep-alive and pipelining on
+ the client side. This provides the lowest latency on the client side (slow
+ network) and the fastest session reuse on the server side to save server
+ resources, similarly to "option forceclose". It also permits non-keepalive
+ capable servers to be served in keep-alive mode to the clients if they
+ conform to the requirements of RFC2616. Please note that some servers do not
+ always conform to those requirements when they see "Connection: close" in the
+ request. The effect will be that keep-alive will never be used. A workaround
+ consists in enabling "option http-pretend-keepalive".
At the moment, logs will not indicate whether requests came from the same
session or not. The accept date reported in the logs corresponds to the end
@@ -2795,8 +2875,8 @@
If this option has been enabled in a "defaults" section, it can be disabled
in a specific instance by prepending the "no" keyword before it.
- See also : "option forceclose", "option http-pretend-keepalive" and
- "option httpclose".
+ See also : "option forceclose", "option http-pretend-keepalive",
+ "option httpclose" and "1.1. The HTTP transaction model".
option http-use-proxy-header
@@ -2888,15 +2968,13 @@
yes | yes | yes | yes
Arguments : none
- As stated in section 1, HAProxy does not yet support the HTTP keep-alive
- mode. So by default, if a client communicates with a server in this mode, it
- will only analyze, log, and process the first request of each connection. To
- workaround this limitation, it is possible to specify "option httpclose". It
- will check if a "Connection: close" header is already set in each direction,
- and will add one if missing. Each end should react to this by actively
- closing the TCP connection after each transfer, thus resulting in a switch to
- the HTTP close mode. Any "Connection" header different from "close" will also
- be removed.
+ By default, when a client communicates with a server, HAProxy will only
+ analyze, log, and process the first request of each connection. If "option
+ httpclose" is set, it will check if a "Connection: close" header is already
+ set in each direction, and will add one if missing. Each end should react to
+ this by actively closing the TCP connection after each transfer, thus
+ resulting in a switch to the HTTP close mode. Any "Connection" header
+ different from "close" will also be removed.
It seldom happens that some servers incorrectly ignore this header and do not
close the connection eventhough they reply "Connection: close". For this
@@ -2915,7 +2993,8 @@
If this option has been enabled in a "defaults" section, it can be disabled
in a specific instance by prepending the "no" keyword before it.
- See also : "option forceclose" and "option http-server-close"
+ See also : "option forceclose", "option http-server-close" and
+ "1.1. The HTTP transaction model".
option httplog [ clf ]
@@ -7268,7 +7347,9 @@
spent accepting these connections will inevitably slightly delay processing
of other connections, and it can happen that request times in the order of
a few tens of milliseconds are measured after a few thousands of new
- connections have been accepted at once.
+ connections have been accepted at once. Setting "option http-server-close"
+ may display larger request times since "Tq" also measures the time spent
+ waiting for additional requests.
- If "Tc" is close to 3000, a packet has probably been lost between the
server and the proxy during the server connection phase. This value should
|
[-]
[+]
|
Changed |
haproxy-1.4.8.tar.gz/examples/haproxy.spec
^
|
@@ -1,6 +1,6 @@
Summary: HA-Proxy is a TCP/HTTP reverse proxy for high availability environments
Name: haproxy
-Version: 1.4.6
+Version: 1.4.8
Release: 1
License: GPL
Group: System Environment/Daemons
@@ -76,6 +76,12 @@
%attr(0755,root,root) %config %{_sysconfdir}/rc.d/init.d/%{name}
%changelog
+* Wed Jun 16 2010 Willy Tarreau <w@1wt.eu>
+- updated to 1.4.8
+
+* Mon Jun 7 2010 Willy Tarreau <w@1wt.eu>
+- updated to 1.4.7
+
* Sun May 16 2010 Willy Tarreau <w@1wt.eu>
- updated to 1.4.6
|
[-]
[+]
|
Changed |
haproxy-1.4.8.tar.gz/src/cfgparse.c
^
|
@@ -5045,6 +5045,22 @@
curproxy->srv = next;
}
+ /* assign automatic UIDs to servers which don't have one yet */
+ next_id = 1;
+ newsrv = curproxy->srv;
+ while (newsrv != NULL) {
+ if (!newsrv->puid) {
+ /* server ID not set, use automatic numbering with first
+ * spare entry starting with next_svid.
+ */
+ next_id = get_next_id(&curproxy->conf.used_server_id, next_id);
+ newsrv->conf.id.key = newsrv->puid = next_id;
+ eb32_insert(&curproxy->conf.used_server_id, &newsrv->conf.id);
+ }
+ next_id++;
+ newsrv = newsrv->next;
+ }
+
curproxy->lbprm.wmult = 1; /* default weight multiplier */
curproxy->lbprm.wdiv = 1; /* default weight divider */
@@ -5155,19 +5171,8 @@
/*
* ensure that we're not cross-dressing a TCP server into HTTP.
*/
- next_id = 1;
newsrv = curproxy->srv;
while (newsrv != NULL) {
- if (!newsrv->puid) {
- /* server ID not set, use automatic numbering with first
- * spare entry starting with next_svid.
- */
- next_id = get_next_id(&curproxy->conf.used_server_id, next_id);
- newsrv->conf.id.key = newsrv->puid = next_id;
- eb32_insert(&curproxy->conf.used_server_id, &newsrv->conf.id);
- }
- next_id++;
-
if ((curproxy->mode != PR_MODE_HTTP) && (newsrv->rdr_len || newsrv->cklen)) {
Alert("config : %s '%s' : server cannot have cookie or redirect prefix in non-HTTP mode.\n",
proxy_type_str(curproxy), curproxy->id);
|
[-]
[+]
|
Changed |
haproxy-1.4.8.tar.gz/src/client.c
^
|
@@ -126,7 +126,6 @@
goto out_close;
}
- LIST_ADDQ(&sessions, &s->list);
LIST_INIT(&s->back_refs);
s->flags = 0;
@@ -146,6 +145,8 @@
s->flags |= SN_MONITOR;
}
+ LIST_ADDQ(&sessions, &s->list);
+
if ((t = task_new()) == NULL) { /* disable this proxy for a while */
Alert("out of memory in event_accept().\n");
EV_FD_CLR(fd, DIR_RD);
@@ -301,10 +302,10 @@
if ((txn->hdr_idx.v = pool_alloc2(p->hdr_idx_pool)) == NULL)
goto out_fail_idx; /* no memory */
- }
- if (p->mode == PR_MODE_HTTP)
+ /* and now initialize the HTTP transaction state */
http_init_txn(s);
+ }
if ((p->mode == PR_MODE_TCP || p->mode == PR_MODE_HTTP)
&& (p->logfac1 >= 0 || p->logfac2 >= 0)) {
@@ -413,6 +414,7 @@
s->rep->prod = &s->si[1];
s->rep->cons = &s->si[0];
s->si[0].ob = s->si[1].ib = s->rep;
+ s->rep->analysers = 0;
s->rep->rto = s->be->timeout.server;
s->rep->wto = s->fe->timeout.client;
|
[-]
[+]
|
Changed |
haproxy-1.4.8.tar.gz/src/proto_http.c
^
|
@@ -2413,7 +2413,7 @@
(msg->msg_state >= HTTP_MSG_BODY || msg->msg_state == HTTP_MSG_ERROR))) {
char *eol, *sol;
- sol = msg->sol;
+ sol = req->data + msg->som;
eol = sol + msg->sl.rq.l;
debug_hdr("clireq", s, sol, eol);
@@ -3603,6 +3603,11 @@
if ((req->flags & BF_READ_TIMEOUT) || tick_is_expired(req->analyse_exp, now_ms)) {
txn->status = 408;
stream_int_retnclose(req->prod, error_message(s, HTTP_ERR_408));
+
+ if (!(s->flags & SN_ERR_MASK))
+ s->flags |= SN_ERR_CLITO;
+ if (!(s->flags & SN_FINST_MASK))
+ s->flags |= SN_FINST_D;
goto return_err_msg;
}
@@ -3632,16 +3637,16 @@
txn->status = 400;
stream_int_retnclose(req->prod, error_message(s, HTTP_ERR_400));
+ if (!(s->flags & SN_ERR_MASK))
+ s->flags |= SN_ERR_PRXCOND;
+ if (!(s->flags & SN_FINST_MASK))
+ s->flags |= SN_FINST_R;
+
return_err_msg:
req->analysers = 0;
s->fe->counters.failed_req++;
if (s->listener->counters)
s->listener->counters->failed_req++;
-
- if (!(s->flags & SN_ERR_MASK))
- s->flags |= SN_ERR_PRXCOND;
- if (!(s->flags & SN_FINST_MASK))
- s->flags |= SN_FINST_R;
return 0;
}
@@ -4216,12 +4221,22 @@
missing_data:
/* stop waiting for data if the input is closed before the end */
- if (req->flags & BF_SHUTR)
+ if (req->flags & BF_SHUTR) {
+ if (!(s->flags & SN_ERR_MASK))
+ s->flags |= SN_ERR_CLICL;
+ if (!(s->flags & SN_FINST_MASK))
+ s->flags |= SN_FINST_D;
goto return_bad_req;
+ }
/* waiting for the last bits to leave the buffer */
- if (req->flags & BF_SHUTW)
+ if (req->flags & BF_SHUTW) {
+ if (!(s->flags & SN_ERR_MASK))
+ s->flags |= SN_ERR_SRVCL;
+ if (!(s->flags & SN_FINST_MASK))
+ s->flags |= SN_FINST_D;
goto return_bad_req;
+ }
http_silent_debug(__LINE__, s);
return 0;
@@ -4318,8 +4333,8 @@
(msg->msg_state >= HTTP_MSG_BODY || msg->msg_state == HTTP_MSG_ERROR))) {
char *eol, *sol;
- sol = msg->sol;
- eol = sol + msg->sl.rq.l;
+ sol = rep->data + msg->som;
+ eol = sol + msg->sl.st.l;
debug_hdr("srvrep", s, sol, eol);
sol += hdr_idx_first_pos(&txn->hdr_idx);
@@ -4493,7 +4508,8 @@
n = msg->sol[msg->sl.st.c] - '0';
if (n < 1 || n > 5)
n = 0;
- s->srv->counters.p.http.rsp[n]++;
+ if (s->srv)
+ s->srv->counters.p.http.rsp[n]++;
/* check if the response is HTTP/1.1 or above */
if ((msg->sl.st.v_l == 8) &&
@@ -4514,10 +4530,12 @@
* and 505 are triggered on demand by client request, so we must not
* count them as server failures.
*/
- if (txn->status >= 100 && (txn->status < 500 || txn->status == 501 || txn->status == 505))
- health_adjust(s->srv, HANA_STATUS_HTTP_OK);
- else
- health_adjust(s->srv, HANA_STATUS_HTTP_STS);
+ if (s->srv) {
+ if (txn->status >= 100 && (txn->status < 500 || txn->status == 501 || txn->status == 505))
+ health_adjust(s->srv, HANA_STATUS_HTTP_OK);
+ else
+ health_adjust(s->srv, HANA_STATUS_HTTP_STS);
+ }
/*
* 2: check for cacheability.
@@ -5957,7 +5975,7 @@
done = 0;
cur_ptr = txn->rsp.sol;
- cur_end = cur_ptr + txn->rsp.sl.rq.l;
+ cur_end = cur_ptr + txn->rsp.sl.st.l;
/* Now we have the status line between cur_ptr and cur_end */
@@ -6003,7 +6021,7 @@
* or an LF at <ptr>.
*/
txn->status = strl2ui(txn->rsp.sol + txn->rsp.sl.st.c, txn->rsp.sl.st.c_l);
- hdr_idx_set_start(&txn->hdr_idx, txn->rsp.sl.rq.l, *cur_end == '\r');
+ hdr_idx_set_start(&txn->hdr_idx, txn->rsp.sl.st.l, *cur_end == '\r');
/* there is no point trying this regex on headers */
return 1;
}
|
[-]
[+]
|
Changed |
haproxy-1.4.8.tar.gz/src/proto_tcp.c
^
|
@@ -692,9 +692,9 @@
buffer_abort(s->rep);
req->analysers = 0;
- s->fe->counters.failed_req++;
+ s->fe->counters.denied_req++;
if (s->listener->counters)
- s->listener->counters->failed_req++;
+ s->listener->counters->denied_req++;
if (!(s->flags & SN_ERR_MASK))
s->flags |= SN_ERR_PRXCOND;
|
[-]
[+]
|
Changed |
haproxy-1.4.8.tar.gz/src/proto_uxst.c
^
|
@@ -514,6 +514,7 @@
s->rep->prod = &s->si[1];
s->rep->cons = &s->si[0];
s->si[0].ob = s->si[1].ib = s->rep;
+ s->rep->analysers = 0;
s->rep->rto = TICK_ETERNITY;
s->rep->cto = TICK_ETERNITY;
|
[-]
[+]
|
Changed |
haproxy-1.4.8.tar.gz/src/proxy.c
^
|
@@ -34,6 +34,7 @@
#include <proto/log.h>
#include <proto/protocols.h>
#include <proto/proto_tcp.h>
+#include <proto/proto_http.h>
#include <proto/proxy.h>
@@ -484,7 +485,7 @@
goto do_block;
if (p->fe_sps_lim &&
- (wait = next_event_delay(&p->fe_sess_per_sec, p->fe_sps_lim, 0))) {
+ (wait = next_event_delay(&p->fe_sess_per_sec, p->fe_sps_lim, 1))) {
/* we're blocking because a limit was reached on the number of
* requests/s on the frontend. We want to re-check ASAP, which
* means in 1 ms before estimated expiration date, because the
@@ -736,6 +737,10 @@
if (unlikely(!s->txn.hdr_idx.v && (be->acl_requires & ACL_USE_L7_ANY))) {
if ((s->txn.hdr_idx.v = pool_alloc2(s->fe->hdr_idx_pool)) == NULL)
return 0; /* not enough memory */
+
+ /* and now initialize the HTTP transaction state */
+ http_init_txn(s);
+
s->txn.hdr_idx.size = MAX_HTTP_HDR;
hdr_idx_init(&s->txn.hdr_idx);
}
|
[-]
[+]
|
Changed |
haproxy-1.4.8.tar.gz/src/session.c
^
|
@@ -50,6 +50,7 @@
struct http_txn *txn = &s->txn;
struct proxy *fe = s->fe;
struct bref *bref, *back;
+ int i;
if (s->pend_pos)
pendconn_free(s->pend_pos);
@@ -82,6 +83,13 @@
http_end_txn(s);
+ for (i = 0; i < s->store_count; i++) {
+ if (!s->store[i].ts)
+ continue;
+ stksess_free(s->store[i].table, s->store[i].ts);
+ s->store[i].ts = NULL;
+ }
+
if (fe) {
pool_free2(fe->hdr_idx_pool, txn->hdr_idx.v);
pool_free2(fe->rsp_cap_pool, txn->rsp.cap);
@@ -794,11 +802,12 @@
/* process store request and store response */
for (i = 0; i < s->store_count; i++) {
- if (stktable_store(s->store[i].table, s->store[i].ts, s->srv->puid) > 0) {
+ if (stktable_store(s->store[i].table, s->store[i].ts, s->srv->puid) > 0)
stksess_free(s->store[i].table, s->store[i].ts);
- s->store[i].ts = NULL;
- }
+ /* always remove pointer to session to ensure we won't free it again */
+ s->store[i].ts = NULL;
}
+ s->store_count = 0; /* everything is stored */
rep->analysers &= ~an_bit;
rep->analyse_exp = TICK_ETERNITY;
|
[-]
[+]
|
Changed |
haproxy-1.4.8.tar.gz/tests/test-fsm.cfg
^
|
@@ -135,19 +135,20 @@
# server = nc6 --half-close -lp4000
# client = (printf "GET / HTTP/1.0\r\n\r\n"; sleep 1) | nc 127.1 8001
# action : wait 9 seconds and check response
-# result : client exits with 504, log is emitted immediately, server must be
-# terminated by hand. Logs indicate "sH--" with correct timers, which
-# is 9s total (sleep 1 + 8 for server response).
-# example: 0/0/0/-1/9002 504 194 - - sH--
+# result : client exits with 504, log is emitted immediately, server exits
+# immediately. Logs indicate "sH--" with correct timers, which
+# is 8s regardless of the "sleep 1".
+# example: 0/0/0/-1/8002 504 194 - - sH--
-########### test15: process_srv(), client close causing server close
+########### test15: process_srv(), client close not causing server close
# setup :
# server = nc6 -lp4000
# client = (printf "GET / HTTP/1.0\r\n\r\n"; sleep 1) | nc 127.1 8001
-# action : wait 1 second and check response
-# result : client exits with 502, log is emitted immediately, server closes.
-# Logs indicate "SH--" with correct timers.
-# example: 0/0/0/-1/1002 502 204 - - SH--
+# action : wait 9 second and check response
+# result : client exits with 504, log is emitted immediately, server exits
+# immediately. Logs indicate "sH--" with correct timers, which
+# is 8s regardless of the "sleep 1".
+# example: 0/0/0/-1/8002 504 194 - - sH--
########### test16: process_srv(), read timeout on server headers
# setup :
@@ -166,7 +167,7 @@
# action : wait at least 12 seconds and check the logs
# result : client returns 503 and must be terminated by hand. Log is emitted
# immediately. Logs indicate "sC--" with correct timers.
-# example: 0/6001/-1/-1/12001 503 212 - - sC--
+# example: 0/0/-1/-1/12001 503 212 - - sC--
########### test18: process_srv(), client close during connection time-out
# setup :
@@ -176,7 +177,7 @@
# action : wait at least 12 seconds and check the logs
# result : client returns 503 and automatically closes. Log is emitted
# immediately. Logs indicate "sC--" with correct timers.
-# example: 0/6001/-1/-1/12001 503 212 - - sC--
+# example: 0/0/-1/-1/12001 503 212 - - sC--
########### test19: process_srv(), immediate server close after empty response
# setup :
@@ -209,10 +210,46 @@
# setup :
# server = (printf "HTTP/1.0 200 OK\r\nTest: test\r\n\r\n") | nc -lp4000
# client = (printf "POST / HTTP/1.0\r\nContent-length: 20\r\n\r\n";cat) | nc 127.1 8001
-# action : wait 5s for the request body to timeout.
+# action : wait 7s for the request body to timeout.
# result : The server receives the request and responds immediately with 200.
-# Log is emitted immediately. Logs indicate "----" with correct timers.
-# example: 5002/0/0/0/5002 200 31 - - ----
+# Log is emitted after the timeout occurs. Logs indicate "cD--" with correct timers.
+# example: 1/0/0/0/7004 200 31 - - cD--
+
+########### test23: process_srv(), client close on request body
+# setup :
+# server = (printf "HTTP/1.0 200 OK\r\nTest: test\r\n\r\n") | nc -lp4000
+# client = (printf "POST / HTTP/1.0\r\nContent-length: 20\r\n\r\n";cat) | nc 127.1 8001
+# action : wait 2s then press Ctrl-C on the client
+# result : The server immediately aborts and the logs are emitted immediately with a 400.
+# Logs indicate "CD--" with correct timers.
+# example: 1/0/0/0/1696 400 31 - - CD--
+
+########### test24 process_srv(), server close on request body
+# setup :
+# server = (printf "HTTP/1.0 200 OK\r\nTest: test\r\n\r\n") | nc -lp4000
+# client = (printf "POST / HTTP/1.0\r\nContent-length: 20\r\n\r\n";cat) | nc 127.1 8001
+# action : wait 2s then press Ctrl-C on the server and press enter a few times on the client
+# result : The logs are emitted immediately with a 200 (server's incomplete response).
+# Logs indicate "SD--" with correct timers. Client must be terminated by hand.
+# example: 1/0/0/0/2186 200 31 - - SD--
+
+########### test25: process_srv(), client timeout on request body when url_param is used
+# setup :
+# server = none
+# client = (printf "POST / HTTP/1.0\r\nContent-length: 20\r\n\r\n";cat) | nc 127.1 8003
+# action : wait 5s for the request body to timeout.
+# result : The client receives a 408 and closes. The log is emitted immediately.
+# Logs indicate "cD--" with correct timers.
+# example: 0/-1/-1/-1/5003 408 212 - - cD--
+
+########### test26: process_srv(), client abort on request body when url_param is used
+# setup :
+# server = none
+# client = (printf "POST / HTTP/1.0\r\nContent-length: 20\r\n\r\n";cat) | nc 127.1 8003
+# action : wait 2s then press Ctrl-C on the client
+# result : The logs are emitted immediately with a 400.
+# Logs indicate "CD--" with correct timers.
+# example: 594/-1/-1/-1/594 400 187 - - CD--
@@ -243,7 +280,7 @@
timeout server 8s
timeout queue 9s
- balance url_param foo check_post
+ balance roundrobin
server srv4000 127.0.0.1:4000
# connect port 8002 to nowhere
@@ -264,6 +301,23 @@
balance url_param foo check_post
server srv4000 192.168.255.255:4000
+# connect port 8003 to localhost:4000 with url_param
+listen frt8003
+ log global
+ bind :8003
+ mode http
+ option httplog
+ maxconn 100
+
+ timeout http-request 5s
+ timeout connect 6s
+ timeout client 7s
+ timeout server 8s
+ timeout queue 9s
+
+ balance url_param foo check_post
+ server srv4000 127.0.0.1:4000
+
# listen frt8002
# log global
|
[-]
[+]
|
Changed |
haproxy.cfg
^
|
@@ -1,79 +1,86 @@
-# this config needs haproxy-1.1.28 or haproxy-1.2.1
-
+#---------------------------------------------------------------------
+# Example configuration for a possible web application. See the
+# full configuration options online.
+#
+# http://haproxy.1wt.eu/download/1.4/doc/configuration.txt
+#
+#---------------------------------------------------------------------
+
+#---------------------------------------------------------------------
+# Global settings
+#---------------------------------------------------------------------
global
- log 127.0.0.1 local0
- log 127.0.0.1 local1 notice
- #log loghost local0 info
- maxconn 4096
- chroot /usr/share/haproxy
- uid 99
- gid 99
- daemon
- #debug
- #quiet
-
+ # to have these messages end up in /var/log/haproxy.log you will
+ # need to:
+ #
+ # 1) configure syslog to accept network log events. This is done
+ # by adding the '-r' option to the SYSLOGD_OPTIONS in
+ # /etc/sysconfig/syslog
+ #
+ # 2) configure local2 events to go to the /var/log/haproxy.log
+ # file. A line like the following can be added to
+ # /etc/sysconfig/syslog
+ #
+ # local2.* /var/log/haproxy.log
+ #
+ log 127.0.0.1 local2
+
+ chroot /var/lib/haproxy
+ pidfile /var/run/haproxy.pid
+ maxconn 4000
+ user haproxy
+ group haproxy
+ daemon
+
+ # turn on stats unix socket
+ stats socket /var/lib/haproxy/stats
+
+#---------------------------------------------------------------------
+# common defaults that all the 'listen' and 'backend' sections will
+# use if not designated in their block
+#---------------------------------------------------------------------
defaults
- log global
- mode http
- option httplog
- option dontlognull
- retries 3
- redispatch
- maxconn 2000
- contimeout 5000
- clitimeout 50000
- srvtimeout 50000
-
-listen appli1-rewrite 0.0.0.0:10001
- cookie SERVERID rewrite
- balance roundrobin
- server app1_1 192.168.34.23:8080 cookie app1inst1 check inter 2000 rise 2 fall 5
- server app1_2 192.168.34.32:8080 cookie app1inst2 check inter 2000 rise 2 fall 5
- server app1_3 192.168.34.27:8080 cookie app1inst3 check inter 2000 rise 2 fall 5
- server app1_4 192.168.34.42:8080 cookie app1inst4 check inter 2000 rise 2 fall 5
-
-listen appli2-insert 0.0.0.0:10002
- option httpchk
- balance roundrobin
- cookie SERVERID insert indirect nocache
- server inst1 192.168.114.56:80 cookie server01 check inter 2000 fall 3
- server inst2 192.168.114.56:81 cookie server02 check inter 2000 fall 3
- capture cookie vgnvisitor= len 32
-
- option httpclose # disable keep-alive
- rspidel ^Set-cookie:\ IP= # do not let this cookie tell our internal IP address
-
-listen appli3-relais 0.0.0.0:10003
- dispatch 192.168.135.17:80
-
-listen appli4-backup 0.0.0.0:10004
- option httpchk /index.html
- option persist
- balance roundrobin
- server inst1 192.168.114.56:80 check inter 2000 fall 3
- server inst2 192.168.114.56:81 check inter 2000 fall 3 backup
-
-listen ssl-relay 0.0.0.0:8443
- option ssl-hello-chk
- balance source
- server inst1 192.168.110.56:443 check inter 2000 fall 3
- server inst2 192.168.110.57:443 check inter 2000 fall 3
- server back1 192.168.120.58:443 backup
-
-listen appli5-backup 0.0.0.0:10005
- option httpchk *
- balance roundrobin
- cookie SERVERID insert indirect nocache
- server inst1 192.168.114.56:80 cookie server01 check inter 2000 fall 3
- server inst2 192.168.114.56:81 cookie server02 check inter 2000 fall 3
- server inst3 192.168.114.57:80 backup check inter 2000 fall 3
- capture cookie ASPSESSION len 32
- srvtimeout 20000
-
- option httpclose # disable keep-alive
- option checkcache # block response if set-cookie & cacheable
-
- rspidel ^Set-cookie:\ IP= # do not let this cookie tell our internal IP address
-
- errorloc 502 http://192.168.114.58/error502.html
+ mode http
+ log global
+ option httplog
+ option dontlognull
+ option http-server-close
+ option forwardfor except 127.0.0.0/8
+ option redispatch
+ retries 3
+ timeout http-request 10s
+ timeout queue 1m
+ timeout connect 10s
+ timeout client 1m
+ timeout server 1m
+ timeout http-keep-alive 10s
+ timeout check 10s
+ maxconn 3000
+
+#---------------------------------------------------------------------
+# main frontend which proxys to the backends
+#---------------------------------------------------------------------
+frontend main *:5000
+ acl url_static path_beg -i /static /images /javascript /stylesheets
+ acl url_static path_end -i .jpg .gif .png .css .js
+
+ use_backend static if url_static
+ default_backend app
+
+#---------------------------------------------------------------------
+# static backend for serving up images, stylesheets and such
+#---------------------------------------------------------------------
+backend static
+ balance roundrobin
+ server static 127.0.0.1:4331 check
+
+#---------------------------------------------------------------------
+# round robin balancing between the various backends
+#---------------------------------------------------------------------
+backend app
+ balance roundrobin
+ server app1 127.0.0.1:5001 check
+ server app2 127.0.0.1:5002 check
+ server app3 127.0.0.1:5003 check
+ server app4 127.0.0.1:5004 check
|
[-]
[+]
|
Changed |
haproxy.init
^
|
@@ -1,114 +1,109 @@
#!/bin/sh
#
-# chkconfig: - 85 15
-# description: HA-Proxy is a TCP/HTTP reverse proxy which is particularly suited \
-# for high availability environments.
+# haproxy
+#
+# chkconfig: - 85 15
+# description: HAProxy is a free, very fast and reliable solution \
+# offering high availability, load balancing, and \
+# proxying for TCP and HTTP-based applications
# processname: haproxy
-# config: /etc/haproxy/haproxy.cfg
-# pidfile: /var/run/haproxy.pid
-
-# Script Author: Simon Matter <simon.matter@invoca.ch>
-# Version: 2004060600
+# config: /etc/haproxy/haproxy.cfg
+# pidfile: /var/run/haproxy.pid
# Source function library.
-if [ -f /etc/init.d/functions ]; then
- . /etc/init.d/functions
-elif [ -f /etc/rc.d/init.d/functions ] ; then
- . /etc/rc.d/init.d/functions
-else
- exit 0
-fi
+. /etc/rc.d/init.d/functions
# Source networking configuration.
. /etc/sysconfig/network
# Check that networking is up.
-[ ${NETWORKING} = "no" ] && exit 0
+[ "$NETWORKING" = "no" ] && exit 0
-# This is our service name
-BASENAME=`basename $0`
-if [ -L $0 ]; then
- BASENAME=`find $0 -name $BASENAME -printf %l`
- BASENAME=`basename $BASENAME`
-fi
+exec="/usr/sbin/haproxy"
+prog=$(basename $exec)
-[ -f /etc/$BASENAME/$BASENAME.cfg ] || exit 1
+[ -e /etc/sysconfig/$prog ] && . /etc/sysconfig/$prog
-RETVAL=0
+lockfile=/var/lock/subsys/haproxy
+
+check() {
+ $exec -c -V -f /etc/$prog/$prog.cfg
+}
start() {
- /usr/sbin/$BASENAME -c -q -f /etc/$BASENAME/$BASENAME.cfg
- if [ $? -ne 0 ]; then
- echo "Errors found in configuration file, check it with '$BASENAME check'."
- return 1
- fi
-
- echo -n "Starting $BASENAME: "
- daemon /usr/sbin/$BASENAME -D -f /etc/$BASENAME/$BASENAME.cfg -p /var/run/$BASENAME.pid
- RETVAL=$?
- echo
- [ $RETVAL -eq 0 ] && touch /var/lock/subsys/$BASENAME
- return $RETVAL
+ $exec -c -q -f /etc/$prog/$prog.cfg
+ if [ $? -ne 0 ]; then
+ echo "Errors in configuration file, check with $prog check."
+ return 1
+ fi
+
+ echo -n $"Starting $prog: "
+ # start it up here, usually something like "daemon $exec"
+ daemon $exec -D -f /etc/$prog/$prog.cfg -p /var/run/$prog.pid
+ retval=$?
+ echo
+ [ $retval -eq 0 ] && touch $lockfile
+ return $retval
}
stop() {
- echo -n "Shutting down $BASENAME: "
- killproc $BASENAME -USR1
- RETVAL=$?
- echo
- [ $RETVAL -eq 0 ] && rm -f /var/lock/subsys/$BASENAME
- [ $RETVAL -eq 0 ] && rm -f /var/run/$BASENAME.pid
- return $RETVAL
+ echo -n $"Stopping $prog: "
+ # stop it here, often "killproc $prog"
+ killproc $prog
+ retval=$?
+ echo
+ [ $retval -eq 0 ] && rm -f $lockfile
+ return $retval
}
restart() {
- /usr/sbin/$BASENAME -c -q -f /etc/$BASENAME/$BASENAME.cfg
- if [ $? -ne 0 ]; then
- echo "Errors found in configuration file, check it with '$BASENAME check'."
- return 1
- fi
- stop
- start
+ $exec -c -q -f /etc/$prog/$prog.cfg
+ if [ $? -ne 0 ]; then
+ echo "Errors in configuration file, check with $prog check."
+ return 1
+ fi
+ stop
+ start
}
-check() {
- /usr/sbin/$BASENAME -c -q -V -f /etc/$BASENAME/$BASENAME.cfg
+reload() {
+ $exec -c -q -f /etc/$prog/$prog.cfg
+ if [ $? -ne 0 ]; then
+ echo "Errors in configuration file, check with $prog check."
+ return 1
+ fi
+ echo -n $"Reloading $prog: "
+ $exec -D -f /etc/$prog/$prog.cfg -p /var/run/$prog.pid -sf $(cat /var/run/$prog.pid)
+ retval=$?
+ echo
+ return $retval
}
-rhstatus() {
- status $BASENAME
+force_reload() {
+ restart
}
-condrestart() {
- [ -e /var/lock/subsys/$BASENAME ] && restart || :
+fdr_status() {
+ status $prog
}
-# See how we were called.
case "$1" in
- start)
- start
- ;;
- stop)
- stop
- ;;
- restart)
- restart
- ;;
- reload)
- restart
- ;;
- condrestart)
- condrestart
- ;;
- status)
- rhstatus
- ;;
- check)
- check
- ;;
- *)
- echo $"Usage: $BASENAME {start|stop|restart|reload|condrestart|status|check}"
- RETVAL=1
+ start|stop|restart|reload)
+ $1
+ ;;
+ force-reload)
+ force_reload
+ ;;
+ check)
+ check
+ ;;
+ status)
+ fdr_status
+ ;;
+ condrestart|try-restart)
+ [ ! -f $lockfile ] || restart
+ ;;
+ *)
+ echo $"Usage: $0 {start|stop|status|restart|try-restart|reload|force-reload}"
+ exit 2
esac
-
-exit $RETVAL
|
[-]
[+]
|
Added |
haproxy.logrotate
^
|
@@ -0,0 +1,12 @@
+/var/log/haproxy.log {
+ daily
+ rotate 10
+ missingok
+ notifempty
+ compress
+ sharedscripts
+ postrotate
+ /bin/kill -HUP `cat /var/run/syslogd.pid 2> /dev/null` 2> /dev/null || true
+ /bin/kill -HUP `cat /var/run/rsyslogd.pid 2> /dev/null` 2> /dev/null || true
+ endscript
+}
|