]> err.no Git - sope/blobdiff - sope-appserver/NGObjWeb/SoObjects/SoObject.m
changed #includes into #imports - does compile against MulleEOF out of the box now
[sope] / sope-appserver / NGObjWeb / SoObjects / SoObject.m
index 337ae90c4da2aac2857260d5c391f10b7547191d..0bcc4abfc0b6122595d3ffdd965df66589e7af1e 100644 (file)
@@ -1,31 +1,30 @@
 /*
-  Copyright (C) 2002-2004 SKYRIX Software AG
+  Copyright (C) 2002-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
+  SOPE 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
   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.
 */
-// $Id$
 
 #include "SoObject.h"
 #include "SoClassRegistry.h"
 #include "SoClass.h"
 #include "SoSecurityManager.h"
-#include <EOControl/EOClassDescription.h>
-#include <NGObjWeb/WOContext.h>
+#include "WOContext+SoObjects.h"
+// #import <EOControl/EOClassDescription.h>
 #include <NGObjWeb/WOApplication.h>
 #include <NGObjWeb/WORequest.h>
 #include "common.h"
@@ -34,8 +33,6 @@
 - (BOOL)isFolderish;
 @end
 
-static NSString *SoRootURLVarKey = @"SoRootURL";
-
 @implementation NSObject(SoObject)
 
 static int debugLookup  = -1;
@@ -44,10 +41,12 @@ static void _initialize(void) {
   if (debugLookup == -1) {
     debugLookup = [[NSUserDefaults standardUserDefaults]
                                   boolForKey:@"SoDebugKeyLookup"] ? 1 : 0;
+    NSLog(@"Note(SoObject): SoDebugKeyLookup is enabled!");
   }
   if (debugBaseURL == -1) {
     debugBaseURL = [[NSUserDefaults standardUserDefaults]
                                     boolForKey:@"SoDebugBaseURL"] ? 1 : 0;
+    NSLog(@"Note(SoObject): SoDebugBaseURL is enabled!");
   }
 }
 
