in flood_round_robin.c [1069:1265]
apr_status_t round_robin_postprocess(profile_t *profile,
request_t *req,
response_t *resp)
{
round_robin_profile_t *rp;
char *cookieheader, *cookievalue, *cookieend;
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)
{
/* Point to the value */
cookieheader += 12;
cookievalue = (char*) memchr(cookieheader, '=',
resp->rbufsize - (int)(cookieheader - (int)(resp->rbuf)));
if (cookievalue)
{
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)
{
int status, size;
char *expanded, *newValue;
regmatch_t match[10];
regex_t re;
expanded = expand_param_string(rp,
rp->url[rp->current_url].responsetemplate);
regcomp(&re, expanded, REG_EXTENDED);
status = regexec(&re, resp->rbuf, 10, match, 0);
if (status != REG_OK) {
apr_file_printf(local_stderr,
"Regular expression match failed (%s)\n",
rp->url[rp->current_url].responsetemplate);
return APR_EGENERAL;
}
size = match[1].rm_eo - match[1].rm_so + 1;
newValue = apr_palloc(rp->pool, size);
apr_cpystrn(newValue, resp->rbuf + match[1].rm_so, size);
apr_hash_set(rp->state, rp->url[rp->current_url].responsename,
rp->url[rp->current_url].responselen, newValue);
regfree(&re);
}
if (rp->url[rp->current_url].responsescript)
{
int exitcode = 0;
apr_status_t rv;
apr_proc_t *proc;
apr_pollfd_t pipeout;
apr_pollset_t *pollset;
apr_procattr_t *procattr;
apr_size_t nbytes, wbytes;
char buf[255];
char **args;
const char *progname;
if ((rv = apr_procattr_create(&procattr, rp->pool)) != APR_SUCCESS) {
apr_file_printf(local_stderr,
"apr_procattr_create failed for '%s': %s\n",
rp->url[rp->current_url].responsescript,
apr_strerror(rv, buf, sizeof(buf)));
return rv;
}
if ((rv = apr_procattr_io_set(procattr, APR_FULL_BLOCK, APR_NO_PIPE,
APR_NO_PIPE)) != APR_SUCCESS) {
apr_file_printf(local_stderr,
"apr_procattr_io_set failed for '%s': %s\n",
rp->url[rp->current_url].responsescript,
apr_strerror(rv, buf, sizeof(buf)));
return rv;
}
if ((rv = apr_procattr_error_check_set(procattr, 1)) != APR_SUCCESS) {
apr_file_printf(local_stderr,
"apr_procattr_error_check_set failed "
"for '%s': %s\n",
rp->url[rp->current_url].responsescript,
apr_strerror(rv, buf, sizeof(buf)));
return rv;
}
apr_tokenize_to_argv(rp->url[rp->current_url].responsescript, &args,
rp->pool);
progname = apr_pstrdup(rp->pool, args[0]);
proc = (apr_proc_t *)apr_pcalloc(rp->pool, sizeof(*proc));
/* create process */
if ((rv = apr_proc_create(proc, progname, (const char * const *)args,
NULL, procattr, rp->pool)) != APR_SUCCESS) {
apr_file_printf(local_stderr,
"Can't spawn postprocess script '%s': %s\n",
rp->url[rp->current_url].responsescript,
apr_strerror(rv, buf, sizeof(buf)));
return rv;
}
if ((rv = apr_file_pipe_timeout_set(proc->in, apr_time_from_sec(10)))
!= APR_SUCCESS) {
apr_file_printf(local_stderr,
"apr_file_pipe_timeout_set failed for '%s': %s\n",
rp->url[rp->current_url].responsescript,
apr_strerror(rv, buf, sizeof(buf)));
return rv;
}
apr_pollset_create(&pollset, 1, rp->pool, 0);
pipeout.desc_type = APR_POLL_FILE;
pipeout.reqevents = APR_POLLOUT;
pipeout.desc.f = proc->in;
pipeout.client_data = NULL;
apr_pollset_add(pollset, &pipeout);
wbytes = 0;
nbytes = strlen(resp->rbuf);
while (wbytes < nbytes) {
apr_size_t bytes;
apr_int32_t nrdes;
const apr_pollfd_t *ardes = NULL;
const apr_pollfd_t *rdes;
if ((rv = apr_pollset_poll(pollset, apr_time_from_sec(10),
&nrdes, &ardes)) != APR_SUCCESS) {
apr_file_printf(local_stderr,
"error writing data to script '%s': %s\n",
rp->url[rp->current_url].responsescript,
apr_strerror(rv, buf, sizeof(buf)));
return rv;
}
/* there can be only one descriptor... */
rdes = &(ardes[0]);
bytes = nbytes;
apr_file_write(rdes->desc.f, resp->rbuf, &bytes);
wbytes += bytes;
}
apr_pollset_remove(pollset, &pipeout);
apr_file_close(proc->in);
if ((rv = apr_proc_wait(proc, &exitcode, NULL, APR_WAIT))
!= APR_CHILD_DONE) {
apr_file_printf(local_stderr,
"apr_proc_wait failed for '%s': %s\n",
rp->url[rp->current_url].responsescript,
apr_strerror(rv, buf, sizeof(buf)));
return rv;
}
if (exitcode != 0) {
apr_file_printf(local_stderr,
"Postprocess script '%s' failed, exit code '%i'\n",
rp->url[rp->current_url].responsescript, exitcode);
return APR_EGENERAL;
}
}
return APR_SUCCESS;
}