You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@httpd.apache.org by Francis Daly <de...@daoine.org> on 2002/11/27 14:38:20 UTC

[PATCH] Case-insensitive listing in mod_autoindex

Hi there,

Apache/1.3.24+ had the option to sort the file list generated by
mod_autoindex in a case-insensitive fashion, by using "IndexOptions
+IgnoreCase".

This functionality has not been carried over to Apache/2.

There is an open bug report on the issue -- 
http://nagoya.apache.org/bugzilla/show_bug.cgi?14276

I'm not sure if there was a deliberate decision taken to remove this
functionality from Apache/2, or if it's just that no-one has yet gotten
around to putting it back in.

On the off-chance that it is the latter, I offer the following patch 
which provides a similar function, but uses a different directive.  It
adds "NameNoCase" as a possible second argument of IndexOrderDefault.
It also adds "(case)" to the output list heading as a link to the
case-insensitively-sorted list, if the client is able to choose that.

Note that this is not equivalent to the old IgnoreCase; if identical
functionality is wanted, then a different patch will be needed.

Built and tested against 2.0.43, it was adjusted to apply cleanly to
the current cvs version of mod_autoindex.c, 1.112.

The second patch should apply cleanly to version 1.12 of
mod_autoindex.xml.  It contains the usual amount of presumption; a true
compatibility note can be added depending on when and if the patch
is accepted.

Any comments welcome,

	f
-- 
Francis Daly        deva@daoine.org

--- mod_autoindex.c-1.112	Wed Nov 27 12:53:44 2002
+++ mod_autoindex.c	Wed Nov 27 13:25:04 2002
@@ -119,10 +119,11 @@
  * Define keys for sorting.
  */
 #define K_NAME 'N'              /* Sort by file name (default) */
+#define K_NO_CASE 'C'           /* Case-insensitive name */
 #define K_LAST_MOD 'M'          /* Last modification date */
 #define K_SIZE 'S'              /* Size (absolute, not as displayed) */
 #define K_DESC 'D'              /* Description */
-#define K_VALID "NMSD"          /* String containing _all_ valid K_ opts */
+#define K_VALID "NCMSD"         /* String containing _all_ valid K_ opts */
 
 #define D_ASCENDING 'A'
 #define D_DESCENDING 'D'
@@ -537,6 +538,9 @@
     if (!strcasecmp(key, "Name")) {
         d_cfg->default_keyid = K_NAME;
     }
+    else if (!strcasecmp(key, "NameNoCase")) {
+        d_cfg->default_keyid = K_NO_CASE;
+    }
     else if (!strcasecmp(key, "Date")) {
         d_cfg->default_keyid = K_LAST_MOD;
     }
@@ -547,8 +551,8 @@
         d_cfg->default_keyid = K_DESC;
     }
     else {
-        return "Second keyword must be 'Name', 'Date', 'Size', or "
-               "'Description'";
+        return "Second keyword must be 'Name', 'NameNoCase', 'Date', "
+               "'Size', or 'Description'";
     }
 
     return NULL;
