-10* (see below).
In addition to the rules, a *match* stanza must contain exactly one
-follow-up line specifying the action to take if it matches. Currently,
-only the *handler* action is recognized:
+follow-up line specifying the action to take if it matches. The
+following actions are supported:
*handler* 'HANDLER'::
'HANDLER' must be a named handler as declared by a *child* or
*fchild* stanza, to which the request is passed.
+*reparse*::
+
+ Apply any side-effects as required by the match stanza (such
+ as rest-string or header modifications), and then retry the
+ matching of the request. During the rematching, the stanza
+ containing the *reparse* action will be disabled. Multiple
+ *reparse* stanzas may be used recursively.
+
Additionally, a *match* stanza may contain any of the following,
optional lines:
#define PATFL_MSS 1
#define PATFL_UNQ 2
+#define HND_CHILD 1
+#define HND_REPARSE 2
+
struct config {
struct child *children;
struct pattern *patterns;
char *childnm;
struct rule **rules;
char *restpat;
- int prio;
+ int handler, prio, disable;
};
static struct config *gconfig, *lconfig;
if(pat->childnm != NULL)
free(pat->childnm);
pat->childnm = sstrdup(s->argv[1]);
+ pat->handler = HND_CHILD;
+ } else if(!strcmp(s->argv[0], "reparse")) {
+ pat->handler = HND_REPARSE;
} else if(!strcmp(s->argv[0], "restpat")) {
if(s->argc < 2) {
flog(LOG_WARNING, "%s:%i: missing pattern for `restpat' directive", s->file, s->lno);
freepattern(pat);
return(NULL);
}
- if(pat->childnm == NULL) {
+ if(pat->handler == 0) {
flog(LOG_WARNING, "%s:%i: missing handler in match declaration", s->file, sl);
freepattern(pat);
return(NULL);
mstr = NULL;
for(pat = cf->patterns; pat != NULL; pat = pat->next) {
- if(match && (pat->prio <= match->pat->prio))
+ if(pat->disable || (match && (pat->prio <= match->pat->prio)))
continue;
rmo = -1;
for(i = 0; (rule = pat->rules[i]) != NULL; i++) {
simpleerror(fd, 404, "Not Found", "The requested resource could not be found on this server.");
return;
}
- ch = NULL;
- if(ch == NULL)
- ch = getchild(lconfig, match->pat->childnm);
- if((ch == NULL) && (gconfig != NULL))
- ch = getchild(gconfig, match->pat->childnm);
- if(ch == NULL) {
- flog(LOG_ERR, "child %s requested, but was not declared", match->pat->childnm);
- simpleerror(fd, 500, "Configuration Error", "The server is erroneously configured. Handler %s was requested, but not declared.", match->pat->childnm);
- freematch(match);
- return;
- }
-
execmatch(req, match);
- if(childhandle(ch, req, fd, NULL, NULL))
- childerror(req, fd);
+ switch(match->pat->handler) {
+ case HND_CHILD:
+ ch = NULL;
+ if(ch == NULL)
+ ch = getchild(lconfig, match->pat->childnm);
+ if((ch == NULL) && (gconfig != NULL))
+ ch = getchild(gconfig, match->pat->childnm);
+ if(ch == NULL) {
+ flog(LOG_ERR, "child %s requested, but was not declared", match->pat->childnm);
+ simpleerror(fd, 500, "Configuration Error", "The server is erroneously configured. Handler %s was requested, but not declared.", match->pat->childnm);
+ break;
+ }
+ if(childhandle(ch, req, fd, NULL, NULL))
+ childerror(req, fd);
+ break;
+ case HND_REPARSE:
+ match->pat->disable = 1;
+ serve(req, fd);
+ match->pat->disable = 0;
+ break;
+ default:
+ abort();
+ }
freematch(match);
}