Roxen.git / server / base_server / configuration.pike

version» Context lines:

Roxen.git/server/base_server/configuration.pike:1:   // A vitual server's main configuration   // Copyright © 1996 - 2000, Roxen IS. - constant cvs_version = "$Id: configuration.pike,v 1.417 2001/02/23 03:58:24 mast Exp $"; + constant cvs_version = "$Id: configuration.pike,v 1.418 2001/02/27 02:54:18 per Exp $";   #include <module.h>   #include <module_constants.h>   #include <roxen.h>   #include <request_trace.h> -  + #include <timers.h>    -  +    #define CATCH(P,X) do{mixed e;if(e=catch{X;})report_error("While "+P+"\n"+describe_backtrace(e));}while(0)      // --- Locale defines ---   //<locale-token project="roxen_start"> LOC_S </locale-token>   //<locale-token project="roxen_config"> LOC_C </locale-token>   //<locale-token project="roxen_message"> LOC_M </locale-token>   //<locale-token project="roxen_config"> DLOCALE </locale-token>   #define LOC_S(X,Y) _STR_LOCALE("roxen_start",X,Y)   #define LOC_C(X,Y) _STR_LOCALE("roxen_config",X,Y)   #define LOC_M(X,Y) _STR_LOCALE("roxen_message",X,Y)
Roxen.git/server/base_server/configuration.pike:175:   }         // The logging format used. This will probably move to the above   // mentioned module in the future.   private mapping (int:string) log_format = ([]);      // A list of priority objects   array (Priority) pri = allocate_pris();    - public mapping modules = ([]); + mapping modules = ([]);   //! All enabled modules in this site.   //! The format is "module":{ "copies":([ num:instance, ... ]) }    - public mapping (RoxenModule:string) otomod = ([]); + mapping (RoxenModule:string) otomod = ([]);   //! A mapping from the module objects to module names         // Caches to speed up the handling of the module search.   // They are all sorted in priority order, and created by the functions   // below.   private array (function) url_module_cache, last_module_cache;   private array (function) logger_module_cache, first_module_cache;   private array (function) filter_module_cache;   private array (array (string|function)) location_module_cache;
Roxen.git/server/base_server/configuration.pike:608:      private void parse_log_formats()   {    string b;    array foo=query("LogFormat")/"\n";    foreach(foo, b)    if(strlen(b) && b[0] != '#' && sizeof(b/":")>1)    log_format[(int)(b/":")[0]] = fix_logging((b/":")[1..]*":");   }    - public void log(mapping file, RequestID request_id) + void log(mapping file, RequestID request_id)   {    function f;      // Call all logging functions    foreach(logger_module_cache||logger_modules(), f)    if( f( request_id, file ) )    return;       if( !log_function )    return;// No file is open for logging.
Roxen.git/server/base_server/configuration.pike:632:    return;       string form;    if(!(form=log_format[file->error]))    form = log_format[0];    if(!form) return;       roxen.run_log_format( form, log_function, request_id, file );   }    - public array(string) userinfo(string u, RequestID|void id) + array(string) userinfo(string u, RequestID|void id)   //! @note DEPRECATED COMPATIBILITY FUNCTION   //!   //! Fetches user information from the authentication module by calling   //! its userinfo() method. Returns zero if no auth module was present.   {    User uid;    foreach( user_databases(), UserDB m )    if( uid = m->find_user( u ) )    return uid->compat_userinfo();   }    - public array(string) userlist(RequestID|void id) + array(string) userlist(RequestID|void id)   //! @note DEPRECATED COMPATIBILITY FUNCTION   //!   //! Fetches the full list of valid usernames from the authentication   //! module by calling its userlist() method. Returns zero if no auth   //! module was present.   {    array(string) list = ({});    foreach( user_databases(), UserDB m )    list |= m->list_users();    return list;   }    - public array(string) user_from_uid(int u, RequestID|void id) + array(string) user_from_uid(int u, RequestID|void id)   //! @note DEPRECATED COMPATIBILITY FUNCTION   //!   //! Return the user data for id u from the authentication module. The   //! id parameter might be left out if FTP. Returns zero if no auth   //! module was present.   {    User uid;    foreach( user_databases(), UserDB m )    if( uid = m->find_user_from_uid( u ) )    return uid->compat_userinfo();
Roxen.git/server/base_server/configuration.pike:773:    if( id && id->misc->authenticated_user    && ( uid = id->misc->authenticated_user->database->find_group( group ) ))    return uid;       foreach( user_databases(), UserDB m )    if( uid = m->find_group( group ) )    return uid;   }       - public string last_modified_by(Stdio.File file, RequestID id) + string last_modified_by(Stdio.File file, RequestID id)   {    Stat s;    int uid;    array u;       if(objectp(file)) s=file->stat();    if(!s || sizeof(s)<5) return "A. Nonymous";    uid=s[5];    u=user_from_uid(uid, id);    if(u) return u[0];
Roxen.git/server/base_server/configuration.pike:1042: Inside #if defined(THREADS)
     #ifdef THREADS   // import Thread;      mapping locked = ([]), thread_safe = ([]);      mixed _lock(object|function f)   {    Thread.MutexKey key;    function|int l; -  +  TIMER_START(module_lock);    if (functionp(f)) {    f = function_object(f);    }    if (l = locks[f])    {    if (l != -1)    {    // Allow recursive locks.    catch{    //werror("lock %O\n", f);
Roxen.git/server/base_server/configuration.pike:1074: Inside #if defined(THREADS)
   // Needed to avoid race-condition.    l = Thread.Mutex()->lock;    if (!locks[f]) {    locks[f]=l;    }    }    //werror("lock %O\n", f);    locked[f]++;    key = l();    } +  TIMER_END(module_lock);    return key;   }      #define LOCK(X) key=_lock(X)   #define UNLOCK() do{key=0;}while(0)   #else   #define LOCK(X)   #define UNLOCK()   #endif   
Roxen.git/server/base_server/configuration.pike:1176:    TRACE_ENTER(sprintf("Request for %s", id->not_query), 0);       string file=id->not_query;    string loc;    function funp;    mixed tmp, tmp2;    mapping|object(Stdio.File)|int fid;       if(!no_magic)    { +  TIMER_START(internal_magic);   #ifndef NO_INTERNAL_HACK    // Find internal-foo-bar images    // min length == 17 (/internal-roxen-?..)    // This will save some time indeed.    string type;    if(sizeof(file) > 17 &&   #if ROXEN_COMPAT <= 2.1    (file[0] == '/') &&    sscanf(file, "%*s/internal-%s-%[^/]", type, loc) == 3   #else    sscanf(file, "/internal-%s-%[^/]", type, loc) == 2   #endif    ) {    switch(type) {    case "roxen":    TRACE_LEAVE("Magic internal roxen image");    if(loc=="unit" || loc=="pixel-of-destiny") -  return (["data":"GIF89a\1\0\1\0\200ÿ\0ÀÀÀ\0\0\0!ù\4\1\0\0\0\0,\0\0\0\0\1\0\1\0\0\1\1""2\0;", +  { +  TIMER_END(internal_magic); +  return (["data":"GIF89a\1\0\1\0\200ÿ\0ÀÀÀ\0\0\0!ù\4\1\0\0\0\0," +  "\0\0\0\0\1\0\1\0\0\1\1""2\0;",    "type":"image/gif" ]); -  +  }    if(has_prefix(loc, "pixel-")) -  return (["data":sprintf("GIF89a\1\0\1\0\200\0\0\0\0\0%c%c%c,\0\0\0\0\1\0\1\0\0\2\2L\1\0;", +  { +  TIMER_END(internal_magic); +  return (["data":sprintf("GIF89a\1\0\1\0\200\0\0\0\0\0%c%c%c,\0\0\0" +  "\0\1\0\1\0\0\2\2L\1\0;",    @parse_color(loc[6..])),    "type":"image/gif" ]); -  +  } +  TIMER_END(internal_magic);    return internal_roxen_image(loc, id);       case "gopher":    TRACE_LEAVE("Magic internal gopher image"); -  +  TIMER_END(internal_magic);    return internal_gopher_image(loc);    }    }   #endif       // Locate internal location resources.    if(!search(file, query("InternalLoc")))    {    TRACE_ENTER("Magic internal module location", 0);    RoxenModule module;
Roxen.git/server/base_server/configuration.pike:1229: Inside #if defined(MODULE_LEVEL_SECURITY)
   {   #ifdef MODULE_LEVEL_SECURITY    if(tmp2 = check_security(find_internal, id, slevel))    if(intp(tmp2))    {    TRACE_LEAVE("Permission to access module denied.");    find_internal = 0;    } else {    TRACE_LEAVE("");    TRACE_LEAVE("Request denied."); +  TIMER_END(internal_magic);    return tmp2;    }   #endif    if(find_internal)    {    TRACE_ENTER("Calling find_internal()...", find_internal);    LOCK(find_internal);    fid=find_internal( rest, id );    UNLOCK();    TRACE_LEAVE(sprintf("find_internal has returned %O", fid));    if(fid)    {    if(mappingp(fid))    {    TRACE_LEAVE("");    TRACE_LEAVE(examine_return_mapping(fid)); -  +  TIMER_END(internal_magic);    return fid;    }    else    {   #ifdef MODULE_LEVEL_SECURITY    int oslevel = slevel;    slevel = misc_cache[ find_internal ][1];    // misc_cache from    // check_security    id->misc->seclevel = slevel;
Roxen.git/server/base_server/configuration.pike:1278:   #endif    );    }    } else    TRACE_LEAVE("");    } else    TRACE_LEAVE("");    } else    TRACE_LEAVE("");    } +  TIMER_END(internal_magic);    }       // Well, this just _might_ be somewhat over-optimized, since it is    // quite unreadable, but, you cannot win them all..    if(!fid)    {   #ifdef URL_MODULES    // Map URL-modules -  +  TIMER_START(url_modules);    foreach(url_module_cache||url_modules(), funp)    {    LOCK(funp);    TRACE_ENTER("URL module", funp);    tmp=funp( id, file );    UNLOCK();       if(mappingp(tmp))    {    TRACE_LEAVE("");    TRACE_LEAVE("Returning data"); -  +  TIMER_END(url_modules);    return tmp;    }    if(objectp( tmp ))    {    array err;       nest ++;    err = catch {    if( nest < 20 )    tmp = (id->conf || this_object())->low_get_file( tmp, no_magic );
Roxen.git/server/base_server/configuration.pike:1318: Inside #if defined(URL_MODULES)
   {    TRACE_LEAVE("Too deep recursion");    error("Too deep recursion in roxen::get_file() while mapping "    +file+".\n");    }    };    nest = 0;    if(err) throw(err);    TRACE_LEAVE("");    TRACE_LEAVE("Returning data"); +  TIMER_END(url_modules);    return tmp;    }    TRACE_LEAVE(""); -  +  TIMER_END(url_modules);    }   #endif    -  +  TIMER_START(location_modules);    foreach(location_module_cache||location_modules(), tmp)    {    loc = tmp[0];    if(!search(file, loc))    {    TRACE_ENTER(sprintf("Location module [%s] ", loc), tmp[1]);   #ifdef MODULE_LEVEL_SECURITY    if(tmp2 = check_security(tmp[1], id, slevel))    if(intp(tmp2))    {    TRACE_LEAVE("Permission to access module denied.");    continue;    } else {    TRACE_LEAVE("");    TRACE_LEAVE("Request denied."); -  +  TIMER_END(location_modules);    return tmp2;    }   #endif    TRACE_ENTER("Calling find_file()...", 0);    LOCK(tmp[1]);    fid=tmp[1]( file[ strlen(loc) .. ] + id->extra_extension, id);    UNLOCK();    TRACE_LEAVE("");    if(fid)    {    id->virtfile = loc;       if(mappingp(fid))    {    TRACE_LEAVE("");    TRACE_LEAVE(examine_return_mapping(fid)); -  +  TIMER_END(location_modules);    return fid;    }    else    {   #ifdef MODULE_LEVEL_SECURITY    int oslevel = slevel;    slevel = misc_cache[ tmp[1] ][1];    // misc_cache from    // check_security    id->misc->seclevel = slevel;
