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 - 2001, Roxen IS.
-
// $Id: module.pike,v 1.
177
2004/05/05
13
:
54
:
58
grubba
Exp $
+
// $Id: module.pike,v 1.
178
2004/05/05
15
:
39
:
47
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:825:
shared = 1; break; } } }); TRACE_LEAVE(sprintf("Returning %O.", locked_by_auth_user ? 2 : shared)); return locked_by_auth_user ? 2 : shared; }
-
//!
Lock
the resource at
@[
path
]
with
the
given
@[
lock
]
.
It's
already
-
//!
checked
that
no other lock that
applies
, i.e.
a call
-
//! @code{check_locks(path,lock->recursive,id)@} would return
-
//! @expr{0@} or @expr{1@}.
+
//!
Register
@[
lock
]
on
the
path
@[
path
]
under
the assumption that
+
//!
there
is
no other lock
already
that
conflicts with this one
, i.e.
+
//!
that
@code{check_locks(path,lock->recursive,id)@} would return
+
//! @expr{0@}
if @expr{lock->lockscope@} is @expr{"DAV:exclusive"@},
or
+
//!
@expr{0@} or
@expr{1@}
if @expr{lock->lockscope@} is
+
//! @expr{"DAV:shared"@}
.
//!
-
//!
The
implementation
must
at
least
support
the @expr{"DAV:write"@}
-
//! lock type (RFC 2518, section 7). Briefly: An exclusive lock on
a
-
//!
file
prohibits
other
users
from
changing its content. An exclusive
-
//! lock
on a
file
or
directory
prohibits
other users from setting or
-
//! deleting any of its properties. An exclusive
lock
on
a
directory
-
//!
prohibits other users from adding or removing files or directories
-
//! in it. A shared lock prohibits other users from obtaining an
-
//! exclusive lock. A resource that doesn't exist can
be
locked,
-
//! provided the directory it would be in exists
.
+
//!
This
function
is
only
provided
as
a
helper
to
call
from
+
//!
@[
lock
_
file
]
if
the
default
lock
implementation
is
to
be
used
.
//! //! @param path //! Path below the filesystem location that the lock applies to. //! It's normalized with @[VFS.normalize_path] and always ends with //! a @expr{"/"@}. //! //! @param lock //! The lock to register. //!
-
//! @returns
-
//! Returns @expr{0@} if the lock is successfully installed or a
-
//! status mapping if an error occurred.
-
//!
+
//! @note
-
//! The default implementation
supports
only @expr{"DAV:write"@}
. It
-
//! uses @[resource_id] to map paths to unique resources
and
-
//! @[authenticated_user_id] to tell users apart.
-
mapping(string:mixed)
lock
_
file
(string path,
-
DAVLock lock,
-
RequestID id)
+
//! 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)
{
-
ASSERT_IF_DEBUG (lock->locktype == "DAV:write");
-
TRACE_ENTER(sprintf("
lock
_
file
(%O, lock(%O), X).", path, lock->locktoken),
+
TRACE_ENTER(sprintf("
register_
lock(%O, lock(%O), X).", path, lock->locktoken),
this);
-
+
ASSERT_IF_DEBUG (lock->locktype == "DAV:write");
path = resource_id (path, id); mixed auth_user = authenticated_user_id (path, id); if (lock->recursive) { if (prefix_locks[path]) { prefix_locks[path][auth_user] = lock; } else { prefix_locks[path] = ([ auth_user:lock ]); } } else { if (file_locks[path]) { file_locks[path][auth_user] = lock; } else { file_locks[path] = ([ auth_user:lock ]); } } TRACE_LEAVE("Ok.");
-
+
}
+
+
//! Register @[lock] on the path @[path] under the assumption that
+
//! there is no other lock already that conflicts with this one, i.e.
+
//! that @code{check_locks(path,lock->recursive,id)@} would return
+
//! @expr{0@} if @expr{lock->lockscope@} is @expr{"DAV:exclusive"@}, or
+
//! @expr{0@} or @expr{1@} if @expr{lock->lockscope@} is
+
//! @expr{"DAV:shared"@}.
+
//!
+
//! The implementation must at least support the @expr{"DAV:write"@}
+
//! lock type (RFC 2518, section 7). Briefly: An exclusive lock on a
+
//! file prohibits other users from changing its content. An exclusive
+
//! lock on a file or directory prohibits other users from setting or
+
//! deleting any of its properties. An exclusive lock on a directory
+
//! prohibits other users from adding or removing files or directories
+
//! in it. A shared lock prohibits other users from obtaining an
+
//! exclusive lock. A resource that doesn't exist can be locked,
+
//! provided the directory it would be in exists (relaxed in RFC
+
//! 2518Bis (working draft)).
+
//!
+
//! It's up to @[find_file] et al to actually check that the necessary
+
//! locks are held. It can preferably use @[write_access] for that,
+
//! which has a default implementation for checking
+
//! @expr{"DAV:write"@} locks.
+
//!
+
//! @param path
+
//! Path below the filesystem location that the lock applies to.
+
//! It's normalized with @[VFS.normalize_path] and always ends with
+
//! a @expr{"/"@}.
+
//!
+
//! @param lock
+
//! The lock to register.
+
//!
+
//! @returns
+
//! Returns @expr{0@} if the lock is successfully installed or if
+
//! locking isn't used. Returns a status mapping if an error
+
//! occurred.
+
mapping(string:mixed) lock_file(string path,
+
DAVLock lock,
+
RequestID id)
+
{
return 0; } //! Remove @[lock] that currently is locking the resource at @[path]. //! //! @param path //! Path below the filesystem location that the lock applies to. //! It's normalized with @[VFS.normalize_path] and always ends with //! a @expr{"/"@}. //!
Roxen.git/server/base_server/module.pike:919:
if (!sizeof (file_locks[path])) m_delete (file_locks, path); } ASSERT_IF_DEBUG (!removed_lock || lock /*%O*/ == removed_lock /*%O*/, lock, removed_lock); TRACE_LEAVE("Ok."); return 0; } //! Check if we may perform a write access to @[path]. //!
-
//!
Checks
if the current locks match the if-header.
+
//!
The
default implementation checks
if the current locks match the
+
//!
if-header.
//! //! Usually called from @[find_file()]. //! //! @note //! Does not support checking against etags yet. //!
-
+
//! @param path
+
//! Path below the filesystem location that the lock applies to.
+
//! It's normalized with @[VFS.normalize_path].
+
//!
+
//! @param recursive
+
//! If @expr{1@} also check write access recursively under @[path].
+
//!
//! @returns //! Returns @expr{0@} (zero) on success and //! a result mapping on failure.
-
mapping(string:mixed)
access
_
path
(string path, RequestID id)
+
mapping(string:mixed)
write_
access(string path,
int(0..1) recursive,
RequestID id)
{
-
+
// FIXME: Implement recursive!
+
if (!sizeof(path) || (path[-1] != '/')) path += "/"; int(0..3)|DAVLock lock = check_locks(path, 0, id);
-
if (lock && intp(lock)) return Roxen.http_status(
423
);
+
if (lock && intp(lock))
+
return Roxen.http_status(
Protocols.HTTP.DAV_LOCKED
);
-
+
path = query_location() + path; // No need for fancy combine_path stuff here.
+
mapping(string:array(array(array(string)))) if_data = id->get_if_data(); array(array(array(string))) condition; if (!if_data || !sizeof(condition = if_data[path] || if_data[0])) {
-
if (lock) return Roxen.http_status(
423
);
+
if (lock) return Roxen.http_status(
Protocols.HTTP.DAV_LOCKED
);
return 0; // No condition and no lock -- Ok. }
-
+
mapping(string:mixed) res;
next_condition: foreach(condition, array(array(string)) sub_cond) { int negate; foreach(sub_cond, array(string) token) { switch(token[0]) { case "not": negate = !negate; break; case "etag":
-
// Not supported yet.
+
// Not supported yet.
We ignore this if some other condition
+
// matches.
+
res = Roxen.http_status (Protocols.HTTP.HTTP_NOT_IMPL,
+
"Etag conditions not supported.");
continue next_condition; // Fail. case "lock": if ((lock && lock->locktoken == token[1]) != negate) { // Lock mismatch. continue next_condition; // Fail. } negate = 0; break; } } return 0; // Found matching sub-condition. }
-
if
(lock)
return
Roxen.http_status(
423);
-
return Roxen
.
http
_
status(412
);
+
return
res
||
Roxen.http_status(
Protocols
.
HTTP.HTTP
_
PRECOND_FAILED
);
} mapping(string:mixed)|int(-1..0)|Stdio.File find_file(string path, RequestID id); //! Delete the file specified by @[path]. //! //! @note //! Should return a 204 status on success. //!