This patch fixed the following errors in the cookie code in Flood:
(1) Original code only handled a single "set-cookie" header for a given
HTTP message. There can be more than one.
(2) Original code did not handle a replacement for a cookie value already
in the "database". The fix searches through and avoids these duplicates by
replacing.
Please examine the attached diff and apply the changes to the file
flood_round_robin.c to resolve these issues.
-Norman Tuttle, developer, OpenDemand Systems, [EMAIL PROTECTED]
--- flood_round_robin.c 2003-10-20 11:37:20.000000000 -0400
+++ \flood-1.1\flood_round_robin.c 2003-09-07 22:22:32.000000000 -0400
@@ -151,14 +151,14 @@
} round_robin_profile_t;
-static char *handle_param_string(round_robin_profile_t *rp, char *template,
+static char *handle_param_string(round_robin_profile_t *rp, char *template,
expand_param_e set)
{
char *cpy, *cur, *prev, *data, *returnValue, *pattern;
int size, matchsize;
regex_t re;
regmatch_t match[2];
-
+
prev = template;
returnValue = NULL;
@@ -203,7 +203,7 @@
/* If there is no data, place the original string back. */
if (!data) {
- data = apr_psprintf(rp->pool, "${%s}",
+ data = apr_psprintf(rp->pool, "${%s}",
apr_pstrmemdup(rp->pool, cur+match[1].rm_so,
match[1].rm_eo - match[1].rm_so));
}
@@ -218,11 +218,11 @@
else
{
if (cpy)
- returnValue = apr_pstrcat(rp->pool, returnValue, cpy, data,
+ returnValue = apr_pstrcat(rp->pool, returnValue, cpy, data,
NULL);
else
returnValue = apr_pstrcat(rp->pool, returnValue, data, NULL);
-
+
}
/* Skip over the trailing } */
@@ -255,8 +255,8 @@
char *cookies;
char *enc_credtls, *credtls, *authz_hdr = NULL;
cookie_t *cook;
-
- p = (round_robin_profile_t*)profile;
+
+ p = (round_robin_profile_t*)profile;
/* Do we want to save the entire response? */
r->wantresponse = p->url[p->current_url].responsetemplate ? 1 : 0;
@@ -271,9 +271,9 @@
if (cook != p->cookie)
cookies = apr_pstrcat(p->pool, cookies, ";", NULL);
- cookies = apr_pstrcat(p->pool, cookies, cook->name, "=",
+ cookies = apr_pstrcat(p->pool, cookies, cook->name, "=",
cook->value, NULL);
- cook = cook->next;
+ cook = cook->next;
}
cookies = apr_pstrcat(p->pool, cookies, CRLF, NULL);
}
@@ -302,14 +302,14 @@
switch (r->method)
{
case GET:
- r->rbuf = apr_psprintf(r->pool,
+ r->rbuf = apr_psprintf(r->pool,
"GET %s%s%s HTTP/1.1" CRLF
"User-Agent: Flood/" FLOOD_VERSION CRLF
"Connection: %s" CRLF
- "Host: %s" CRLF
+ "Host: %s" CRLF
"%s"
"%s" CRLF,
- r->parsed_uri->path,
+ r->parsed_uri->path,
r->parsed_uri->query ? "?" : "",
r->parsed_uri->query ? r->parsed_uri->query :
"",
r->keepalive ? "Keep-Alive" : "Close",
@@ -320,14 +320,14 @@
r->rbufsize = strlen(r->rbuf);
break;
case HEAD:
- r->rbuf = apr_psprintf(r->pool,
+ r->rbuf = apr_psprintf(r->pool,
"HEAD %s%s%s HTTP/1.1" CRLF
"User-Agent: Flood/" FLOOD_VERSION CRLF
"Connection: %s" CRLF
- "Host: %s" CRLF
+ "Host: %s" CRLF
"%s"
"%s" CRLF,
- r->parsed_uri->path,
+ r->parsed_uri->path,
r->parsed_uri->query ? "?" : "",
r->parsed_uri->query ? r->parsed_uri->query :
"",
r->keepalive ? "Keep-Alive" : "Close",
@@ -340,17 +340,17 @@
case POST:
/* FIXME */
if (r->payload) {
- r->rbuf = apr_psprintf(r->pool,
+ r->rbuf = apr_psprintf(r->pool,
"POST %s%s%s HTTP/1.1" CRLF
"User-Agent: Flood/" FLOOD_VERSION CRLF
"Connection: %s" CRLF
"Host: %s" CRLF
- "Content-Length: %d" CRLF
+ "Content-Length: %d" CRLF
"Content-type:
application/x-www-form-urlencoded" CRLF
"%s"
"%s" CRLF
"%s",
- r->parsed_uri->path,
+ r->parsed_uri->path,
r->parsed_uri->query ? "?" : "",
r->parsed_uri->query ? r->parsed_uri->query
: "",
r->keepalive ? "Keep-Alive" : "Close",
@@ -360,7 +360,7 @@
cookies,
(char*)r->payload);
} else { /* There is no payload, but it's still a POST */
- r->rbuf = apr_psprintf(r->pool,
+ r->rbuf = apr_psprintf(r->pool,
"POST %s%s%s HTTP/1.1" CRLF
"User-Agent: Flood/" FLOOD_VERSION CRLF
"Connection: %s" CRLF
@@ -368,7 +368,7 @@
"%s"
"%s" CRLF "",
- r->parsed_uri->path,
+ r->parsed_uri->path,
r->parsed_uri->query ? "?" : "",
r->parsed_uri->query ? r->parsed_uri->query
: "",
r->keepalive ? "Keep-Alive" : "Close",
@@ -393,7 +393,7 @@
if (e->first_cdata.first->next)
{
apr_text *t;
- t = e->first_cdata.first;
+ t = e->first_cdata.first;
url->url = apr_pstrdup(pool, t->text);
while ((t = t->next))
{
@@ -411,7 +411,7 @@
apr_xml_attr *attr = e->attr;
while (attr)
{
- if (strncasecmp(attr->name, XML_URLLIST_METHOD,
+ if (strncasecmp(attr->name, XML_URLLIST_METHOD,
FLOOD_STRLEN_MAX) == 0) {
if (strncasecmp(attr->value, XML_URLLIST_METHOD_POST, 4) == 0)
url->method = POST;
@@ -428,7 +428,7 @@
return APR_EGENERAL;
}
}
- else if (strncasecmp(attr->name, XML_URLLIST_PAYLOAD,
+ else if (strncasecmp(attr->name, XML_URLLIST_PAYLOAD,
FLOOD_STRLEN_MAX) == 0) {
url->payload = (char*)attr->value;
}
@@ -438,7 +438,7 @@
url->predelay = strtoll(attr->value, &endptr, 10);
if (*endptr != '\0')
{
- apr_file_printf(local_stderr,
+ apr_file_printf(local_stderr,
"Attribute %s has invalid value %s.\n",
XML_URLLIST_PREDELAY, attr->value);
return APR_EGENERAL;
@@ -464,7 +464,7 @@
url->postdelay = strtoll(attr->value, &endptr, 10);
if (*endptr != '\0')
{
- apr_file_printf(local_stderr,
+ apr_file_printf(local_stderr,
"Attribute %s has invalid value %s.\n",
XML_URLLIST_POSTDELAY, attr->value);
return APR_EGENERAL;
@@ -484,38 +484,38 @@
}
url->postdelayprecision *= APR_USEC_PER_SEC;
}
- else if (strncasecmp(attr->name,
- XML_URLLIST_PAYLOAD_TEMPLATE,
+ else if (strncasecmp(attr->name,
+ XML_URLLIST_PAYLOAD_TEMPLATE,
FLOOD_STRLEN_MAX) == 0) {
url->payloadtemplate = (char*)attr->value;
}
- else if (strncasecmp(attr->name,
- XML_URLLIST_REQUEST_TEMPLATE,
+ else if (strncasecmp(attr->name,
+ XML_URLLIST_REQUEST_TEMPLATE,
FLOOD_STRLEN_MAX) == 0) {
url->requesttemplate = (char*)attr->value;
}
- else if (strncasecmp(attr->name,
- XML_URLLIST_RESPONSE_TEMPLATE,
+ else if (strncasecmp(attr->name,
+ XML_URLLIST_RESPONSE_TEMPLATE,
FLOOD_STRLEN_MAX) == 0) {
url->responsetemplate = (char*)attr->value;
}
- else if (strncasecmp(attr->name,
- XML_URLLIST_RESPONSE_SCRIPT,
+ else if (strncasecmp(attr->name,
+ XML_URLLIST_RESPONSE_SCRIPT,
FLOOD_STRLEN_MAX) == 0) {
url->responsescript = (char*)attr->value;
}
- else if (strncasecmp(attr->name,
+ else if (strncasecmp(attr->name,
XML_URLLIST_RESPONSE_NAME,
FLOOD_STRLEN_MAX) == 0) {
url->responsename = (char*)attr->value;
url->responselen = strlen((char*)attr->value);
}
- else if (strncasecmp(attr->name,
+ else if (strncasecmp(attr->name,
XML_URLLIST_USER,
FLOOD_STRLEN_MAX) == 0) {
url->user = (char*)attr->value;
}
- else if (strncasecmp(attr->name,
+ else if (strncasecmp(attr->name,
XML_URLLIST_PASSWORD,
FLOOD_STRLEN_MAX) == 0) {
url->password = (char*)attr->value;
@@ -531,7 +531,7 @@
return APR_SUCCESS;
}
-
+
static apr_status_t parse_xml_seq_info(apr_xml_elem *e,
round_robin_profile_t *p,
apr_pool_t *pool)
@@ -548,8 +548,8 @@
FLOOD_STRLEN_MAX) == 0) {
seqname = (char*)attr->value;
seqnamelen = strlen(seqname);
- }
- else if (strncasecmp(attr->name,
+ }
+ else if (strncasecmp(attr->name,
XML_URLLIST_SEQUENCE_LIST,
FLOOD_STRLEN_MAX) == 0) {
/* FIXME: ap_getword needs to be in apr-util! */
@@ -559,14 +559,14 @@
while (*end && (end = strchr(end, ','))) {
count++;
end++;
- }
+ }
seqlist = apr_palloc(pool, sizeof(char*) * count);
seqcount = count;
cur = (char*)attr->value;
end = strchr(cur, ',');
for (num = 0; num < count; num++) {
- while (apr_isspace(*cur)) {
+ while (apr_isspace(*cur)) {
cur++;
}
if (end) {
@@ -579,10 +579,10 @@
seqlist[num] = apr_pstrdup(pool, cur);
}
}
- }
- attr = attr->next;
+ }
+ attr = attr->next;
}
- }
+ }
for (curseq = 0; curseq < seqcount; curseq++) {
apr_hash_set(p->state, seqname, seqnamelen, seqlist[curseq]);
for (child_url_elem = e->first_child; child_url_elem;
@@ -604,19 +604,19 @@
}
/* Expand them. */
if (p->url[p->current_url].payloadtemplate) {
- p->url[p->current_url].payloadtemplate =
+ p->url[p->current_url].payloadtemplate =
handle_param_string(p,
p->url[p->current_url].payloadtemplate,
EPE_PASSTHROUGH);
}
if (p->url[p->current_url].requesttemplate) {
- p->url[p->current_url].requesttemplate =
+ p->url[p->current_url].requesttemplate =
handle_param_string(p,
p->url[p->current_url].requesttemplate,
EPE_PASSTHROUGH);
}
if (p->url[p->current_url].responsetemplate) {
- p->url[p->current_url].responsetemplate =
+ p->url[p->current_url].responsetemplate =
handle_param_string(p,
p->url[p->current_url].responsetemplate,
EPE_PASSTHROUGH);
@@ -640,7 +640,7 @@
if (e->attr) {
apr_xml_attr *attr = e->attr;
while (attr) {
- if (strncasecmp(attr->name,
+ if (strncasecmp(attr->name,
XML_URLLIST_SEQUENCE_LIST,
FLOOD_STRLEN_MAX) == 0) {
char *end = (char*)attr->value;
@@ -715,7 +715,7 @@
apr_file_printf(local_stderr,
"Profile '%s' has element <%s> with no value,
assuming 1.\n",
profile_name, XML_PROFILE_COUNT);
- p->execute_rounds = 1;
+ p->execute_rounds = 1;
}
}
@@ -800,16 +800,16 @@
if (rp->url[rp->current_url].requesttemplate)
{
- r->uri = parse_param_string(rp,
+ r->uri = parse_param_string(rp,
rp->url[rp->current_url].requesttemplate);
}
else
r->uri = rp->url[rp->current_url].url;
-
+
r->method = rp->url[rp->current_url].method;
/* We're created by calloc, so no need to set payload to be null or
- * payloadsize to be 0.
+ * payloadsize to be 0.
*/
if (rp->url[rp->current_url].payload)
{
@@ -818,7 +818,7 @@
}
else if (rp->url[rp->current_url].payloadtemplate)
{
- r->payload = parse_param_string(rp,
+ r->payload = parse_param_string(rp,
rp->url[rp->current_url].payloadtemplate);
r->payloadsize = strlen(r->payload);
}
@@ -877,7 +877,7 @@
}
if (!r->parsed_uri->port)
{
- r->parsed_uri->port =
+ r->parsed_uri->port =
apr_uri_default_port_for_scheme(r->parsed_uri->scheme);
}
if (!r->parsed_uri->path) /* If / is not there, be nice. */
@@ -897,70 +897,43 @@
response_t *resp)
{
round_robin_profile_t *rp;
- char *cookieheader, *cookievalue, *cookieend, *respend;
- unsigned size;
+ char *cookieheader, *cookievalue, *cookieend;
rp = (round_robin_profile_t*)profile;
- cookieend = resp->rbuf; /* sets next search point to beginning of rbuf */
- respend = cookieend + resp->rbufsize; /* response ends at end of rbuf */
-
- /*-----------------6/30/2003 0:15AM-----------------
- * Improved this code a little. Now handles multiple cookies - NT
- * Also will properly handle case of replacing cookies.
- * The current search may still find false positives.
- * --------------------------------------------------*/
- while ((cookieheader = strstr(cookieend, "Set-Cookie: ")) != NULL)
- { /* The while handles the poss. of >1 Set-Cookie! */
- /* Point to the value */
- cookieheader += 12;
- cookievalue = (char*) memchr(cookieheader, '=', respend - cookieheader);
- if (cookievalue)
- {
- cookie_t *cookie = NULL, *cook = rp->cookie;
-
- size = cookievalue - cookieheader;
- while (cook)
- {
- if ((strlen(cook->name)==size)&&
- (!strncasecmp(cookieheader, cook->name, size)))
- { /* Size check needed because one name may be subset of other */
- cookie = cook; /* found cookie, exit loop */
- break;
- }
- cook = cook -> next;
- }
- if (!cookie) /* at this point same as saying (!cook) */
- {
- cookie = apr_pcalloc(rp->pool, sizeof(cookie_t));
- cookie->name = apr_palloc(rp->pool, ++size);
- /* bump up size for null termination */
- apr_cpystrn(cookie->name, cookieheader, size);
- }
-
- cookieheader = cookievalue + 1;
- cookieend = (char*) memchr(cookieheader, '\r', respend - cookieheader);
- /* above calculation derives REAL cookieend */
- if (!cookieend) /* This should not be happening. */
- break; /* Stop cookie search now! Drop current attempt! */
- cookievalue = (char*) memchr(cookieheader, ';', cookieend -
cookieheader);
- /* First using REAL cookieend! */
- if (!cookievalue)
- cookievalue = cookieend;
- size = cookievalue + 1 - cookieheader;
- /* !cook: If exited while loop above without finding cookie match,
- * then value wasn't previously set. */
- if ((!cook)||(size > strlen(cookie->value)+1))
- {
- cookie->value = apr_palloc(rp->pool, size);
- }
- apr_cpystrn(cookie->value, cookieheader, size); /* copy in new value */
- if (!cook) /* if cookie wasn't in linked list, put it in now! */
+ /* FIXME: This algorithm sucks. I need to be shot for writing such
+ * atrocious code. Grr. */
+ cookieheader = strstr(resp->rbuf, "Set-Cookie: ");
+ if (cookieheader)
+ {
+ /* Point to the value */
+ cookieheader += 12;
+ cookievalue = (char*) memchr(cookieheader, '=',
+ resp->rbufsize - (int)(cookieheader -
(int)(resp->rbuf)));
+ if (cookievalue)
{
- cookie->next = rp->cookie;
- rp->cookie = cookie;
+ cookie_t * cookie = apr_pcalloc(rp->pool, sizeof(cookie_t));
+
+ ++cookievalue;
+ cookie->name = apr_palloc(rp->pool, cookievalue - cookieheader);
+ apr_cpystrn(cookie->name, cookieheader, cookievalue -
cookieheader);
+
+ cookieheader = cookievalue;
+ cookieend = (char*) memchr(cookieheader, '\r',
+ resp->rbufsize - (int)(cookieheader -
(int)(resp->rbuf)));
+ cookievalue = (char*) memchr(cookieheader, ';',
+ cookieend - cookieheader);
+ if (!cookievalue)
+ cookievalue = cookieend;
+
+ ++cookievalue;
+
+ cookie->value = apr_palloc(rp->pool, cookievalue - cookieheader);
+ apr_cpystrn(cookie->value, cookieheader,
+ cookievalue - cookieheader);
+ cookie->next = rp->cookie;
+ rp->cookie = cookie;
}
- }
}
if (rp->url[rp->current_url].responsetemplate)
{
@@ -969,7 +942,7 @@
regmatch_t match[10];
regex_t re;
- expanded = expand_param_string(rp,
+ expanded = expand_param_string(rp,
rp->url[rp->current_url].responsetemplate);
regcomp(&re, expanded, REG_EXTENDED);
status = regexec(&re, resp->rbuf, 10, match, 0);
@@ -1001,7 +974,7 @@
char **args;
const char *progname;
-
+
if ((rv = apr_procattr_create(&procattr, rp->pool)) != APR_SUCCESS) {
apr_file_printf(local_stderr,
@@ -1169,7 +1142,7 @@
/* Adjust counters for profile */
if (rp->current_url >= rp->urls) {
rp->current_url = 0;
-
+
/* Loop cond tells us when to stop. */
rp->current_round++;
}
@@ -1183,7 +1156,7 @@
if (rp->current_round >= rp->execute_rounds)
return 0;
else { /* we'll continue, so do delay stuff now if necessary */
-
+
/* If they want a sleep, do it now. */
if (rp->url[real_current_url].postdelay) {
apr_int64_t real_postdelay = rp->url[real_current_url].postdelay;