You are viewing a plain text version of this content. The canonical link for it is here.
Posted to test-cvs@httpd.apache.org by ja...@apache.org on 2003/09/08 00:56:53 UTC
cvs commit: httpd-test/flood config.h.in flood_round_robin.c
jacekp 2003/09/07 15:56:53
Modified: flood config.h.in flood_round_robin.c
Log:
Added attribute responsescript (element <url>), which allows flood to
delegate response processing to external script.
Revision Changes Path
1.28 +1 -0 httpd-test/flood/config.h.in
Index: config.h.in
===================================================================
RCS file: /home/cvs/httpd-test/flood/config.h.in,v
retrieving revision 1.27
retrieving revision 1.28
diff -u -r1.27 -r1.28
--- config.h.in 9 Aug 2003 08:19:45 -0000 1.27
+++ config.h.in 7 Sep 2003 22:56:53 -0000 1.28
@@ -23,6 +23,7 @@
#define XML_URLLIST_PAYLOAD_TEMPLATE "payloadtemplate"
#define XML_URLLIST_REQUEST_TEMPLATE "requesttemplate"
#define XML_URLLIST_RESPONSE_TEMPLATE "responsetemplate"
+#define XML_URLLIST_RESPONSE_SCRIPT "responsescript"
#define XML_URLLIST_RESPONSE_NAME "responsename"
#define XML_URLLIST_PROXY "proxy"
#define XML_URLLIST_PREDELAY "predelay"
1.35 +125 -0 httpd-test/flood/flood_round_robin.c
Index: flood_round_robin.c
===================================================================
RCS file: /home/cvs/httpd-test/flood/flood_round_robin.c,v
retrieving revision 1.34
retrieving revision 1.35
diff -u -r1.34 -r1.35
--- flood_round_robin.c 3 Feb 2003 17:10:56 -0000 1.34
+++ flood_round_robin.c 7 Sep 2003 22:56:53 -0000 1.35
@@ -61,6 +61,8 @@
#include <apr_lib.h>
#include <apr_hash.h>
#include <apr_base64.h>
+#include <apr_poll.h>
+#include <apr_thread_proc.h>
#if APR_HAVE_STRINGS_H
#include <strings.h> /* strncasecmp */
@@ -114,6 +116,7 @@
char *payloadtemplate;
char *requesttemplate;
char *responsetemplate;
+ char *responsescript;
char *responsename;
int responselen;
char *user;
@@ -496,6 +499,11 @@
url->responsetemplate = (char*)attr->value;
}
else if (strncasecmp(attr->name,
+ XML_URLLIST_RESPONSE_SCRIPT,
+ FLOOD_STRLEN_MAX) == 0) {
+ url->responsescript = (char*)attr->value;
+ }
+ else if (strncasecmp(attr->name,
XML_URLLIST_RESPONSE_NAME,
FLOOD_STRLEN_MAX) == 0) {
url->responsename = (char*)attr->value;
@@ -951,6 +959,123 @@
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 **args;
+ const char *progname;
+
+
+ if (apr_procattr_create(&procattr, rp->pool) != APR_SUCCESS) {
+ apr_file_printf(local_stderr,
+ "apr_procattr_create failed for '%s'\n",
+ rp->url[rp->current_url].responsescript);
+ return APR_EGENERAL;
+ }
+
+ if (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'\n",
+ rp->url[rp->current_url].responsescript);
+ return APR_EGENERAL;
+ }
+
+ if (apr_procattr_error_check_set(procattr, 1)) {
+ apr_file_printf(local_stderr,
+ "apr_procattr_error_check_set failed for '%s'\n",
+ rp->url[rp->current_url].responsescript);
+ return APR_EGENERAL;
+ }
+
+ 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 (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'\n",
+ rp->url[rp->current_url].responsescript);
+ return APR_EGENERAL;
+ }
+
+ if (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'\n",
+ rp->url[rp->current_url].responsescript);
+ return APR_EGENERAL;
+ }
+
+ 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) {
+
+ int bytes;
+ apr_int32_t nrdes;
+ const apr_pollfd_t *ardes = NULL;
+
+ apr_pollset_poll(pollset, apr_time_from_sec(10), &nrdes, &ardes);
+
+ if (!nrdes) {
+ apr_file_printf(local_stderr,
+ "timeout writing data to script '%s'\n",
+ rp->url[rp->current_url].responsescript);
+ return APR_EGENERAL;
+ }
+
+ /* there can be only one descriptor... */
+ const apr_pollfd_t *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);
+
+ rv = apr_proc_wait(proc, &exitcode, NULL, APR_WAIT);
+
+ /* child may be gone already... */
+ if (!rv & (APR_CHILD_DONE | APR_SUCCESS)) {
+ apr_file_printf(local_stderr,
+ "apr_proc_wait failed for '%s'\n",
+ rp->url[rp->current_url].responsescript);
+ return APR_EGENERAL;
+ }
+
+ 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;
Re: cvs commit: httpd-test/flood config.h.in flood_round_robin.c
Posted by Jacek Prucia <j....@defbank.com.pl>.
On Sun, 7 Sep 2003 22:22:44 -0400 (EDT)
Cliff Woolley <jw...@virginia.edu> wrote:
>
> > is a safe bet. If this looks really obscure considering APR
> > concepts, then please feel free to commit a fix.
>
> Fix commited.
Thanks for the fix!
> Please test, since I didn't. :)
Fix seems to be OK and error messages are more descriptive than 'Error
string not specified yet'. :)
regards,
Jacek Prucia
RE: cvs commit: httpd-test/flood config.h.in flood_round_robin.c
Posted by Cliff Woolley <jw...@virginia.edu>.
> is a safe bet. If this looks really obscure considering APR concepts, then
> please feel free to commit a fix.
Fix commited. Please test, since I didn't. :)
PS: I also fixed a buglet or two.
--Cliff
RE: cvs commit: httpd-test/flood config.h.in flood_round_robin.c
Posted by Sander Striker <st...@apache.org>.
> From: Jacek Prucia [mailto:jacek.prucia@acn.waw.pl]
> Sent: Monday, September 08, 2003 2:41 AM
> On Sun, 7 Sep 2003 20:06:09 -0400 (EDT)
> Cliff Woolley <jw...@virginia.edu> wrote:
>
> > On Sun, 7 Sep 2003 jacekp@apache.org wrote:
> >
> > > + if (apr_procattr_create(&procattr, rp->pool) != APR_SUCCESS) {
> > > + apr_file_printf(local_stderr,
> > > + "apr_procattr_create failed for '%s'\n",
> > > + rp->url[rp->current_url].responsescript);
> > > + return APR_EGENERAL;
> > > + }
> >
> > Why do all of these return APR_EGENERAL rather than catching the
> > apr_status_t from the function that was called (apr_procattr_create in
> > this case) and returning that? Is this just a flood thing I don't know
> > about?
>
> Nope. I'm not so familliar with APR, so a message to stderr plus APR_EGENERAL
> is a safe bet. If this looks really obscure considering APR concepts, then
> please feel free to commit a fix.
Basically do something like this:
apr_status_t rv;
...
rv = apr_procattr_create(&procattr, rp->pool);
if (rv) { /* Or in full: if (rv != APR_SUCCESS) */
apr_file_printf(local_stderr,
"apr_procattr_create failed for '%s'\n",
rp->url[rp->current_url].responsescript);
return rv;
}
IOW, preserve the error and pass it down back the calling chain.
Sander
Re: cvs commit: httpd-test/flood config.h.in flood_round_robin.c
Posted by Jacek Prucia <ja...@acn.waw.pl>.
On Sun, 7 Sep 2003 20:06:09 -0400 (EDT)
Cliff Woolley <jw...@virginia.edu> wrote:
> On Sun, 7 Sep 2003 jacekp@apache.org wrote:
>
> > + if (apr_procattr_create(&procattr, rp->pool) != APR_SUCCESS) {
> > + apr_file_printf(local_stderr,
> > + "apr_procattr_create failed for '%s'\n",
> > + rp->url[rp->current_url].responsescript);
> > + return APR_EGENERAL;
> > + }
>
> Why do all of these return APR_EGENERAL rather than catching the
> apr_status_t from the function that was called (apr_procattr_create in
> this case) and returning that? Is this just a flood thing I don't know
> about?
Nope. I'm not so familliar with APR, so a message to stderr plus APR_EGENERAL
is a safe bet. If this looks really obscure considering APR concepts, then
please feel free to commit a fix.
regards,
Jacek Prucia
Re: cvs commit: httpd-test/flood config.h.in flood_round_robin.c
Posted by Cliff Woolley <jw...@virginia.edu>.
On Sun, 7 Sep 2003 jacekp@apache.org wrote:
> + if (apr_procattr_create(&procattr, rp->pool) != APR_SUCCESS) {
> + apr_file_printf(local_stderr,
> + "apr_procattr_create failed for '%s'\n",
> + rp->url[rp->current_url].responsescript);
> + return APR_EGENERAL;
> + }
Why do all of these return APR_EGENERAL rather than catching the
apr_status_t from the function that was called (apr_procattr_create in
this case) and returning that? Is this just a flood thing I don't know
about?
--Cliff