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 <fr...@daoine.org> on 2003/05/13 20:32:09 UTC
[PATCH] IndexResults for mod_autoindex
Hi there,
included is a patch against current CVS which adds "IndexResults" as an
option. It controls which files get listed in a mod_autoindex-generated
page.
Specifically, it can be set to allow URLs for which the requestor is not
(yet) authenticated be listed.
Further patches to hide the file size and modify time; and to change
the icon displayed to an "unauthorized" one; will follow if this is
considered useful.
All the best,
f
--
Francis Daly francis@daoine.org
Index: docs/manual/mod/mod_autoindex.xml
===================================================================
RCS file: /home/cvspublic/httpd-2.0/docs/manual/mod/mod_autoindex.xml,v
retrieving revision 1.15
diff -u -p -r1.15 mod_autoindex.xml
--- docs/manual/mod/mod_autoindex.xml 11 Apr 2003 01:25:52 -0000 1.15
+++ docs/manual/mod/mod_autoindex.xml 13 May 2003 18:07:15 -0000
@@ -854,6 +854,38 @@ Name|Date|Size|Description</syntax>
</directivesynopsis>
<directivesynopsis>
+<name>IndexResults</name>
+<description>Changes the list of files to show in a directory index,
+based on the HTTP status</description>
+<syntax>IndexResults <var>[-]code</var> [<var>[-]code</var>] ...</syntax>
+<default>IndexResults 3xx</default>
+<contextlist><context>server config</context><context>virtual host</context>
+<context>directory</context><context>.htaccess</context>
+</contextlist>
+<override>Indexes</override>
+<compatibility>Available in Apache 2.1 and later</compatibility>
+
+<usage>
+ <p>The <directive>IndexResults</directive> directive changes the
+ list of files to show in a directory index. <var>code</var>
+ is a HTTP status (from 100 to 999)(like <code>401</code>, for
+ "unauthorized"), or a range (from 1xx to 9xx)(like <code>4xx</code>,
+ meaning "all 400-series statuses") for additional files to list.
+ Prefix <var>code</var> with a minus (-) to explicitly hide that
+ status or range. Multiple IndexResults arguments or directives are
+ processed in order, which means a range always overrides an
+ earlier status. The <code>2xx</code> ("successful") range is
+ always present. By default, the list contains the <code>3xx</code>
+ range ("redirection"), but that can be explicitly overridden by a
+ <code>-3xx</code> if that is really wanted.</p>
+
+ <example><title>Show unauthorized filenames</title>
+ IndexResults 401
+ </example>
+</usage>
+</directivesynopsis>
+
+<directivesynopsis>
<name>ReadmeName</name>
<description>Name of the file that will be inserted at the end
of the index listing</description>
Index: modules/generators/mod_autoindex.c
===================================================================
RCS file: /home/cvspublic/httpd-2.0/modules/generators/mod_autoindex.c,v
retrieving revision 1.119
diff -u -p -r1.119 mod_autoindex.c
--- modules/generators/mod_autoindex.c 2 Mar 2003 18:06:16 -0000 1.119
+++ modules/generators/mod_autoindex.c 13 May 2003 18:07:16 -0000
@@ -155,6 +155,17 @@ typedef struct ai_desc_t {
int wildcards;
} ai_desc_t;
+/* range_info is for IndexResults */
+typedef struct range_info {
+ int code;
+ int show;
+ struct range_info *next;
+} range_info;
+
+#define AI_FULL_RANGE 99
+/* int that is never otherwise valid in range_info.code */
+
+
typedef struct autoindex_config_struct {
char *default_icon;
@@ -177,6 +188,8 @@ typedef struct autoindex_config_struct {
apr_array_header_t *hdr_list;
apr_array_header_t *rdme_list;
+ range_info *range_allow[10];
+
} autoindex_config_rec;
static char c_by_encoding, c_by_type, c_by_path;
@@ -321,6 +334,85 @@ static const char *add_desc(cmd_parms *c
return NULL;
}
+void range_allow_modify(range_info *given[], apr_pool_t *p,
+ const int entry, const int show)
+{
+ /*
+ * given - (pointer to) an array of 10 pointers to range_info. writeable.
+ * p - pool out of which new range_info's can be allocated
+ * show is - 1 => show
+ * - 0 => hide
+ * entry is - < 10 => that full range
+ * - else => that single value
+ */
+
+ range_info *current;
+ range_info *prev = NULL;
+
+ if (entry < 10) {
+ /* replace current with the new full range */
+ if (!given[entry]) {
+ given[entry] = apr_palloc(p, sizeof(range_info));
+ }
+ given[entry]->code = AI_FULL_RANGE;
+ given[entry]->show = show;
+ given[entry]->next = NULL;
+ return;
+ }
+
+ current = given[entry/100];
+ /* move to the end of the chain; stop if this entry is already present */
+ while (current) {
+ if (entry == current->code) {
+ current->show = show;
+ return;
+ }
+ prev = current;
+ current = current->next;
+ }
+
+ current = apr_palloc(p, sizeof(range_info));
+ if (prev) {
+ prev->next = current;
+ } else {
+ given[entry/100] = current;
+ }
+
+ current->code = entry;
+ current->show = show;
+ current->next = NULL;
+ return;
+}
+
+static const char *set_results(cmd_parms *cmd, void *d, const char *name)
+{
+ autoindex_config_rec *dr = d;
+ int entry;
+ int show = 1;
+ if (name[0] == '-') {
+ show = 0;
+ name++;
+ }
+
+ /* verify that the form is valid */
+ if (name[0] == '\0' || name[1] == '\0' || name[2] == '\0' ||
+ name[3] != '\0') {
+ return "Value (after leading minus) must be three characters long";
+ }
+
+ /* verify that the value is valid */
+ if ((name[0] < '1' || name[0] > '9')
+ || !((isdigit(name[1]) && isdigit(name[2]))
+ || (name[1] == 'x' && name[2] == 'x'))) {
+ return "Value must be [-]### or [-]#xx, where # is a digit";
+ }
+
+ entry = atoi(name);
+ range_allow_modify(dr->range_allow, cmd->pool, entry, show);
+ return NULL;
+}
+
+
static const char *add_ignore(cmd_parms *cmd, void *d, const char *ext)
{
push_item(((autoindex_config_rec *) d)->ign_list, 0, ext, cmd->path, NULL);
@@ -585,6 +677,8 @@ static const command_rec autoindex_cmds[
"one or more file extensions"),
AP_INIT_ITERATE2("AddDescription", add_desc, BY_PATH, DIR_CMD_PERMS,
"Descriptive text followed by one or more filenames"),
+ AP_INIT_ITERATE("IndexResults", set_results, NULL, DIR_CMD_PERMS,
+ "one or more http status codes"),
AP_INIT_TAKE1("HeaderName", add_header, NULL, DIR_CMD_PERMS,
"a filename"),
AP_INIT_TAKE1("ReadmeName", add_readme, NULL, DIR_CMD_PERMS,
@@ -598,7 +692,7 @@ static const command_rec autoindex_cmds[
{NULL}
};
-static void *create_autoindex_config(apr_pool_t *p, char *dummy)
+static void *create_autoindex_config(apr_pool_t *p, char *dir)
{
autoindex_config_rec *new =
(autoindex_config_rec *) apr_pcalloc(p, sizeof(autoindex_config_rec));
@@ -621,6 +715,15 @@ static void *create_autoindex_config(apr
new->default_keyid = '\0';
new->default_direction = '\0';
+ /* new->range_allow is already initialised as 10 NULL pointers */
+ /* include, effectively, a global "IndexResults 3xx" */
+ if (dir == NULL) {
+ new->range_allow[3] = apr_palloc(p, sizeof(range_info));
+ new->range_allow[3]->code = AI_FULL_RANGE;
+ new->range_allow[3]->show = 1;
+ new->range_allow[3]->next = NULL;
+ }
+
return (void *) new;
}
@@ -642,6 +745,50 @@ static void *merge_autoindex_configs(apr
new->desc_list = apr_array_append(p, add->desc_list, base->desc_list);
new->icon_list = apr_array_append(p, add->icon_list, base->icon_list);
new->rdme_list = apr_array_append(p, add->rdme_list, base->rdme_list);
+ {
+ int i;
+ range_info *mod;
+ range_info *old;
+ range_info *copy;
+ for (i=0; i<10; i++) {
+ mod = add->range_allow[i];
+
+ /* if there is no change at all to i this time, use base */
+ if (!mod || mod->code == 0) {
+ new->range_allow[i] = base->range_allow[i];
+ continue;
+ }
+
+ /* else if the change involves a range, use add */
+ if (mod->code == AI_FULL_RANGE) {
+ new->range_allow[i] = add->range_allow[i];
+ continue;
+ }
+
+ /* else deep-copy base, then merge the changes */
+ old = base->range_allow[i];
+ if (old && old->code) {
+ copy = apr_palloc(p, sizeof(range_info));
+ new->range_allow[i] = copy;
+ while (old && old->code) {
+ copy->code = old->code;
+ copy->show = old->show;
+ old = old->next;
+ if (old) {
+ copy->next = apr_palloc(p, sizeof(range_info));
+ copy = copy->next;
+ } else {
+ copy->next = NULL;
+ }
+ }
+ }
+ while (mod && mod->code) {
+ range_allow_modify(new->range_allow, p, mod->code, mod->show);
+ mod = mod->next;
+ }
+ }
+ }
+
if (add->opts & NO_OPTIONS) {
/*
* If the current directory says 'no options' then we also
@@ -803,6 +950,24 @@ static char *find_default_item(char *bog
#define find_default_icon(d,n) find_default_item(n, d->icon_list)
#define find_default_alt(d,n) find_default_item(n, d->alt_list)
+static int show_result(autoindex_config_rec *d, int status)
+{
+ range_info *current;
+ int show = 0; /* default don't show */
+
+ current = d->range_allow[status / 100];
+ while (current) {
+ if (current->code == status) {
+ return current->show;
+ }
+ if (current->code == AI_FULL_RANGE) {
+ show = current->show;
+ }
+ current = current->next;
+ }
+ return show;
+}
+
/*
* Look through the list of pattern/description pairs and return the first one
* if any) that matches the filename in the request. If multiple patterns
@@ -1324,7 +1489,7 @@ static struct ent *make_autoindex_entry(
if ((rr->finfo.filetype != APR_DIR && rr->finfo.filetype != APR_REG)
|| !(rr->status == OK || ap_is_HTTP_SUCCESS(rr->status)
- || ap_is_HTTP_REDIRECT(rr->status))) {
+ || show_result(d, rr->status))) {
ap_destroy_sub_req(rr);
return (NULL);
}