httpd-cvs mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From cove...@apache.org
Subject svn commit: r758626 - in /httpd/httpd/trunk: CHANGES docs/manual/mod/mod_proxy_ftp.xml modules/proxy/mod_proxy_ftp.c
Date Thu, 26 Mar 2009 13:25:35 GMT
Author: covener
Date: Thu Mar 26 13:25:25 2009
New Revision: 758626

URL: http://svn.apache.org/viewvc?rev=758626&view=rev
Log:
Add mod_proxy_ftp directives ProxyFtpListOnWildcard and ProxyFtpEscapeWildcards
to allow filenames with globbing characters to be retrieved instead of
presented in a directory listing.

Submitted by: Dan Poirier <poirier pobox.com>
Reviewed by: covener


Modified:
    httpd/httpd/trunk/CHANGES
    httpd/httpd/trunk/docs/manual/mod/mod_proxy_ftp.xml
    httpd/httpd/trunk/modules/proxy/mod_proxy_ftp.c

Modified: httpd/httpd/trunk/CHANGES
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/CHANGES?rev=758626&r1=758625&r2=758626&view=diff
==============================================================================
--- httpd/httpd/trunk/CHANGES [utf-8] (original)
+++ httpd/httpd/trunk/CHANGES [utf-8] Thu Mar 26 13:25:25 2009
@@ -2,6 +2,10 @@
 
 Changes with Apache 2.3.3
 
+  *) mod_proxy_ftp: Add ProxyFtpListOnWildcard directive to allow files with
+     globbing characters to be retrieved instead of converted into a 
+     directory listing.  PR 46789 [Dan Poirier <poirier pobox.com>]
+
   *) Provide ap_set_retained_data()/ap_get_retained_data() for preservation
      of module state across unload/load.  [Jeff Trawick]
 

Modified: httpd/httpd/trunk/docs/manual/mod/mod_proxy_ftp.xml
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/docs/manual/mod/mod_proxy_ftp.xml?rev=758626&r1=758625&r2=758626&view=diff
==============================================================================
--- httpd/httpd/trunk/docs/manual/mod/mod_proxy_ftp.xml (original)
+++ httpd/httpd/trunk/docs/manual/mod/mod_proxy_ftp.xml Thu Mar 26 13:25:25 2009
@@ -144,5 +144,57 @@
       </note>
     </section> <!-- /ftppass -->
 
+    <section id="wildcard"><title>Why do I get a file listing when I expected
+        a file to be downloaded?</title>
+      <p>In order to allow both browsing the directories on an FTP server and
+        downloading files, Apache looks at the request URL.  If it looks like
+        a directory, or contains wildcard characters ("*?[{~"), then it
+        guesses that a listing is wanted instead of a download.</p>
+      <p>You can disable the special handling of names with wildcard characters.
+        See the <directive>ProxyFtpListOnWildcard</directive> directive.
+      </p>
+    </section> <!-- /wildcard -->
+       
+<directivesynopsis>
+<name>ProxyFtpListOnWildcard</name>
+<description>Whether wildcards in requested filenames trigger a file listing</description>
+<syntax>ProxyFtpListOnWildcard [on|off]</syntax>
+<default>on</default>
+<contextlist><context>server config</context><context>virtual host</context>
+  <context>directory</context></contextlist>
+<compatibility>Available in Apache xxx and later</compatibility>
+
+<usage>
+  <p>The <directive>ProxyFtpListOnWildcard</directive> directive
+    controls whether wildcard characters ("*?[{~") in requested
+    filenames cause <module>mod_proxy_ftp</module> to return a listing
+    of files instead of downloading a file.  By default (value on),
+    they do.  Set to "off" to allow downloading files even if they
+    have wildcard characters in their names.</p>
+</usage>
+</directivesynopsis>
+
+<directivesynopsis>
+<name>ProxyFtpEscapeWildcards</name>
+<description>Whether wildcards in requested filenames are escaped when sent to the
FTP server</description>
+<syntax>ProxyFtpEscapeWildcards [on|off]</syntax>
+<default>on</default>
+<contextlist><context>server config</context><context>virtual host</context>
+  <context>directory</context></contextlist>
+<compatibility>Available in Apache xxx and later</compatibility>
+
+<usage>
+  <p>The <directive>ProxyFtpEscapeWildcards</directive> directive
+    controls whether wildcard characters ("*?[{~") in requested
+    filenames are escaped with backslash before sending them to the
+    FTP server.  That is the default behavior, but many FTP servers
+    don't know about the escaping and try to serve the literal filenames
+    they were sent, including the backslashes in the names.  </p>
+    <p>Set to "off" to allow downloading files with wildcards
+    in their names from FTP servers that don't understand wildcard
+    escaping.</p>
+</usage>
+</directivesynopsis>
+
 
 </modulesynopsis>

Modified: httpd/httpd/trunk/modules/proxy/mod_proxy_ftp.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/proxy/mod_proxy_ftp.c?rev=758626&r1=758625&r2=758626&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/proxy/mod_proxy_ftp.c (original)
+++ httpd/httpd/trunk/modules/proxy/mod_proxy_ftp.c Thu Mar 26 13:25:25 2009
@@ -37,6 +37,68 @@
 
 module AP_MODULE_DECLARE_DATA proxy_ftp_module;
 
