From d6a621ff5cf84572980d2a98d1ac455f90a54a73 Mon Sep 17 00:00:00 2001 From: helge Date: Tue, 8 Feb 2005 19:05:35 +0000 Subject: [PATCH] optimized IMAP4 selects git-svn-id: http://svn.opengroupware.org/SOGo/trunk@535 d1b88da0-ebda-0310-925b-ed51d893ca5b --- SOGo/SoObjects/Mailer/ChangeLog | 9 ++++ SOGo/SoObjects/Mailer/SOGoMailAccount.m | 41 +++++++++++++-- SOGo/SoObjects/Mailer/SOGoMailAccounts.m | 17 +++--- SOGo/SoObjects/Mailer/SOGoMailBaseObject.h | 1 + SOGo/SoObjects/Mailer/SOGoMailBaseObject.m | 6 +++ SOGo/SoObjects/Mailer/SOGoMailManager.m | 61 ++++++++++++++-------- SOGo/SoObjects/Mailer/Version | 2 +- 7 files changed, 101 insertions(+), 36 deletions(-) diff --git a/SOGo/SoObjects/Mailer/ChangeLog b/SOGo/SoObjects/Mailer/ChangeLog index e5807252..eb33a837 100644 --- a/SOGo/SoObjects/Mailer/ChangeLog +++ b/SOGo/SoObjects/Mailer/ChangeLog @@ -1,5 +1,14 @@ 2005-02-08 Helge Hess + * v0.9.70 + + * SOGoMailManager.m: only perform IMAP4 select if the folder changes + (gives a major speed boost), can be disabled with the + 'SOGoAlwaysSelectIMAP4Folder' default + + * SOGoMailAccount.m: added code to take the IMAP4 login from the + HTTP request + * v0.9.69 * reworked for new NGImap4 v4.5.210 API diff --git a/SOGo/SoObjects/Mailer/SOGoMailAccount.m b/SOGo/SoObjects/Mailer/SOGoMailAccount.m index 68c6ca8e..1ff8084b 100644 --- a/SOGo/SoObjects/Mailer/SOGoMailAccount.m +++ b/SOGo/SoObjects/Mailer/SOGoMailAccount.m @@ -23,6 +23,7 @@ #include "SOGoMailFolder.h" #include "SOGoMailManager.h" #include "SOGoDraftsFolder.h" +#include #include "common.h" @implementation SOGoMailAccount @@ -78,19 +79,49 @@ static NSString *sieveFolderName = @"Filters"; return NO; } +- (NSString *)imap4LoginFromHTTP { + WORequest *rq; + NSString *s; + NSArray *creds; + + rq = [[(WOApplication *)[WOApplication application] context] request]; + + s = [rq headerForKey:@"x-webobjects-remote-user"]; + if ([s length] > 0) + return s; + + if ((s = [rq headerForKey:@"authorization"]) == nil) { + /* no basic auth */ + return nil; + } + + creds = [SoHTTPAuthenticator parseCredentials:s]; + if ([creds count] < 2) + /* somehow invalid */ + return nil; + + return [creds objectAtIndex:0]; /* the user */ +} + - (NSURL *)imap4URL { /* imap://agenortest@mail.opengroupware.org/INBOX/withsubdirs/subdir1 */ NSString *s; NSRange r; - + if (self->imap4URL != nil) return self->imap4URL; s = [self nameInContainer]; r = [s rangeOfString:@"@"]; if (r.length == 0) { - [self errorWithFormat:@"missing login in account folder name: %@", s]; - return nil; + NSString *u; + + u = [self imap4LoginFromHTTP]; + if ([u length] == 0) { + [self errorWithFormat:@"missing login in account folder name: %@", s]; + return nil; + } + s = [[u stringByAppendingString:@"@"] stringByAppendingString:s]; } if ([s hasSuffix:@":80"]) { // HACK [self logWithFormat:@"WARNING: incorrect value for IMAP4 URL: '%@'", s]; @@ -104,6 +135,10 @@ static NSString *sieveFolderName = @"Filters"; return self->imap4URL; } +- (NSString *)imap4Login { + return [[self imap4URL] user]; +} + /* name lookup */ - (id)lookupFolder:(NSString *)_key ofClassNamed:(NSString *)_cn diff --git a/SOGo/SoObjects/Mailer/SOGoMailAccounts.m b/SOGo/SoObjects/Mailer/SOGoMailAccounts.m index 3f1c24e9..6c9e7c0d 100644 --- a/SOGo/SoObjects/Mailer/SOGoMailAccounts.m +++ b/SOGo/SoObjects/Mailer/SOGoMailAccounts.m @@ -1,5 +1,5 @@ /* - Copyright (C) 2004 SKYRIX Software AG + Copyright (C) 2004-2005 SKYRIX Software AG This file is part of OpenGroupware.org. @@ -18,7 +18,6 @@ Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -// $Id: SOGoMailAccounts.m 274 2004-08-26 13:10:49Z znek $ #include "SOGoMailAccounts.h" #include "common.h" @@ -32,14 +31,14 @@ - (NSArray *)toManyRelationshipKeys { static AgenorUserManager *um = nil; NSString *uid, *account; - - if(!um) - um = [AgenorUserManager sharedUserManager]; - uid = [[self container] davDisplayName]; + + if (um == nil) + um = [[AgenorUserManager sharedUserManager] retain]; + + uid = [[self container] davDisplayName]; account = [um getIMAPAccountStringForUID:uid]; - if(!account) - return nil; - return [NSArray arrayWithObject:account]; + + return account ? [NSArray arrayWithObject:account] : nil; } /* name lookup */ diff --git a/SOGo/SoObjects/Mailer/SOGoMailBaseObject.h b/SOGo/SoObjects/Mailer/SOGoMailBaseObject.h index ee8455e9..77951f9c 100644 --- a/SOGo/SoObjects/Mailer/SOGoMailBaseObject.h +++ b/SOGo/SoObjects/Mailer/SOGoMailBaseObject.h @@ -58,6 +58,7 @@ - (SOGoMailManager *)mailManager; - (NSURL *)imap4URL; +- (NSString *)imap4Login; - (NSString *)imap4Password; - (NSString *)imap4FolderName; - (NGImap4Client *)imap4Client; diff --git a/SOGo/SoObjects/Mailer/SOGoMailBaseObject.m b/SOGo/SoObjects/Mailer/SOGoMailBaseObject.m index 344ec6b7..07c45371 100644 --- a/SOGo/SoObjects/Mailer/SOGoMailBaseObject.m +++ b/SOGo/SoObjects/Mailer/SOGoMailBaseObject.m @@ -105,6 +105,12 @@ static BOOL debugOn = YES; return [[self mailManager] imap4FolderNameForURL:[self imap4URL]]; } +- (NSString *)imap4Login { + if (![[self container] respondsToSelector:_cmd]) + return nil; + + return [[self container] imap4Login]; +} - (NSString *)imap4Password { /* Extract password from basic authentication. diff --git a/SOGo/SoObjects/Mailer/SOGoMailManager.m b/SOGo/SoObjects/Mailer/SOGoMailManager.m index d92c2000..eb27b402 100644 --- a/SOGo/SoObjects/Mailer/SOGoMailManager.m +++ b/SOGo/SoObjects/Mailer/SOGoMailManager.m @@ -37,18 +37,23 @@ static BOOL debugOn = NO; static BOOL debugCache = NO; static BOOL debugKeys = NO; static BOOL poolingOff = NO; +static BOOL alwaysSelect = NO; static NSTimeInterval PoolScanInterval = 5 * 60; static NSString *imap4Separator = nil; + (void)initialize { NSUserDefaults *ud = [NSUserDefaults standardUserDefaults]; - debugOn = [ud boolForKey:@"SOGoEnableIMAP4Debug"]; - debugCache = [ud boolForKey:@"SOGoEnableIMAP4CacheDebug"]; - poolingOff = [ud boolForKey:@"SOGoDisableIMAP4Pooling"]; - + debugOn = [ud boolForKey:@"SOGoEnableIMAP4Debug"]; + debugCache = [ud boolForKey:@"SOGoEnableIMAP4CacheDebug"]; + poolingOff = [ud boolForKey:@"SOGoDisableIMAP4Pooling"]; + alwaysSelect = [ud boolForKey:@"SOGoAlwaysSelectIMAP4Folder"]; + if (debugOn) NSLog(@"Note: SOGoEnableIMAP4Debug is enabled!"); if (poolingOff) NSLog(@"WARNING: IMAP4 connection pooling is disabled!"); + + if (alwaysSelect) + NSLog(@"WARNING: 'SOGoAlwaysSelectIMAP4Folder' enabled (slow down)"); imap4Separator = [[ud stringForKey:@"SOGoIMAP4StringSeparator"] copy]; if ([imap4Separator length] == 0) @@ -212,6 +217,28 @@ static NSString *imap4Separator = nil; [entry flushMailCaches]; } +- (BOOL)selectFolder:(id)_url inClient:(NGImap4Client *)_client { + NSDictionary *result; + NSString *newFolder; + + newFolder = [_url isKindOfClass:[NSURL class]] + ? [self imap4FolderNameForURL:_url] + : _url; + + if (!alwaysSelect) { + if ([[_client selectedFolderName] isEqualToString:newFolder]) + return YES; + } + + result = [_client select:newFolder]; + if (![[result valueForKey:@"result"] boolValue]) { + [self errorWithFormat:@"could not select URL: %@: %@", _url, result]; + return NO; + } + + return YES; +} + /* folder hierarchy */ - (NSArray *)_getDirectChildren:(NSArray *)_array folderName:(NSString *)_fn { @@ -439,11 +466,8 @@ static NSString *imap4Separator = nil; /* select folder and fetch */ - result = [[entry client] select:[self imap4FolderNameForURL:_url]]; - if (![[result valueForKey:@"result"] boolValue]) { - [self errorWithFormat:@"could not select URL: %@: %@", _url, result]; + if (![self selectFolder:_url inClient:[entry client]]) return nil; - } result = [[entry client] sort:_so qualifier:_qualifier encoding:@"UTF-8"]; if (![[result valueForKey:@"result"] boolValue]) { @@ -493,12 +517,9 @@ static NSString *imap4Separator = nil; return nil; /* select folder */ - - result = [client select:[self imap4FolderNameForURL:_url]]; - if (![[result valueForKey:@"result"] boolValue]) { - [self errorWithFormat:@"could not select URL: %@: %@", _url, result]; + + if (![self selectFolder:_url inClient:client]) return nil; - } /* fetch parts */ @@ -529,12 +550,9 @@ static NSString *imap4Separator = nil; /* select folder */ p = [self imap4FolderNameForURL:_url removeFileName:NO]; - result = [client select:p]; - if (![[result valueForKey:@"result"] boolValue]) { - [self errorWithFormat:@"could not select URL: %@: %@", _url, result]; + if (![self selectFolder:p inClient:client]) return nil; - } - + /* expunge */ result = [client expunge]; @@ -560,12 +578,9 @@ static NSString *imap4Separator = nil; /* select folder */ - result = [client select:[self imap4FolderNameForURL:_url - removeFileName:YES]]; - if (![[result valueForKey:@"result"] boolValue]) { - [self errorWithFormat:@"could not select URL: %@: %@", _url, result]; + if (![self selectFolder:[self imap4FolderNameForURL:_url removeFileName:YES] + inClient:client]) return nil; - } /* fetch parts */ diff --git a/SOGo/SoObjects/Mailer/Version b/SOGo/SoObjects/Mailer/Version index 4a26ace7..49a93192 100644 --- a/SOGo/SoObjects/Mailer/Version +++ b/SOGo/SoObjects/Mailer/Version @@ -1,6 +1,6 @@ # Version file -SUBMINOR_VERSION:=69 +SUBMINOR_VERSION:=70 # v0.9.69 requires libNGMime v4.5.210 # v0.9.55 requires libNGExtensions v4.5.136 -- 2.39.5