From 6a2c8b3636b046a3763cb88a27a2406cd2d94108 Mon Sep 17 00:00:00 2001 From: helge Date: Wed, 20 Jul 2005 15:30:41 +0000 Subject: [PATCH] further improved etag support git-svn-id: http://svn.opengroupware.org/SOGo/trunk@853 d1b88da0-ebda-0310-925b-ed51d893ca5b --- SOGo/SoObjects/Mailer/ChangeLog | 10 +++++++ SOGo/SoObjects/Mailer/GNUmakefile.preamble | 6 ++++ SOGo/SoObjects/Mailer/SOGoMailBodyPart.m | 29 ++++++++++++++++++++ SOGo/SoObjects/Mailer/SOGoMailObject.h | 1 + SOGo/SoObjects/Mailer/SOGoMailObject.m | 32 ++++++++++++++++++++-- SOGo/SoObjects/SOGo/SOGoObject.m | 6 ++-- 6 files changed, 77 insertions(+), 7 deletions(-) diff --git a/SOGo/SoObjects/Mailer/ChangeLog b/SOGo/SoObjects/Mailer/ChangeLog index 7116760f..e2ef8d5a 100644 --- a/SOGo/SoObjects/Mailer/ChangeLog +++ b/SOGo/SoObjects/Mailer/ChangeLog @@ -1,5 +1,15 @@ 2005-07-20 Helge Hess + * v0.9.115 + + * SOGoMailObject.m: do not use clientObject when fetching the + coreinfos, added a -doesMailExist method to cheaply check for + mail existance + + * SOGoMailBodyPart.m, SOGoMailObject.m: added a constant etag for + content (possible for IMAP4 content), check etag prior delivering + content (return a 304 in case the constant etag is supplied) + * SOGoMailObject.m: added handling for some specific headers (v0.9.114) 2005-07-19 Helge Hess diff --git a/SOGo/SoObjects/Mailer/GNUmakefile.preamble b/SOGo/SoObjects/Mailer/GNUmakefile.preamble index c302ad8b..848ebbb2 100644 --- a/SOGo/SoObjects/Mailer/GNUmakefile.preamble +++ b/SOGo/SoObjects/Mailer/GNUmakefile.preamble @@ -1 +1,7 @@ # compilation settings + +ADDITIONAL_CPPFLAGS += \ + -Wall -DCOMPILE_FOR_GSTEP_MAKE=1 \ + -DUIX_MAILER_MAJOR_VERSION=$(MAJOR_VERSION) \ + -DUIX_MAILER_MINOR_VERSION=$(MINOR_VERSION) \ + -DUIX_MAILER_SUBMINOR_VERSION=$(SUBMINOR_VERSION) diff --git a/SOGo/SoObjects/Mailer/SOGoMailBodyPart.m b/SOGo/SoObjects/Mailer/SOGoMailBodyPart.m index f13feabd..28b6ea32 100644 --- a/SOGo/SoObjects/Mailer/SOGoMailBodyPart.m +++ b/SOGo/SoObjects/Mailer/SOGoMailBodyPart.m @@ -26,6 +26,7 @@ @implementation SOGoMailBodyPart +static NSString *mailETag = nil; static BOOL debugOn = NO; + (int)version { @@ -36,6 +37,12 @@ static BOOL debugOn = NO; NSAssert2([super version] == 1, @"invalid superclass (%@) version %i !", NSStringFromClass([self superclass]), [super version]); + + mailETag = [[NSString alloc] initWithFormat:@"\"imap4url_%d_%d_%03d\"", + UIX_MAILER_MAJOR_VERSION, + UIX_MAILER_MINOR_VERSION, + UIX_MAILER_SUBMINOR_VERSION]; + NSLog(@"Note: using constant etag for mail parts: '%@'", mailETag); } - (void)dealloc { @@ -236,9 +243,21 @@ static BOOL debugOn = NO; /* actions */ - (id)GETAction:(id)_ctx { + NSException *error; WOResponse *r; NSData *data; + NSString *etag; + if ((error = [self matchesRequestConditionInContext:_ctx]) != nil) { + // TODO: currently we fetch the body structure to get here - check this! + /* check whether the mail still exists */ + if (![[self mailObject] doesMailExist]) { + return [NSException exceptionWithHTTPStatus:404 /* Not Found */ + reason:@"mail was deleted"]; + } + return error; /* return 304 or 416 */ + } + [self debugWithFormat:@"should fetch body part: %@", [self bodyPartIdentifier]]; @@ -255,6 +274,10 @@ static BOOL debugOn = NO; [r setHeader:[self davContentType] forKey:@"content-type"]; [r setHeader:[NSString stringWithFormat:@"%d", [data length]] forKey:@"content-length"]; + + if ((etag = [self davEntityTag]) != nil) + [r setHeader:etag forKey:@"etag"]; + [r setContent:data]; return r; } @@ -291,6 +314,12 @@ static BOOL debugOn = NO; return self; } +/* etag support */ + +- (id)davEntityTag { + return mailETag; +} + /* debugging */ - (BOOL)isDebuggingEnabled { diff --git a/SOGo/SoObjects/Mailer/SOGoMailObject.h b/SOGo/SoObjects/Mailer/SOGoMailObject.h index d82a14cf..1b5b7591 100644 --- a/SOGo/SoObjects/Mailer/SOGoMailObject.h +++ b/SOGo/SoObjects/Mailer/SOGoMailObject.h @@ -53,6 +53,7 @@ /* core infos */ +- (BOOL)doesMailExist; - (id)fetchCoreInfos; // TODO: what does it do? - (NGImap4Envelope *)envelope; diff --git a/SOGo/SoObjects/Mailer/SOGoMailObject.m b/SOGo/SoObjects/Mailer/SOGoMailObject.m index cd50bbed..80477ac7 100644 --- a/SOGo/SoObjects/Mailer/SOGoMailObject.m +++ b/SOGo/SoObjects/Mailer/SOGoMailObject.m @@ -166,13 +166,29 @@ static BOOL debugSoParts = NO; /* core infos */ +- (BOOL)doesMailExist { + static NSArray *existsKey = nil; + id msgs; + + if (existsKey == nil) /* we use size, other suggestions? */ + existsKey = [[NSArray alloc] initWithObjects:@"RFC822.SIZE", nil]; + + msgs = [self fetchParts:existsKey]; // returns dict + msgs = [msgs valueForKey:@"fetch"]; + return [msgs count] > 0 ? YES : NO; +} + - (id)fetchCoreInfos { id msgs; if (self->coreInfos != nil) return [self->coreInfos isNotNull] ? self->coreInfos : nil; - + +#if 0 // TODO: old code, why was it using clientObject?? msgs = [[self clientObject] fetchParts:coreInfoKeys]; // returns dict +#else + msgs = [self fetchParts:coreInfoKeys]; // returns dict +#endif if (heavyDebug) [self logWithFormat:@"M: %@", msgs]; msgs = [msgs valueForKey:@"fetch"]; if ([msgs count] == 0) @@ -670,8 +686,18 @@ static BOOL debugSoParts = NO; /* actions */ - (id)GETAction:(id)_ctx { - WOResponse *r; - NSData *content; + NSException *error; + WOResponse *r; + NSData *content; + + if ((error = [self matchesRequestConditionInContext:_ctx]) != nil) { + /* check whether the mail still exists */ + if (![self doesMailExist]) { + return [NSException exceptionWithHTTPStatus:404 /* Not Found */ + reason:@"mail was deleted"]; + } + return error; /* return 304 or 416 */ + } content = [self content]; if ([content isKindOfClass:[NSException class]]) diff --git a/SOGo/SoObjects/SOGo/SOGoObject.m b/SOGo/SoObjects/SOGo/SOGoObject.m index f63fc6e1..ac1e4fe1 100644 --- a/SOGo/SoObjects/SOGo/SOGoObject.m +++ b/SOGo/SoObjects/SOGo/SOGoObject.m @@ -297,12 +297,10 @@ static BOOL kontactGroupDAV = YES; 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:@","]]; + [self debugWithFormat:@"etag '%@' matches: %@", etag, + [etags componentsJoinedByString:@","]]; /* one etag matches, so stop the request */ return [NSException exceptionWithHTTPStatus:304 /* Not Modified */ reason:@"object was not modified"]; -- 2.39.5