As per the suggestions I have received, I am resubmitting the attached diff for the cookies changes in the proper format. See the inline comments for what has been fixed by this patch.
Note that this patch alone does not provide the most robust solution as it ignores the possibility of different cookies with the same name going to different hosts, but for this and observation of expiration dates, etc, we would have to expand the Flood model of cookies to store that information as well, which is currently not being done. Perhaps somebody can add these capabilities. The patch did resolve issues that we had with client sites regarding our handling of cookies. -Norman Tuttle, developer, OpenDemand Systems [EMAIL PROTECTED]
--- \flood-1.1\flood_round_robin.c 2003-09-07 22:22:32.000000000 -0400 +++ flood_round_robin.c 2003-10-27 11:48:50.000000000 -0500 @@ -897,42 +897,69 @@ response_t *resp) { round_robin_profile_t *rp; - char *cookieheader, *cookievalue, *cookieend; + char *cookieheader, *cookievalue, *cookieend, *respend; + unsigned size; rp = (round_robin_profile_t*)profile; /* FIXME: This algorithm sucks. I need to be shot for writing such * atrocious code. Grr. */ - cookieheader = strstr(resp->rbuf, "Set-Cookie: "); - if (cookieheader) - { + /* Made following changes, in view of limitations of code design - NT: */ + /* 1) handle multiple cookies */ + /* 2) replace cookies having same name */ + cookieend = resp->rbuf; /* sets next search point to beginning of rbuf */ + respend = cookieend + resp->rbufsize; /* response ends at end of rbuf */ + while ((cookieheader = strstr(cookieend, "Set-Cookie: ")) != NULL) + { /* The while handles the possibility of >1 Set-Cookie! */ /* Point to the value */ cookieheader += 12; - cookievalue = (char*) memchr(cookieheader, '=', - resp->rbufsize - (int)(cookieheader - (int)(resp->rbuf))); + cookievalue = (char*) memchr(cookieheader, '=', respend - cookieheader); if (cookievalue) { - cookie_t * cookie = apr_pcalloc(rp->pool, sizeof(cookie_t)); + 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) + { + cookie = apr_pcalloc(rp->pool, sizeof(cookie_t)); + cookie->name = apr_palloc(rp->pool, ++size); + /* bump up size to include null termination */ + apr_cpystrn(cookie->name, cookieheader, cookievalue - cookieheader); + } - ++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))); + 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); 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; + 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! */ + { + cookie->next = rp->cookie; + rp->cookie = cookie; + } } } if (rp->url[rp->current_url].responsetemplate)