Project

General

Profile

Actions

Docs ResponseHandling » History » Revision 1

Revision 1/8 | Next »
stbuehler, 2008-03-03 15:10


Response handling in response.c; this may help to understand how the config works too.

The conditional checks are activated at specific points as you will see; so modules which do something in there uri_clean handler will probably never trigger if you wrap them in a $PHYSICAL["existing-path"] conditional.

In every "handle <something>" call the module handlers are called in the order the modules have been loaded. But this does not mean that by inserting a module before another will make it always handling the request before the other, as not every module implements every handler. BR
One example for this is mod_rewrite/mod_redirect: rewrite handles uri_raw, rediret uri_clean - so rewrite will always act before redirect (for now - i suggest you load mod_rewrite before mod_redirect so you are on the safe side if this changes).

The request handling is restarted if a handler returns HANDLER_COMEBACK (mod_rewrite, mod_proxy_core, mod_magnet). BR
'''TODO''': At which point should "config_cond_cache_reset(srv, con);" be executed? BR
'''TODO''': What about HANDLER_WAIT_FOR_FD? BR

If a request handler does not return HANDLER_GO_ON, request handling stops (remaining module handlers are not called!) and the return value from the handler is returned.

con->mode indicates which module wants to generate the content; con->mode == DIRECT ends in mod_staticfile (the default value); modules should set it to their own id if they handle the request: con->mode = p->id.

If con->mode != DIRECT you have to generate error-messages yourself, so if you want lighty to send an error (or trigger the error-handler) con->mode must be DIRECT; just set con->http_status to an error status and return HANDLER_FINISHED.

If you want to know if another module already handled the request, do something like this: {{{
if (con->mode != DIRECT || con->http_status != 0) return HANDLER_GO_ON;
}}}

So, lets start (this is basically the simplified code from response.c): {{{
handle_request() {
if (mode == DIRECT and (http_status != 0 or http_status != 200)) return HANDLER_FINISHED

if (mode == DIRECT and empty(physical.path)) {
// We need a physical path, i.e. a filename
activate_conditionals($SERVER["socket"], $HTTP["scheme"], $HTTP["host"], $HTTP["remote-ip"],
$HTTP["referer"], $HTTP["user-agent"], $HTTP["cookie"], $HTTP["request-method"])
split(request.uri -> uri.path_raw '?' uri.query)
handle(uri_raw)
urldecode_and_simplify(uri.raw -> uri.path);  // "sanatising" 
activate_conditionals($HTTP["url"], $HTTP["query-string"])
handle(uri_clean)
response to the query 'OPTIONS *'
set default physical.doc_root (server.document-root from the last matching conditional)
set default physical.rel_path = uri.path
[lighty-1.5] filename_unix2local(phyiscal.rel_path)
handle(docroot)
lowercase physical.rel_path on case insensitive platforms
physical.path = physical.docroot + physical.rel_path
[lighty-1.5] remove trailing DIR_SEPERATOR from physical.path
handle(phyiscal)
activate_conditionals($PHYSICAL["path"])
}
if (mode == DIRECT) {
// Now we should have a physical.path
if (exists(phyiscal.path)) {
if (is_symlink(phyiscal.path) and not conf.follow_symlinks) return FORBIDDEN() // 403
if (is_dir(phyiscal.path) and uri.path does not end with a '/') return redirect_to_dir(); // append '/'
} else if (some physical.path component was not a directory) { // errno = ENOTDIR
split phyiscal.path into (a existing filename) physical.path and request.path_info
}
[lighty-1.5] activate_conditionals($PHYSICAL["existing-path"])
[lighty-1.4] handle(subrequest_start)
[lighty-1.5] handle(start_backend)
[lighty-1.4] if (mode  DIRECT and http_status  0) {
// no one wanted to send content
if (request.http_method 'OPTIONS') OK() // 200
else FORBIDDEN() // 403;
}
}
[lighty-1.4] handle(subrequest);
[lighty-1.5] if (mode  DIRECT) {
// no one wanted to send content
FORBIDDEN() // 403
}
}

}}}

Updated by stbuehler about 16 years ago · 1 revisions