From 4b8ec230fa9bdc23770f5517b7962c5a75bb4485 Mon Sep 17 00:00:00 2001 From: helge Date: Wed, 20 Jul 2005 15:17:51 +0000 Subject: [PATCH] fixed etag processing git-svn-id: http://svn.opengroupware.org/SOGo/trunk@852 d1b88da0-ebda-0310-925b-ed51d893ca5b --- SOGo/SoObjects/SOGo/ChangeLog | 9 ++++++ SOGo/SoObjects/SOGo/SOGoContentObject.m | 6 +++- SOGo/SoObjects/SOGo/SOGoObject.m | 41 +++++++++++++++++++++++-- SOGo/SoObjects/SOGo/Version | 2 +- 4 files changed, 54 insertions(+), 4 deletions(-) diff --git a/SOGo/SoObjects/SOGo/ChangeLog b/SOGo/SoObjects/SOGo/ChangeLog index 8658cf46..f5b83e26 100644 --- a/SOGo/SoObjects/SOGo/ChangeLog +++ b/SOGo/SoObjects/SOGo/ChangeLog @@ -1,5 +1,14 @@ 2005-07-20 Helge Hess + * v0.9.66 + + * SOGoContentObject.m: properly quote etag + + * SOGoObject.m: changed to check etag when the content is accessed in + WebDAV mode and return a 304 if the tag stayed the same. + Do not strip quotes from etags in if-*match headers. + Properly implement if-none-match for GET requests. + * SOGoContentObject.m: moved generic etag checking to SOGoObject (to share implementation with Mailer) (v0.9.65) diff --git a/SOGo/SoObjects/SOGo/SOGoContentObject.m b/SOGo/SoObjects/SOGo/SOGoContentObject.m index 193bb9d6..724f1914 100644 --- a/SOGo/SoObjects/SOGo/SOGoContentObject.m +++ b/SOGo/SoObjects/SOGo/SOGoContentObject.m @@ -241,13 +241,17 @@ - (id)davEntityTag { // TODO: cache tag in ivar? => if you do, remember to flush after PUT GCSFolder *folder; + char buf[64]; if ((folder = [self ocsFolder]) == nil) { [self errorWithFormat:@"Did not find folder of content object."]; return nil; } - return [folder versionOfContentWithName:[self nameInContainer]]; + sprintf(buf, "\"gcs%08d\"", + [[folder versionOfContentWithName:[self nameInContainer]] + unsignedIntValue]); + return [NSString stringWithCString:buf]; } /* WebDAV */ diff --git a/SOGo/SoObjects/SOGo/SOGoObject.m b/SOGo/SoObjects/SOGo/SOGoObject.m index 3bf55bea..f63fc6e1 100644 --- a/SOGo/SoObjects/SOGo/SOGoObject.m +++ b/SOGo/SoObjects/SOGo/SOGoObject.m @@ -163,15 +163,19 @@ static BOOL kontactGroupDAV = YES; // default method) WORequest *rq; WOResponse *r; - NSString *uri; + NSString *uri; r = [(WOContext *)_ctx response]; rq = [(WOContext *)_ctx request]; if ([rq isSoWebDAVRequest]) { if ([self respondsToSelector:@selector(contentAsString)]) { + NSException *error; id etag; + if ((error = [self matchesRequestConditionInContext:_ctx]) != nil) + return error; + [r appendContentString:[self contentAsString]]; if ((etag = [self davEntityTag]) != nil) @@ -211,8 +215,10 @@ static BOOL kontactGroupDAV = YES; NSString *etag; etag = [[etags objectAtIndex:i] stringByTrimmingSpaces]; +#if 0 /* this is non-sense, right? */ if ([etag hasPrefix:@"\""] && [etag hasSuffix:@"\""]) etag = [etag substringWithRange:NSMakeRange(1, [etag length] - 2)]; +#endif if (etag != nil) [ma addObject:etag]; } @@ -220,7 +226,10 @@ static BOOL kontactGroupDAV = YES; } - (NSException *)checkIfMatchCondition:(NSString *)_c inContext:(id)_ctx { - /* only run the request if one of the etags matches the resource etag */ + /* + Only run the request if one of the etags matches the resource etag, + usually used to ensure consistent PUTs. + */ NSArray *etags; NSString *etag; @@ -274,6 +283,34 @@ static BOOL kontactGroupDAV = YES; Can be used for PUT to ensure that the object does not exist in the store and for GET to retrieve the content only if if the etag changed. */ + + if (![_c isEqualToString:@"*"] && + [[[_ctx request] method] isEqualToString:@"GET"]) { + NSString *etag; + NSArray *etags; + + if ((etags = [self parseETagList:_c]) == nil) + return nil; + if ([etags count] == 0) /* no etags to check for? */ + return nil; + + etag = [self davEntityTag]; + if ([etag length] == 0) /* has no etag, ignore */ + return nil; + + [self logWithFormat:@"CHECK %@ vs %@", etag, etags]; + + if ([etags containsObject:etag]) { + [self logWithFormat:@"etag '%@' matches: %@", etag, + [etags componentsJoinedByString:@","]]; + /* one etag matches, so stop the request */ + return [NSException exceptionWithHTTPStatus:304 /* Not Modified */ + reason:@"object was not modified"]; + } + + return nil; + } + #if 0 if ([_c isEqualToString:@"*"]) return nil; diff --git a/SOGo/SoObjects/SOGo/Version b/SOGo/SoObjects/SOGo/Version index 6313547e..46a95765 100644 --- a/SOGo/SoObjects/SOGo/Version +++ b/SOGo/SoObjects/SOGo/Version @@ -1,6 +1,6 @@ # version file -SUBMINOR_VERSION:=65 +SUBMINOR_VERSION:=66 # v0.9.63 requires libNGiCal v4.5.54 # v0.9.60 requires libNGiCal v4.5.49 -- 2.39.5