httpd-apreq-cvs mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From is...@apache.org
Subject svn commit: r464941 - /httpd/apreq/branches/enhanced-cgi/library/module_cgi.c
Date Tue, 17 Oct 2006 15:15:55 GMT
Author: issac
Date: Tue Oct 17 08:15:54 2006
New Revision: 464941

URL: http://svn.apache.org/viewvc?view=rev&rev=464941
Log:
enable CGI scripts running from a terminal (shell) to lazily request their query_string/body/cookie
parameters interactively via stdin/stdout

Modified:
    httpd/apreq/branches/enhanced-cgi/library/module_cgi.c

Modified: httpd/apreq/branches/enhanced-cgi/library/module_cgi.c
URL: http://svn.apache.org/viewvc/httpd/apreq/branches/enhanced-cgi/library/module_cgi.c?view=diff&rev=464941&r1=464940&r2=464941
==============================================================================
--- httpd/apreq/branches/enhanced-cgi/library/module_cgi.c (original)
+++ httpd/apreq/branches/enhanced-cgi/library/module_cgi.c Tue Oct 17 08:15:54 2006
@@ -38,6 +38,15 @@
 #define CGILOG_LEVELMASK 7
 #define CGILOG_MARK     __FILE__, __LINE__
 
+/** Interactive patch:
+ * TODO Don't use 65K buffer
+ * TODO Handle empty/non-existant parameters
+ * TODO Allow body elements to be files
+ * TODO When running body/get/cookies all at once, include previous cached
+ * values (and don't start at 0 in count)
+ * TODO What happens if user does apreq_param, but needs POST value - we'll
+ * never catch it now, as args param will match...
+ */
 
 
 
@@ -61,6 +70,8 @@
     apr_bucket_brigade          *in;
     apr_bucket_brigade          *tmpbb;
 
+    int interactive_mode;
+    apr_file_t *sout, *sin;
 };
 
 #define CRLF "\015\012"
@@ -82,6 +93,19 @@
     {NULL,      -1},
 };
 
