* released 1.1.25
* added the 'tcplog' option, which provides enhanced, HTTP-like logs for
generic TCP proxies, or lighter logs for HTTP proxies.
* fixed a time-out condition wrongly reported as client time-out in data
phase if the client timeout was lower than the connect timeout times the
number of retries.
* doc: added some precisions about the log timers
diff --git a/haproxy.c b/haproxy.c
index ebf2832..ef46dfe 100644
--- a/haproxy.c
+++ b/haproxy.c
@@ -53,8 +53,8 @@
#include <linux/netfilter_ipv4.h>
#endif
-#define HAPROXY_VERSION "1.1.24"
-#define HAPROXY_DATE "2003/09/21"
+#define HAPROXY_VERSION "1.1.25"
+#define HAPROXY_DATE "2003/10/15"
/* this is for libc5 for example */
#ifndef TCP_NODELAY
@@ -664,7 +664,7 @@
void display_version() {
printf("HA-Proxy version " HAPROXY_VERSION " " HAPROXY_DATE"\n");
- printf("Copyright 2000-2002 Willy Tarreau <willy AT meta-x DOT org>\n\n");
+ printf("Copyright 2000-2003 Willy Tarreau <willy AT meta-x DOT org>\n\n");
}
/*
@@ -1947,6 +1947,7 @@
char *uri;
char *pxid;
char *srv;
+ struct tm *tm;
/* This is a first attempt at a better logging system.
* For now, we rely on send_log() to provide the date, although it obviously
@@ -1960,14 +1961,12 @@
(unsigned char *)&s->cli_addr.sin_addr :
(unsigned char *)"\0\0\0\0";
- uri = (log & LW_REQ) ? s->logs.uri : "<BADREQ>";
+ uri = (log & LW_REQ) ? s->logs.uri ? s->logs.uri : "<BADREQ>" : "";
pxid = p->id;
- //srv = (log & LW_SVID) ? s->srv->id : "<svid>";
- srv = ((p->to_log & LW_SVID) && s->srv != NULL) ? s->srv->id : "<NOSRV>";
+ srv = (p->to_log & LW_SVID) ? (s->srv != NULL) ? s->srv->id : "<NOSRV>" : "-";
- if (p->to_log & LW_DATE) {
- struct tm *tm = localtime(&s->logs.tv_accept.tv_sec);
-
+ tm = localtime(&s->logs.tv_accept.tv_sec);
+ if (p->to_log & LW_REQ) {
send_log(p, LOG_INFO, "%d.%d.%d.%d:%d [%02d/%s/%04d:%02d:%02d:%02d] %s %s %d/%d/%d/%d %d %lld %s %s %c%c%c%c \"%s\"\n",
pn[0], pn[1], pn[2], pn[3], ntohs(s->cli_addr.sin_port),
tm->tm_mday, monthname[tm->tm_mon], tm->tm_year+1900,
@@ -1987,21 +1986,16 @@
uri);
}
else {
- send_log(p, LOG_INFO, "%d.%d.%d.%d:%d %s %s %d/%d/%d/%d %d %lld %s %s %c%c%c%c \"%s\"\n",
+ send_log(p, LOG_INFO, "%d.%d.%d.%d:%d [%02d/%s/%04d:%02d:%02d:%02d] %s %s %d/%d %lld %c%c\n",
pn[0], pn[1], pn[2], pn[3], ntohs(s->cli_addr.sin_port),
+ tm->tm_mday, monthname[tm->tm_mon], tm->tm_year+1900,
+ tm->tm_hour, tm->tm_min, tm->tm_sec,
pxid, srv,
- s->logs.t_request,
- (s->logs.t_connect >= 0) ? s->logs.t_connect - s->logs.t_request : -1,
- (s->logs.t_data >= 0) ? s->logs.t_data - s->logs.t_connect : -1,
+ (s->logs.t_connect >= 0) ? s->logs.t_connect : -1,
s->logs.t_close,
- s->logs.status, s->logs.bytes,
- s->logs.cli_cookie ? s->logs.cli_cookie : "-",
- s->logs.srv_cookie ? s->logs.srv_cookie : "-",
+ s->logs.bytes,
sess_term_cond[(s->flags & SN_ERR_MASK) >> SN_ERR_SHIFT],
- sess_fin_state[(s->flags & SN_FINST_MASK) >> SN_FINST_SHIFT],
- (p->options & PR_O_COOK_ANY) ? sess_cookie[(s->flags & SN_CK_MASK) >> SN_CK_SHIFT] : '-',
- (p->options & PR_O_COOK_ANY) ? sess_set_cookie[(s->flags & SN_SCK_MASK) >> SN_SCK_SHIFT] : '-',
- uri);
+ sess_fin_state[(s->flags & SN_FINST_MASK) >> SN_FINST_SHIFT]);
}
s->logs.logwait = 0;
@@ -2793,6 +2787,11 @@
}
else if (c == CL_STDATA) {
process_data:
+ /* FIXME: this error handling is partly buggy because we always report
+ * a 'DATA' phase while we don't know if the server was in IDLE, CONN
+ * or HEADER phase. BTW, it's not logical to expire the client while
+ * we're waiting for the server to connect.
+ */
/* read or write error */
if (t->res_cw == RES_ERROR || t->res_cr == RES_ERROR) {
tv_eternity(&t->crexpire);
@@ -2808,8 +2807,6 @@
/* last read, or end of server write */
else if (t->res_cr == RES_NULL || s == SV_STSHUTW || s == SV_STCLOSE) {
FD_CLR(t->cli_fd, StaticReadEvent);
- // if (req->l == 0) /* nothing to write on the server side */
- // FD_CLR(t->srv_fd, StaticWriteEvent);
tv_eternity(&t->crexpire);
shutdown(t->cli_fd, SHUT_RD);
t->cli_state = CL_STSHUTR;
@@ -2826,8 +2823,6 @@
/* read timeout */
else if (tv_cmp2_ms(&t->crexpire, &now) <= 0) {
FD_CLR(t->cli_fd, StaticReadEvent);
- // if (req->l == 0) /* nothing to write on the server side */
- // FD_CLR(t->srv_fd, StaticWriteEvent);
tv_eternity(&t->crexpire);
shutdown(t->cli_fd, SHUT_RD);
t->cli_state = CL_STSHUTR;
@@ -2850,8 +2845,8 @@
return 1;
}
- if (req->l >= req->rlim - req->data) {
- /* no room to read more data */
+ if (req->l >= req->rlim - req->data || t->srv_state < SV_STDATA) {
+ /* no room to read more data, or server not ready yet */
if (FD_ISSET(t->cli_fd, StaticReadEvent)) {
/* stop reading until we get some space */
FD_CLR(t->cli_fd, StaticReadEvent);
@@ -2870,7 +2865,7 @@
}
if ((rep->l == 0) ||
- ((s == SV_STHEADERS) /* FIXME: this may be optimized && (rep->w == rep->h)*/)) {
+ ((s < SV_STDATA) /* FIXME: this may be optimized && (rep->w == rep->h)*/)) {
if (FD_ISSET(t->cli_fd, StaticWriteEvent)) {
FD_CLR(t->cli_fd, StaticWriteEvent); /* stop writing */
tv_eternity(&t->cwexpire);
@@ -4672,10 +4667,12 @@
else if (!strcmp(args[1], "forwardfor"))
/* insert x-forwarded-for field */
curproxy->options |= PR_O_FWDFOR;
- else if (!strcmp(args[1], "httplog")) {
+ else if (!strcmp(args[1], "httplog"))
/* generate a complete HTTP log */
curproxy->to_log |= LW_DATE | LW_CLIP | LW_SVID | LW_REQ | LW_PXID | LW_RESP;
- }
+ else if (!strcmp(args[1], "tcplog"))
+ /* generate a detailed TCP log */
+ curproxy->to_log |= LW_DATE | LW_CLIP | LW_SVID | LW_PXID;
else if (!strcmp(args[1], "dontlognull")) {
/* don't log empty requests */
curproxy->options |= PR_O_NULLNOLOG;