@@ -247,9 +246,9 @@ static void _initialize(void) {
     NSString *name;
     
     if (parent == self) {
-      [self logWithFormat:
-             @"WARNING: container==object in baseURL calculation (loop?): %@",
-             self];
+      [self warnWithFormat:
+              @"container==object in baseURL calculation (loop?): %@",
+              self];
     }
     
     baseURL = [parent baseURLInContext:_ctx];
@@ -260,14 +259,15 @@ static void _initialize(void) {
     baseURL = [baseURL stringByAppendingString:name];
     
     if (debugBaseURL) {
-      [self logWithFormat:@"baseURL(%@,%@): %@", 
-              [self nameInContainer], [[self container] baseURL], baseURL];
+      [self logWithFormat:@"baseURL: name=%@ (container=%@)\n  container: %@\n  own: %@", 
+             [self nameInContainer], NSStringFromClass([[self container] class]),
+             [[self container] baseURL], baseURL];
     }
   }
   else {
     baseURL = [self rootURLInContext:_ctx];
     if (debugBaseURL) {
-      [self logWithFormat:@"ROOT baseURL(no container, name=%@): %@", 
+      [self logWithFormat:@"ROOT baseURL(no container, name=%@):\n  own: %@", 
               [self nameInContainer], baseURL];
     }
   }
@@ -283,7 +283,15 @@ static void _initialize(void) {
   
   return baseURL;
 }
-- (NSString *)rootURLInContext:(id)_ctx {
+
+NSString *SoObjectRootURLInContext(WOContext *_ctx, id self /* logger */, BOOL withAppPart) {
+  /*
+    Note: Evolution doesn't correctly transfer the "Host:" header, it
+    misses the port argument :-(
+
+    Note: this is called by SoObjectWebDAVDispatcher.m.
+  */
+  // TODO: this should be a WOContext method?
   NSMutableString *ms;
   BOOL      isHTTPS = NO; // TODO: what about https??
   NSString  *rootURL;
@@ -292,27 +300,18 @@ static void _initialize(void) {
   int       port;
   _initialize();
   
-  if ((rootURL = [(WOContext *)_ctx objectForKey:SoRootURLVarKey]) != nil) {
-    if (debugBaseURL) {
-      [self logWithFormat:@"  using root-url from context (SoRootURL): %@",
-              rootURL];
-    }
-    return rootURL;
-  }
-
   // TODO: this is somewhat weird, why don't we use WOContext for URL gen.?
   
-  rq   = [(WOContext *)_ctx request];
+  rq   = [_ctx request];
   port = [[rq headerForKey:@"x-webobjects-server-port"] intValue];
   
   /* TODO: how to handle Evolution bug which sends invalid port ? */
   if (port == 0) {
     static BOOL didWarn = NO;
     if (!didWarn) {
-      [self logWithFormat:
-             @"WARNING(%s:%i): got an empty port, probably buggy "
-             @"SOUP host header!",
-             __PRETTY_FUNCTION__, __LINE__];
+      [self warnWithFormat:@"(%s:%i): got an empty port, probably buggy "
+              @"SOAP host header!",
+              __PRETTY_FUNCTION__, __LINE__];
       didWarn = YES;
     }
     port = 23000;
@@ -320,38 +319,52 @@ static void _initialize(void) {
 
   ms = [[NSMutableString alloc] initWithCapacity:128];
   
-  if ((tmp = [rq headerForKey:@"host"])) { 
+  if ((tmp = [rq headerForKey:@"host"]) != nil) { 
     /* check whether we have a host header with port */
     if ([tmp rangeOfString:@":"].length == 0)
       tmp = nil;
   }
-
-  if (tmp) {
+  if (tmp != nil) { /* we have a host header with port */
     isHTTPS = 
       [[rq headerForKey:@"x-webobjects-server-url"] hasPrefix:@"https"];
     [ms appendString:isHTTPS ? @"https://" : @"http://"]; 
     [ms appendString:tmp];
   }
-  else if ((tmp = [rq headerForKey:@"x-webobjects-server-url"])) {
+  else if ((tmp = [rq headerForKey:@"x-webobjects-server-url"]) != nil) {
     /* sometimes the URL is just wrong! (suggests port 80) */
-    if ([tmp hasSuffix:@":0"] && [tmp length] > 2) // TODO: bad bad bad
+    if ([tmp hasSuffix:@":0"] && [tmp length] > 2) { // TODO: bad bad bad
+      [self logWithFormat:@"WARNING(%s): got incorrect URL from Apache: '%@'",
+             __PRETTY_FUNCTION__, tmp];
       tmp = [tmp substringToIndex:([tmp length] - 2)];
+    }
+    else if ([tmp hasSuffix:@":443"] && [tmp hasPrefix:@"http://"]) {
+      /* see OGo bug #1435, Debian Apache hack */
+      [self logWithFormat:@"WARNING(%s): got 'http' protocol but 443 port, "
+             @"assuming Debian/Apache bug (OGo #1435): '%@'",
+             __PRETTY_FUNCTION__, tmp];
+      tmp = [tmp substringWithRange:NSMakeRange(4, [tmp length] - 4 - 4)];
+      tmp = [@"https" stringByAppendingString:tmp];
+    }
     [ms appendString:tmp];
   }
   else {
+    // TODO: isHTTPS always no in this case?
     [ms appendString:isHTTPS ? @"https://" : @"http://"]; 
   
     [ms appendString:[rq headerForKey:@"x-webobjects-server-name"]];
     if ((isHTTPS ? (port != 443) : (port != 80)) && port != 0)
       [ms appendFormat:@":%i", port];
   }
-  if (![ms hasSuffix:@"/"]) [ms appendString:@"/"];
   
-  /* appname, two cases: */
-  /*   a) direct access,  eg /MyFolder */
-  /*   b) access via app, eg /MyApp/so/MyFolder */
-  [ms appendString:[rq applicationName]];
-  [ms appendString:@"/"];
+  if (withAppPart) {
+    if (![ms hasSuffix:@"/"]) [ms appendString:@"/"];
+    
+    /* appname, two cases: */
+    /*   a) direct access,  eg /MyFolder */
+    /*   b) access via app, eg /MyApp/so/MyFolder */
+    [ms appendString:[rq applicationName]];
+    if (![ms hasSuffix:@"/"]) [ms appendString:@"/"];
+  }
   
   /* done */
   rootURL = [[ms copy] autorelease];
@@ -360,15 +373,35 @@ static void _initialize(void) {
     [self logWithFormat:@"  constructed root-url: %@", rootURL];
   
   /* some hack for the request handler? */
-  rh = [rq requestHandlerKey];
-  if ([[[_ctx application] registeredRequestHandlerKeys] containsObject:rh])
-    rootURL = [rootURL stringByAppendingFormat:@"%@/", rh];
+  if (withAppPart) {
+    rh = [rq requestHandlerKey];
+    if ([[[_ctx application] registeredRequestHandlerKeys] containsObject:rh])
+      rootURL = [rootURL stringByAppendingFormat:@"%@/", rh];
+  }
+  
+  return rootURL;
+}
+
+- (NSString *)rootURLInContext:(id)_ctx {
+  NSString *rootURL;
+
+  /* check cache */
+  if ((rootURL = [_ctx rootURL]) != nil) {
+    if (debugBaseURL) {
+      [self logWithFormat:@"  using root-url from context: %@",
+              rootURL];
+    }
+    return rootURL;
+  }
+  
+  rootURL = SoObjectRootURLInContext(_ctx, self, YES);
   
+  /* remember in cache */
   if (debugBaseURL) {
-    [self logWithFormat:@"  setting root-url in context (SoRootURL): %@",
+    [self logWithFormat:@"  setting root-url in context: %@",
            rootURL];
   }
-  [(WOContext *)_ctx setObject:rootURL forKey:SoRootURLVarKey];
+  [(WOContext *)_ctx setRootURL:rootURL];
   return rootURL;
 }