]> err.no Git - sope/commitdiff
improved handling of HTTP charset parameter
authorhelge <helge@e4a50df8-12e2-0310-a44c-efbce7f8a7e3>
Thu, 31 May 2007 14:32:41 +0000 (14:32 +0000)
committerhelge <helge@e4a50df8-12e2-0310-a44c-efbce7f8a7e3>
Thu, 31 May 2007 14:32:41 +0000 (14:32 +0000)
git-svn-id: http://svn.opengroupware.org/SOPE/trunk@1493 e4a50df8-12e2-0310-a44c-efbce7f8a7e3

sope-appserver/NGObjWeb/ChangeLog
sope-appserver/NGObjWeb/NGHttp+WO.m
sope-appserver/NGObjWeb/Version
sope-appserver/NGObjWeb/WOMessage.m
sope-appserver/NGObjWeb/WORequest.m
sope-appserver/NGObjWeb/WOSimpleHTTPParser.m

index 08ec83ef1cbca26d2d01dc7ac1c3e1b0bad41f85..752289932aa4607734a5c8a29c7039c0cf3d2221 100644 (file)
@@ -1,3 +1,17 @@
+2007-05-31  Helge Hess  <helge.hess@opengroupware.org>
+
+       * 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  <helge.hess@opengroupware.org>
 
        * DAVPropMap.plist: added HTTPMail junkemail property (v4.7.10)
index 151158d76e0fb0d7783c0c92af9b27ade5c276c3..91a213e205ed6ade77b08b8fb5d6112cac52d5e3 100644 (file)
@@ -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! (<?xml declaration
+         //      and BOM
+         enc = NSUTF8StringEncoding;
+       }
+      }
+    }
+
+    if (enc != 0)
+      [request setContentEncoding:enc];
+  }
+  
   /* process cookies */
   {
     NSEnumerator *cs;
     WOCookie *cookie;
     
     cs = [[self woCookies] objectEnumerator];
-    while ((cookie = [cs nextObject]))
+    while ((cookie = [cs nextObject]) != nil)
       [request addCookie:cookie];
   }
   
@@ -95,17 +133,17 @@ static Class NSArrayClass = Nil;
       NSArrayClass = [NSArray class];
     
     keys = [self headerFieldNames];
-    while ((key = [keys nextObject])) {
+    while ((key = [keys nextObject]) != nil) {
       NSEnumerator *values;
       id value;
       
       values = [self valuesOfHeaderFieldWithName:key];
-      while ((value = [values nextObject])) {
+      while ((value = [values nextObject]) != nil) {
         if ([value isKindOfClass:NSArrayClass]) {
           NSEnumerator *ev2;
 
           ev2 = [value objectEnumerator];
-          while ((value = [ev2 nextObject])) {
+          while ((value = [ev2 nextObject]) != nil) {
             value = [value stringValue];
             [request appendHeader:value forKey:key];
           }
index 929e94f51b953e83d182644414ed1f6802b429d3..c90763d7b2083a208fda7697bf32f68f6f265d15 100644 (file)
@@ -1,7 +1,8 @@
 # version file
 
-SUBMINOR_VERSION:=10
+SUBMINOR_VERSION:=11
 
+# v4.7.11  requires libNGExtensions v4.7.194
 # v4.5.234 requires libDOM          v4.5.21
 # v4.5.214 requires libNGExtensions v4.5.179
 # v4.5.122 requires libNGExtensions v4.5.153
index 212ec943a28b34434a0908e38cfc3c51f007f078..a2c9740631b6834425b74e704eeb3be87d400fe9 100644 (file)
@@ -348,8 +348,14 @@ static __inline__ NSMutableData *_checkBody(WOMessage *self) {
   
   if ((c = [self content]) == nil)
     return nil;
-
+  
   s = [[NSString alloc] initWithData:c encoding:[self contentEncoding]];
+  if (s == nil) {
+    [self warnWithFormat:
+           @"could not convert request content (len=%d) to encoding %i (%@)",
+           [c length], [self contentEncoding],
+           [NSString localizedNameOfStringEncoding:[self contentEncoding]]];
+  }
   return [s autorelease];
 }
 - (BOOL)doesStreamContent {
index e9c004a748168ffeb1d7ad8f6134eaf92a29f701..cd53107485589a3c3369a6fdcb4a2da586bebe3e 100644 (file)
@@ -77,13 +77,13 @@ static BOOL debugOn = NO;
   /* apply defaults on some globals ... */
     
   apath = [ud stringForKey:@"WORequestValueSessionID"];
-  if ([apath length] > 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];
index 184194fd316b463a9af3086c4a78a40fb474b1fb..36cbb9d90408f62f66a2942a6c6b965a0af91526 100644 (file)
@@ -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 <NGObjWeb/WOResponse.h>
 #include <NGObjWeb/WORequest.h>
+#include <NGMime/NGMimeType.h>
 #include "common.h"
 #include <string.h>
 
@@ -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! (<?xml declaration
+       //      and BOM
+       enc = NSUTF8StringEncoding;
+      }
+    }
+  }
+
+  if (enc != 0)
+    [_msg setContentEncoding:enc];
+}
+
 - (WORequest *)parseRequest {
   NSException *e = nil;
   WORequest   *r = nil;
@@ -805,7 +855,7 @@ static NSString *stringForHeaderName(char *p) { /* Note: arg is _not_ const */
   
   /* process header */
   
-  if ((e = [self parseHeader])) {
+  if ((e = [self parseHeader]) != nil) {
     ASSIGN(self->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];