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