]> err.no Git - sope/blobdiff - sope-appserver/NGObjWeb/WOComponentRequestHandler.m
minor improvement to WOHttpAdaptor, bumped framework revisions
[sope] / sope-appserver / NGObjWeb / WOComponentRequestHandler.m
index 0209ec3994a8c30c9dd2108285de3fc665c8362e..70b5bf3f77c14b5b71611a037afd52071221cf8d 100644 (file)
@@ -1,20 +1,20 @@
 /*
-  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];