Project

General

Profile

Docs ResponseHandling » History » Revision 2

Revision 1 (stbuehler, 2008-03-03 15:10) → Revision 2/8 (stbuehler, 2008-03-03 15:19)

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

 (I removed the `con->` prefix from the code so it is easier to read; so `mode` is `con->mode` in the source) 

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

 In every `handle(something)` "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` HANDLER_COMEBACK (mod_rewrite, mod_proxy_core, mod_magnet). [[BR]] 
 '''TODO''': At which point should `config_cond_cache_reset(srv, con);` "config_cond_cache_reset(srv, con);" be executed? [[BR]] 
 '''TODO''': What about `HANDLER_WAIT_FOR_FD`? HANDLER_WAIT_FOR_FD? [[BR]] 

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

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

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

 }}}