mirror of
https://gitlab.com/davical-project/davical.git
synced 2026-08-31 18:46:02 +00:00
Refactor checking of If-*-Match headers into a single place.
This also exposes and fixes a bug in PUT vcard where If-None-Match: "*" was not being correctly processed.
This commit is contained in:
parent
ea874375b6
commit
200b3a08dd
@ -197,7 +197,7 @@ class CalDAVRequest
|
||||
if ( $this->method == 'PROPFIND' || $this->method == 'REPORT' || $this->method == 'PROPPATCH' || $this->method == 'BIND' || $this->method == 'MKTICKET' || $this->method == 'ACL' ) {
|
||||
if ( !preg_match( '{^(text|application)/xml$}', $this->content_type ) ) {
|
||||
@dbg_error_log( "LOG request", 'Request is "%s" but client set content-type to "%s". Assuming they meant XML!',
|
||||
$request->method, $this->content_type );
|
||||
$this->method, $this->content_type );
|
||||
$this->content_type = 'text/xml';
|
||||
}
|
||||
}
|
||||
@ -1076,6 +1076,59 @@ EOSQL;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Check that the incoming Etag matches the one for the existing (or non-existing) resource.
|
||||
*
|
||||
* @param boolean $exists Whether the destination exists
|
||||
* @param string $dest_etag The etag for the destination.
|
||||
*/
|
||||
function CheckEtagMatch( $exists, $dest_etag ) {
|
||||
global $c;
|
||||
|
||||
if ( ! $exists ) {
|
||||
if ( (isset($this->etag_if_match) && $this->etag_if_match != '') ) {
|
||||
/**
|
||||
* RFC2068, 14.25:
|
||||
* If none of the entity tags match, or if "*" is given and no current
|
||||
* entity exists, the server MUST NOT perform the requested method, and
|
||||
* MUST return a 412 (Precondition Failed) response.
|
||||
*/
|
||||
$this->PreconditionFailed(412, 'if-match', translate('No resource exists at the destination.'));
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
||||
if ( isset($c->strict_etag_checking) && $c->strict_etag_checking )
|
||||
$trim_chars = '\'\\" ';
|
||||
else
|
||||
$trim_chars = ' ';
|
||||
|
||||
if ( isset($this->etag_if_match) && $this->etag_if_match != '' && trim( $this->etag_if_match, $trim_chars) != trim( $dest_etag, $trim_chars ) ) {
|
||||
/**
|
||||
* RFC2068, 14.25:
|
||||
* If none of the entity tags match, or if "*" is given and no current
|
||||
* entity exists, the server MUST NOT perform the requested method, and
|
||||
* MUST return a 412 (Precondition Failed) response.
|
||||
*/
|
||||
$this->PreconditionFailed(412,'if-match',sprintf('Existing resource ETag of <<%s>> does not match <<%s>>', $dest_etag, $this->etag_if_match) );
|
||||
}
|
||||
else if ( isset($this->etag_none_match) && $this->etag_none_match != ''
|
||||
&& ($this->etag_none_match == $dest_etag || $this->etag_none_match == '*') ) {
|
||||
/**
|
||||
* RFC2068, 14.26:
|
||||
* If any of the entity tags match the entity tag of the entity that
|
||||
* would have been returned in the response to a similar GET request
|
||||
* (without the If-None-Match header) on that resource, or if "*" is
|
||||
* given and any current entity exists for that resource, then the
|
||||
* server MUST NOT perform the requested method.
|
||||
*/
|
||||
$this->PreconditionFailed(412,'if-none-match', translate( 'Existing resource matches "If-None-Match" header - not accepted.'));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Is the user has the privileges to do what is requested.
|
||||
*/
|
||||
|
||||
@ -63,13 +63,7 @@ else {
|
||||
$dest->NeedPrivilege('DAV::write-content');
|
||||
}
|
||||
|
||||
if ( isset($request->etag_none_match) && $request->etag_none_match != '*' && $dest->Exists() ) {
|
||||
$request->DoResponse(412);
|
||||
}
|
||||
|
||||
if ( isset($request->etag_if_match) && $request->etag_if_match != $dest->unique_tag() ) {
|
||||
$request->DoResponse(412);
|
||||
}
|
||||
$request->CheckEtagMatch( $dest->Exists(), $dest->unique_tag() );
|
||||
|
||||
$collection_id = $container->GetProperty('collection_id');
|
||||
|
||||
|
||||
@ -76,39 +76,7 @@ if ( $dav_resource->IsCollection() ) {
|
||||
|
||||
$etag = md5($request->raw_post);
|
||||
|
||||
if ( ! $dav_resource->Exists() && (isset($request->etag_if_match) && $request->etag_if_match != '') ) {
|
||||
/**
|
||||
* RFC2068, 14.25:
|
||||
* If none of the entity tags match, or if "*" is given and no current
|
||||
* entity exists, the server MUST NOT perform the requested method, and
|
||||
* MUST return a 412 (Precondition Failed) response.
|
||||
*/
|
||||
$request->PreconditionFailed(412,'if-match');
|
||||
}
|
||||
|
||||
if ( $dav_resource->Exists() ) {
|
||||
if ( isset($request->etag_if_match) && $request->etag_if_match != '' && $request->etag_if_match != $dav_resource->unique_tag() ) {
|
||||
/**
|
||||
* RFC2068, 14.25:
|
||||
* If none of the entity tags match, or if "*" is given and no current
|
||||
* entity exists, the server MUST NOT perform the requested method, and
|
||||
* MUST return a 412 (Precondition Failed) response.
|
||||
*/
|
||||
$request->PreconditionFailed(412,'if-match',sprintf('Existing resource ETag of "%s" does not match "%s"', $dav_resource->unique_tag(), $request->etag_if_match) );
|
||||
}
|
||||
else if ( isset($request->etag_none_match) && $request->etag_none_match != ''
|
||||
&& ($request->etag_none_match == $dav_resource->unique_tag() || $request->etag_none_match == '*') ) {
|
||||
/**
|
||||
* RFC2068, 14.26:
|
||||
* If any of the entity tags match the entity tag of the entity that
|
||||
* would have been returned in the response to a similar GET request
|
||||
* (without the If-None-Match header) on that resource, or if "*" is
|
||||
* given and any current entity exists for that resource, then the
|
||||
* server MUST NOT perform the requested method.
|
||||
*/
|
||||
$request->PreconditionFailed(412,'if-none-match', translate( 'Existing resource matches "If-None-Match" header - not accepted.'));
|
||||
}
|
||||
}
|
||||
$request->CheckEtagMatch( $dav_resource->Exists(), $dav_resource->unique_tag() );
|
||||
|
||||
$put_action_type = ($dav_resource->Exists() ? 'UPDATE' : 'INSERT');
|
||||
$collection = $dav_resource->GetParentContainer();
|
||||
|
||||
@ -65,13 +65,7 @@ else {
|
||||
$dest->NeedPrivilege('DAV::write-content');
|
||||
}
|
||||
|
||||
if ( isset($request->etag_none_match) && $request->etag_none_match != '*' && $dest->Exists() ) {
|
||||
$request->PreconditionFailed(412,'if-none-match', translate('A resource already exists at the destination.'));
|
||||
}
|
||||
|
||||
if ( isset($request->etag_if_match) && $request->etag_if_match != $dest->unique_tag() ) {
|
||||
$request->PreconditionFailed(412,'if-match',sprintf('Existing resource ETag of "%s" does not match "%s"', $dest->unique_tag(), $request->etag_if_match) );
|
||||
}
|
||||
$request->CheckEtagMatch( $dest->Exists(), $dest->unique_tag() );
|
||||
|
||||
$collection_id = $container->GetProperty('collection_id');
|
||||
|
||||
|
||||
@ -6,7 +6,7 @@ URL=http://regression.host/caldav.php/user1/addressbook/F06EC844-EACD-4ADF-8823-
|
||||
|
||||
HEADER=User-Agent: DAViCalTester/public
|
||||
HEADER=Content-Type: text/vcard; charset=utf-8
|
||||
HEADER=If-None-Match: *
|
||||
HEADER=If-Match: "3419498c6e5eae71dc1704f1787faf1c"
|
||||
HEAD
|
||||
|
||||
BEGINDATA
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user