You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@httpd.apache.org by Rodent of Unusual Size <co...@decus.org> on 1997/10/20 21:06:51 UTC

[PATCH] for mod_autoindex: no-sorting, last-modified

    Okey, here's an improved (?) patch over the one submitted.  It

    o adds the IndexOptions keyword "SuppressColumnSorting"
    o sets the Last-Modified to the mtime of the directory if possible;
      if stat(r->filename) fails (as it probably will on OS/2), no
      Last-Modified is set.  (I find the alternative - waiting until the
      directory has been scanned and setting it to the newest file - to
      be nearly pinning my bogometer.)

    If voted in, the actual patch will be much bigger due to indent
    issues I fixed along the way - but they'll be cosmetic only.

    For 1.3b3.

    #ken    P-)}

Index: modules/standard/mod_autoindex.c
===================================================================
RCS file: /export/home/cvs/apachen/src/modules/standard/mod_autoindex.c,v
retrieving revision 1.51
diff -u -w -r1.51 mod_autoindex.c
--- mod_autoindex.c	1997/10/16 18:55:51	1.51
+++ mod_autoindex.c	1997/10/20 19:02:13
@@ -87,6 +87,7 @@
 #define SUPPRESS_SIZE 16
 #define SUPPRESS_DESC 32
 #define SUPPRESS_PREAMBLE 64
+#define SUPPRESS_COLSORT 128
 
 /*
  * Define keys for sorting.
@@ -269,6 +270,9 @@
 	    opts |= SUPPRESS_DESC;
 	else if (!strcasecmp(w, "SuppressHTMLPreamble"))
 	    opts |= SUPPRESS_PREAMBLE;
+        else if (!strcasecmp(w, "SuppressColumnSorting")) {
+            opts |= SUPPRESS_COLSORT;
+	}
 	else if (!strcasecmp(w, "None"))
 	    opts = 0;
 	else if (!strncasecmp(w, "IconWidth", 9)) {
@@ -295,9 +299,10 @@
 		d_cfg->icon_height = DEFAULT_ICON_HEIGHT;
 	    }
 	}
-	else
+        else {
 	    return "Invalid directory indexing option";
     }
+    }
     return add_opts_int(cmd, d, opts);
 }
 
@@ -515,11 +520,8 @@
     int plaintext = 0;
     request_rec *rr;
     autoindex_config_rec *cfg =
-    (autoindex_config_rec *) get_module_config
-    (
-	r->per_dir_config,
-	&autoindex_module
-    );
+        (autoindex_config_rec *) get_module_config(r->per_dir_config,
+                                                   &autoindex_module);
     int autoindex_opts = find_opts(cfg, r);
 
     /* XXX: this is a load of crap, it needs to do a full sub_req_lookup_uri */
@@ -528,15 +530,18 @@
     if (stat(fn, &finfo) == -1) {
 	/* A brief fake multiviews search for README.html */
 	fn[strlen(fn) - 5] = '\0';
-	if (stat(fn, &finfo) == -1)
+        if (stat(fn, &finfo) == -1) {
 	    return 0;
+        }
 	plaintext = 1;
-	if (hrule)
+        if (hrule) {
 	    rputs("<HR>\n", r);
+        }
 	rputs("<PRE>\n", r);
     }
-    else if (hrule)
+    else if (hrule) {
 	rputs("<HR>\n", r);
+    }
     /* XXX: when the above is rewritten properly, this necessary security
      * check will be redundant. -djg */
     rr = sub_req_lookup_file(fn, r);
@@ -574,19 +579,23 @@
 		ch = buf[i];
 		buf[i] = '\0';
 		rputs(&buf[c], r);
-		if (ch == '<')
+                if (ch == '<') {
 		    rputs("&lt;", r);
-		else if (ch == '>')
+                }
+                else if (ch == '>') {
 		    rputs("&gt;", r);
-		else if (ch == '&')
+                }
+                else if (ch == '&') {
 		    rputs("&amp;", r);
+                }
 		c = i + 1;
 	    }
 	}
     }
     pfclose(r->pool, f);
-    if (plaintext)
+    if (plaintext) {
 	rputs("</PRE>\n", r);
+    }
     return 1;
 }
 
@@ -742,11 +751,12 @@
  * selected again.  Non-active fields always start in ascending order.
  */
 static void emit_link(request_rec *r, char *anchor, char fname, char curkey,
-		      char curdirection)
+                      char curdirection, int nosort)
 {
     char qvalue[5];
     int reverse;
 
+    if (!nosort) {
     qvalue[0] = '?';
     qvalue[1] = fname;
     qvalue[2] = '=';
@@ -755,6 +765,10 @@
     qvalue[3] = reverse ? D_DESCENDING : D_ASCENDING;
     rvputs(r, "<A HREF=\"", qvalue, "\">", anchor, "</A>", NULL);
 }
+    else {
+        rputs(anchor, r);
+    }
+}
 
 static void output_directories(struct ent **ar, int n,
 			       autoindex_config_rec * d, request_rec *r,
@@ -763,6 +777,7 @@
     int x, len;
     char *name = r->uri;
     char *tp;
+    int static_columns = (autoindex_opts & SUPPRESS_COLSORT);
     pool *scratch = make_sub_pool(r->pool);
 
     if (name[0] == '\0')
@@ -784,18 +799,20 @@
 	    }
 	    rputs("> ", r);
 	}
