* released 1.1.21

* changed the debug output format so that it now includes the session unique
  ID followed by the instance name at the beginning of each line.
* in debug mode, accept now shows the client's IP and port.
* added one 3 small debugging scripts to search and pretty print debug output
* changed the default health check request to "OPTIONS /" instead of
  "OPTIONS *" since not all servers implement the later one.
* "option httpchk" now accepts an optional parameter allowing the user to
  specify and URI other than '/' during health-checks.
* made Makefile more robust to pcre-config errors
* added 3 new pretty-print scripts : debug2ansi, debug2html and debugfind
* upgraded Formilux package to haproxy-1.1.21-flx.1.pkg
* removed the now obsolete haproxy2html.sh
This commit is contained in:
willy tarreau 2005-12-17 13:57:42 +01:00
parent b1ff9dbde2
commit 2f6ba6579f
11 changed files with 108 additions and 46 deletions

View File

@ -1,6 +1,16 @@
ChangeLog :
===========
2003/05/06 : 1.1.21
- changed the debug output format so that it now includes the session unique
ID followed by the instance name at the beginning of each line.
- in debug mode, accept now shows the client's IP and port.
- added one 3 small debugging scripts to search and pretty print debug output
- changed the default health check request to "OPTIONS /" instead of
"OPTIONS *" since not all servers implement the later one.
- "option httpchk" now accepts an optional parameter allowing the user to
specify and URI other than '/' during health-checks.
2003/04/21 : 1.1.20
- fixed two problems with time-outs, one where a server would be logged as
timed out during transfer that take longer to complete than the fixed

View File

@ -15,7 +15,7 @@ REGEX=libc
#REGEX=pcre
# This is the directory hosting include/pcre.h and lib/libpcre.* when REGEX=pcre
PCREDIR := $(shell pcre-config --prefix 2>/dev/null)
PCREDIR := $(shell pcre-config --prefix 2>/dev/null || :)
#PCREDIR=/usr/local
# This is for Linux 2.4 with netfilter

View File

@ -1,9 +1,9 @@
H A - P r o x y
---------------
version 1.1.18
version 1.1.21
willy tarreau
2003/04/06
2003/05/06
================
| Introduction |
@ -588,14 +588,18 @@ Le mode par d
certains cas de pannes, des serveurs peuvent continuer à accepter les connexions
sans les traiter. Depuis la version 1.1.16, haproxy est en mesure d'envoyer des
requêtes HTTP courtes et très peu coûteuses. Les versions 1.1.16 et 1.1.17
utilisent "OPTIONS / HTTP/1.0". Depuis la version 1.1.18, les requêtes ont été
changées en "OPTIONS * HTTP/1.0" pour des raisons de contrôle d'accès aux
ressources. Elles présentent l'avantage d'être facilement extractibles des logs,
et de ne pas induire d'accès aux fichiers côté serveur. Seules les réponses 2xx
et 3xx sont considérées valides, les autres (y compris non-réponses) aboutissent
à un échec. Le temps maximal imparti pour une réponse est égal à l'intervalle
entre deux tests (paramètre "inter"). Pour activer ce mode, spécifier l'option
"httpchk".
utilisent "OPTIONS / HTTP/1.0". Dans les versions 1.1.18 à 1.1.20, les requêtes
ont été changées en "OPTIONS * HTTP/1.0" pour des raisons de contrôle d'accès aux
ressources. Cependant, cette requête documentée dans la RFC2068 n'est pas
comprise par tous les serveurs. Donc à partir de la version 1.1.21, la requête
par défaut est revenue à "OPTIONS / HTTP/1.0", mais il est possible de
paramétrer la partie URI. Les requêtes OPTIONS présentent l'avantage d'être
facilement extractibles des logs, et de ne pas induire d'accès aux fichiers côté
serveur. Seules les réponses 2xx et 3xx sont considérées valides, les autres (y
compris non-réponses) aboutissent à un échec. Le temps maximal imparti pour une
réponse est égal à l'intervalle entre deux tests (paramètre "inter"). Pour
activer ce mode, spécifier l'option "httpchk", éventuellement suivie d'une
URI. Voir les exemples ci-après.
Depuis la version 1.1.17, il est possible de définir des serveurs de secours,
utilisés uniquement lorsqu'aucun des autres serveurs ne fonctionne. Pour cela,
@ -626,7 +630,7 @@ Exemples :
server web1 192.168.1.1:80 cookie server01 check
server web2 192.168.1.2:80 cookie server02 check inter 500 rise 1 fall 2
# même que précédemment avec surveillance HTTP
# même que précédemment avec surveillance HTTP par 'OPTIONS / HTTP/1.0'
listen http_proxy 0.0.0.0:80
mode http
cookie SERVERID
@ -635,6 +639,15 @@ Exemples :
server web1 192.168.1.1:80 cookie server01 check
server web2 192.168.1.2:80 cookie server02 check inter 500 rise 1 fall 2
# même que précédemment avec surveillance HTTP par 'OPTIONS /index.html HTTP/1.0'
listen http_proxy 0.0.0.0:80
mode http
cookie SERVERID
balance roundrobin
option httpchk /index.html
server web1 192.168.1.1:80 cookie server01 check
server web2 192.168.1.2:80 cookie server02 check inter 500 rise 1 fall 2
# Insertion automatique de cookie dans la réponse du serveur, et suppression
# automatique dans la requête, tout en indiquant aux caches de ne pas garder
# ce cookie.