+static char* chomp(char* str) {
+    apr_size_t p = strlen(str);
+    while (--p > 0) {
+        switch ((char)(str[p])) {
+        case '\015':
+        case '\012':str[p]='\000';
+                    break;
+        default:return str;
+        }
+        }
+    return str;
+}
+
 static const char *cgi_header_in(apreq_handle_t *handle,
                                  const char *name)
 {
@@ -178,8 +202,6 @@
     apr_file_t *file;
     apr_bucket *eos, *pipe;
 
-    req->body  = apr_table_make(pool, APREQ_DEFAULT_NELTS);
-
     if (cl_header != NULL) {
         char *dummy;
         apr_int64_t content_length = apr_strtoi64(cl_header, &dummy, 0);
@@ -326,10 +348,36 @@
 {
     struct cgi_handle *req = (struct cgi_handle *)handle;
 
+    if (req->interactive_mode && req->jar_status != APR_SUCCESS) {
+        char buf[65536];
+        char *name, *val;
+        apreq_cookie_t *p;
+        int i = 1;
+        apr_file_printf(req->sout, "[CGI] Requested all cookies\n");
+        while (1) {
+            apr_file_printf(req->sout, "[CGI] Please enter a name for cookie %d (or END
to end): ",
+                     i++);
+            apr_file_gets(buf, 65536, req->sin);
+            chomp(buf);
+            if (!strcmp(buf, "END")) {
+                break;
+            }
+            name = apr_pstrdup(handle->pool, buf);
+            apr_file_printf(req->sout, "[CGI] Please enter a value for cookie %s: ",
+                     name);
+            apr_file_gets(buf, 65536, req->sin);
+            chomp(buf);
+            p = apreq_cookie_make(handle->pool, name, strlen(name), buf, strlen(buf));
+            apreq_cookie_tainted_on(p);
+            apreq_value_table_add(&p->v, req->jar);
+            val = (char *)p->v.data;
+        }
+        req->jar_status = APR_SUCCESS;
+    } /** Fallthrough */
+
     if (req->jar_status == APR_EINIT) {
         const char *cookies = cgi_header_in(handle, "Cookie");
         if (cookies != NULL) {
-            req->jar = apr_table_make(handle->pool, APREQ_DEFAULT_NELTS);
             req->jar_status =
                 apreq_parse_cookie_header(handle->pool, req->jar, cookies);
         }
@@ -346,10 +394,36 @@
 {
     struct cgi_handle *req = (struct cgi_handle *)handle;
 
+    if (req->interactive_mode && req->args_status != APR_SUCCESS) {
+        char buf[65536];
+        char *name, *val;
+        apreq_param_t *p;
+        int i = 1;
+        apr_file_printf(req->sout, "[CGI] Requested all argument parameters\n");
+        while (1) {
+            apr_file_printf(req->sout, "[CGI] Please enter a name for parameter %d (or
END to end): ",
+                     i++);
+            apr_file_gets(buf, 65536, req->sin);
+            chomp(buf);
+            if (!strcmp(buf, "END")) {
+                break;
+            }
+            name = apr_pstrdup(handle->pool, buf);
+            apr_file_printf(req->sout, "[CGI] Please enter a value for parameter %s: ",
+                     name);
+            apr_file_gets(buf, 65536, req->sin);
+            chomp(buf);
+            p = apreq_param_make(handle->pool, name, strlen(name), buf, strlen(buf));
+            apreq_param_tainted_on(p);
+            apreq_value_table_add(&p->v, req->args);
+            val = (char *)p->v.data;
+        }
+        req->args_status = APR_SUCCESS;
+    } /** Fallthrough */
+
     if (req->args_status == APR_EINIT) {
         const char *qs = cgi_query_string(handle);
         if (qs != NULL) {
-            req->args = apr_table_make(handle->pool, APREQ_DEFAULT_NELTS);
             req->args_status =
                 apreq_parse_query_string(handle->pool, req->args, qs);
         }
@@ -369,19 +443,31 @@
 {
     struct cgi_handle *req = (struct cgi_handle *)handle;
     const apr_table_t *t;
-    const char *val;
+    char *val = NULL;
 
-    if (req->jar_status == APR_EINIT)
+    if (req->jar_status == APR_EINIT && !req->interactive_mode)
         cgi_jar(handle, &t);
     else
         t = req->jar;
 
-    if (t == NULL)
-        return NULL;
+    val = (char *)apr_table_get(t, name);
+    if (val == NULL) {
+        if (!req->interactive_mode) {
+            return NULL;
+        } else {
+            char buf[65536];
+            apreq_cookie_t *p;
+            apr_file_printf(req->sout, "[CGI] Please enter a value for cookie %s: ",
+                            name);
+            apr_file_gets(buf, 65536, req->sin);
+            chomp(buf);
+            p = apreq_cookie_make(handle->pool, name, strlen(name), buf, strlen(buf));
+            apreq_cookie_tainted_on(p);
+            apreq_value_table_add(&p->v, req->jar);
+            val = (char *)p->v.data;
+        }
+    }
 
-    val = apr_table_get(t, name);
-    if (val == NULL)
-        return NULL;
 
     return apreq_value_to_cookie(val);
 }
@@ -391,19 +477,31 @@
 {
     struct cgi_handle *req = (struct cgi_handle *)handle;
     const apr_table_t *t;
-    const char *val;
+    char *val = NULL;
 
-    if (req->args_status == APR_EINIT)
+    if (req->args_status == APR_EINIT && !req->interactive_mode)
         cgi_args(handle, &t);
     else
         t = req->args;
 
-    if (t == NULL)
-        return NULL;
+    val = (char *)apr_table_get(t, name);
+    if (val == NULL) {
+        if (!req->interactive_mode) {
+            return NULL;
+        } else {
+            char buf[65536];
+            apreq_param_t *p;
+            apr_file_printf(req->sout, "[CGI] Please enter a value for parameter %s: ",
+                            name);
+            apr_file_gets(buf, 65536, req->sin);
+            chomp(buf);
+            p = apreq_param_make(handle->pool, name, strlen(name), buf, strlen(buf));
+            apreq_param_tainted_on(p);
+            apreq_value_table_add(&p->v, req->args);
+            val = (char *)p->v.data;
+        }
+    }
 
-    val = apr_table_get(t, name);
-    if (val == NULL)
-        return NULL;
 
     return apreq_value_to_param(val);
 }
@@ -415,6 +513,33 @@
 {
     struct cgi_handle *req = (struct cgi_handle *)handle;
 
+    if (req->interactive_mode && req->body_status != APR_SUCCESS) {
+        char buf[65536];
+        char *name, *val;
+        apreq_param_t *p;
+        int i = 1;
+        apr_file_printf(req->sout, "[CGI] Requested all body parameters\n");
+        while (1) {
+            apr_file_printf(req->sout, "[CGI] Please enter a name for parameter %d (or
END to end): ",
+                     i++);
+            apr_file_gets(buf, 65536, req->sin);
+            chomp(buf);
+            if (!strcmp(buf, "END")) {
+                break;
+            }
+            name = apr_pstrdup(handle->pool, buf);
+            apr_file_printf(req->sout, "[CGI] Please enter a value for parameter %s: ",
+                     name);
+            apr_file_gets(buf, 65536, req->sin);
+            chomp(buf);
+            p = apreq_param_make(handle->pool, name, strlen(name), buf, strlen(buf));
+            apreq_param_tainted_on(p);
+            apreq_value_table_add(&p->v, req->body);
+            val = (char *)p->v.data;
+        }
+        req->body_status = APR_SUCCESS;
+    } /** Fallthrough */
+    
     switch (req->body_status) {
 
     case APR_EINIT:
@@ -436,14 +561,34 @@
                                    const char *name)
 {
     struct cgi_handle *req = (struct cgi_handle *)handle;
-    const char *val;
+    char *val = NULL;
     apreq_hook_t *h;
 
+    if (req->interactive_mode) {
+        val = (char *)apr_table_get(req->body, name);
+        if (val == NULL) {
+            return NULL;
+        } else {
+            char buf[65536];
+            apreq_param_t *p;
+            apr_file_printf(req->sout, "[CGI] Please enter a value for parameter %s: ",
+                            name);
+            apr_file_gets(buf, 65536, req->sin);
+            chomp(buf);
+            p = apreq_param_make(handle->pool, name, strlen(name), buf, strlen(buf));
+            apreq_param_tainted_on(p);
+            apreq_value_table_add(&p->v, req->body);
+            val = (char *)p->v.data;
+            return apreq_value_to_param(val);
+        }
+    }
+
+
     switch (req->body_status) {
 
     case APR_SUCCESS:
 
-        val = apr_table_get(req->body, name);
+        val = (char *)apr_table_get(req->body, name);
         if (val != NULL)
             return apreq_value_to_param(val);
         return NULL;
@@ -459,7 +604,7 @@
 
     case APR_INCOMPLETE:
 
-        val = apr_table_get(req->body, name);
+        val = (char *)apr_table_get(req->body, name);
         if (val != NULL)
             return apreq_value_to_param(val);
 
@@ -492,7 +637,7 @@
         if (req->body == NULL)
             return NULL;
 
-        val = apr_table_get(req->body, name);
+        val = (char *)apr_table_get(req->body, name);
         if (val != NULL)
             return apreq_value_to_param(val);
         return NULL;
@@ -650,6 +795,31 @@
 }
 #endif
 
+/** Determine if we're interactive mode or not.  Order is
+  QUERY_STRING ? NO : Interactive
+
+ I think we should just rely on GATEWAY_INTERFACE to set
+ non-interactive mode, and be interactive if it's not there
+
+ Behaviour change should really be:
+ Always check query_string before prompting user,
+  but rewrite body/cookies to get if interactive
+
+ Definately more work needed here...
+*/
+static int is_interactive_mode(apr_pool_t *pool) {
+    char *value = NULL, qs[] = "GATEWAY_INTERFACE";
+    apr_status_t rv;
+
+    rv = apr_env_get(&value, qs, pool);
+    if (rv != APR_SUCCESS)
+        if (rv == APR_ENOENT)
+            return 1;
+        
+        /** handle else? (!SUCCESS && !ENOENT) */
+    return 0;
+}
+
 static APREQ_MODULE(cgi, 20050425);
 
 APREQ_DECLARE(apreq_handle_t *)apreq_handle_cgi(apr_pool_t *pool)
@@ -674,9 +844,19 @@
     req->read_limit           = (apr_uint64_t) -1;
     req->brigade_limit        = APREQ_DEFAULT_BRIGADE_LIMIT;
 
+    req->args = apr_table_make(pool, APREQ_DEFAULT_NELTS);
+    req->body = apr_table_make(pool, APREQ_DEFAULT_NELTS);
+    req->jar  = apr_table_make(pool, APREQ_DEFAULT_NELTS);
+
     req->args_status =
         req->jar_status =
             req->body_status = APR_EINIT;
+
+    if (is_interactive_mode(pool)) {
+        req->interactive_mode = 1;
+        apr_file_open_stdout(&(req->sout), pool);
+        apr_file_open_stdin(&(req->sin), pool);
+    }
 
     apr_pool_userdata_setn(&req->handle, USER_DATA_KEY, NULL, pool);
 



Mime
View raw message