From 803f1eab11dd1fe8c566b944f1da0eadb57ef423 Mon Sep 17 00:00:00 2001 From: helge Date: Mon, 1 Nov 2004 10:26:36 +0000 Subject: [PATCH] added support for complex davResourceTypes git-svn-id: http://svn.opengroupware.org/SOPE/trunk@330 e4a50df8-12e2-0310-a44c-efbce7f8a7e3 --- sope-appserver/NGObjWeb/ChangeLog | 12 +++ .../NGObjWeb/SoObjects/SoDefaultRenderer.m | 11 ++- sope-appserver/NGObjWeb/Version | 2 +- .../NGObjWeb/WebDAV/SoWebDAVRenderer.m | 91 ++++++++++++++++--- .../NGExtensions/NGExtensions/NSString+Ext.h | 1 - 5 files changed, 100 insertions(+), 17 deletions(-) diff --git a/sope-appserver/NGObjWeb/ChangeLog b/sope-appserver/NGObjWeb/ChangeLog index 6672cb90..98c82249 100644 --- a/sope-appserver/NGObjWeb/ChangeLog +++ b/sope-appserver/NGObjWeb/ChangeLog @@ -1,3 +1,15 @@ +2004-11-01 Helge Hess + + * WebDAV/SoWebDAVRenderer.m: added support for multiple resource type + tags (v4.3.80) + +2004-10-31 Helge Hess + + * WebDAV/SoWebDAVRenderer.m: preserve etag in response if set (v4.3.79) + + * SoObjects/SoDefaultRenderer.m: fixed typo, check exceptions for 200 + HTTP codes and do not return them as an error (v4.3.78) + 2004-10-27 Marcus Mueller * DynamicElements/{WOResetButton.m, WOText.m, WOFileUpload.m, diff --git a/sope-appserver/NGObjWeb/SoObjects/SoDefaultRenderer.m b/sope-appserver/NGObjWeb/SoObjects/SoDefaultRenderer.m index 314dbedc..9bd1bc79 100644 --- a/sope-appserver/NGObjWeb/SoObjects/SoDefaultRenderer.m +++ b/sope-appserver/NGObjWeb/SoObjects/SoDefaultRenderer.m @@ -96,8 +96,15 @@ static int debugOn = 0; if (debugOn) [self debugWithFormat:@" as exception"]; - if ((stat = [_ex httpStatus]) > 0) + // TODO: add ability to specify HTTP headers in the user info? + + if ((stat = [_ex httpStatus]) > 0) { [r setStatus:stat]; + if (stat >= 200 && stat < 300) { + [r appendContentString:[_ex reason]]; + return nil; + } + } else [r setStatus:500]; @@ -106,7 +113,7 @@ static int debugOn = 0; @"\n" @"\n" @"" - @"

An error occured during object publishing

"]; + @"

An error occurred during object publishing

"]; [r appendContentString:@"

"]; [r appendContentString:[_ex reason]]; [r appendContentString:@"

