option in the docs page, like e.g. we did for SSLInsecureRenegotiation.
wrowe asks; you mean <Compatibility> tag? Yes, of course.
- * mod_dir: add FallbackResource directive
- PR 47184
- Trunk patch: http://svn.apache.org/viewvc?view=rev&revision=785425
- http://svn.apache.org/viewvc?view=rev&revision=795450
- 2.2.x patch: http://people.apache.org/~niq/patches/47184.patch
- (identical but for offsets, but patch failed on trunk version)
- plus docs patch from r795450
- +1: niq, pgollucci
- +1: rbowen - After much debate on IRC, we've agreed on FallbackResource as being the right name for this.
-
*) core authnz: improve misleading error message. PR 38322.
Trunk: N/A
2.2.x: https://issues.apache.org/bugzilla/attachment.cgi?id=25698
</note>
</usage>
</directivesynopsis>
+<directivesynopsis>
+<name>FallbackResource</name>
+<description>Define a default URL for requests that don't map to a file</description>
+<syntax>FallbackResource <var>local-url</var></syntax>
+<default>None - httpd will return 404 (Not Found)</default>
+<contextlist><context>server config</context><context>virtual host</context>
+<context>directory</context><context>.htaccess</context></contextlist>
+<override>Indexes</override>
+<usage>
+ <p>Use this to set a handler for any URL that doesn't map to anything
+ in your filesystem, and would otherwise return HTTP 404 (Not Found).
+ For example</p>
+ <example>
+ <code>FallbackResource default.php</code>
+ </example>
+ <p>will cause requests for non-existent files to be handled by
+ <code>default.php</code>, while requests for files that exist
+ are unaffected.</p>
+</usage>
+</directivesynopsis>
</modulesynopsis>
typedef struct dir_config_struct {
apr_array_header_t *index_names;
slash_cfg do_slash;
+ const char *dflt;
} dir_config_rec;
#define DIR_CMD_PERMS OR_INDEXES
static const command_rec dir_cmds[] =
{
+ AP_INIT_TAKE1("FallbackResource", ap_set_string_slot,
+ (void*)APR_OFFSETOF(dir_config_rec, dflt),
+ DIR_CMD_PERMS, "Set a default handler"),
AP_INIT_ITERATE("DirectoryIndex", add_index, NULL, DIR_CMD_PERMS,
"a list of file names"),
AP_INIT_FLAG("DirectorySlash", configure_slash, NULL, DIR_CMD_PERMS,
new->index_names = add->index_names ? add->index_names : base->index_names;
new->do_slash =
(add->do_slash == SLASH_UNSET) ? base->do_slash : add->do_slash;
+ new->dflt = add->dflt ? add->dflt : base->dflt;
return new;
}
+static int fixup_dflt(request_rec *r)
+{
+ dir_config_rec *d = ap_get_module_config(r->per_dir_config, &dir_module);
+ const char *name_ptr;
+ request_rec *rr;
+ int error_notfound = 0;
+ if ((r->finfo.filetype != APR_NOFILE) || (r->handler != NULL)) {
+ return DECLINED;
+ }
+ name_ptr = d->dflt;
+ if (r->args != NULL) {
+ name_ptr = apr_pstrcat(r->pool, name_ptr, "?", r->args, NULL);
+ }
+ rr = ap_sub_req_lookup_uri(name_ptr, r, r->output_filters);
+ if (rr->status == HTTP_OK
+ && ( (rr->handler && !strcmp(rr->handler, "proxy-server"))
+ || rr->finfo.filetype == APR_REG)) {
+ ap_internal_fast_redirect(rr, r);
+ return OK;
+ }
+ else if (ap_is_HTTP_REDIRECT(rr->status)) {
+
+ apr_pool_join(r->pool, rr->pool);
+ r->notes = apr_table_overlay(r->pool, r->notes, rr->notes);
+ r->headers_out = apr_table_overlay(r->pool, r->headers_out,
+ rr->headers_out);
+ r->err_headers_out = apr_table_overlay(r->pool, r->err_headers_out,
+ rr->err_headers_out);
+ error_notfound = rr->status;
+ }
+ else if (rr->status && rr->status != HTTP_NOT_FOUND
+ && rr->status != HTTP_OK) {
+ error_notfound = rr->status;
+ }
+
+ ap_destroy_sub_req(rr);
+ if (error_notfound) {
+ return error_notfound;
+ }
+
+ /* nothing for us to do, pass on through */
+ return DECLINED;
+}
static int fixup_dir(request_rec *r)
{
dir_config_rec *d;
static void register_hooks(apr_pool_t *p)
{
ap_hook_fixups(fixup_dir,NULL,NULL,APR_HOOK_LAST);
+ ap_hook_fixups(fixup_dflt,NULL,NULL,APR_HOOK_LAST);
}
module AP_MODULE_DECLARE_DATA dir_module = {