/*
- 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
+ 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.
*/
if ((tmp = [_r headerForKey:@"server"]) == nil) {
// TODO: add application name as primary name
- [_r setHeader:@"SOPE 4.2/WebDAV" forKey:@"server"];
+ static NSString *server = nil;
+
+ if (server == nil) {
+ server = [[NSString alloc] initWithFormat:@"SOPE %i.%i.%i/WebDAV",
+ SOPE_MAJOR_VERSION, SOPE_MINOR_VERSION,
+ SOPE_SUBMINOR_VERSION];
+ }
+
+ [_r setHeader:server forKey:@"server"];
}
[_r setHeader:@"close" forKey:@"connection"];
}
if ([_object isKindOfClass:[NSData class]]) {
+ NSString *s;
+
[r setHeader:[self mimeTypeForData:_object inContext:_ctx]
forKey:@"content-type"];
- sprintf(buf, "%d", [_object length]);
- [r setHeader:[NSString stringWithCString:buf] forKey:@"content-length"];
+ sprintf((char *)buf, "%d", [_object length]);
+ s = [[NSString alloc] initWithCString:(const char *)buf];
+ if (s != nil) [r setHeader:s forKey:@"content-length"];
+ [s release];
if (!_onlyHead) [r setContent:_object];
return YES;
}
if ([_object isKindOfClass:[NSString class]]) {
- NSData *data;
+ NSData *data;
+ NSString *s;
[r setHeader:[self mimeTypeForString:_object inContext:_ctx]
forKey:@"content-type"];
data = [_object dataUsingEncoding:NSUTF8StringEncoding];
- sprintf(buf, "%d", [data length]);
- [r setHeader:[NSString stringWithCString:buf] forKey:@"content-length"];
+ sprintf((char *)buf, "%d", [data length]);
+ s = [[NSString alloc] initWithCString:(const char *)buf];
+ [r setHeader:s forKey:@"content-length"];
+ [s release];
[r setContent:data];
return YES;
}
return YES;
}
- [self logWithFormat:@"ERROR: don't know how to render: %@", _object];
+ [self errorWithFormat:@"don't know how to render: %@", _object];
return NO;
}
if (href == nil) {
if (debugOn) {
- [self logWithFormat:
- @"WARNING: using baseURL for href, "
- @"entry did not provide a URL: %@", baseURL];
+ [self warnWithFormat:
+ @"using baseURL for href, entry did not provide a URL: %@",
+ baseURL];
}
href = [baseURL stringValue];
}
if ((key = [_propMap objectForKey:@"{DAV:}href"]) != nil) {
if ((href = [entry valueForKey:key]) == nil) {
if (debugOn) {
- [self debugWithFormat:
- @"WARNING: no value for {DAV:}href key '%@': %@",
- key, entry];
+ [self warnWithFormat:
+ @"no value for {DAV:}href key '%@': %@", key, entry];
}
}
}
else if (debugOn) {
- [self debugWithFormat:
- @"WARNING: no key for {DAV:}href in property map !"];
+ [self warnWithFormat:@"no key for {DAV:}href in property map !"];
}
}
if ((stat = [entry valueForKey:@"{DAV:}status"]) == nil) {
if (formatOutput) [r appendContentCharacter:'\n'];
}
else {
- [self logWithFormat:
- @"WARNING: WebDAV result entry has no valid href: %@", entry];
+ [self warnWithFormat:@"WebDAV result entry has no valid href: %@", entry];
}
[r appendContentString:@"<D:propstat>"];
- if (stat) {
- [r appendContentString:@"<D:status>"];
- [r appendContentXMLString:[stat stringValue]];
- [r appendContentString:@"</D:status>"];
- }
-
[r appendContentString:@"<D:prop>"];
if (formatOutput) [r appendContentCharacter:'\n'];
}
}
- [r appendContentString:@"</D:prop></D:propstat></D:response>"];
+ [r appendContentString:@"</D:prop>"];
+ if (formatOutput) [r appendContentCharacter:'\n'];
+
+ if (stat != nil) {
+ [r appendContentString:@"<D:status>"];
+ [r appendContentXMLString:[stat stringValue]];
+ [r appendContentString:@"</D:status>"];
+ }
+
+ [r appendContentString:@"</D:propstat></D:response>"];
if (formatOutput) [r appendContentCharacter:'\n'];
}
/* generate multistatus */
[r setStatus:207 /* multistatus */];
+ [r setContentEncoding:NSUTF8StringEncoding];
+ [r setHeader:@"text/xml; charset=\"utf-8\"" forKey:@"content-type"];
[r setHeader:@"no-cache" forKey:@"pragma"];
[r setHeader:@"no-cache" forKey:@"cache-control"];
r = [_ctx response];
- [r setStatus:200];
+ [r setStatus:200 /* OK */];
[r setContentEncoding:NSUTF8StringEncoding];
[r setHeader:@"text/xml; charset=\"utf-8\"" forKey:@"content-type"];
[r setHeader:[_object stringValue] forKey:@"lock-token"];
}
- (BOOL)renderOptions:(id)_object inContext:(WOContext *)_ctx {
- WOResponse *r = [_ctx response];
+ WOResponse *r;
- [r setStatus:200];
+ r = [_ctx response];
+ [r setStatus:200 /* OK */];
[r setHeader:@"1,2" forKey:@"DAV"]; // TODO: select protocol level
//[r setHeader:@"" forKey:@"Etag"];
- [r setHeader:[_object componentsJoinedByString:@", "] forKey:@"allow"];
+
+ if (![_object isNotNull])
+ ;
+ else if ([_object isKindOfClass:[NSArray class]]) {
+ /* DEPRECATED */
+ [r setHeader:[_object componentsJoinedByString:@", "] forKey:@"allow"];
+ }
+ else {
+ [self logWithFormat:@"ERROR: unexpected options result: %@ (class=%@)",
+ _object, [_object class]];
+ }
return YES;
}
notificationType = [rq headerForKey:@"notification-type"];
lifetime = [rq headerForKey:@"subscription-lifetime"];
- [r setStatus:200];
- if (notificationType)
+ [r setStatus:200 /* OK */];
+ if (notificationType != nil)
[r setHeader:notificationType forKey:@"notification-type"];
- if (lifetime)
+ if (lifetime != nil)
[r setHeader:lifetime forKey:@"subscription-lifetime"];
- if (callback)
+ if (callback != nil)
[r setHeader:callback forKey:@"callback"];
[r setHeader:[self baseURLForContext:_ctx] forKey:@"content-location"];
[r setHeader:_object forKey:@"subscription-id"];
nsToPrefix:nsToPrefix];
[r setStatus:207 /* multistatus */];
+ [r setContentEncoding:NSUTF8StringEncoding];
+ [r setHeader:@"text/xml; charset=\"utf-8\"" forKey:@"content-type"];
[r appendContentString:@"<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"];
[r appendContentString:@"<D:multistatus"];
[r appendContentString:[self nsDeclsForMap:nsToPrefix]];
[r appendContentString:[[_ctx request] uri]];
[r appendContentString:@"</D:href>"];
if (formatOutput) [r appendContentCharacter:'\n'];
- [r appendContentString:@"<D:propstat><D:status>HTTP/1.1 200 OK</D:status>"];
+ [r appendContentString:@"<D:propstat>"];
if (formatOutput) [r appendContentCharacter:'\n'];
[r appendContentString:@"<D:prop>"];
if (formatOutput) [r appendContentCharacter:'\n'];
}
}
- [r appendContentString:@"</D:prop></D:propstat></D:response>"];
+ [r appendContentString:@"</D:prop>"];
+ if (formatOutput) [r appendContentCharacter:'\n'];
+ [r appendContentString:@"<D:status>HTTP/1.1 200 OK</D:status>"];
+ [r appendContentString:@"</D:propstat></D:response>"];
if (formatOutput) [r appendContentCharacter:'\n'];
[r appendContentString:@"</D:multistatus>"];
if (formatOutput) [r appendContentCharacter:'\n'];
if ([_object isKindOfClass:[NSDictionary class]]) {
NSArray *pending, *inactive;
- pending = [_object objectForKey:@"pending"];
- inactive = [_object objectForKey:@"inactive"];
+ pending = [(NSDictionary *)_object objectForKey:@"pending"];
+ inactive = [(NSDictionary *)_object objectForKey:@"inactive"];
[r setStatus:207 /* Multi-Status */];
- [r setHeader:@"text/xml" forKey:@"content-type"];
+ [r setContentEncoding:NSUTF8StringEncoding];
+ [r setHeader:@"text/xml; charset=\"utf-8\"" forKey:@"content-type"];
[r appendContentString:@"<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"];
[r appendContentString:@"<D:multistatus "];
}
else if ([_object isKindOfClass:[NSArray class]]) {
[r setStatus:207 /* Multi-Status */];
- [r setHeader:@"text/xml" forKey:@"content-type"];
+ [r setContentEncoding:NSUTF8StringEncoding];
+ [r setHeader:@"text/xml; charset=\"utf-8\"" forKey:@"content-type"];
[r appendContentString:@"<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"];
[r appendContentString:@"<D:multistatus "];