+typedef struct {
+    int ftp_list_on_wildcard;
+    int ftp_list_on_wildcard_set;
+    int ftp_escape_wildcards;
+    int ftp_escape_wildcards_set;
+} proxy_ftp_dir_conf;
+
+static void *create_proxy_ftp_dir_config(apr_pool_t *p, char *dummy)
+{
+    proxy_ftp_dir_conf *new =
+        (proxy_ftp_dir_conf *) apr_pcalloc(p, sizeof(proxy_ftp_dir_conf));
+
+    /* Put these in the dir config so they work inside <Location> */
+    new->ftp_list_on_wildcard = 1;
+    new->ftp_escape_wildcards = 1;
+
+    return (void *) new;
+}
+
+static void *merge_proxy_ftp_dir_config(apr_pool_t *p, void *basev, void *addv)
+{
+    proxy_ftp_dir_conf *new = (proxy_ftp_dir_conf *) apr_pcalloc(p, sizeof(proxy_ftp_dir_conf));
+    proxy_ftp_dir_conf *add = (proxy_ftp_dir_conf *) addv;
+    proxy_ftp_dir_conf *base = (proxy_ftp_dir_conf *) basev;
+
+    /* Put these in the dir config so they work inside <Location> */
+    new->ftp_list_on_wildcard = add->ftp_list_on_wildcard_set ?
+                                add->ftp_list_on_wildcard :
+                                base->ftp_list_on_wildcard;
+    new->ftp_list_on_wildcard_set = add->ftp_list_on_wildcard_set ?
+                                1 :
+                                base->ftp_list_on_wildcard_set;
+    new->ftp_escape_wildcards = add->ftp_escape_wildcards_set ?
+                                add->ftp_escape_wildcards :
+                                base->ftp_escape_wildcards;
+    new->ftp_escape_wildcards_set = add->ftp_escape_wildcards_set ?
+                                1 :
+                                base->ftp_escape_wildcards_set;
+
+    return new;
+}
+
+static const char *set_ftp_list_on_wildcard(cmd_parms *cmd, void *dconf,
+                                            int flag)
+{
+    proxy_ftp_dir_conf *conf = dconf;
+
+    conf->ftp_list_on_wildcard = flag;
+    conf->ftp_list_on_wildcard_set = 1;
+    return NULL;
+}
+
+static const char *set_ftp_escape_wildcards(cmd_parms *cmd, void *dconf,
+                                            int flag)
+{
+    proxy_ftp_dir_conf *conf = dconf;
+
+    conf->ftp_escape_wildcards = flag;
+    conf->ftp_escape_wildcards_set = 1;
+    return NULL;
+}
+
 /*
  * Decodes a '%' escaped string, and returns the number of characters
  */
@@ -63,13 +125,21 @@
  * Escape the globbing characters in a path used as argument to
  * the FTP commands (SIZE, CWD, RETR, MDTM, ...).
  * ftpd assumes '\\' as a quoting character to escape special characters.
+ * Just returns the original string if ProxyFtpEscapeWildcards has been
+ * configured "off".
  * Returns: escaped string
  */
 #define FTP_GLOBBING_CHARS "*?[{~"
-static char *ftp_escape_globbingchars(apr_pool_t *p, const char *path)
+static const char *ftp_escape_globbingchars(apr_pool_t *p, const char *path, proxy_ftp_dir_conf
*dconf)
 {
-    char *ret = apr_palloc(p, 2*strlen(path)+sizeof(""));
+    char *ret;
     char *d;
+    
+    if (!dconf->ftp_escape_wildcards) {
+        return path;
+    }
+
+    ret = apr_palloc(p, 2*strlen(path)+sizeof(""));
     for (d = ret; *path; ++path) {
         if (strchr(FTP_GLOBBING_CHARS, *path) != NULL)
             *d++ = '\\';
@@ -809,6 +879,8 @@
 #if defined(USE_MDTM) && (defined(HAVE_TIMEGM) || defined(HAVE_GMTOFF))
     apr_time_t mtime = 0L;
 #endif
+    proxy_ftp_dir_conf *fdconf = ap_get_module_config(r->per_dir_config,
+                                                      &proxy_ftp_module);
 
     /* stuff for PASV mode */
     int connect = 0, use_port = 0;
@@ -1157,7 +1229,7 @@
          * We could also have extended gen_test_char.c with a special T_ESCAPE_FTP_PATH
          */
         rc = proxy_ftp_command(apr_pstrcat(p, "CWD ",
-                           ftp_escape_globbingchars(p, path), CRLF, NULL),
+                           ftp_escape_globbingchars(p, path, fdconf), CRLF, NULL),
                            r, origin, bb, &ftpmessage);
         *strp = '/';
         /* responses: 250, 421, 500, 501, 502, 530, 550 */
@@ -1480,9 +1552,10 @@
     }
 
     /* If len == 0 then it must be a directory (you can't RETR nothing)
-     * Also, don't allow to RETR by wildcard. Instead, create a dirlisting
+     * Also, don't allow to RETR by wildcard. Instead, create a dirlisting,
+     * unless ProxyFtpListOnWildcard is off.
      */
