2 Copyright (C) 2000-2005 SKYRIX Software AG
4 This file is part of SOPE.
6 SOPE is free software; you can redistribute it and/or modify it under
7 the terms of the GNU Lesser General Public License as published by the
8 Free Software Foundation; either version 2, or (at your option) any
11 SOPE is distributed in the hope that it will be useful, but WITHOUT ANY
12 WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
14 License for more details.
16 You should have received a copy of the GNU Lesser General Public
17 License along with SOPE; see the file COPYING. If not, write to the
18 Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
22 #include <NGObjWeb/WOSessionStore.h>
25 This store keeps all sessions as archived files inside of a directory.
26 It provides session fail-over, but restoring/saving a session takes some
34 The session-directory can be selected using the WOFileSessionPath default.
36 Note: it doesn't provide session distribution between instances, since the
37 store doesn't lock the session files.
40 @class NSString, NSFileManager;
42 @interface WOFileSessionStore : WOSessionStore
44 NSFileManager *fileManager;
49 #include <NGObjWeb/WOContext.h>
50 #include <NGObjWeb/WOSession.h>
51 #include <NGObjWeb/WOApplication.h>
54 @implementation WOFileSessionStore
56 static BOOL logExpire = YES;
59 return [super version] + 0;
62 NSAssert2([super version] == 2,
63 @"invalid superclass (%@) version %i !",
64 NSStringFromClass([self superclass]), [super version]);
67 - (id)initWithSessionPath:(NSString *)_path {
71 if ([_path length] == 0) {
76 fm = [NSFileManager defaultManager];
77 if (![fm fileExistsAtPath:_path isDirectory:&isDir]) {
78 if (![fm createDirectoryAtPath:_path attributes:nil]) {
79 NSLog(@"%s: could not create a directory at path: %@",
80 __PRETTY_FUNCTION__, _path);
86 NSLog(@"%s: not a directory path: %@", __PRETTY_FUNCTION__, _path);
91 if ((self = [super init])) {
92 self->snPath = [_path copy];
93 self->fileManager = [fm retain];
99 p = [[NSUserDefaults standardUserDefaults]
100 stringForKey:@"WOFileSessionPath"];
101 return [self initWithSessionPath:p];
105 [self->fileManager release];
106 [self->snPath release];
112 - (int)activeSessionsCount {
114 //return [[self->fileManager directoryContentsAtPath:self->snPath] count];
119 - (NSString *)pathForSessionID:(NSString *)_sid {
120 return [self->snPath stringByAppendingPathComponent:_sid];
123 - (void)saveSessionForContext:(WOContext *)_context {
127 if (![_context hasSession])
130 sn = [_context session];
131 snp = [self pathForSessionID:[sn sessionID]];
133 if ([sn isTerminating]) {
136 // TODO: NOT IMPLEMENTED (serialized-session termination)
137 //NSMapRemove(self->idToSession, [sn sessionID]);
139 NSLog(@"session %@ terminated at %@ ..",
140 [sn sessionID], [NSCalendarDate calendarDate]);
146 data = [NSArchiver archivedDataWithRootObject:sn];
149 if (![data writeToFile:snp atomically:YES]) {
151 @"could not write data of session %@ to file: '%@'", sn, snp];
155 [self logWithFormat:@"could not archive session: '%@'", sn];
159 - (id)restoreSessionWithID:(NSString *)_sid request:(WORequest *)_request {
160 NSAutoreleasePool *pool;
162 WOSession *session = nil;
164 if ([_sid length] == 0)
167 if (![_sid isKindOfClass:[NSString class]]) {
168 [self warnWithFormat:@"%s: got invalid session id (expected string !): %@",
169 __PRETTY_FUNCTION__, _sid];
173 if ([_sid isEqualToString:@"expired"])
176 pool = [[NSAutoreleasePool alloc] init];
178 snp = [self pathForSessionID:_sid];
180 if ([self->fileManager fileExistsAtPath:snp]) {
183 if ((data = [self->fileManager contentsAtPath:snp])) {
184 session = [NSUnarchiver unarchiveObjectWithData:data];
185 // NSLog(@"unarchived session: %@", session);
187 if (![session isKindOfClass:[WOSession class]]) {
188 NSLog(@"object unarchived from %@ isn't a WOSession: %@ ...",
194 [self logWithFormat:@"could not read sn file: '%@'", snp];
199 [self logWithFormat:@"session file does not exist: '%@'", snp];
209 [self logWithFormat:@"session with id %@ expired.", _sid];
212 return [session autorelease];
217 - (void)sessionExpired:(NSString *)_sessionID {
220 // TODO: NOT IMPLEMENTED (serialized session expiration)
221 NSLog(@"%@ expired.", _sessionID);
222 // NSMapRemove(self->idToSession, _sessionID);
227 - (void)sessionTerminated:(WOSession *)_session {
228 _session = RETAIN(_session);
231 // TODO: NOT IMPLEMENTED (serialized session termination)
232 NSLog(@"%@ terminated.", [_session sessionID]);
233 // NSMapRemove(self->idToSession, [_session sessionID]);
238 [[WOApplication application]
240 @"WOFileSessionStore: session %@ terminated.",
241 [_session sessionID]];
246 - (NSString *)description {
247 return [NSString stringWithFormat:@"<%@[0x%p]: path=%@>",
248 NSStringFromClass([self class]), self, self->snPath];
251 @end /* WOFileSessionStore */