"]; diff --git a/sope-appserver/NGObjWeb/Version b/sope-appserver/NGObjWeb/Version index 984868a4..ca086d87 100644 --- a/sope-appserver/NGObjWeb/Version +++ b/sope-appserver/NGObjWeb/Version @@ -1,6 +1,6 @@ # version file -SUBMINOR_VERSION:=77 +SUBMINOR_VERSION:=80 # v4.3.42 requires libNGExtensions v4.3.116 # v4.3.40 requires libNGExtensions v4.3.115 diff --git a/sope-appserver/NGObjWeb/WebDAV/SoWebDAVRenderer.m b/sope-appserver/NGObjWeb/WebDAV/SoWebDAVRenderer.m index d6f36e8d..1afcb9fe 100644 --- a/sope-appserver/NGObjWeb/WebDAV/SoWebDAVRenderer.m +++ b/sope-appserver/NGObjWeb/WebDAV/SoWebDAVRenderer.m @@ -144,8 +144,11 @@ static BOOL formatOutput = NO; - (BOOL)renderObjectBodyResult:(id)_object inContext:(WOContext *)_ctx onlyHead:(BOOL)_onlyHead { - WOResponse *r = [_ctx response]; + WOResponse *r; NSString *tmp; + unsigned char buf[128]; + + r = [_ctx response]; /* TODO: implement proper etag support. This probably implies that we need @@ -153,19 +156,21 @@ static BOOL formatOutput = NO; We cannot use davEntityTag on the input parameter, since this is usually the plain object. */ - tmp = @"0"; // fallback, cannot use the thing above - [r setHeader:tmp forKey:@"ETag"]; // required for WebFolder PUTs + if ((tmp = [r headerForKey:@"etag"]) == nil) { + tmp = @"0"; // fallback, cannot use the thing above + [r setHeader:tmp forKey:@"etag"]; // required for WebFolder PUTs + } if ([_object isKindOfClass:[NSData class]]) { [r setHeader:[self mimeTypeForData:_object inContext:_ctx] forKey:@"content-type"]; - [r setHeader:[NSString stringWithFormat:@"%d", [_object length]] - forKey:@"content-length"]; + sprintf(buf, "%d", [_object length]); + [r setHeader:[NSString stringWithCString:buf] forKey:@"content-length"]; if (!_onlyHead) [r setContent:_object]; return YES; } - + if ([_object isKindOfClass:[NSString class]]) { NSData *data; @@ -173,8 +178,8 @@ static BOOL formatOutput = NO; forKey:@"content-type"]; data = [_object dataUsingEncoding:NSUTF8StringEncoding]; - [r setHeader:[NSString stringWithFormat:@"%d", [data length]] - forKey:@"content-length"]; + sprintf(buf, "%d", [data length]); + [r setHeader:[NSString stringWithCString:buf] forKey:@"content-length"]; [r setContent:data]; return YES; } @@ -299,6 +304,69 @@ static BOOL formatOutput = NO; return YES; } +- (NSString *)stringForResourceType:(id)_value ofProperty:(NSString *)_prop + prefixes:(NSDictionary *)_prefixes +{ + NSString *davNS; + + davNS = [_prefixes objectForKey:@"DAV:"]; + + if ([_value isKindOfClass:[NSArray class]]) { + /* + Use arrays to allow for something like this: + + + Item Format: + ( TAG ) => tag in DAV: namespace + ( TAG, NS ) => tag in NS namespace + ( TAG, NS, PREFIX ) => tag in NS namespace with PREFIX + */ + NSMutableString *ms; + NSEnumerator *e; + id item; + + if ([_value count] == 0) + return nil; + + ms = [NSMutableString stringWithCapacity:16]; + e = [_value objectEnumerator]; + while ((item = [e nextObject]) != nil) { + unsigned count; + + if (![item isKindOfClass:[NSArray class]]) { + item = [item stringValue]; + if ([item length] == 0) continue; + [ms appendFormat:@"<%@:%@ />", davNS, item]; + continue; + } + + /* process array tags */ + + if ((count = [item count]) == 0) + continue; + + if (count == 1) + [ms appendFormat:@"<%@:%@ />", davNS, [item objectAtIndex:0]]; + else if (count == 2) { + /* 0=tag, 1=nsuri */ + [ms appendFormat:@"<%@ xmlns=\"%@\" />", + [item objectAtIndex:0], [item objectAtIndex:1]]; + } + else { + /* 0=tag, 1=nsuri, 2=nsprefix */ + [ms appendFormat:@"<%@:%@ xmlns:%@=\"%@\" />", + [item objectAtIndex:2], [item objectAtIndex:0], + [item objectAtIndex:2], [item objectAtIndex:1]]; + } + } + return ms; + } + + _value = [_value stringValue]; + if ([_value length] == 0) return nil; + + return [NSString stringWithFormat:@"<%@:%@/>", davNS, _value]; +} - (NSString *)stringForValue:(id)_value ofProperty:(NSString *)_prop prefixes:(NSDictionary *)_prefixes { @@ -313,11 +381,8 @@ static BOOL formatOutput = NO; /* special processing for some properties */ if ([_prop isEqualToString:@"{DAV:}resourcetype"]) { - _value = [_value stringValue]; - if ([_value length] == 0) return nil; - - return [NSString stringWithFormat:@"<%@:%@/>", - [_prefixes objectForKey:@"DAV:"], _value]; + return [self stringForResourceType:_value ofProperty:_prop + prefixes:_prefixes]; } else if ([_prop isEqualToString:@"{DAV:}creationdate"]) datefmt = @"%Y-%m-%dT%H:%M:%S%zZ"; diff --git a/sope-core/NGExtensions/NGExtensions/NSString+Ext.h b/sope-core/NGExtensions/NGExtensions/NSString+Ext.h index f2b877a5..50bf3ccb 100644 --- a/sope-core/NGExtensions/NGExtensions/NSString+Ext.h +++ b/sope-core/NGExtensions/NGExtensions/NSString+Ext.h @@ -18,7 +18,6 @@ Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -// $Id$ #ifndef __NGExtensions_NSString_Ext_H__ #define __NGExtensions_NSString_Ext_H__ -- 2.39.5