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 - (WOSession *)restoreSessionWithID:(NSString *)_sid
160 request:(WORequest *)_request
162 NSAutoreleasePool *pool;
164 WOSession *session = nil;
166 if ([_sid length] == 0)
169 if (![_sid isKindOfClass:[NSString class]]) {
170 [self warnWithFormat:@"%s: got invalid session id (expected string !): %@",
171 __PRETTY_FUNCTION__, _sid];
175 if ([_sid isEqualToString:@"expired"])
178 pool = [[NSAutoreleasePool alloc] init];
180 snp = [self pathForSessionID:_sid];
182 if ([self->fileManager fileExistsAtPath:snp]) {
185 if ((data = [self->fileManager contentsAtPath:snp])) {
186 session = [NSUnarchiver unarchiveObjectWithData:data];
187 // NSLog(@"unarchived session: %@", session);
189 if (![session isKindOfClass:[WOSession class]]) {
190 NSLog(@"object unarchived from %@ isn't a WOSession: %@ ...",
196 [self logWithFormat:@"could not read sn file: '%@'", snp];
201 [self logWithFormat:@"session file does not exist: '%@'", snp];
211 [self logWithFormat:@"session with id %@ expired.", _sid];
214 return [session autorelease];
219 - (void)sessionExpired:(NSString *)_sessionID {
222 // TODO: NOT IMPLEMENTED (serialized session expiration)
223 NSLog(@"%@ expired.", _sessionID);
224 // NSMapRemove(self->idToSession, _sessionID);
229 - (void)sessionTerminated:(WOSession *)_session {
230 _session = RETAIN(_session);
233 // TODO: NOT IMPLEMENTED (serialized session termination)
234 NSLog(@"%@ terminated.", [_session sessionID]);
235 // NSMapRemove(self->idToSession, [_session sessionID]);
240 [[WOApplication application]
242 @"WOFileSessionStore: session %@ terminated.",
243 [_session sessionID]];
248 - (NSString *)description {
249 return [NSString stringWithFormat:@"<%@[0x%08X]: path=%@>",
250 NSStringFromClass([self class]), self, self->snPath];
253 @end /* WOFileSessionStore */