@@ -573,7 +577,7 @@
     AP_INIT_RAW_ARGS("IndexOptions", add_opts, NULL, DIR_CMD_PERMS,
                      "one or more index options [+|-][]"),
     AP_INIT_TAKE2("IndexOrderDefault", set_default_order, NULL, DIR_CMD_PERMS,
-                  "{Ascending,Descending} {Name,Size,Description,Date}"),
+                  "{Ascending,Descending} {Name,NameNoCase,Size,Description,Date}"),
     AP_INIT_ITERATE("IndexIgnore", add_ignore, NULL, DIR_CMD_PERMS,
                     "one or more file extensions"),
     AP_INIT_ITERATE2("AddDescription", add_desc, BY_PATH, DIR_CMD_PERMS,
@@ -1552,6 +1556,10 @@
         ap_rputs("<th>", r);
         emit_link(r, "Name", K_NAME, keyid, direction, 
                   colargs, static_columns);
+        if (!static_columns) {
+            emit_link(r, " (case)", K_NO_CASE, keyid, direction, 
+                      colargs, static_columns);
+        }
         if (!(autoindex_opts & SUPPRESS_LAST_MOD)) {
             ap_rputs("</th><th>", r);
             emit_link(r, "Last modified", K_LAST_MOD, keyid, direction, 
@@ -1597,7 +1605,13 @@
         }
         emit_link(r, "Name", K_NAME, keyid, direction, 
                   colargs, static_columns);
-        ap_rputs(pad_scratch + 4, r);
+        if (!static_columns) {
+            emit_link(r, " (case)", K_NO_CASE, keyid, direction, 
+                      colargs, static_columns);
+            ap_rputs(pad_scratch + 4 + 7, r);
+        } else {
+            ap_rputs(pad_scratch + 4, r);
+        }
         /*
          * Emit the guaranteed-at-least-one-space-between-columns byte.
          */
@@ -1891,6 +1905,17 @@
         else {
             result = strcmp(c1->desc ? c1->desc : "",
                             c2->desc ? c2->desc : "");
+        }
+        if (result) {
+            return result;
+        }
+        break;
+    case K_NO_CASE:
+        if (c1->version_sort) {
+            result = apr_strnatcasecmp(c1->name, c2->name);
+        } 
+        else {
+            result = strcasecmp(c1->name, c2->name);
         }
         if (result) {
             return result;

--- mod_autoindex.xml-1.12	Wed Nov 27 13:04:42 2002
+++ mod_autoindex.xml	Wed Nov 27 13:07:49 2002
@@ -813,7 +813,7 @@
 <name>IndexOrderDefault</name>
 <description>Sets the default ordering of the directory index</description>
 <syntax>IndexOrderDefault Ascending|Descending
-Name|Date|Size|Description</syntax>
+Name|NameNoCase|Date|Size|Description</syntax>
 <default>IndexOrderDefault Ascending Name</default>
 <contextlist><context>server config</context><context>virtual host</context>
 <context>directory</context><context>.htaccess</context>
@@ -832,9 +832,9 @@
     arguments. The first must be either <code>Ascending</code> or
     <code>Descending</code>, indicating the direction of the sort.
     The second argument must be one of the keywords <code>Name</code>,
-    <code>Date</code>, <code>Size</code>, or <code>Description</code>,
-    and identifies the primary key. The secondary key is
-    <em>always</em> the ascending filename.</p>
+    <code>NameNoCase</code>, <code>Date</code>, <code>Size</code>, or 
+    <code>Description</code>, and identifies the primary key. The 
+    secondary key is <em>always</em> the ascending filename.</p>
 
     <p>You can force a directory listing to only be displayed in a
     particular order by combining this directive with the <code><a
@@ -842,6 +842,8 @@
     >SuppressColumnSorting</a></code> index option; this will prevent
     the client from requesting the directory listing in a different
     order.</p>
+
+    <note>NameNoCase is available after 2.0.44</note>
 </usage>
 </directivesynopsis>
 

Re: [PATCH] Case-insensitive listing in mod_autoindex

Posted by "William A. Rowe, Jr." <wr...@apache.org>.
At 03:25 AM 11/28/2002, Francis Daly wrote:
>On Wed, Nov 27, 2002 at 11:29:36AM -0600, William A. Rowe, Jr. wrote:
>> Francis, to the extent you don't want to reinvent the wheel;
>> 
>> http://cvs.apache.org/viewcvs/apache-1.3/src/modules/standard/mod_autoindex.c
>> 
>> should help you find that patch.  Because 2.0 split before the feature
>> was added, we 'missed' the new feature.
>
>Cheers, the 1.3 code was the "heavy inspiration" for this patch.
>
>Attached is a patch to introduce "IgnoreCase" as an allowable
>"IndexOption", restoring a function from the late 1.3 series.
>
>It's a fairly straightforward patch, but with one gotcha that
>might be the reason why it hasn't been included prior to now:
>this addition forces the 17th bit of the options to be used.

Not a problem - it's totally private to the module.  +1 to this patch
on concept.  If nobody beats me to it, I'll apply when I have a chance
to run regressions later this weekend.


Re: [PATCH] Case-insensitive listing in mod_autoindex

Posted by Francis Daly <de...@daoine.org>.
On Wed, Nov 27, 2002 at 11:29:36AM -0600, William A. Rowe, Jr. wrote:
> Francis, to the extent you don't want to reinvent the wheel;
> 
> http://cvs.apache.org/viewcvs/apache-1.3/src/modules/standard/mod_autoindex.c
> 
> should help you find that patch.  Because 2.0 split before the feature
> was added, we 'missed' the new feature.

Cheers, the 1.3 code was the "heavy inspiration" for this patch.

Attached is a patch to introduce "IgnoreCase" as an allowable
"IndexOption", restoring a function from the late 1.3 series.

It's a fairly straightforward patch, but with one gotcha that
might be the reason why it hasn't been included prior to now:

this addition forces the 17th bit of the options to be used.

It works fine on my 32-bit-int system, but may have an impact
on a 16-bit-int system.  The value was apr_int32_t already, but
was referred to as an int in some places.  I think I've switched
them all (both) to apr_int32_t, although it'd be worth someone
with access to a 16-bit-int system letting their compiler verify
that.

The suggested docs patch is "strongly reminiscent" of the 1.3.27
docs.  This is not a coincidence.

Built and tested against the released 2.0.43 code, the patches
apply (with a line offset) to the current CVS versions.

As usual, criticisms and suggested improvements welcome.

	f
-- 
Francis Daly        deva@daoine.org

--- modules/generators/mod_autoindex.c	Wed Nov 27 20:44:33 2002
+++ modules/generators/mod_autoindex.c	Wed Nov 27 21:59:51 2002
@@ -110,6 +110,7 @@
 #define FANCY_INDEXING      0x2000
 #define TABLE_INDEXING      0x4000
 #define IGNORE_CLIENT       0x8000
+#define SORT_NOCASE         0x10000
 
 #define K_NOADJUST 0
 #define K_ADJUST 1
@@ -353,7 +354,7 @@
     opts_add = d_cfg->incremented_opts;
     opts_remove = d_cfg->decremented_opts;
     while (optstr[0]) {
-        int option = 0;
+        apr_int32_t option = 0;
 
         w = ap_getword_conf(cmd->pool, &optstr);
         if ((*w == '+') || (*w == '-')) {
@@ -407,6 +408,9 @@
         else if (!strcasecmp(w, "VersionSort")) {
             option = VERSION_SORT;
         }
+        else if (!strcasecmp(w, "IgnoreCase")) {
+            option = SORT_NOCASE;
+        }
         else if (!strcasecmp(w, "None")) {
             if (action != '\0') {
                 return "Cannot combine '+' or '-' with 'None' keyword";
@@ -727,6 +731,7 @@
     int ascending, version_sort;
     char key;
     int isdir;
+    int ignore_case;
 };
 
 static char *find_item(request_rec *r, apr_array_header_t *list, int path_only)
@@ -1274,7 +1279,7 @@
 }
 
 static struct ent *make_autoindex_entry(const apr_finfo_t *dirent, 
-                                        int autoindex_opts,
+                                        apr_int32_t autoindex_opts,
                                         autoindex_config_rec *d,
                                         request_rec *r, char keyid,
                                         char direction,
@@ -1337,6 +1342,7 @@
     p->key = apr_toupper(keyid);
     p->ascending = (apr_toupper(direction) == D_ASCENDING);
     p->version_sort = !!(autoindex_opts & VERSION_SORT);
+    p->ignore_case = !!(autoindex_opts & SORT_NOCASE);
 
     if (autoindex_opts & (FANCY_INDEXING | TABLE_INDEXING)) {
         p->lm = rr->finfo.mtime;
@@ -1888,6 +1894,17 @@
             return result;
         }
         break;
+    }
+    if (c1->ignore_case) {
+        if (c1->version_sort) {
+            result = apr_strnatcasecmp(c1->name, c2->name);
+        }
+        else {
+            result = strcasecmp(c1->name, c2->name);
+        }
+        if (result) {
+            return result;
+        }
     }
     if (c1->version_sort) {
         return apr_strnatcmp(c1->name, c2->name);

--- manual/mod/mod_autoindex.xml	Thu Nov 21 01:39:04 2002
+++ manual/mod/mod_autoindex.xml	Wed Nov 27 23:57:13 2002
@@ -73,6 +73,10 @@
     option below may be added to any request for the directory
     resource.</p>
 
+    <p>After Apache 2.0.44, the sorting by file name
+    can be case-sensitive or not, according to <code><a
+    href="#indexoptions:ignorecase">IndexOptions IgnoreCase</a></code>
+
     <ul>
       <li><code>C=N</code> sorts the directory by file name</li>
 
@@ -592,6 +596,19 @@
       loaded. If no value is given for the option, it defaults to
       the standard width of the icons supplied with the Apache
       software.</dd>
+
+      <dt><a name="indexoptions:ignorecase"
+               id="indexoptions:ignorecase">IgnoreCase</a> (<em>Apache
+      2.0.44 and later</em>)</dt>
+
+      <dd> If this option is enabled, names are sorted in
+      case-insensitive manner. For instance, if the sort order is
+      ascending by name, and <code>IgnoreCase</code> is enabled, file
+      <code>Zeta</code> will be listed after file <code>alpha</code>
+      (Note: file <code>GAMMA</code> will always be listed before file
+      <code>gamma</code>). <b>This option only has an effect if <a
+      href="#indexoptions:fancyindexing"><code>FancyIndexing</code></a>
+      is also enabled.</b></dd>
 
       <dt><a name="indexoptions:ignoreclient"
                id="indexoptions:ignoreclient">IgnoreClient</a></dt>

Re: [PATCH] Case-insensitive listing in mod_autoindex

Posted by "William A. Rowe, Jr." <wr...@apache.org>.
Francis, to the extent you don't want to reinvent the wheel;

http://cvs.apache.org/viewcvs/apache-1.3/src/modules/standard/mod_autoindex.c

should help you find that patch.  Because 2.0 split before the feature
was added, we 'missed' the new feature.

At 11:02 AM 11/27/2002, Francis Daly wrote:
>On Wed, Nov 27, 2002 at 11:33:08AM -0500, Joshua Slive wrote:
>> On Wed, 27 Nov 2002, Francis Daly wrote:
>
>> > Note that this is not equivalent to the old IgnoreCase; if identical
>> > functionality is wanted, then a different patch will be needed.
>> 
>> Unless there is a good reason to change, it is better to keep the
>> configuration the same as in 1.3.  There is no need to throw unnecessary
>> obstacles in the way of upgraders.
>
>Cool -- I'll see about putting together a straightforward forward-port
>of the IgnoreCase IndexOption as an alternative to this patch, then.
>
>(Unless someone beats me to it, of course.)
>
>All the best,
>
>        f
>-- 
>Francis Daly        deva@daoine.org


Re: [PATCH] Case-insensitive listing in mod_autoindex

Posted by Francis Daly <de...@daoine.org>.
On Wed, Nov 27, 2002 at 11:33:08AM -0500, Joshua Slive wrote:
> On Wed, 27 Nov 2002, Francis Daly wrote:

> > Note that this is not equivalent to the old IgnoreCase; if identical
> > functionality is wanted, then a different patch will be needed.
> 
> Unless there is a good reason to change, it is better to keep the
> configuration the same as in 1.3.  There is no need to throw unnecessary
> obstacles in the way of upgraders.

Cool -- I'll see about putting together a straightforward forward-port
of the IgnoreCase IndexOption as an alternative to this patch, then.

(Unless someone beats me to it, of course.)

All the best,

	f
-- 
Francis Daly        deva@daoine.org

Re: [PATCH] Case-insensitive listing in mod_autoindex

Posted by Joshua Slive <jo...@slive.ca>.
On Wed, 27 Nov 2002, Francis Daly wrote:
> Note that this is not equivalent to the old IgnoreCase; if identical
> functionality is wanted, then a different patch will be needed.

Unless there is a good reason to change, it is better to keep the
configuration the same as in 1.3.  There is no need to throw unnecessary
obstacles in the way of upgraders.

Joshua.