From: helge Date: Thu, 31 May 2007 14:32:41 +0000 (+0000) Subject: improved handling of HTTP charset parameter X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=231bada2061a4229ddf86b7d320a028c140c88ba;p=sope improved handling of HTTP charset parameter git-svn-id: http://svn.opengroupware.org/SOPE/trunk@1493 e4a50df8-12e2-0310-a44c-efbce7f8a7e3 --- diff --git a/sope-appserver/NGObjWeb/ChangeLog b/sope-appserver/NGObjWeb/ChangeLog index 08ec83ef..75228993 100644 --- a/sope-appserver/NGObjWeb/ChangeLog +++ b/sope-appserver/NGObjWeb/ChangeLog @@ -1,3 +1,17 @@ +2007-05-31 Helge Hess + + * v4.7.11 + + * NGHttp+WO.m, WOSimpleHTTPParser.m: process the 'charset' parameter + of the request content type to extract the content encoding of the + request + + * WOMessage.m: print a warning if -contentAsString got called but the + content could not be converted using the charset assigned to the + WORequest + + * WORequest.m: minor code cleanups, use isNotEmpty + 2007-05-28 Helge Hess * DAVPropMap.plist: added HTTPMail junkemail property (v4.7.10) diff --git a/sope-appserver/NGObjWeb/NGHttp+WO.m b/sope-appserver/NGObjWeb/NGHttp+WO.m index 151158d7..91a213e2 100644 --- a/sope-appserver/NGObjWeb/NGHttp+WO.m +++ b/sope-appserver/NGObjWeb/NGHttp+WO.m @@ -60,9 +60,10 @@ static Class NSArrayClass = Nil; NSAutoreleasePool *pool; WORequest *request; NSDictionary *woHeaders; - - pool = [[NSAutoreleasePool alloc] init]; + pool = [[NSAutoreleasePool alloc] init]; + + /* Note: headers are added below ... */ woHeaders = nil; request = [[WORequest alloc] @@ -76,13 +77,50 @@ static Class NSArrayClass = Nil; [request _setHttpRequest:self]; + /* process charset */ + // DUP: WOSimpleHTTPParser + { + NSStringEncoding enc = 0; + NGMimeType *rqContentType = [self contentType]; + NSString *charset = [rqContentType valueOfParameter:@"charset"]; + + if ([charset isNotEmpty]) { + enc = [NSString stringEncodingForEncodingNamed:charset]; + } + else if (rqContentType != nil) { + /* process default charsets for content types */ + NSString *majorType = [rqContentType type]; + + if ([majorType isEqualToString:@"text"]) { + NSString *subType = [rqContentType subType]; + + if ([subType isEqualToString:@"calendar"]) { + /* RFC2445, section 4.1.4 */ + enc = NSUTF8StringEncoding; + } + } + else if ([majorType isEqualToString:@"application"]) { + NSString *subType = [rqContentType subType]; + + if ([subType isEqualToString:@"xml"]) { + // TBD: we should look at the actual content! ( 0) + if ([apath isNotEmpty]) WORequestValueSessionID = [apath copy]; apath = [ud stringForKey:@"WORequestValueInstance"]; - if ([apath length] > 0) + if ([apath isNotEmpty]) WORequestValueInstance = [apath copy]; apath = [ud stringForKey:@"WONoSelectionString"]; - if ([apath length] > 0) + if ([apath isNotEmpty]) WONoSelectionString = [apath copy]; /* load language mappings */ @@ -133,7 +133,7 @@ static BOOL debugOn = NO; /* new parse */ - if (uri != nil) { + if (uri != NULL) { const char *start = NULL; /* skip adaptor prefix */ @@ -195,7 +195,7 @@ static BOOL debugOn = NO; /* parsing done (found '\0') */ done: ; // required for MacOSX-S - if (uriBuf != nil) free(uriBuf); + if (uriBuf != NULL) free(uriBuf); } } @@ -206,7 +206,7 @@ static BOOL debugOn = NO; content:(NSData *)_body userInfo:(NSDictionary *)_userInfo { - if ((self = [super init])) { + if ((self = [super init]) != nil) { self->_uri = [__uri copy]; self->method = [_method copy]; [self _parseURI]; diff --git a/sope-appserver/NGObjWeb/WOSimpleHTTPParser.m b/sope-appserver/NGObjWeb/WOSimpleHTTPParser.m index 184194fd..36cbb9d9 100644 --- a/sope-appserver/NGObjWeb/WOSimpleHTTPParser.m +++ b/sope-appserver/NGObjWeb/WOSimpleHTTPParser.m @@ -1,5 +1,6 @@ /* - Copyright (C) 2000-2005 SKYRIX Software AG + Copyright (C) 2000-2007 SKYRIX Software AG + Copyright (C) 2007 Helge Hess This file is part of SOPE. @@ -22,6 +23,7 @@ #include "WOSimpleHTTPParser.h" #include #include +#include #include "common.h" #include @@ -678,6 +680,54 @@ static NSString *stringForHeaderName(char *p) { /* Note: arg is _not_ const */ /* parsing */ +- (void)_fixupContentEncodingOfMessageBasedOnContentType:(WOMessage *)_msg { + // DUP: NGHttp+WO.m + NSStringEncoding enc = 0; + NSString *ctype; + NGMimeType *rqContentType; + NSString *charset; + + if (![(ctype = [_msg headerForKey:@"content-type"]) isNotEmpty]) + /* an HTTP message w/o a content type? */ + return; + + if ((rqContentType = [NGMimeType mimeType:ctype]) == nil) { + [self warnWithFormat:@"could not parse MIME type: '%@'", ctype]; + return; + } + + charset = [rqContentType valueOfParameter:@"charset"]; + + if ([charset isNotEmpty]) { + enc = [NSString stringEncodingForEncodingNamed:charset]; + } + else if (rqContentType != nil) { + /* process default charsets for content types */ + NSString *majorType = [rqContentType type]; + + if ([majorType isEqualToString:@"text"]) { + NSString *subType = [rqContentType subType]; + + if ([subType isEqualToString:@"calendar"]) { + /* RFC2445, section 4.1.4 */ + enc = NSUTF8StringEncoding; + } + } + else if ([majorType isEqualToString:@"application"]) { + NSString *subType = [rqContentType subType]; + + if ([subType isEqualToString:@"xml"]) { + // TBD: we should look at the actual content! (lastException, e); return nil; } @@ -814,7 +864,7 @@ static NSString *stringForHeaderName(char *p) { /* Note: arg is _not_ const */ /* check for expectations */ - if ((expect = [self->headers objectForKey:@"expect"])) { + if ((expect = [self->headers objectForKey:@"expect"]) != nil) { if ([expect rangeOfString:@"100-continue" options:NSCaseInsensitiveSearch].length > 0) { if (![self processContinueExpectation]) @@ -840,6 +890,7 @@ static NSString *stringForHeaderName(char *p) { /* Note: arg is _not_ const */ headers:self->headers content:self->content userInfo:nil]; + [self _fixupContentEncodingOfMessageBasedOnContentType:r]; [self reset]; if (heavyDebugOn) @@ -926,6 +977,7 @@ static NSString *stringForHeaderName(char *p) { /* Note: arg is _not_ const */ [r setHTTPVersion:self->httpVersion]; [r setHeaders:self->headers]; [r setContent:self->content]; + [self _fixupContentEncodingOfMessageBasedOnContentType:r]; [self reset];