Roxen.git
/
server
/
base_server
/
module.pike
version
»
Context lines:
10
20
40
80
file
none
3
Roxen.git/server/base_server/module.pike:1:
// This file is part of Roxen WebServer. // Copyright © 1996 - 2004, Roxen IS.
-
// $Id: module.pike,v 1.
230
2008/
05
/
21
14
:
50
:
23
mast Exp $
+
// $Id: module.pike,v 1.
231
2008/
08
/
15
12
:
33
:
53
mast Exp $
#include <module_constants.h> #include <module.h> #include <request_trace.h> constant __pragma_save_parent__ = 1; inherit "basic_defvar"; mapping(string:array(int)) error_log=([]);
Roxen.git/server/base_server/module.pike:21:
private Configuration _my_configuration; private string _module_local_identifier; private string _module_identifier = lambda() { mixed init_info = roxen->bootstrap_info->get(); if (arrayp (init_info)) { [_my_configuration, _module_local_identifier] = init_info; return _my_configuration->name + "/" + _module_local_identifier; } }();
-
static
mapping _api_functions = ([]);
+
protected
mapping _api_functions = ([]);
string|array(string) module_creator; string module_url; RXML.TagSet module_tag_set; /* These functions exist in here because otherwise the messages in the * event log do not always end up in the correct module/configuration. * And the reason for that is that if the messages are logged from * subclasses in the module, the DWIM in roxenlib.pike cannot see that * they are logged from a module. This solution is not really all that
Roxen.git/server/base_server/module.pike:166:
} Configuration my_configuration() //! Returns the Configuration object of the virtual server the module //! belongs to. { return _my_configuration; }
-
nomask
void set_configuration(Configuration c)
+
final
void set_configuration(Configuration c)
{ if(_my_configuration && _my_configuration != c) error("set_configuration() called twice.\n"); _my_configuration = c; } void set_module_creator(string|array(string) c) //! Set the name and optionally email address of the author of the //! module. Names on the format "author name <author_email>" will //! end up as links on the module's information page in the admin
Roxen.git/server/base_server/module.pike:421:
} TRACE_LEAVE(""); return(res); } class DefaultPropertySet { inherit PropertySet;
-
static
Stat stat;
+
protected
Stat stat;
-
static
void create (string path, string abs_path, RequestID id, Stat stat)
+
protected
void create (string path, string abs_path, RequestID id, Stat stat)
{ ::create (path, abs_path, id); this_program::stat = stat; } Stat get_stat() {return stat;}
-
static
mapping(string:string) response_headers;
+
protected
mapping(string:string) response_headers;
mapping(string:string) get_response_headers() { if (!response_headers) { // Old kludge inherited from configuration.try_get_file. if (!id->misc->common) id->misc->common = ([]); RequestID sub_id = id->clone_me(); sub_id->misc->common = id->misc->common;
Roxen.git/server/base_server/module.pike:762:
{ // Leave this to the standard auth system by default. User uid = my_configuration()->authenticate (id); return uid && uid->name(); } // Mapping from resource id to a mapping from user id to the lock // that apply to the resource. // // Only used internally by the default lock implementation.
-
static
mapping(string:mapping(mixed:DAVLock)) file_locks = ([]);
+
protected
mapping(string:mapping(mixed:DAVLock)) file_locks = ([]);
// Mapping from resource id to a mapping from user id to the lock // that apply recursively to the resource and all other resources // it's a prefix of. // // Only used internally by the default lock implementation.
-
static
mapping(string:mapping(mixed:DAVLock)) prefix_locks = ([]);
+
protected
mapping(string:mapping(mixed:DAVLock)) prefix_locks = ([]);
#define LOOP_OVER_BOTH(PATH, LOCKS, CODE) \ do { \ foreach (file_locks; PATH; LOCKS) {CODE;} \ foreach (prefix_locks; PATH; LOCKS) {CODE;} \ } while (0) //! Find some or all locks that apply to @[path]. //! //! @param path
Roxen.git/server/base_server/module.pike:1023:
//! Normalized path (below the filesystem location) that the lock //! applies to. //! //! @param lock //! The lock to register. //! //! @note //! The default implementation only handles the @expr{"DAV:write"@} //! lock type. It uses @[resource_id] to map paths to unique resources //! and @[authenticated_user_id] to tell users apart.
-
static
void register_lock(string path, DAVLock lock, RequestID id)
+
protected
void register_lock(string path, DAVLock lock, RequestID id)
{ TRACE_ENTER(sprintf("register_lock(%O, lock(%O), X).", path, lock->locktoken), this); ASSERT_IF_DEBUG (lock->locktype == "DAV:write"); mixed auth_user = authenticated_user_id (path, id); path = resource_id (path, id); if (lock->recursive) { if (prefix_locks[path]) { prefix_locks[path][auth_user] = lock; } else {
Roxen.git/server/base_server/module.pike:1063:
//! @param path //! Normalized path (below the filesystem location) that the lock //! applies to. //! //! @param lock //! The lock to unregister. (It must not be changed or destructed.) //! //! @param id //! The request id may have the value @expr{0@} (zero) if called //! by @[Configuration()->expire_locks()].
-
static
void unregister_lock (string path, DAVLock lock, RequestID|int(0..0) id)
+
protected
void unregister_lock (string path, DAVLock lock,
+
RequestID|int(0..0) id)
{ TRACE_ENTER(sprintf("unregister_lock(%O, lock(%O), X).", path, lock->locktoken), this); mixed auth_user = id && authenticated_user_id (path, id); path = resource_id (path, id); DAVLock removed_lock; if (lock->recursive) { if (id) { removed_lock = m_delete(prefix_locks[path], auth_user); } else {
Roxen.git/server/base_server/module.pike:1321:
//! write access to @[path]. It should at least call //! @[check_if_header] to check DAV locks. It takes the same arguments //! and has the same return value as that function. //! //! WARNING: This function has some design issues and will very likely //! get a different interface. Compatibility is NOT guaranteed. //! //! A filesystem module should typically put all needed write access //! checks here and then use this from @[find_file()], //! @[delete_file()] etc.
-
static
mapping(string:mixed)|int(0..1) write_access(string relative_path,
+
protected
mapping(string:mixed)|int(0..1) write_access(string relative_path,
int(0..1) recursive, RequestID id) { return check_if_header (relative_path, recursive, id); } mapping(string:mixed)|int(-1..0)|Stdio.File find_file(string path, RequestID id); //! Used by the default @[recurse_delete_files] implementation to //! delete a file or an empty directory. //! //! @returns //! Returns a 2xx series status mapping on success (typically 204 No //! Content). Returns 0 if the file doesn't exist. Returns an //! appropriate status mapping for any other error. //! //! @note //! The default implementation falls back to @[find_file()].
-
static
mapping(string:mixed) delete_file(string path, RequestID id)
+
protected
mapping(string:mixed) delete_file(string path, RequestID id)
{ // Fall back to find_file(). RequestID tmp_id = id->clone_me(); tmp_id->not_query = query_location() + path; tmp_id->method = "DELETE"; // FIXME: Logging? return find_file(path, tmp_id) || tmp_id->misc->error_code && Roxen.http_status (tmp_id->misc->error_code); }
Roxen.git/server/base_server/module.pike:1450:
//! @param destination //! Destination path below the filesystem location. //! //! @param behavior //! Specifies how to copy properties. See the @[PropertyBehavior] //! type for details. //! //! @returns //! @expr{0@} (zero) on success or an appropriate status mapping for //! any error.
-
static
mapping(string:mixed) copy_properties(string source, string destination,
-
PropertyBehavior behavior, RequestID id)
+
protected
mapping(string:mixed) copy_properties(
+
string source, string destination, PropertyBehavior behavior, RequestID id)
{ SIMPLE_TRACE_ENTER(this, "copy_properties(%O, %O, %O, %O)", source, destination, behavior, id); PropertySet source_properties = query_property_set(source, id); PropertySet destination_properties = query_property_set(destination, id); multiset(string) property_set = source_properties->query_all_properties(); mapping(string:mixed) res; foreach(property_set; string property_name;) { SIMPLE_TRACE_ENTER(this, "Copying the property %O.", property_name);
Roxen.git/server/base_server/module.pike:1532:
//! location. //! //! @returns //! Returns a 2xx series status mapping on success (typically 201 //! Created if the destination didn't exist before, or 204 No //! Content otherwise). Returns 0 if the source doesn't exist. //! Returns an appropriate status mapping for any other error. That //! includes an empty mapping in case there's a failure on some //! subpart or at the destination, to signify a 207 Multi-Status //! response using the info in @[id->get_multi_status()].
-
static
mapping(string:mixed) copy_collection(string source,
-
string destination,
-
PropertyBehavior behavior,
-
Overwrite overwrite,
-
MultiStatus.Prefixed result,
-
RequestID id)
+
protected
mapping(string:mixed) copy_collection(
+
string source, string destination, PropertyBehavior behavior,
+
Overwrite overwrite, MultiStatus.Prefixed result, RequestID id)
{ SIMPLE_TRACE_ENTER(this, "copy_collection(%O, %O, %O, %O, %O, %O).", source, destination, behavior, overwrite, result, id); Stat st = stat_file(destination, id); if (st) { // Destination exists. Check the overwrite header. switch(overwrite) { case DO_OVERWRITE: // RFC 2518 8.8.4 // If a resource exists at the destination, and the Overwrite
Roxen.git/server/base_server/module.pike:1635:
//! //! @param overwrite //! Specifies how to handle the situation if the destination already //! exists. See the @[Overwrite] type for details. //! //! @returns //! Returns a 2xx series status mapping on success (typically 201 //! Created if the destination didn't exist before, or 204 No //! Content otherwise). Returns 0 if the source doesn't exist. //! Returns an appropriate status mapping for any other error.
-
static
mapping(string:mixed) copy_file(string source, string destination,
+
protected
mapping(string:mixed) copy_file(string source, string destination,
PropertyBehavior behavior, Overwrite overwrite, RequestID id) { SIMPLE_TRACE_ENTER(this, "copy_file(%O, %O, %O, %O, %O)\n", source, destination, behavior, overwrite, id); TRACE_LEAVE("Not implemented."); return Roxen.http_status (Protocols.HTTP.HTTP_NOT_IMPL); } //! Copy a resource recursively from @[source] to @[destination].
Roxen.git/server/base_server/module.pike:1764:
//! exists. See the @[Overwrite] type for details. //! //! @returns //! Returns a 2xx series status mapping on success (typically 201 //! Created if the destination didn't exist before, or 204 No //! Content otherwise). Returns 0 if the source doesn't exist. //! Returns an appropriate status mapping for any other error. That //! includes an empty mapping in case there's a failure on some //! subpart or at the destination, to signify a 207 Multi-Status //! response using the info in @[id->get_multi_status()].
-
static
mapping(string:mixed) move_file(string source, string destination,
+
protected
mapping(string:mixed) move_file(string source, string destination,
PropertyBehavior behavior, Overwrite overwrite, RequestID id) { // Fall back to find_file(). RequestID tmp_id = id->clone_me(); tmp_id->not_query = query_location() + source; tmp_id->misc["new-uri"] = query_location() + destination; tmp_id->request_headers->destination = id->url_base() + query_location()[1..] + destination; tmp_id->method = "MOVE";
Roxen.git/server/base_server/module.pike:1821:
//! Created if the destination didn't exist before, or 204 No //! Content otherwise). Returns 0 if the source doesn't exist. //! Returns an appropriate status mapping for any other error. That //! includes an empty mapping in case there's a failure on some //! subpart or at the destination, to signify a 207 Multi-Status //! response using the info in @[id->get_multi_status()]. //! //! @note //! The function must be prepared to recurse to check DAV locks //! properly.
-
static
mapping(string:mixed) move_collection(string source, string destination,
-
PropertyBehavior behavior,
+
protected
mapping(string:mixed) move_collection(
+
string source, string destination, PropertyBehavior behavior,
Overwrite overwrite, RequestID id) { // Fall back to find_file(). RequestID tmp_id = id->clone_me(); tmp_id->not_query = query_location() + source; tmp_id->misc["new-uri"] = query_location() + destination; tmp_id->request_headers->destination = id->url_base() + query_location()[1..] + destination; tmp_id->method = "MOVE"; mapping(string:mixed) res = find_file(source, tmp_id);
Roxen.git/server/base_server/module.pike:1991:
Stdio.File file=Stdio.File(); if(!file->open(path,"r")) return 0; if(has_suffix(index, "()")) index = index[..sizeof(index) - 3]; // Pass path to original file so that include statements for local files // work correctly. return compile_string((pre || "") + file->read(), path)[index]; }
-
static
private mapping __my_tables = ([]);
+
private mapping __my_tables = ([]);
array(mapping(string:mixed)) sql_query( string query, mixed ... args ) //! Do a SQL-query using @[get_my_sql], the table names in the query //! should be written as &table; instead of table. As an example, if //! the tables 'meta' and 'data' have been created with create_tables //! or get_my_table, this query will work: //! //! SELECT &meta;.id AS id, &data;.data as DATA //! FROM &data;, &meta; WHERE &my.meta;.xsize=200 //! { return get_my_sql()->query( replace( query, __my_tables ), @args ); } object sql_big_query( string query, mixed ... args )
-
//! Identical to @[sql_query], but the @[Sql.
sql
()->big_query] method
-
//! will be used instead of the @[Sql.
sql
()->query] method.
+
//! Identical to @[sql_query], but the @[Sql.
Sql
()->big_query] method
+
//! will be used instead of the @[Sql.
Sql
()->query] method.
{ return get_my_sql()->big_query( replace( query, __my_tables ), @args ); } array(mapping(string:mixed)) sql_query_ro( string query, mixed ... args ) //! Do a read-only SQL-query using @[get_my_sql], the table names in the query //! should be written as &table; instead of table. As an example, if //! the tables 'meta' and 'data' have been created with create_tables //! or get_my_table, this query will work: //! //! SELECT &meta;.id AS id, &data;.data as DATA //! FROM &data;, &meta; WHERE &my.meta;.xsize=200 //! { return get_my_sql(1)->query( replace( query, __my_tables ), @args ); } object sql_big_query_ro( string query, mixed ... args )
-
//! Identical to @[sql_query_ro], but the @[Sql.
sql
()->big_query] method
-
//! will be used instead of the @[Sql.
sql
()->query] method.
+
//! Identical to @[sql_query_ro], but the @[Sql.
Sql
()->big_query] method
+
//! will be used instead of the @[Sql.
Sql
()->query] method.
{ return get_my_sql(1)->big_query( replace( query, __my_tables ), @args ); }
-
static
int create_sql_tables( mapping(string:array(string)) definitions,
-
string|void comment,
-
int|void no_unique_names )
+
protected
int create_sql_tables( mapping(string:array(string)) definitions,
+
string|void comment, int|void no_unique_names )
//! Create multiple tables in one go. See @[get_my_table] //! Returns the number of tables that were actually created. { int ddc; if( !no_unique_names ) foreach( indices( definitions ), string t ) ddc+=get_my_table( t, definitions[t], comment, 1 ); else { Sql.Sql sql = get_my_sql();
Roxen.git/server/base_server/module.pike:2058:
if( !catch { sql->query("CREATE TABLE "+t+" ("+definitions[t]*","+")" ); } ) ddc++; DBManager.is_module_table( this_object(), my_db, t, comment ); } } return ddc; }
-
static
string sql_table_exists( string name )
+
protected
string sql_table_exists( string name )
//! Return the real name of the table 'name' if it exists. { if(strlen(name)) name = "_"+name; string res = hash(_my_configuration->name)->digits(36) + "_" + replace(sname(), ({ "#","-" }), ({ "_","_" })) + name; return catch(get_my_sql()->query( "SELECT * FROM "+res+" LIMIT 1" ))?0:res; }
-
static
string|int get_my_table( string|array(string) name,
+
protected
string|int get_my_table( string|array(string) name,
void|array(string)|string definition,
-
string|void comment,
-
int|void flag )
+
string|void comment, int|void flag )
//! @decl string get_my_table( string name, array(string) types ) //! @decl string get_my_table( string name, string definition ) //! @decl string get_my_table( string definition ) //! @decl string get_my_table( array(string) definition ) //! //! Returns the name of a table in the 'shared' database that is //! unique for this module. It is possible to select another database //! by using @[set_my_db] before calling this function. //! //! You can use @[create_sql_tables] instead of this function if you want
Roxen.git/server/base_server/module.pike:2184:
// describe_error( error ) ); // } if( flag ) { __my_tables[ "&"+oname+";" ] = res; return ddc; } return __my_tables[ "&"+oname+";" ] = res; }
-
static
string my_db = "local";
+
protected
string my_db = "local";
-
static
void set_my_db( string to )
+
protected
void set_my_db( string to )
//! Select the database in which tables will be created with //! get_my_table, and also the one that will be returned by //! @[get_my_sql] { my_db = to; } Sql.Sql get_my_sql( int|void read_only, void|string charset ) //! Return a SQL-object for the database set with @[set_my_db], //! defaulting to the 'shared' database. If @[read_only] is specified, //! the database will be opened in read_only mode. @[charset] may be //! used to specify a charset for the connection if the database //! supports it. //! //! See also @[DBManager.get] { return DBManager.cached_get( my_db, _my_configuration, read_only, charset ); }