2
examples/debug2ansi Normal file
View File

@ -0,0 +1,2 @@
#!/bin/sh
tr -d '\015' | sed -e 's,\(: Cookie:.*$\),'$'\e''\[35m\1'$'\e''\[0m,gi' -e 's,\(: Set-Cookie:.*$\),'$'\e''\[31m\1'$'\e''\[0m,gi' -e 's,\(^[^:]*:[^:]*srvhdr.*\)$,'$'\e''\[32m\1'$'\e''\[0m,i' -e 's,\(^[^:]*:[^:]*clihdr.*\)$,'$'\e''\[34m\1'$'\e''\[0m,i'

2
examples/debug2html Normal file
View File

@ -0,0 +1,2 @@
#!/bin/sh
(echo '<html><body><pre>'; tr -d '\015' | sed -e 's,\(: Cookie:.*$\),<font color="#e000c0">\1</font>,gi' -e 's,\(: Set-Cookie:.*$\),<font color="#e0a000">\1</font>,gi' -e 's,\(^[^:]*:[^:]*srvhdr.*\)$,<font color="#00a000">\1</font>,i' -e 's,\(^[^:]*:[^:]*clihdr.*\)$,<font color="#0000c0">\1</font>,i' -e 's,\(^.*\)$,<tt>\1</tt>,' ; echo '</pre></body></html>')

8
examples/debugfind Normal file
View File

