This probably belongs in contrib/patches. It is a quick'n'dirty hack I did few
days ago, to simulate applet making network connection.  Basically it allows
for something like this:

<url responsescript="/path/to/script.py">http://www.example.com/</url>

Such script get's whole response buffer (headers and the body). You can then
just do about everything you want. Parse script (plain regexp, or HTML
parser), check various elements, and (my case) simulate some dorky applet
making connections to server where it came from. If everything is ok, then
scrpt schould exit with zero. Any other exit code triggers error and stops
processing (much like regexp failure).

This patch just has one simple problem. If the job is fancy (like my applet
connection), then it distorts response times, as apr_proc_wait is blocking.
Because of that it doesn't seem like this code belongs in main trunk. How
about contrib/patches?

regards,
Jacek Prucia



diff -urN flood.orig/config.h.in flood/config.h.in
--- flood.orig/config.h.in      2003-08-09 23:23:51.000000000 +0200
+++ flood/config.h.in   2003-08-10 09:25:38.000000000 +0200
@@ -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"
diff -urN flood.orig/flood_round_robin.c flood/flood_round_robin.c
--- flood.orig/flood_round_robin.c      2003-08-09 09:33:27.000000000 +0200
+++ flood/flood_round_robin.c   2003-08-10 09:41:21.000000000 +0200
@@ -61,6 +61,7 @@
 #include <apr_lib.h>
 #include <apr_hash.h>
 #include <apr_base64.h>
+#include <apr_thread_proc.h>
 
 #if APR_HAVE_STRINGS_H
 #include <strings.h>    /* strncasecmp */
@@ -114,6 +115,7 @@
     char *payloadtemplate;
     char *requesttemplate;
     char *responsetemplate;
+    char *responsescript;
     char *responsename;
     int responselen;
     char *user;
@@ -496,6 +498,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;
@@ -952,6 +959,87 @@
                      rp->url[rp->current_url].responselen, newValue);
         regfree(&re);
     }
+    if (rp->url[rp->current_url].responsescript)
+    {
+        int exitcode = 0;
+        apr_size_t nbytes;
+        apr_proc_t *proc;
+        apr_procattr_t *procattr;
+
+        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));
+
+        // createproc
+        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;
+        }
+
+        nbytes = strlen(resp->rbuf);
+        if (apr_file_write_full(proc->in, resp->rbuf, nbytes, NULL)
+                                != APR_SUCCESS) {
+            apr_file_printf(local_stderr,
+                            "apr_file_write_full failed for '%s'\n",
+                            rp->url[rp->current_url].responsescript);
+            return APR_EGENERAL;
+        }
+        apr_file_close(proc->in);
+
+        if (apr_proc_wait(proc, &exitcode, NULL, APR_WAIT) != 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' done with '%i' exit 
code\n",
+                            rp->url[rp->current_url].responsescript, exitcode);
+            return APR_EGENERAL;
+        }
+
+    }
 
     return APR_SUCCESS;
 }

Reply via email to