-    if (len == 0 || ftp_check_globbingchars(path)) {
+    if (len == 0 || (ftp_check_globbingchars(path) && fdconf->ftp_list_on_wildcard))
{
         dirlisting = 1;
     }
     else {
@@ -1503,7 +1576,7 @@
         /* Therefore: switch to binary if the user did not specify ";type=a" */
         ftp_set_TYPE(xfer_type, r, origin, bb, &ftpmessage);
         rc = proxy_ftp_command(apr_pstrcat(p, "SIZE ",
-                           ftp_escape_globbingchars(p, path), CRLF, NULL),
+                           ftp_escape_globbingchars(p, path, fdconf), CRLF, NULL),
                            r, origin, bb, &ftpmessage);
         if (rc == -1 || rc == 421) {
             return ftp_proxyerror(r, backend, HTTP_BAD_GATEWAY,
@@ -1522,7 +1595,7 @@
                              "proxy: FTP: SIZE shows this is a directory");
             dirlisting = 1;
             rc = proxy_ftp_command(apr_pstrcat(p, "CWD ",
-                           ftp_escape_globbingchars(p, path), CRLF, NULL),
+                           ftp_escape_globbingchars(p, path, fdconf), CRLF, NULL),
                            r, origin, bb, &ftpmessage);
             /* possible results: 250, 421, 500, 501, 502, 530, 550 */
             /* 250 Requested file action okay, completed. */
@@ -1583,7 +1656,7 @@
          *     The "." and subsequent digits ("sss") are optional. <..>
          *     Time values are always represented in UTC (GMT)
          */
-        rc = proxy_ftp_command(apr_pstrcat(p, "MDTM ", ftp_escape_globbingchars(p, path),
CRLF, NULL),
+        rc = proxy_ftp_command(apr_pstrcat(p, "MDTM ", ftp_escape_globbingchars(p, path,
fdconf), CRLF, NULL),
                                r, origin, bb, &ftpmessage);
         /* then extract the Last-Modified time from it (YYYYMMDDhhmmss or YYYYMMDDhhmmss.xxx
GMT). */
         if (rc == 213) {
@@ -1622,7 +1695,7 @@
     }
 #endif /* USE_MDTM */
 /* FIXME: Handle range requests - send REST */
-        buf = apr_pstrcat(p, "RETR ", ftp_escape_globbingchars(p, path), CRLF, NULL);
+        buf = apr_pstrcat(p, "RETR ", ftp_escape_globbingchars(p, path, fdconf), CRLF, NULL);
     }
     rc = proxy_ftp_command(buf, r, origin, bb, &ftpmessage);
     /* rc is an intermediate response for the LIST or RETR commands */
@@ -1659,7 +1732,7 @@
         ftp_set_TYPE('A', r, origin, bb, NULL);
 
         rc = proxy_ftp_command(apr_pstrcat(p, "CWD ",
-                               ftp_escape_globbingchars(p, path), CRLF, NULL),
+                               ftp_escape_globbingchars(p, path, fdconf), CRLF, NULL),
                                r, origin, bb, &ftpmessage);
         /* possible results: 250, 421, 500, 501, 502, 530, 550 */
         /* 250 Requested file action okay, completed. */
@@ -1929,12 +2002,22 @@
                               NULL, AP_FTYPE_RESOURCE);
 }
 
+static const command_rec proxy_ftp_cmds[] =
+{
+    AP_INIT_FLAG("ProxyFtpListOnWildcard", set_ftp_list_on_wildcard, NULL,
+     RSRC_CONF|ACCESS_CONF, "Whether wildcard characters in a path cause mod_proxy_ftp to
list the files instead of trying to get them. Defaults to on."),
+    AP_INIT_FLAG("ProxyFtpEscapeWildcards", set_ftp_escape_wildcards, NULL,
+     RSRC_CONF|ACCESS_CONF, "Whether the proxy should escape wildcards in paths before sending
them to the FTP server.  Defaults to on, but most FTP servers will need it turned off if you
need to manage paths that contain wildcard characters."),
+    {NULL}
+};
+
+
 module AP_MODULE_DECLARE_DATA proxy_ftp_module = {
     STANDARD20_MODULE_STUFF,
-    NULL,                       /* create per-directory config structure */
-    NULL,                       /* merge per-directory config structures */
+    create_proxy_ftp_dir_config,/* create per-directory config structure */
+    merge_proxy_ftp_dir_config, /* merge per-directory config structures */
     NULL,                       /* create per-server config structure */
     NULL,                       /* merge per-server config structures */
-    NULL,                       /* command apr_table_t */
+    proxy_ftp_cmds,             /* command apr_table_t */
     ap_proxy_ftp_register_hook  /* register hooks */
 };



Mime
View raw message