Roxen.git/server/base_server/configuration.pike:1398:       TRACE_ENTER("Automatic redirect to location_module.", tmp[1]);    TRACE_LEAVE("Returning data");       // Keep query (if any).    // FIXME: Should probably keep config <foo>    string new_query = Roxen.http_encode_string(id->not_query) + "/" +    (id->query?("?"+id->query):"");    new_query=Roxen.add_pre_state(new_query, id->prestate);    +  TIMER_END(location_modules);    return Roxen.http_redirect(new_query, id);    }    } -  +  TIMER_END(location_modules);    }       if(fid == -1)    {    if(no_magic)    {    TRACE_LEAVE("No magic requested. Returning -1.");    return -1;    } -  +  TIMER_START(directory_module);    if(dir_module)    {    LOCK(dir_module);    TRACE_ENTER("Directory module", dir_module);    fid = dir_module->parse_directory(id);    UNLOCK();    }    else    {    TRACE_LEAVE("No directory module. Returning 'no such file'");    return 0;    } -  +  TIMER_END(directory_module);    if(mappingp(fid))    {    TRACE_LEAVE("Returning data");    return (mapping)fid;    }    }       // Map the file extensions, but only if there is a file... -  +  TIMER_START(extension_module);    if(objectp(fid) &&    (tmp = file_extension_modules(loc = Roxen.extension(id->not_query, id))))    {    foreach(tmp, funp)    {    TRACE_ENTER(sprintf("Extension module [%s] ", loc), funp);   #ifdef MODULE_LEVEL_SECURITY    if(tmp=check_security(funp, id, slevel))    if(intp(tmp))    {    TRACE_LEAVE("Permission to access module denied.");    continue;    }    else    {    TRACE_LEAVE("");    TRACE_LEAVE("Permission denied"); -  +  TIMER_END(extension_module);    return tmp;    }   #endif    LOCK(funp);    tmp=funp(fid, loc, id);    UNLOCK();    if(tmp)    {    if(!objectp(tmp))    {    TRACE_LEAVE("");    TRACE_LEAVE("Returning data"); -  +  TIMER_END(extension_module);    return tmp;    }    if(fid && tmp != fid)    destruct(fid);    TRACE_LEAVE("Returned new open file");    fid = tmp;    break;    } else    TRACE_LEAVE("");    }    } -  +  TIMER_END(extension_module);       if(objectp(fid))    { -  +  TIMER_START(content_type_module);    if(stringp(id->extension)) {    id->not_query += id->extension;    loc = Roxen.extension(id->not_query, id);    }    TRACE_ENTER("Content-type mapping module", types_module);    tmp=type_from_filename(id->not_query, 1, loc);    TRACE_LEAVE(tmp?sprintf("Returned type %s %s.", tmp[0], tmp[1]||"")    : "Missing type.");    if(tmp)    {    TRACE_LEAVE(""); -  +  TIMER_END(content_type_module);    return ([ "file":fid, "type":tmp[0], "encoding":tmp[1] ]);    }    TRACE_LEAVE(""); -  +  TIMER_END(content_type_module);    return ([ "file":fid, ]);    } -  +     if(!fid)    TRACE_LEAVE("Returned 'no such file'.");    else    TRACE_LEAVE("Returning data");    return fid;   }      mixed handle_request( RequestID id )   {    function funp;    mixed file;    REQUEST_WERR("handle_request()"); -  +  TIMER_START(handle_request); +  TIMER_START(first_modules);    foreach(first_module_cache||first_modules(), funp)    {    if(file = funp( id ))    break;    if(id->conf != this_object()) {    REQUEST_WERR("handle_request(): Redirected (2)");    return id->conf->handle_request(id);    }    } -  +  TIMER_END(first_modules);    if(!mappingp(file) && !mappingp(file = get_file(id)))    {    mixed ret; -  +  TIMER_START(last_modules);    foreach(last_module_cache||last_modules(), funp) if(ret = funp(id)) break;    if (ret == 1) {    REQUEST_WERR("handle_request(): Recurse"); -  +  TIMER_END(last_modules); +  TIMER_END(handle_request);    return handle_request(id);    }    file = ret; -  +  TIMER_END(last_modules);    } -  +  TIMER_END(handle_request);    REQUEST_WERR("handle_request(): Done"); -  +  MERGE_TIMERS(roxen);    return file;   }      mapping get_file(RequestID id, int|void no_magic, int|void internal_get)   //! Return a result mapping for the id object at hand, mapping all   //! modules, including the filter modules. This function is mostly a   //! wrapper for <ref>low_get_file()</ref>.   { -  +  TIMER_START(get_file);    int orig_internal_get = id->misc->internal_get;    id->misc->internal_get = internal_get;       mapping|int res;    mapping res2;    function tmp;    res = low_get_file(id, no_magic); -  +  TIMER_END(get_file);       // finally map all filter type modules.    // Filter modules are like TYPE_LAST modules, but they get called    // for _all_ files. -  +  TIMER_START(filter_modules);    foreach(filter_module_cache||filter_modules(), tmp)    {    TRACE_ENTER("Filter module", tmp);    if(res2=tmp(res,id))    {    if(res && res->file && (res2->file != res->file))    destruct(res->file);    TRACE_LEAVE("Rewrote result.");    res=res2;    } else    TRACE_LEAVE("");    } -  +  TIMER_END(filter_modules);       id->misc->internal_get = orig_internal_get;    return res;   }      array(string) find_dir(string file, RequestID id, void|int(0..1) verbose)   {    array dir;    TRACE_ENTER(sprintf("List directory %O.", file), 0);