@ -0,0 +1,8 @@
#!/bin/bash
if [ $# -lt 2 ]; then
echo "Usage: $0 regex debug_file > extracted_file"
exit 1
fi
word=$1
file=$2
exec grep $(for i in $(grep $word $file |cut -f1 -d: | sort -u ) ; do echo -n '\('$i':\)\|'; done; echo '^$') $file

View File

@ -1,18 +0,0 @@
#!/bin/sh
function do_compile {
$FLXMAKE COPTS="-march=$arch -mcpu=$cpu -O2 -mpreferred-stack-boundary=2 -malign-loops=0 -malign-jumps=0 -DNETFILTER -DTRANSPARENT"
}
function do_prepack {
mkdir -p $ROOTDIR/sbin/init.d ; cp init.d/haproxy $ROOTDIR/sbin/init.d
mkdir -p $ROOTDIR/usr/sbin ; cp haproxy $ROOTDIR/usr/sbin
mkdir -p $ROOTDIR/usr/share/examples/$PKGRADIX-$PKGVER/etc
cp examples/haproxy.cfg $ROOTDIR/usr/share/examples/$PKGRADIX-$PKGVER/etc/haproxy.cfg
cp examples/rc.highsock $ROOTDIR/usr/share/examples/$PKGRADIX-$PKGVER/etc/rc.highsock
cp examples/config.rc.haproxy $ROOTDIR/usr/share/examples/$PKGRADIX-$PKGVER/etc/config.rc.haproxy
mkdir -p $ROOTDIR/usr/share/$PKGRADIX-$PKGVER ; cp doc/haproxy.txt $ROOTDIR/usr/share/$PKGRADIX-$PKGVER
ln -s ../examples/$PKGRADIX-$PKGVER $ROOTDIR/usr/share/$PKGRADIX-$PKGVER/examples
make clean
}

View File

@ -0,0 +1,21 @@
#!/bin/sh
function do_compile {
$FLXMAKE COPTS="-march=$arch -mcpu=$cpu -Os -mpreferred-stack-boundary=2 -momit-leaf-frame-pointer -malign-jumps=0 -DNETFILTER -DTRANSPARENT"
}
function do_prepack {
mkdir -p $ROOTDIR/sbin/init.d ; cp init.d/haproxy $ROOTDIR/sbin/init.d
mkdir -p $ROOTDIR/usr/sbin ; cp haproxy $ROOTDIR/usr/sbin
mkdir -p $ROOTDIR/usr/share/examples/$PKGRADIX/$PKGRADIX-$PKGVER/etc
cp examples/haproxy.cfg $ROOTDIR/usr/share/examples/$PKGRADIX/$PKGRADIX-$PKGVER/etc/haproxy.cfg
cp examples/rc.highsock $ROOTDIR/usr/share/examples/$PKGRADIX/$PKGRADIX-$PKGVER/etc/rc.highsock
cp examples/config.rc.haproxy $ROOTDIR/usr/share/examples/$PKGRADIX/$PKGRADIX-$PKGVER/etc/config.rc.haproxy
mkdir -p $ROOTDIR/usr/share/$PKGRADIX/$PKGRADIX-$PKGVER
cp doc/haproxy.txt $ROOTDIR/usr/share/$PKGRADIX/$PKGRADIX-$PKGVER
ln -s ../../examples/$PKGRADIX/$PKGRADIX-$PKGVER $ROOTDIR/usr/share/$PKGRADIX/$PKGRADIX-$PKGVER/examples
cp examples/debug2ansi examples/debug2html examples/debugfind $ROOTDIR/usr/share/$PKGRADIX/$PKGRADIX-$PKGVER/
make clean
}

View File

@ -70,7 +70,7 @@ listen appli4-backup 0.0.0.0:10004
mode http
option httplog
option dontlognull
option httpchk
option httpchk /index.html
option persist
balance roundrobin
server inst1 192.168.114.56:80 check inter 2000 fall 3
@ -87,7 +87,7 @@ listen appli5-backup 0.0.0.0:10005
mode http
option httplog
option dontlognull
option httpchk
option httpchk *
balance roundrobin
cookie SERVERID insert indirect nocache
server inst1 192.168.114.56:80 cookie server01 check inter 2000 fall 3

View File

@ -1,3 +0,0 @@
#!/bin/sh
#(echo '<html><body>'; sed -e 's,\(ASPSESSIONID[^; ]*\),<font color=red>\1</font>,g' -e 's,\(^srvhdr.*\)$,<font color=blue>\1</font>,' -e 's,\(^clihdr.*\)$,<font color=green>\1</font>,' -e 's,\(^.*\)$,<tt>\1</tt>,' -e 's/$/<br>/' ; echo '</body></html>')
(echo '<html><body>'; tr -d '\015' | sed -e 's,\(: Cookie:.*$\),<font color="#e000c0">\1</font>,gi' -e 's,\(: Set-Cookie:.*$\),<font color="#e0a000">\1</font>,gi' -e 's,\(^srvhdr.*\)$,<font color="#00a000">\1</font>,i' -e 's,\(^clihdr.*\)$,<font color="#0000c0">\1</font>,i' -e 's,\(^.*\)$,<tt>\1</tt>,' -e 's/$/<br>/' ; echo '</body></html>')

View File

@ -53,8 +53,8 @@
#include <linux/netfilter_ipv4.h>
#endif
#define HAPROXY_VERSION "1.1.20"
#define HAPROXY_DATE "2003/04/21"
#define HAPROXY_VERSION "1.1.21"
#define HAPROXY_DATE "2003/05/06"
/* this is for libc5 for example */
#ifndef TCP_NODELAY
@ -94,6 +94,7 @@
#define DEF_CHKINTR 2000
#define DEF_FALLTIME 3
#define DEF_RISETIME 2
#define DEF_CHECK_REQ "OPTIONS / HTTP/1.0\r\n\r\n"
/* default connections limit */
#define DEFAULT_MAXCONN 2000
@ -402,6 +403,7 @@ struct session {
int status; /* HTTP status from the server, negative if from proxy */
long long bytes; /* number of bytes transferred from the server */
} logs;
unsigned int uniq_id; /* unique ID used for the traces */
};
struct proxy {
@ -437,6 +439,8 @@ struct proxy {
struct hdr_exp *rsp_exp; /* regular expressions for response headers */
char *req_add[MAX_NEWHDR], *rsp_add[MAX_NEWHDR]; /* headers to be added */
int grace; /* grace time after stop request */
char *check_req; /* HTTP request to use if PR_O_HTTP_CHK is set, else NULL */
int check_len; /* Length of the HTTP request */
struct {
char *msg400; /* message for error 400 */
int len400; /* message length for error 400 */
@ -1994,6 +1998,8 @@ int event_accept(int fd) {
s->logs.status = -1;
s->logs.bytes = 0;
s->uniq_id = totalconn;
if ((p->mode == PR_MODE_TCP || p->mode == PR_MODE_HTTP)
&& (p->logfac1 >= 0 || p->logfac2 >= 0)) {
struct sockaddr_in sockname;
@ -2020,8 +2026,20 @@ int event_accept(int fd) {
}
if ((global.mode & MODE_DEBUG) && !(global.mode & MODE_QUIET)) {
struct sockaddr_in sockname;
unsigned char *pn, *sn;
int namelen;
int len;
len = sprintf(trash, "accept(%04x)=%04x\n", (unsigned short)fd, (unsigned short)cfd);
namelen = sizeof(sockname);
if (get_original_dst(cfd, (struct sockaddr_in *)&sockname, &namelen) == -1)
getsockname(cfd, (struct sockaddr *)&sockname, &namelen);
sn = (unsigned char *)&sockname.sin_addr;
pn = (unsigned char *)&s->cli_addr.sin_addr;
len = sprintf(trash, "%08x:%s.accept(%04x)=%04x from [%d.%d.%d.%d:%d]\n",
s->uniq_id, p->id, (unsigned short)fd, (unsigned short)cfd,
pn[0], pn[1], pn[2], pn[3], ntohs(s->cli_addr.sin_port));
write(1, trash, len);
}
@ -2108,13 +2126,13 @@ int event_srv_chk_w(int fd) {
else {
if (s->proxy->options & PR_O_HTTP_CHK) {
int ret;
/* we want to check if this host replies to "OPTIONS * HTTP/1.0"
/* we want to check if this host replies to "OPTIONS / HTTP/1.0"
* so we'll send the request, and won't wake the checker up now.
*/
#ifndef MSG_NOSIGNAL
ret = send(fd, "OPTIONS * HTTP/1.0\r\n\r\n", 22, MSG_DONTWAIT);
ret = send(fd, s->proxy->check_req, s->proxy->check_len, MSG_DONTWAIT);
#else
ret = send(fd, "OPTIONS * HTTP/1.0\r\n\r\n", 22, MSG_DONTWAIT | MSG_NOSIGNAL);
ret = send(fd, s->proxy->check_req, s->proxy->check_len, MSG_DONTWAIT | MSG_NOSIGNAL);
#endif
if (ret == 22) {
FD_SET(fd, StaticReadEvent); /* prepare for reading reply */
@ -2399,7 +2417,7 @@ int process_cli(struct session *t) {
if ((global.mode & MODE_DEBUG) && !(global.mode & MODE_QUIET)) {
int len, max;
len = sprintf(trash, "clihdr[%04x:%04x]: ", (unsigned short)t->cli_fd, (unsigned short)t->srv_fd);
len = sprintf(trash, "%08x:%s.clihdr[%04x:%04x]: ", t->uniq_id, t->proxy->id, (unsigned short)t->cli_fd, (unsigned short)t->srv_fd);
max = ptr - req->h;
UBOUND(max, sizeof(trash) - len - 1);
len += strlcpy2(trash + len, req->h, max + 1);
@ -2860,7 +2878,7 @@ int process_cli(struct session *t) {
else { /* CL_STCLOSE: nothing to do */
if ((global.mode & MODE_DEBUG) && !(global.mode & MODE_QUIET)) {
int len;
len = sprintf(trash, "clicls[%04x:%04x]\n", (unsigned short)t->cli_fd, (unsigned short)t->srv_fd);
len = sprintf(trash, "%08x:%s.clicls[%04x:%04x]\n", t->uniq_id, t->proxy->id, (unsigned short)t->cli_fd, (unsigned short)t->srv_fd);
write(1, trash, len);
}
return 0;
@ -3100,7 +3118,7 @@ int process_srv(struct session *t) {
if ((global.mode & MODE_DEBUG) && !(global.mode & MODE_QUIET)) {
int len, max;
len = sprintf(trash, "srvhdr[%04x:%04x]: ", (unsigned short)t->cli_fd, (unsigned short)t->srv_fd);
len = sprintf(trash, "%08x:%s.srvhdr[%04x:%04x]: ", t->uniq_id, t->proxy->id, (unsigned short)t->cli_fd, (unsigned short)t->srv_fd);
max = ptr - rep->h;
UBOUND(max, sizeof(trash) - len - 1);
len += strlcpy2(trash + len, rep->h, max + 1);
@ -3548,7 +3566,7 @@ int process_srv(struct session *t) {
else { /* SV_STCLOSE : nothing to do */
if ((global.mode & MODE_DEBUG) && !(global.mode & MODE_QUIET)) {
int len;
len = sprintf(trash, "srvcls[%04x:%04x]\n", (unsigned short)t->cli_fd, (unsigned short)t->srv_fd);
len = sprintf(trash, "%08x:%s.srvcls[%04x:%04x]\n", t->uniq_id, t->proxy->id, (unsigned short)t->cli_fd, (unsigned short)t->srv_fd);
write(1, trash, len);
}
return 0;
@ -3595,7 +3613,7 @@ int process_session(struct task *t) {
if ((global.mode & MODE_DEBUG) && !(global.mode & MODE_QUIET)) {
int len;
len = sprintf(trash, "closed[%04x:%04x]\n", (unsigned short)s->cli_fd, (unsigned short)s->srv_fd);
len = sprintf(trash, "%08x:%s.closed[%04x:%04x]\n", s->uniq_id, s->proxy->id, (unsigned short)s->cli_fd, (unsigned short)s->srv_fd);
write(1, trash, len);
}
@ -4424,6 +4442,15 @@ int cfg_parse_listen(char *file, int linenum, char **args) {
else if (!strcmp(args[1], "httpchk")) {
/* use HTTP request to check servers' health */
curproxy->options |= PR_O_HTTP_CHK;
if (*args[2]) {
int reqlen = strlen(args[2]) + strlen("OPTIONS / HTTP/1.0\r\n\r\n");
curproxy->check_req = (char *)malloc(reqlen);
curproxy->check_len = snprintf(curproxy->check_req, reqlen,
"OPTIONS %s HTTP/1.0\r\n\r\n", args[2]); /* URI to use */
} else {
curproxy->check_req = strdup(DEF_CHECK_REQ); /* default request */
curproxy->check_len = strlen(DEF_CHECK_REQ);
}
}
else if (!strcmp(args[1], "persist")) {
/* persist on using the server specified by the cookie, even when it's down */