/*
- Copyright (C) 2000-2004 SKYRIX Software AG
+ Copyright (C) 2000-2005 SKYRIX Software AG
- This file is part of OpenGroupware.org.
+ This file is part of SOPE.
- OGo is free software; you can redistribute it and/or modify it under
- the terms of the GNU Lesser General Public License as published by the
+ SOPE is free software; you can redistribute it and/or modify it under
+ the terms of the GNU Lesser General Pulic License as published by the
Free Software Foundation; either version 2, or (at your option) any
later version.
- OGo is distributed in the hope that it will be useful, but WITHOUT ANY
+ SOPE is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
License for more details.
You should have received a copy of the GNU Lesser General Public
- License along with OGo; see the file COPYING. If not, write to the
+ License along with SOPE; see the file COPYING. If not, write to the
Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA.
*/
- (void)_setCurrentContext:(WOContext *)_ctx;
@end
+@interface WORequestHandler(URI)
+- (BOOL)doesRejectFavicon;
+@end
+
@implementation WOComponentRequestHandler
+ (int)version {
- (WOResponse *)restoreSessionWithID:(NSString *)_sid
inContext:(WOContext *)_ctx
{
- WOApplication *app = [WOApplication application];
- WOResponse *response = nil;
+ WOApplication *app;
+ WOSession *session;
+ app = [WOApplication application];
if (_sid == nil) {
// invalid session ID (or no session-ID ?!, which is no error ?) */
- response = [app handleSessionRestorationErrorInContext:_ctx];
+ return [app handleSessionRestorationErrorInContext:_ctx];
}
- else {
- WOSession *session = nil;
+
+ if ((session = [app restoreSessionWithID:_sid inContext:_ctx]) != nil) {
+ /* awake restored session */
+ [_ctx setSession:session];
+ [session _awakeWithContext:_ctx];
- if ((session = [app restoreSessionWithID:_sid inContext:_ctx])) {
- // awake restored session
- [_ctx setSession:session];
- [session _awakeWithContext:_ctx];
-
- [session awake];
- response = nil;
- }
- else {
- response = [app handleSessionRestorationErrorInContext:_ctx];
- }
+ [session awake];
+ return nil;
}
- return response;
+
+ return [app handleSessionRestorationErrorInContext:_ctx];
}
/*
*/
- (WOResponse *)handleRequest:(WORequest *)_request {
+ // TODO: this should be integrated into the WORequestHandler default
+ // mechanism
NSString *sessionID = nil;
WOApplication *application = nil;
- WOContext *context = nil;
+ WOContext *context;
WOResponse *response = nil;
WOSession *session = nil;
WOComponent *component = nil;
NSString *handlerPath = nil;
if (_request == nil) return nil;
-
+
+ if ([self doesRejectFavicon] && [[_request uri] isNotNull]) {
+ // TODO: code copied from WORequestHandler ...
+ if ([@"/favicon.ico" isEqualToString:[_request uri]]) {
+ response = [WOResponse responseWithRequest:_request];
+ [response setStatus:404 /* not found */];
+ [self debugWithFormat:@"rejected favicon request: %@", [_request uri]];
+ return response;
+ }
+ }
+
application = [WOApplication application];
handlerPath = [_request requestHandlerPath];
-
+
#if 0
- NSLog(@"[component request handler] path=%@ ..", handlerPath);
+ [self logWithFormat:@"[component request handler] path: '%@'", handlerPath];
#endif
if (![application allowsConcurrentRequestHandling]) {
session/context.element-id
*/
- if ([handlerPath length] > 0) {
+ if ([handlerPath isNotEmpty]) {
NSArray *spath = [_request requestHandlerPathArray];
-
+
if ([spath count] > 1)
[context setRequestSenderID:[spath objectAtIndex:1]];
- if ([spath count] > 0)
+ if ([spath isNotEmpty])
sessionID = [spath objectAtIndex:0];
}
- if ([sessionID length] == 0)
+ if (![sessionID isNotEmpty])
sessionID = [application sessionIDFromRequest:_request];
-#if 0
- NSLog(@"%s: made context %@ (cid=%@, sn=%@) ..", __PRETTY_FUNCTION__
- context, [context contextID], sessionID);
+#if 1
+ [self logWithFormat:@"%s: made context %@ (cid=%@, sn=%@) ..",
+ __PRETTY_FUNCTION__, context, [context contextID], sessionID];
#endif
[application awake];
/* restore or create session */
- if (sessionID) {
- response = [self restoreSessionWithID:sessionID inContext:context];
- session = response ? nil : [context session];
+ if ([sessionID isNotEmpty]) {
+ if ((response = [self restoreSessionWithID:sessionID inContext:context]))
+ session = nil;
+ else {
+ /*
+ Note: this creates a _new_ session if the restoration handler did not
+ return a response! We check that below by comparing the session
+ IDs.
+ */
+ session = [context session];
+ }
+
+ [self debugWithFormat:@"restored session (id=%@): %@", sessionID, session];
+
+ if (session && (![sessionID isEqualToString:[session sessionID]])) {
+ [self errorWithFormat:@"session-ids do not match (%@ vs %@)",
+ sessionID, [session sessionID]];
+ }
- if (session) {
- /* awake stored page */
- component = [session restorePageForContextID:[context currentElementID]];
+ if ([session isNotNull]) {
+ NSString *eid;
- if (component == nil)
- response = [application handlePageRestorationErrorInContext:context];
-#if DEBUG
- else {
- NSLog(@"%s: restored request component %@", __PRETTY_FUNCTION__,
- component);
+ /*
+ only try to restore a page if we still have the same session and if
+ the request contains an element-id (eg if we reconnect to the main
+ URL we do not have an element-id
+ */
+ eid = [context currentElementID];
+ if ([sessionID isEqualToString:[session sessionID]] && eid != nil) {
+ /* awake stored page from "old" session */
+ component = [session restorePageForContextID:eid];
+
+ if (component == nil) {
+ [self logWithFormat:@"could not restore component from session: %@",
+ session];
+ response = [application handlePageRestorationErrorInContext:context];
+ }
}
-#endif
+ else /* a new session was created (but no restore-error response ret.) */
+ component = [application pageWithName:nil inContext:context];
}
else if (response == nil) {
- [[WOApplication application]
- logWithFormat:
- @"WARNING: got no session restoration error, "
- @"but missing session !"];
+ [[WOApplication application] warnWithFormat:
+ @"got no session restoration error, "
+ @"but missing session!"];
}
}
else {
/* create new session */
session = [application _initializeSessionInContext:context];
- if (session) {
+ if ([session isNotNull]) {
/* awake created session */
[session awake];
component = [application pageWithName:nil inContext:context];
/* run invoke-action phase */
newPage = [application invokeActionForRequest:_request inContext:context];
-
+
/* process resulting page */
if (newPage == nil) {
if ((newPage = [context page]) == nil) {
else if ([newPage isKindOfClass:[WOComponent class]])
[context setPage:newPage];
-#if DEBUG
[self debugWithFormat:@"%s: new page: %@", __PRETTY_FUNCTION__, newPage];
-#endif
/* generate response */
-#if 1 /* new code, ensure that _fixupResponse is called */
+
response = [self generateResponseForComponent:[context page]
inContext:context
application:application];
-#else /* old code */
- response = [context response];
- [application appendToResponse:response inContext:context];
-#endif
}
else {
- NSLog(@"WARNING(%s): did not enter request/response transaction ...",
- __PRETTY_FUNCTION__);
+ [self warnWithFormat:@"%s: did not enter request/response transaction ...",
+ __PRETTY_FUNCTION__];
}
-
+
/* tear down */
/* sleep objects */
[session sleep];
/* save objects */
- if (session) {
+
+ if (session != nil) {
if ([context savePageRequired])
[session savePage:[context page]];
- NSLog(@"saving session %@", [session sessionID]);
+ [self debugWithFormat:@"saving session %@", [session sessionID]];
+
+ if ([session storesIDsInCookies]) {
+ [self debugWithFormat:@"add cookie to session: %@", session];
+ [self addCookiesForSession:session
+ toResponse:response
+ inContext:context];
+ }
+
+#if 1 // TODO: explain that
[application saveSessionForContext:context];
+#else
+ [self saveSession:session
+ inContext:context
+ withResponse:response
+ application:application];
+#endif
}
[application sleep];