-	emit_link(r, "Name", K_NAME, keyid, direction);
+        emit_link(r, "Name", K_NAME, keyid, direction, static_columns);
 	rputs("                   ", r);
 	if (!(autoindex_opts & SUPPRESS_LAST_MOD)) {
-	    emit_link(r, "Last modified", K_LAST_MOD, keyid, direction);
+            emit_link(r, "Last modified", K_LAST_MOD, keyid, direction,
+                      static_columns);
 	    rputs("     ", r);
 	}
 	if (!(autoindex_opts & SUPPRESS_SIZE)) {
-	    emit_link(r, "Size", K_SIZE, keyid, direction);
+            emit_link(r, "Size", K_SIZE, keyid, direction, static_columns);
 	    rputs("  ", r);
 	}
 	if (!(autoindex_opts & SUPPRESS_DESC)) {
-	    emit_link(r, "Description", K_DESC, keyid, direction);
+            emit_link(r, "Description", K_DESC, keyid, direction,
+                      static_columns);
 	}
 	rputs("\n<HR>\n", r);
     }
@@ -992,6 +1009,7 @@
     int autoindex_opts = find_opts(autoindex_conf, r);
     char keyid;
     char direction;
+    struct stat finfo;
 
     if (!(d = popendir(r->pool, name))) {
 	aplog_error(APLOG_MARK, APLOG_ERR, r->server,
@@ -999,13 +1017,17 @@
 	return HTTP_FORBIDDEN;
     }
 
+    if (stat(r->filename, &finfo) != -1) {
+        r->mtime = finfo.st_mtime;
+        set_last_modified(r);
+    }
     r->content_type = "text/html";
 
     send_http_header(r);
 
     if (r->header_only) {
 	pclosedir(r->pool, d);
-	return 0;
+        return OK;
     }
     hard_timeout("send directory", r);
 
@@ -1013,8 +1035,9 @@
 
     title_endp = title_name + strlen(title_name) - 1;
 
-    while (title_endp > title_name && *title_endp == '/')
+    while (title_endp > title_name && *title_endp == '/') {
 	*title_endp-- = '\0';
+    }
 
     if ((!(tmp = find_header(autoindex_conf, r)))
 	|| (!(insert_readme(name, tmp, title_name, NO_HRULE, FRONT_MATTER, r)))
@@ -1026,11 +1049,16 @@
     /*
      * Figure out what sort of indexing (if any) we're supposed to use.
      */
+    if (autoindex_opts & SUPPRESS_COLSORT) {
+	keyid = K_NAME;
+	direction = D_ASCENDING;
+    }
+    else {
     qstring = r->args;
 
     /*
-     * If no QUERY_STRING was specified, we use the default: ascending  by
-     * name.
+	 * If no QUERY_STRING was specified, we use the default: ascending
+	 * by name.
      */
     if ((qstring == NULL) || (*qstring == '\0')) {
 	keyid = K_NAME;
@@ -1046,6 +1074,7 @@
 	    direction = D_ASCENDING;
 	}
     }
+    }
 
     /* 
      * Since we don't know how many dir. entries there are, put them into a 
@@ -1091,7 +1120,7 @@
     rputs("</BODY></HTML>\n", r);
 
     kill_timeout(r);
-    return 0;
+    return OK;
 }
 
 /* The formal handler... */

Re: [PATCH] for mod_autoindex: no-sorting, last-modified

Posted by Dean Gaudet <dg...@arctic.org>.

On Mon, 20 Oct 1997, Rodent of Unusual Size wrote:

>     Okey, here's an improved (?) patch over the one submitted.  It
> 
>     o adds the IndexOptions keyword "SuppressColumnSorting"

+1

>     o sets the Last-Modified to the mtime of the directory if possible;
>       if stat(r->filename) fails (as it probably will on OS/2), no
>       Last-Modified is set.  (I find the alternative - waiting until the
>       directory has been scanned and setting it to the newest file - to
>       be nearly pinning my bogometer.)

No, setting last-modified based on mtime of . is bogus if ScanHTMLTitles
is set (or whatever it's called).  It's also bogus if there's a README, a
HEADER, or a FOOTER.  In fact it's just like XBitHack Full with g+x.  So
I'm a big +0 on this.

I'd +1 any of the following (or combos):

    - there was a flag enabling it, default off

    - it was enabled by default if none of the above issues exist (i.e.
	do the relatively cheap tests to see if ScanHTMLTitles is
	set, and if any README/HEADER/FOOTER exist -- this has "constant"
	latency)

    - like last, but use the max of the mtimes of the README/HEADER/FOOTER
	subrequests and the . mtime

The full solution would actually to be to use the max(mtime) over all
mtimes of all subrequests, and do the subreq_lookups all before doing the
headers.  This is not much different from how it's done now -- except that
the header delay could make it look slower to the user. 

Once you've gone to that expense, you can also do an md5sum over all the
ETags and issue a weak ETag as well. 

It's a simpler problem than issuing Last-Modified/ETag for mod_include ... 
but it's a similar problem. 

>     If voted in, the actual patch will be much bigger due to indent
>     issues I fixed along the way - but they'll be cosmetic only.

-1, please don't commit indentation changes along with code fixes.  Do it
in two commits.  Otherwise it makes the one diff very hard to read. 

Dean

P.S. Oh, btw, several times now I've thought how nice it would be to have
a ServingCache directory which is writable by the httpd userid, under
which it creates cached information about the normal directory hierarchy.
So it could actually cache the output of these things (and other things,
like md5-content).  With the separate hierarchy you don't have to worry
so much about mucking with your content tree.