Permalink
Browse files

Parse text encoding from Content-Type header when supplied

Thanks to Shaun Harrison for this suggestion!
  • Loading branch information...
1 parent 0b59da7 commit 0add004169cd62e61057376c3cde62567b2d2f40 @pokeb committed Jan 9, 2009
Showing with 50 additions and 2 deletions.
  1. +5 −0 ASIHTTPRequest.h
  2. +21 −1 ASIHTTPRequest.m
  3. +1 −0 ASIHTTPRequestTests.h
  4. +23 −1 ASIHTTPRequestTests.m
View
@@ -166,6 +166,9 @@ typedef enum _ASINetworkErrorType {
BOOL haveBuiltPostBody;
unsigned long long uploadBufferSize;
+
+ NSStringEncoding defaultResponseEncoding;
+ NSStringEncoding responseEncoding;
}
#pragma mark init / dealloc
@@ -305,4 +308,6 @@ typedef enum _ASINetworkErrorType {
@property (assign) BOOL showAccurateProgress;
@property (assign,readonly) unsigned long long totalBytesRead;
@property (assign) unsigned long long uploadBufferSize;
+@property (assign) NSStringEncoding defaultResponseEncoding;
+@property (assign) NSStringEncoding responseEncoding;
@end
View
@@ -72,6 +72,7 @@ - (id)initWithURL:(NSURL *)newURL
requestAuthentication = NULL;
haveBuiltPostBody = NO;
request = NULL;
+ [self setDefaultResponseEncoding:NSISOLatin1StringEncoding];
[self setUploadBufferSize:0];
[self setResponseHeaders:nil];
[self setTimeOutSeconds:10];
@@ -171,7 +172,8 @@ - (NSString *)dataString
if (!receivedData) {
return nil;
}
- return [[[NSString alloc] initWithBytes:[receivedData bytes] length:[receivedData length] encoding:NSUTF8StringEncoding] autorelease];
+
+ return [[[NSString alloc] initWithBytes:[receivedData bytes] length:[receivedData length] encoding:[self responseEncoding]] autorelease];
}
@@ -738,6 +740,22 @@ - (BOOL)readResponseHeadersReturningAuthenticationFailure
}
}
+ // Handle response text encoding
+ // If the Content-Type header specified an encoding, we'll use that, otherwise we use defaultStringEncoding (which defaults to NSISOLatin1StringEncoding)
+ NSString *contentType = [[self responseHeaders] objectForKey:@"Content-Type"];
+ NSStringEncoding encoding = [self defaultResponseEncoding];
+ if (contentType) {
+ NSArray *parts = [contentType componentsSeparatedByString:@"="];
+ NSString *IANAEncoding = [parts objectAtIndex:[parts count]-1];
+ if (IANAEncoding) {
+ CFStringEncoding cfEncoding = CFStringConvertIANACharSetNameToEncoding((CFStringRef)IANAEncoding);
+ if (cfEncoding != kCFStringEncodingInvalidId) {
+ encoding = CFStringConvertEncodingToNSStringEncoding(cfEncoding);
+ }
+ }
+ }
+ [self setResponseEncoding:encoding];
+
// Handle cookies
NSArray *cookies = [NSHTTPCookie cookiesWithResponseHeaderFields:responseHeaders forURL:url];
[self setResponseCookies:cookies];
@@ -1182,4 +1200,6 @@ + (void)clearSession
@synthesize showAccurateProgress;
@synthesize totalBytesRead;
@synthesize uploadBufferSize;
+@synthesize defaultResponseEncoding;
+@synthesize responseEncoding;
@end
View
@@ -24,5 +24,6 @@
- (void)testCookies;
- (void)testBasicAuthentication;
- (void)testDigestAuthentication;
+- (void)testCharacterEncoding;
@end
View
@@ -53,9 +53,31 @@ - (void)testBasicDownload
STAssertTrue(success,@"Failed to generate an error for a bad host");
}
+- (void)testCharacterEncoding
+{
+
+ NSArray *IANAEncodings = [NSArray arrayWithObjects:@"UTF-8",@"US-ASCII",@"ISO-8859-1",@"UTF-16",nil];
+ NSUInteger NSStringEncodings[] = {NSUTF8StringEncoding,NSASCIIStringEncoding,NSISOLatin1StringEncoding,NSUnicodeStringEncoding};
+
+ int i;
+ for (i=0; i<[IANAEncodings count]; i++) {
+ NSURL *url = [[[NSURL alloc] initWithString:[NSString stringWithFormat:@"http://allseeing-i.com/ASIHTTPRequest/tests/Character-Encoding/%@",[IANAEncodings objectAtIndex:i]]] autorelease];
+ ASIHTTPRequest *request = [[[ASIHTTPRequest alloc] initWithURL:url] autorelease];
+ [request start];
+ BOOL success = [request responseEncoding] == NSStringEncodings[i];
+ STAssertTrue(success,[NSString stringWithFormat:@"Failed to use the correct text encoding for %@i",[IANAEncodings objectAtIndex:i]]);
+ }
+
+ NSURL *url = [[[NSURL alloc] initWithString:@"http://allseeing-i.com/ASIHTTPRequest/tests/Character-Encoding/Something-else"] autorelease];
+ ASIHTTPRequest *request = [[[ASIHTTPRequest alloc] initWithURL:url] autorelease];
+ [request setDefaultResponseEncoding:NSWindowsCP1251StringEncoding];
+ [request start];
+ BOOL success = [request responseEncoding] == [request defaultResponseEncoding];
+ STAssertTrue(success,[NSString stringWithFormat:@"Failed to use the default string encoding"]);
+}
+
- (void)testTimeOut
{
- //Grab data
NSURL *url = [[[NSURL alloc] initWithString:@"http://allseeing-i.com"] autorelease];
ASIHTTPRequest *request = [[[ASIHTTPRequest alloc] initWithURL:url] autorelease];
[request setTimeOutSeconds:0.0001]; //It's pretty unlikely we will be able to grab the data this quickly, so the request should timeout

0 comments on commit 0add004

Please sign in to comment.