Le mercredi 14 octobre 2009 22:39:39, Willy Tarreau a écrit :
> > > Do it for either 1.3 or 1.4, I'll do the back/forward port. If you
> > > prefer to proceed on both, of course feel free to do so :-)
> >
> > I can do both, this will let you work on something else ;)
>
> Nice, I appreciate it.
OK, here comes the 2 patch files for haproxy-1.3.21 and haproxy-1.4-dev4.
Please note 3 minor changes in those versions (proto_http.c / proto_http.h) :
1. void manage_client_side_appsession(struct session *t, char *buf);
becomes
void manage_client_side_appsession(struct session *t, const char *buf);
2. An unused variable in get_srv_from_appsession(...) has been removed.
3. After some more tests, I've applied a fix on request_count (used for debug)
to have nearly the same behaviour in normal mode and "request-learn" mode.
--
Cyril Bonté
diff -Naur haproxy-1.4-dev4/include/proto/proto_http.h haproxy-1.4-dev4-appsession-final/include/proto/proto_http.h
--- haproxy-1.4-dev4/include/proto/proto_http.h 2009-10-12 06:40:53.000000000 +0200
+++ haproxy-1.4-dev4-appsession-final/include/proto/proto_http.h 2009-10-14 22:55:55.000000000 +0200
@@ -74,6 +74,7 @@
int apply_filter_to_req_line(struct session *t, struct buffer *req, struct hdr_exp *exp);
int apply_filters_to_request(struct session *t, struct buffer *req, struct hdr_exp *exp);
int apply_filters_to_response(struct session *t, struct buffer *rtr, struct hdr_exp *exp);
+void manage_client_side_appsession(struct session *t, const char *buf);
void manage_client_side_cookies(struct session *t, struct buffer *req);
void manage_server_side_cookies(struct session *t, struct buffer *rtr);
void check_response_for_cacheability(struct session *t, struct buffer *rtr);
diff -Naur haproxy-1.4-dev4/include/types/proxy.h haproxy-1.4-dev4-appsession-final/include/types/proxy.h
--- haproxy-1.4-dev4/include/types/proxy.h 2009-10-12 06:40:53.000000000 +0200
+++ haproxy-1.4-dev4-appsession-final/include/types/proxy.h 2009-10-12 21:24:42.000000000 +0200
@@ -124,6 +124,9 @@
#define PR_O2_INDEPSTR 0x00001000 /* independant streams, don't update rex on write */
#define PR_O2_SOCKSTAT 0x00002000 /* collect & provide separate statistics for sockets */
+/* bits for proxy->appsession_options */
+#define PR_O_AS_REQL 0x00000001 /* learn the session id from the request */
+
struct error_snapshot {
struct timeval when; /* date of this event, (tv_sec == 0) means "never" */
unsigned int len; /* original length of the last invalid request/response */
@@ -177,6 +180,7 @@
char *appsession_name; /* name of the cookie to look for */
int appsession_name_len; /* strlen(appsession_name), computed only once */
int appsession_len; /* length of the appsession cookie value to be used */
+ int appsession_options; /* options for appsession */
struct appsession_hash htbl_proxy; /* Per Proxy hashtable */
char *capture_name; /* beginning of the name of the cookie to capture */
int capture_namelen; /* length of the cookie name to match */
diff -Naur haproxy-1.4-dev4/include/types/session.h haproxy-1.4-dev4-appsession-final/include/types/session.h
--- haproxy-1.4-dev4/include/types/session.h 2009-10-12 06:40:53.000000000 +0200
+++ haproxy-1.4-dev4-appsession-final/include/types/session.h 2009-10-12 21:25:15.000000000 +0200
@@ -162,6 +162,7 @@
int conn_retries; /* number of connect retries left */
int flags; /* some flags describing the session */
unsigned term_trace; /* term trace: 4*8 bits indicating which part of the code closed */
+ char *sessid; /* the session id, if found in the request or in the response */
struct buffer *req; /* request buffer */
struct buffer *rep; /* response buffer */
struct stream_interface si[2]; /* client and server stream interfaces */
diff -Naur haproxy-1.4-dev4/src/cfgparse.c haproxy-1.4-dev4-appsession-final/src/cfgparse.c
--- haproxy-1.4-dev4/src/cfgparse.c 2009-10-12 06:40:53.000000000 +0200
+++ haproxy-1.4-dev4-appsession-final/src/cfgparse.c 2009-10-12 21:26:10.000000000 +0200
@@ -1517,6 +1517,7 @@
}
}
else if (!strcmp(args[0], "appsession")) { /* cookie name */
+ int cur_arg;
if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
err_code |= ERR_WARN;
@@ -1546,6 +1547,14 @@
err_code |= ERR_ALERT | ERR_ABORT;
goto out;
}
+
+ cur_arg = 6;
+ while (*(args[cur_arg])) {
+ if (!strcmp(args[cur_arg], "request-learn")) {
+ curproxy->appsession_options |= PR_O_AS_REQL;
+ }
+ cur_arg++;
+ }
} /* Url App Session */
else if (!strcmp(args[0], "capture")) {
if (warnifnotcap(curproxy, PR_CAP_FE, file, linenum, args[0], NULL))
diff -Naur haproxy-1.4-dev4/src/client.c haproxy-1.4-dev4-appsession-final/src/client.c
--- haproxy-1.4-dev4/src/client.c 2009-10-12 06:40:53.000000000 +0200
+++ haproxy-1.4-dev4-appsession-final/src/client.c 2009-10-12 21:26:38.000000000 +0200
@@ -184,7 +184,7 @@
*/
s->be = s->fe = p;
- s->req = s->rep = NULL; /* will be allocated later */
+ s->sessid = s->req = s->rep = NULL; /* will be allocated later */
s->si[0].state = s->si[0].prev_state = SI_ST_EST;
s->si[0].err_type = SI_ET_NONE;
diff -Naur haproxy-1.4-dev4/src/proto_http.c haproxy-1.4-dev4-appsession-final/src/proto_http.c
--- haproxy-1.4-dev4/src/proto_http.c 2009-10-12 06:40:53.000000000 +0200
+++ haproxy-1.4-dev4-appsession-final/src/proto_http.c 2009-10-14 23:38:28.000000000 +0200
@@ -3557,6 +3557,73 @@
/*
+ * Try to retrieve the server associated to the appsession.
+ * If the server is found, it's assigned to the session.
+ */
+void manage_client_side_appsession(struct session *t, const char *buf) {
+ struct http_txn *txn = &t->txn;
+ appsess *asession = NULL;
+ char *sessid_temp = NULL;
+
+ if (t->be->appsession_options & PR_O_AS_REQL) {
+ /* request-learn option is enabled : store the sessid in the session for future use */
+ if (t->sessid != NULL) {
+ /* free previously allocated memory as we don't need the session id found in the URL anymore */
+ pool_free2(apools.sessid, t->sessid);
+ }
+
+ if ((t->sessid = pool_alloc2(apools.sessid)) == NULL) {
+ Alert("Not enough memory process_cli():asession->sessid:malloc().\n");
+ send_log(t->be, LOG_ALERT, "Not enough memory process_cli():asession->sessid:malloc().\n");
+ return;
+ }
+
+ memcpy(t->sessid, buf, t->be->appsession_len);
+ t->sessid[t->be->appsession_len] = 0;
+ }
+
+ if ((sessid_temp = pool_alloc2(apools.sessid)) == NULL) {
+ Alert("Not enough memory process_cli():asession->sessid:malloc().\n");
+ send_log(t->be, LOG_ALERT, "Not enough memory process_cli():asession->sessid:malloc().\n");
+ return;
+ }
+
+ memcpy(sessid_temp, buf, t->be->appsession_len);
+ sessid_temp[t->be->appsession_len] = 0;
+
+ asession = appsession_hash_lookup(&(t->be->htbl_proxy), sessid_temp);
+ /* free previously allocated memory */
+ pool_free2(apools.sessid, sessid_temp);
+
+ if (asession != NULL) {
+ asession->expire = tick_add_ifset(now_ms, t->be->timeout.appsession);
+ if (!(t->be->appsession_options & PR_O_AS_REQL)) {
+ asession->request_count++;
+ }
+
+ if (asession->serverid != NULL) {
+ struct server *srv = t->be->srv;
+ while (srv) {
+ if (strcmp(srv->id, asession->serverid) == 0) {
+ if (srv->state & SRV_RUNNING || t->be->options & PR_O_PERSIST) {
+ /* we found the server and it's usable */
+ txn->flags &= ~TX_CK_MASK;
+ txn->flags |= TX_CK_VALID;
+ t->flags |= SN_DIRECT | SN_ASSIGNED;
+ t->srv = srv;
+ break;
+ } else {
+ txn->flags &= ~TX_CK_MASK;
+ txn->flags |= TX_CK_DOWN;
+ }
+ }
+ srv = srv->next;
+ }
+ }
+ }
+}
+
+/*
* Manage client-side cookie. It can impact performance by about 2% so it is
* desirable to call it only when needed.
*/
@@ -3567,9 +3634,6 @@
char *del_colon, *del_cookie, *colon;
int app_cookies;
- appsess *asession_temp = NULL;
- appsess local_asession;
-
char *cur_ptr, *cur_end, *cur_next;
int cur_idx, old_idx;
@@ -3799,63 +3863,7 @@
/* first, let's see if the cookie is our appcookie*/
/* Cool... it's the right one */
-
- asession_temp = &local_asession;
-
- if ((asession_temp->sessid = pool_alloc2(apools.sessid)) == NULL) {
- Alert("Not enough memory process_cli():asession->sessid:malloc().\n");
- send_log(t->be, LOG_ALERT, "Not enough memory process_cli():asession->sessid:malloc().\n");
- return;
- }
-
- memcpy(asession_temp->sessid, p3, t->be->appsession_len);
- asession_temp->sessid[t->be->appsession_len] = 0;
- asession_temp->serverid = NULL;
-
- /* only do insert, if lookup fails */
- asession_temp = appsession_hash_lookup(&(t->be->htbl_proxy), asession_temp->sessid);
- if (asession_temp == NULL) {
- if ((asession_temp = pool_alloc2(pool2_appsess)) == NULL) {
- /* free previously allocated memory */
- pool_free2(apools.sessid, local_asession.sessid);
- Alert("Not enough memory process_cli():asession:calloc().\n");
- send_log(t->be, LOG_ALERT, "Not enough memory process_cli():asession:calloc().\n");
- return;
- }
-
- asession_temp->sessid = local_asession.sessid;
- asession_temp->serverid = local_asession.serverid;
- asession_temp->request_count = 0;
- appsession_hash_insert(&(t->be->htbl_proxy), asession_temp);
- } else {
- /* free previously allocated memory */
- pool_free2(apools.sessid, local_asession.sessid);
- }
- if (asession_temp->serverid == NULL) {
- /* TODO redispatch request */
- Alert("Found Application Session without matching server.\n");
- } else {
- struct server *srv = t->be->srv;
- while (srv) {
- if (strcmp(srv->id, asession_temp->serverid) == 0) {
- if (srv->state & SRV_RUNNING || t->be->options & PR_O_PERSIST) {
- /* we found the server and it's usable */
- txn->flags &= ~TX_CK_MASK;
- txn->flags |= TX_CK_VALID;
- t->flags |= SN_DIRECT | SN_ASSIGNED;
- t->srv = srv;
- break;
- } else {
- txn->flags &= ~TX_CK_MASK;
- txn->flags |= TX_CK_DOWN;
- }
- }
- srv = srv->next;
- }/* end while(srv) */
- }/* end else if server == NULL */
-
- asession_temp->expire = tick_add_ifset(now_ms, t->be->timeout.appsession);
- asession_temp->request_count++;
+ manage_client_side_appsession(t, p3);
#if defined(DEBUG_HASH)
Alert("manage_client_side_cookies\n");
appsession_hash_dump(&(t->be->htbl_proxy));
@@ -4133,9 +4141,6 @@
struct http_txn *txn = &t->txn;
char *p1, *p2, *p3, *p4;
- appsess *asession_temp = NULL;
- appsess local_asession;
-
char *cur_ptr, *cur_end, *cur_next;
int cur_idx, old_idx, delta;
@@ -4276,60 +4281,64 @@
/* Cool... it's the right one */
- size_t server_id_len = strlen(t->srv->id) + 1;
- asession_temp = &local_asession;
-
- if ((asession_temp->sessid = pool_alloc2(apools.sessid)) == NULL) {
+ if (t->sessid != NULL) {
+ /* free previously allocated memory as we don't need it anymore */
+ pool_free2(apools.sessid, t->sessid);
+ }
+ /* Store the sessid in the session for future use */
+ if ((t->sessid = pool_alloc2(apools.sessid)) == NULL) {
Alert("Not enough Memory process_srv():asession->sessid:malloc().\n");
send_log(t->be, LOG_ALERT, "Not enough Memory process_srv():asession->sessid:malloc().\n");
return;
}
- memcpy(asession_temp->sessid, p3, t->be->appsession_len);
- asession_temp->sessid[t->be->appsession_len] = 0;
- asession_temp->serverid = NULL;
-
- /* only do insert, if lookup fails */
- asession_temp = appsession_hash_lookup(&(t->be->htbl_proxy), asession_temp->sessid);
- if (asession_temp == NULL) {
- if ((asession_temp = pool_alloc2(pool2_appsess)) == NULL) {
- Alert("Not enough Memory process_srv():asession:calloc().\n");
- send_log(t->be, LOG_ALERT, "Not enough Memory process_srv():asession:calloc().\n");
- return;
- }
- asession_temp->sessid = local_asession.sessid;
- asession_temp->serverid = local_asession.serverid;
- asession_temp->request_count = 0;
- appsession_hash_insert(&(t->be->htbl_proxy), asession_temp);
- } else {
- /* free wasted memory */
- pool_free2(apools.sessid, local_asession.sessid);
- }
-
- if (asession_temp->serverid == NULL) {
- if ((asession_temp->serverid = pool_alloc2(apools.serverid)) == NULL) {
- Alert("Not enough Memory process_srv():asession->sessid:malloc().\n");
- send_log(t->be, LOG_ALERT, "Not enough Memory process_srv():asession->sessid:malloc().\n");
- return;
- }
- asession_temp->serverid[0] = '\0';
- }
-
- if (asession_temp->serverid[0] == '\0')
- memcpy(asession_temp->serverid, t->srv->id, server_id_len);
-
- asession_temp->expire = tick_add_ifset(now_ms, t->be->timeout.appsession);
- asession_temp->request_count++;
-#if defined(DEBUG_HASH)
- Alert("manage_server_side_cookies\n");
- appsession_hash_dump(&(t->be->htbl_proxy));
-#endif
+ memcpy(t->sessid, p3, t->be->appsession_len);
+ t->sessid[t->be->appsession_len] = 0;
}/* end if ((t->proxy->appsession_name != NULL) ... */
break; /* we don't want to loop again since there cannot be another cookie on the same line */
} /* we're now at the end of the cookie value */
-
/* keep the link from this header to next one */
old_idx = cur_idx;
} /* end of cookie processing on this header */
+
+ if (t->sessid != NULL) {
+ appsess *asession = NULL;
+ /* only do insert, if lookup fails */
+ asession = appsession_hash_lookup(&(t->be->htbl_proxy), t->sessid);
+ if (asession == NULL) {
+ if ((asession = pool_alloc2(pool2_appsess)) == NULL) {
+ Alert("Not enough Memory process_srv():asession:calloc().\n");
+ send_log(t->be, LOG_ALERT, "Not enough Memory process_srv():asession:calloc().\n");
+ return;
+ }
+ if ((asession->sessid = pool_alloc2(apools.sessid)) == NULL) {
+ Alert("Not enough Memory process_srv():asession->sessid:malloc().\n");
+ send_log(t->be, LOG_ALERT, "Not enough Memory process_srv():asession->sessid:malloc().\n");
+ return;
+ }
+ memcpy(asession->sessid, t->sessid, t->be->appsession_len);
+ asession->sessid[t->be->appsession_len] = 0;
+
+ size_t server_id_len = strlen(t->srv->id) + 1;
+ if ((asession->serverid = pool_alloc2(apools.serverid)) == NULL) {
+ Alert("Not enough Memory process_srv():asession->sessid:malloc().\n");
+ send_log(t->be, LOG_ALERT, "Not enough Memory process_srv():asession->sessid:malloc().\n");
+ return;
+ }
+ asession->serverid[0] = '\0';
+ memcpy(asession->serverid, t->srv->id, server_id_len);
+
+ asession->request_count = 0;
+ appsession_hash_insert(&(t->be->htbl_proxy), asession);
+ }
+
+ asession->expire = tick_add_ifset(now_ms, t->be->timeout.appsession);
+ asession->request_count++;
+ }
+
+#if defined(DEBUG_HASH)
+ Alert("manage_server_side_cookies\n");
+ appsession_hash_dump(&(t->be->htbl_proxy));
+#endif
}
@@ -4427,9 +4436,6 @@
*/
void get_srv_from_appsession(struct session *t, const char *begin, int len)
{
- struct http_txn *txn = &t->txn;
- appsess *asession_temp = NULL;
- appsess local_asession;
char *request_line;
if (t->be->appsession_name == NULL ||
@@ -4448,69 +4454,11 @@
/* skip jsessionid= */
request_line += t->be->appsession_name_len + 1;
- /* First try if we already have an appsession */
- asession_temp = &local_asession;
-
- if ((asession_temp->sessid = pool_alloc2(apools.sessid)) == NULL) {
- Alert("Not enough memory process_cli():asession_temp->sessid:calloc().\n");
- send_log(t->be, LOG_ALERT, "Not enough Memory process_cli():asession_temp->sessid:calloc().\n");
- return;
- }
-
- /* Copy the sessionid */
- memcpy(asession_temp->sessid, request_line, t->be->appsession_len);
- asession_temp->sessid[t->be->appsession_len] = 0;
- asession_temp->serverid = NULL;
-
- /* only do insert, if lookup fails */
- asession_temp = appsession_hash_lookup(&(t->be->htbl_proxy), asession_temp->sessid);
- if (asession_temp == NULL) {
- if ((asession_temp = pool_alloc2(pool2_appsess)) == NULL) {
- /* free previously allocated memory */
- pool_free2(apools.sessid, local_asession.sessid);
- Alert("Not enough memory process_cli():asession:calloc().\n");
- send_log(t->be, LOG_ALERT, "Not enough memory process_cli():asession:calloc().\n");
- return;
- }
- asession_temp->sessid = local_asession.sessid;
- asession_temp->serverid = local_asession.serverid;
- asession_temp->request_count=0;
- appsession_hash_insert(&(t->be->htbl_proxy), asession_temp);
- }
- else {
- /* free previously allocated memory */
- pool_free2(apools.sessid, local_asession.sessid);
- }
-
- asession_temp->expire = tick_add_ifset(now_ms, t->be->timeout.appsession);
- asession_temp->request_count++;
-
+ manage_client_side_appsession(t, request_line);
#if defined(DEBUG_HASH)
Alert("get_srv_from_appsession\n");
appsession_hash_dump(&(t->be->htbl_proxy));
#endif
- if (asession_temp->serverid == NULL) {
- /* TODO redispatch request */
- Alert("Found Application Session without matching server.\n");
- } else {
- struct server *srv = t->be->srv;
- while (srv) {
- if (strcmp(srv->id, asession_temp->serverid) == 0) {
- if (srv->state & SRV_RUNNING || t->be->options & PR_O_PERSIST) {
- /* we found the server and it's usable */
- txn->flags &= ~TX_CK_MASK;
- txn->flags |= TX_CK_VALID;
- t->flags |= SN_DIRECT | SN_ASSIGNED;
- t->srv = srv;
- break;
- } else {
- txn->flags &= ~TX_CK_MASK;
- txn->flags |= TX_CK_DOWN;
- }
- }
- srv = srv->next;
- }
- }
}
diff -Naur haproxy-1.4-dev4/src/session.c haproxy-1.4-dev4-appsession-final/src/session.c
--- haproxy-1.4-dev4/src/session.c 2009-10-12 06:40:53.000000000 +0200
+++ haproxy-1.4-dev4-appsession-final/src/session.c 2009-10-12 21:41:23.000000000 +0200
@@ -77,6 +77,9 @@
pool_free2(pool2_buffer, s->req);
pool_free2(pool2_buffer, s->rep);
+ if (s->sessid)
+ pool_free2(apools.sessid, s->sessid);
+
if (fe) {
pool_free2(fe->hdr_idx_pool, txn->hdr_idx.v);
diff -Naur haproxy-1.3.21/include/proto/proto_http.h haproxy-1.3.21-appsession-final/include/proto/proto_http.h
--- haproxy-1.3.21/include/proto/proto_http.h 2009-10-12 06:20:09.000000000 +0200
+++ haproxy-1.3.21-appsession-final/include/proto/proto_http.h 2009-10-14 23:12:55.000000000 +0200
@@ -75,6 +75,7 @@
int apply_filter_to_req_line(struct session *t, struct buffer *req, struct hdr_exp *exp);
int apply_filters_to_request(struct session *t, struct buffer *req, struct hdr_exp *exp);
int apply_filters_to_response(struct session *t, struct buffer *rtr, struct hdr_exp *exp);
+void manage_client_side_appsession(struct session *t, const char *buf);
void manage_client_side_cookies(struct session *t, struct buffer *req);
void manage_server_side_cookies(struct session *t, struct buffer *rtr);
void check_response_for_cacheability(struct session *t, struct buffer *rtr);
diff -Naur haproxy-1.3.21/include/types/proxy.h haproxy-1.3.21-appsession-final/include/types/proxy.h
--- haproxy-1.3.21/include/types/proxy.h 2009-10-12 06:20:09.000000000 +0200
+++ haproxy-1.3.21-appsession-final/include/types/proxy.h 2009-10-14 22:58:41.000000000 +0200
@@ -120,6 +120,9 @@
/* 0x80..0x800 already used in 1.4 */
#define PR_O2_INDEPSTR 0x00001000 /* independant streams, don't update rex on write */
+/* bits for proxy->appsession_options */
+#define PR_O_AS_REQL 0x00000001 /* learn the session id from the request */
+
/* This structure is used to apply fast weighted round robin on a server group */
struct fwrr_group {
struct eb_root curr; /* tree for servers in "current" time range */
@@ -207,6 +210,7 @@
char *appsession_name; /* name of the cookie to look for */
int appsession_name_len; /* strlen(appsession_name), computed only once */
int appsession_len; /* length of the appsession cookie value to be used */
+ int appsession_options; /* options for appsession */
struct appsession_hash htbl_proxy; /* Per Proxy hashtable */
char *capture_name; /* beginning of the name of the cookie to capture */
int capture_namelen; /* length of the cookie name to match */
diff -Naur haproxy-1.3.21/include/types/session.h haproxy-1.3.21-appsession-final/include/types/session.h
--- haproxy-1.3.21/include/types/session.h 2009-10-12 06:20:09.000000000 +0200
+++ haproxy-1.3.21-appsession-final/include/types/session.h 2009-10-14 22:59:06.000000000 +0200
@@ -162,6 +162,7 @@
int conn_retries; /* number of connect retries left */
int flags; /* some flags describing the session */
unsigned term_trace; /* term trace: 4*8 bits indicating which part of the code closed */
+ char *sessid; /* the session id, if found in the request or in the response */
struct buffer *req; /* request buffer */
struct buffer *rep; /* response buffer */
struct stream_interface si[2]; /* client and server stream interfaces */
diff -Naur haproxy-1.3.21/src/cfgparse.c haproxy-1.3.21-appsession-final/src/cfgparse.c
--- haproxy-1.3.21/src/cfgparse.c 2009-10-12 06:20:09.000000000 +0200
+++ haproxy-1.3.21-appsession-final/src/cfgparse.c 2009-10-14 23:00:08.000000000 +0200
@@ -1326,6 +1326,7 @@
}
}/* end else if (!strcmp(args[0], "cookie")) */
else if (!strcmp(args[0], "appsession")) { /* cookie name */
+ int cur_arg;
if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
err_code |= ERR_WARN;
@@ -1355,6 +1356,14 @@
err_code |= ERR_ALERT | ERR_ABORT;
goto out;
}
+
+ cur_arg = 6;
+ while (*(args[cur_arg])) {
+ if (!strcmp(args[cur_arg], "request-learn")) {
+ curproxy->appsession_options |= PR_O_AS_REQL;
+ }
+ cur_arg++;
+ }
} /* Url App Session */
else if (!strcmp(args[0], "capture")) {
if (warnifnotcap(curproxy, PR_CAP_FE, file, linenum, args[0], NULL))
diff -Naur haproxy-1.3.21/src/client.c haproxy-1.3.21-appsession-final/src/client.c
--- haproxy-1.3.21/src/client.c 2009-10-12 06:20:09.000000000 +0200
+++ haproxy-1.3.21-appsession-final/src/client.c 2009-10-14 23:00:49.000000000 +0200
@@ -179,7 +179,7 @@
}
s->ana_state = 0; /* analysers may change it but must reset it upon exit */
- s->req = s->rep = NULL; /* will be allocated later */
+ s->sessid = s->req = s->rep = NULL; /* will be allocated later */
s->si[0].state = s->si[0].prev_state = SI_ST_EST;
s->si[0].err_type = SI_ET_NONE;
diff -Naur haproxy-1.3.21/src/proto_http.c haproxy-1.3.21-appsession-final/src/proto_http.c
--- haproxy-1.3.21/src/proto_http.c 2009-10-12 06:20:09.000000000 +0200
+++ haproxy-1.3.21-appsession-final/src/proto_http.c 2009-10-14 23:46:44.000000000 +0200
@@ -3368,6 +3368,73 @@
/*
+ * Try to retrieve the server associated to the appsession.
+ * If the server is found, it's assigned to the session.
+ */
+void manage_client_side_appsession(struct session *t, const char *buf) {
+ struct http_txn *txn = &t->txn;
+ appsess *asession = NULL;
+ char *sessid_temp = NULL;
+
+ if (t->be->appsession_options & PR_O_AS_REQL) {
+ /* request-learn option is enabled : store the sessid in the session for future use */
+ if (t->sessid != NULL) {
+ /* free previously allocated memory as we don't need the session id found in the URL anymore */
+ pool_free2(apools.sessid, t->sessid);
+ }
+
+ if ((t->sessid = pool_alloc2(apools.sessid)) == NULL) {
+ Alert("Not enough memory process_cli():asession->sessid:malloc().\n");
+ send_log(t->be, LOG_ALERT, "Not enough memory process_cli():asession->sessid:malloc().\n");
+ return;
+ }
+
+ memcpy(t->sessid, buf, t->be->appsession_len);
+ t->sessid[t->be->appsession_len] = 0;
+ }
+
+ if ((sessid_temp = pool_alloc2(apools.sessid)) == NULL) {
+ Alert("Not enough memory process_cli():asession->sessid:malloc().\n");
+ send_log(t->be, LOG_ALERT, "Not enough memory process_cli():asession->sessid:malloc().\n");
+ return;
+ }
+
+ memcpy(sessid_temp, buf, t->be->appsession_len);
+ sessid_temp[t->be->appsession_len] = 0;
+
+ asession = appsession_hash_lookup(&(t->be->htbl_proxy), sessid_temp);
+ /* free previously allocated memory */
+ pool_free2(apools.sessid, sessid_temp);
+
+ if (asession != NULL) {
+ asession->expire = tick_add_ifset(now_ms, t->be->timeout.appsession);
+ if (!(t->be->appsession_options & PR_O_AS_REQL)) {
+ asession->request_count++;
+ }
+
+ if (asession->serverid != NULL) {
+ struct server *srv = t->be->srv;
+ while (srv) {
+ if (strcmp(srv->id, asession->serverid) == 0) {
+ if (srv->state & SRV_RUNNING || t->be->options & PR_O_PERSIST) {
+ /* we found the server and it's usable */
+ txn->flags &= ~TX_CK_MASK;
+ txn->flags |= TX_CK_VALID;
+ t->flags |= SN_DIRECT | SN_ASSIGNED;
+ t->srv = srv;
+ break;
+ } else {
+ txn->flags &= ~TX_CK_MASK;
+ txn->flags |= TX_CK_DOWN;
+ }
+ }
+ srv = srv->next;
+ }
+ }
+ }
+}
+
+/*
* Manage client-side cookie. It can impact performance by about 2% so it is
* desirable to call it only when needed.
*/
@@ -3378,9 +3445,6 @@
char *del_colon, *del_cookie, *colon;
int app_cookies;
- appsess *asession_temp = NULL;
- appsess local_asession;
-
char *cur_ptr, *cur_end, *cur_next;
int cur_idx, old_idx;
@@ -3610,63 +3674,7 @@
/* first, let's see if the cookie is our appcookie*/
/* Cool... it's the right one */
-
- asession_temp = &local_asession;
-
- if ((asession_temp->sessid = pool_alloc2(apools.sessid)) == NULL) {
- Alert("Not enough memory process_cli():asession->sessid:malloc().\n");
- send_log(t->be, LOG_ALERT, "Not enough memory process_cli():asession->sessid:malloc().\n");
- return;
- }
-
- memcpy(asession_temp->sessid, p3, t->be->appsession_len);
- asession_temp->sessid[t->be->appsession_len] = 0;
- asession_temp->serverid = NULL;
-
- /* only do insert, if lookup fails */
- asession_temp = appsession_hash_lookup(&(t->be->htbl_proxy), asession_temp->sessid);
- if (asession_temp == NULL) {
- if ((asession_temp = pool_alloc2(pool2_appsess)) == NULL) {
- /* free previously allocated memory */
- pool_free2(apools.sessid, local_asession.sessid);
- Alert("Not enough memory process_cli():asession:calloc().\n");
- send_log(t->be, LOG_ALERT, "Not enough memory process_cli():asession:calloc().\n");
- return;
- }
-
- asession_temp->sessid = local_asession.sessid;
- asession_temp->serverid = local_asession.serverid;
- asession_temp->request_count = 0;
- appsession_hash_insert(&(t->be->htbl_proxy), asession_temp);
- } else {
- /* free previously allocated memory */
- pool_free2(apools.sessid, local_asession.sessid);
- }
- if (asession_temp->serverid == NULL) {
- /* TODO redispatch request */
- Alert("Found Application Session without matching server.\n");
- } else {
- struct server *srv = t->be->srv;
- while (srv) {
- if (strcmp(srv->id, asession_temp->serverid) == 0) {
- if (srv->state & SRV_RUNNING || t->be->options & PR_O_PERSIST) {
- /* we found the server and it's usable */
- txn->flags &= ~TX_CK_MASK;
- txn->flags |= TX_CK_VALID;
- t->flags |= SN_DIRECT | SN_ASSIGNED;
- t->srv = srv;
- break;
- } else {
- txn->flags &= ~TX_CK_MASK;
- txn->flags |= TX_CK_DOWN;
- }
- }
- srv = srv->next;
- }/* end while(srv) */
- }/* end else if server == NULL */
-
- asession_temp->expire = tick_add_ifset(now_ms, t->be->timeout.appsession);
- asession_temp->request_count++;
+ manage_client_side_appsession(t, p3);
#if defined(DEBUG_HASH)
Alert("manage_client_side_cookies\n");
appsession_hash_dump(&(t->be->htbl_proxy));
@@ -3944,9 +3952,6 @@
struct http_txn *txn = &t->txn;
char *p1, *p2, *p3, *p4;
- appsess *asession_temp = NULL;
- appsess local_asession;
-
char *cur_ptr, *cur_end, *cur_next;
int cur_idx, old_idx, delta;
@@ -4087,60 +4092,64 @@
/* Cool... it's the right one */
- size_t server_id_len = strlen(t->srv->id) + 1;
- asession_temp = &local_asession;
-
- if ((asession_temp->sessid = pool_alloc2(apools.sessid)) == NULL) {
+ if (t->sessid != NULL) {
+ /* free previously allocated memory as we don't need it anymore */
+ pool_free2(apools.sessid, t->sessid);
+ }
+ /* Store the sessid in the session for future use */
+ if ((t->sessid = pool_alloc2(apools.sessid)) == NULL) {
Alert("Not enough Memory process_srv():asession->sessid:malloc().\n");
send_log(t->be, LOG_ALERT, "Not enough Memory process_srv():asession->sessid:malloc().\n");
return;
}
- memcpy(asession_temp->sessid, p3, t->be->appsession_len);
- asession_temp->sessid[t->be->appsession_len] = 0;
- asession_temp->serverid = NULL;
-
- /* only do insert, if lookup fails */
- asession_temp = appsession_hash_lookup(&(t->be->htbl_proxy), asession_temp->sessid);
- if (asession_temp == NULL) {
- if ((asession_temp = pool_alloc2(pool2_appsess)) == NULL) {
- Alert("Not enough Memory process_srv():asession:calloc().\n");
- send_log(t->be, LOG_ALERT, "Not enough Memory process_srv():asession:calloc().\n");
- return;
- }
- asession_temp->sessid = local_asession.sessid;
- asession_temp->serverid = local_asession.serverid;
- asession_temp->request_count = 0;
- appsession_hash_insert(&(t->be->htbl_proxy), asession_temp);
- } else {
- /* free wasted memory */
- pool_free2(apools.sessid, local_asession.sessid);
- }
-
- if (asession_temp->serverid == NULL) {
- if ((asession_temp->serverid = pool_alloc2(apools.serverid)) == NULL) {
- Alert("Not enough Memory process_srv():asession->sessid:malloc().\n");
- send_log(t->be, LOG_ALERT, "Not enough Memory process_srv():asession->sessid:malloc().\n");
- return;
- }
- asession_temp->serverid[0] = '\0';
- }
-
- if (asession_temp->serverid[0] == '\0')
- memcpy(asession_temp->serverid, t->srv->id, server_id_len);
-
- asession_temp->expire = tick_add_ifset(now_ms, t->be->timeout.appsession);
- asession_temp->request_count++;
-#if defined(DEBUG_HASH)
- Alert("manage_server_side_cookies\n");
- appsession_hash_dump(&(t->be->htbl_proxy));
-#endif
+ memcpy(t->sessid, p3, t->be->appsession_len);
+ t->sessid[t->be->appsession_len] = 0;
}/* end if ((t->proxy->appsession_name != NULL) ... */
break; /* we don't want to loop again since there cannot be another cookie on the same line */
} /* we're now at the end of the cookie value */
-
/* keep the link from this header to next one */
old_idx = cur_idx;
} /* end of cookie processing on this header */
+
+ if (t->sessid != NULL) {
+ appsess *asession = NULL;
+ /* only do insert, if lookup fails */
+ asession = appsession_hash_lookup(&(t->be->htbl_proxy), t->sessid);
+ if (asession == NULL) {
+ if ((asession = pool_alloc2(pool2_appsess)) == NULL) {
+ Alert("Not enough Memory process_srv():asession:calloc().\n");
+ send_log(t->be, LOG_ALERT, "Not enough Memory process_srv():asession:calloc().\n");
+ return;
+ }
+ if ((asession->sessid = pool_alloc2(apools.sessid)) == NULL) {
+ Alert("Not enough Memory process_srv():asession->sessid:malloc().\n");
+ send_log(t->be, LOG_ALERT, "Not enough Memory process_srv():asession->sessid:malloc().\n");
+ return;
+ }
+ memcpy(asession->sessid, t->sessid, t->be->appsession_len);
+ asession->sessid[t->be->appsession_len] = 0;
+
+ size_t server_id_len = strlen(t->srv->id) + 1;
+ if ((asession->serverid = pool_alloc2(apools.serverid)) == NULL) {
+ Alert("Not enough Memory process_srv():asession->sessid:malloc().\n");
+ send_log(t->be, LOG_ALERT, "Not enough Memory process_srv():asession->sessid:malloc().\n");
+ return;
+ }
+ asession->serverid[0] = '\0';
+ memcpy(asession->serverid, t->srv->id, server_id_len);
+
+ asession->request_count = 0;
+ appsession_hash_insert(&(t->be->htbl_proxy), asession);
+ }
+
+ asession->expire = tick_add_ifset(now_ms, t->be->timeout.appsession);
+ asession->request_count++;
+ }
+
+#if defined(DEBUG_HASH)
+ Alert("manage_server_side_cookies\n");
+ appsession_hash_dump(&(t->be->htbl_proxy));
+#endif
}
@@ -4238,9 +4247,6 @@
*/
void get_srv_from_appsession(struct session *t, const char *begin, int len)
{
- struct http_txn *txn = &t->txn;
- appsess *asession_temp = NULL;
- appsess local_asession;
char *request_line;
if (t->be->appsession_name == NULL ||
@@ -4259,69 +4265,11 @@
/* skip jsessionid= */
request_line += t->be->appsession_name_len + 1;
- /* First try if we already have an appsession */
- asession_temp = &local_asession;
-
- if ((asession_temp->sessid = pool_alloc2(apools.sessid)) == NULL) {
- Alert("Not enough memory process_cli():asession_temp->sessid:calloc().\n");
- send_log(t->be, LOG_ALERT, "Not enough Memory process_cli():asession_temp->sessid:calloc().\n");
- return;
- }
-
- /* Copy the sessionid */
- memcpy(asession_temp->sessid, request_line, t->be->appsession_len);
- asession_temp->sessid[t->be->appsession_len] = 0;
- asession_temp->serverid = NULL;
-
- /* only do insert, if lookup fails */
- asession_temp = appsession_hash_lookup(&(t->be->htbl_proxy), asession_temp->sessid);
- if (asession_temp == NULL) {
- if ((asession_temp = pool_alloc2(pool2_appsess)) == NULL) {
- /* free previously allocated memory */
- pool_free2(apools.sessid, local_asession.sessid);
- Alert("Not enough memory process_cli():asession:calloc().\n");
- send_log(t->be, LOG_ALERT, "Not enough memory process_cli():asession:calloc().\n");
- return;
- }
- asession_temp->sessid = local_asession.sessid;
- asession_temp->serverid = local_asession.serverid;
- asession_temp->request_count=0;
- appsession_hash_insert(&(t->be->htbl_proxy), asession_temp);
- }
- else {
- /* free previously allocated memory */
- pool_free2(apools.sessid, local_asession.sessid);
- }
-
- asession_temp->expire = tick_add_ifset(now_ms, t->be->timeout.appsession);
- asession_temp->request_count++;
-
+ manage_client_side_appsession(t, request_line);
#if defined(DEBUG_HASH)
Alert("get_srv_from_appsession\n");
appsession_hash_dump(&(t->be->htbl_proxy));
#endif
- if (asession_temp->serverid == NULL) {
- /* TODO redispatch request */
- Alert("Found Application Session without matching server.\n");
- } else {
- struct server *srv = t->be->srv;
- while (srv) {
- if (strcmp(srv->id, asession_temp->serverid) == 0) {
- if (srv->state & SRV_RUNNING || t->be->options & PR_O_PERSIST) {
- /* we found the server and it's usable */
- txn->flags &= ~TX_CK_MASK;
- txn->flags |= TX_CK_VALID;
- t->flags |= SN_DIRECT | SN_ASSIGNED;
- t->srv = srv;
- break;
- } else {
- txn->flags &= ~TX_CK_MASK;
- txn->flags |= TX_CK_DOWN;
- }
- }
- srv = srv->next;
- }
- }
}
diff -Naur haproxy-1.3.21/src/session.c haproxy-1.3.21-appsession-final/src/session.c
--- haproxy-1.3.21/src/session.c 2009-10-12 06:20:09.000000000 +0200
+++ haproxy-1.3.21-appsession-final/src/session.c 2009-10-14 23:09:30.000000000 +0200
@@ -78,6 +78,9 @@
pool_free2(pool2_buffer, s->req);
pool_free2(pool2_buffer, s->rep);
+ if (s->sessid)
+ pool_free2(apools.sessid, s->sessid);
+
if (fe) {
pool_free2(fe->hdr_idx_pool, txn->hdr_idx.v);