Now handling LOCK + refresh LOCK on a calendar resource.

This commit is contained in:
Andrew McMillan 2006-12-06 13:52:13 +13:00
parent ecc3b2cb06
commit 7f13003a14
2 changed files with 35 additions and 8 deletions

View File

@ -10,7 +10,7 @@
* @package rscds
* @subpackage CalDAVRequest
* @author Andrew McMillan <andrew@mcmillan.net.nz>
* @copyright Andrew McMillan
* @copyright Catalyst .Net Ltd
* @license http://gnu.org/copyleft/gpl.html GNU GPL v2
*/
@ -54,7 +54,9 @@ class CalDAVRequest
* LOCK things use an "If" header to hold the lock in some cases, and "Lock-token" in others
*/
if ( isset($_SERVER['HTTP_IF']) ) $this->if_clause = $_SERVER['HTTP_IF'];
if ( isset($_SERVER['HTTP_LOCK-TOKEN']) ) $this->lock_token = $_SERVER['HTTP_LOCK-TOKEN'];
if ( isset($_SERVER['HTTP_LOCK_TOKEN']) && preg_match( '#[<]opaquelocktoken:(.*)[>]#', $_SERVER['HTTP_LOCK_TOKEN'], $matches ) ) {
$this->lock_token = $matches[1];
}
/**
* LOCK things use a "Timeout" header to set a series of reducing alternative values
@ -245,13 +247,22 @@ class CalDAVRequest
function ValidateLockToken( $lock_token ) {
if ( isset($this->lock_token) && $this->lock_token == $lock_token ) return true;
if ( isset($this->if_clause) ) {
dbg_error_log( "caldav", "Checking lock token '%s' against '%s'", $lock_token, $this->if_clause );
$tokens = preg_split( '/[<>]/', $this->if_clause );
foreach( $tokens AS $k => $v ) {
dbg_error_log( "caldav", "Checking lock token '%s' against '%s'", $lock_token, $v );
if ( 'opaquelocktoken:' == substr( $v, 0, 16 ) ) {
if ( substr( $v, 16 ) == $lock_token ) return true;
if ( substr( $v, 16 ) == $lock_token ) {
dbg_error_log( "caldav", "Lock token '%s' validated OK against '%s'", $lock_token, $v );
return true;
}
}
}
}
else {
@dbg_error_log( "caldav", "Invalid lock token '%s' - not in Lock-token (%s) or If headers (%s) ", $lock_token, $this->lock_token, $this->if_clause );
}
return false;
}
@ -364,6 +375,8 @@ class CalDAVRequest
case 415: $status_text = "Unsupported Media Type"; break;
case 416: $status_text = "Requested Range Not Satisfiable"; break;
case 417: $status_text = "Expectation Failed"; break;
case 423: $status_text = "Locked"; break;
case 424: $status_text = "Failed Dependency"; break;
case 500: $status_text = "Internal Server Error"; break;
case 501: $status_text = "Not Implemented"; break;
case 502: $status_text = "Bad Gateway"; break;

View File

@ -93,28 +93,42 @@ function lock_resource( $user_no, $path ) {
dbg_error_log( "LOCK", "Attempting to lock resource '%s'", $path);
if ( ($lock_token = $request->IsLocked()) ) { // NOTE Assignment in if() is expected here.
dbg_error_log( "LOCK", "Attempting to renew resource lock on '%s'", $path);
if ( $request->ValidateLockToken($lock_token) ) {
$sql = "UPDATE locks SET start = current_timestamp WHERE opaquelocktoken = ?;";
$qry = new PgQuery($sql, $lock_token );
$qry->Exec("LOCK",__LINE__,__FILE__);
}
else {
/** FIXME: Deny the lock */
/**
* Already locked - deny it
*/
$response = array(
new XMLElement( 'href', $request->path ),
new XMLElement( 'status', 'HTTP/1.1 423 Resource Locked')
);
$response = new XMLElement( "multistatus", new XMLElement( 'response', $response), array('xmlns'=>'DAV:') );
$xmldoc = $response->Render(0,'<?xml version="1.0" encoding="utf-8" ?>');
$request->DoResponse( 423, $xmldoc, 'text/xml; charset="utf-8"' );
}
}
else {
/**
* A fresh lock
*/
$lock_token = uuid();
$sql = "INSERT INTO locks ( dav_name, opaquelocktoken, type, scope, depth, owner, timeout, start ) VALUES( ?, ?, ?, ?, ?, ?, ?::interval, current_timestamp );";
$qry = new PgQuery($sql, $request->path, $lock_token, $lockinfo['type'], $lockinfo['scope'], $request->depth, $lockinfo['owner'], $request->timeout.' seconds' );
$qry->Exec("LOCK",__LINE__,__FILE__);
header( "Lock-Token: <opaquelocktoken:$lock_token>" );
}
$lock_row = $request->GetLockRow($lock_token);
$activelock = array(
new XMLElement( 'locktype', new XMLElement( $lockinfo['type'] )),
new XMLElement( 'lockscope', new XMLElement( $lockinfo['scope'] )),
new XMLElement( 'locktype', new XMLElement( $lock_row->type )),
new XMLElement( 'lockscope', new XMLElement( $lock_row->scope )),
new XMLElement( 'depth', $request->GetDepthName() ),
new XMLElement( 'owner', new XMLElement( 'href', $lockinfo['owner'] )),
new XMLElement( 'owner', new XMLElement( 'href', $lock_row->owner )),
new XMLElement( 'timeout', 'Second-'.$request->timeout),
new XMLElement( 'locktoken', new XMLElement( 'href', 'opaquelocktoken:'.$lock_token ))
);
@ -153,7 +167,7 @@ else {
}
$prop = new XMLElement( "prop", $response, array('xmlns'=>'DAV:') );
dbg_log_array( "LOCK", "XML", $response, true );
// dbg_log_array( "LOCK", "XML", $response, true );
$xmldoc = $prop->Render(0,'<?xml version="1.0" encoding="utf-8" ?>');
$request->DoResponse( 200, $xmldoc, 'text/xml; charset="utf-8"' );