Parse text encoding from Content-Type header when supplied
Thanks to Shaun Harrison for this suggestion!
Showing
4 changed files
with
50 additions
and
2 deletions
@@ -166,6 +166,9 @@ typedef enum _ASINetworkErrorType { | @@ -166,6 +166,9 @@ typedef enum _ASINetworkErrorType { | ||
166 | BOOL haveBuiltPostBody; | 166 | BOOL haveBuiltPostBody; |
167 | 167 | ||
168 | unsigned long long uploadBufferSize; | 168 | unsigned long long uploadBufferSize; |
169 | + | ||
170 | + NSStringEncoding defaultResponseEncoding; | ||
171 | + NSStringEncoding responseEncoding; | ||
169 | } | 172 | } |
170 | 173 | ||
171 | #pragma mark init / dealloc | 174 | #pragma mark init / dealloc |
@@ -305,4 +308,6 @@ typedef enum _ASINetworkErrorType { | @@ -305,4 +308,6 @@ typedef enum _ASINetworkErrorType { | ||
305 | @property (assign) BOOL showAccurateProgress; | 308 | @property (assign) BOOL showAccurateProgress; |
306 | @property (assign,readonly) unsigned long long totalBytesRead; | 309 | @property (assign,readonly) unsigned long long totalBytesRead; |
307 | @property (assign) unsigned long long uploadBufferSize; | 310 | @property (assign) unsigned long long uploadBufferSize; |
311 | +@property (assign) NSStringEncoding defaultResponseEncoding; | ||
312 | +@property (assign) NSStringEncoding responseEncoding; | ||
308 | @end | 313 | @end |
@@ -72,6 +72,7 @@ static NSError *ASIUnableToCreateRequestError; | @@ -72,6 +72,7 @@ static NSError *ASIUnableToCreateRequestError; | ||
72 | requestAuthentication = NULL; | 72 | requestAuthentication = NULL; |
73 | haveBuiltPostBody = NO; | 73 | haveBuiltPostBody = NO; |
74 | request = NULL; | 74 | request = NULL; |
75 | + [self setDefaultResponseEncoding:NSISOLatin1StringEncoding]; | ||
75 | [self setUploadBufferSize:0]; | 76 | [self setUploadBufferSize:0]; |
76 | [self setResponseHeaders:nil]; | 77 | [self setResponseHeaders:nil]; |
77 | [self setTimeOutSeconds:10]; | 78 | [self setTimeOutSeconds:10]; |
@@ -171,7 +172,8 @@ static NSError *ASIUnableToCreateRequestError; | @@ -171,7 +172,8 @@ static NSError *ASIUnableToCreateRequestError; | ||
171 | if (!receivedData) { | 172 | if (!receivedData) { |
172 | return nil; | 173 | return nil; |
173 | } | 174 | } |
174 | - return [[[NSString alloc] initWithBytes:[receivedData bytes] length:[receivedData length] encoding:NSUTF8StringEncoding] autorelease]; | 175 | + |
176 | + return [[[NSString alloc] initWithBytes:[receivedData bytes] length:[receivedData length] encoding:[self responseEncoding]] autorelease]; | ||
175 | } | 177 | } |
176 | 178 | ||
177 | 179 | ||
@@ -738,6 +740,22 @@ static NSError *ASIUnableToCreateRequestError; | @@ -738,6 +740,22 @@ static NSError *ASIUnableToCreateRequestError; | ||
738 | } | 740 | } |
739 | } | 741 | } |
740 | 742 | ||
743 | + // Handle response text encoding | ||
744 | + // If the Content-Type header specified an encoding, we'll use that, otherwise we use defaultStringEncoding (which defaults to NSISOLatin1StringEncoding) | ||
745 | + NSString *contentType = [[self responseHeaders] objectForKey:@"Content-Type"]; | ||
746 | + NSStringEncoding encoding = [self defaultResponseEncoding]; | ||
747 | + if (contentType) { | ||
748 | + NSArray *parts = [contentType componentsSeparatedByString:@"="]; | ||
749 | + NSString *IANAEncoding = [parts objectAtIndex:[parts count]-1]; | ||
750 | + if (IANAEncoding) { | ||
751 | + CFStringEncoding cfEncoding = CFStringConvertIANACharSetNameToEncoding((CFStringRef)IANAEncoding); | ||
752 | + if (cfEncoding != kCFStringEncodingInvalidId) { | ||
753 | + encoding = CFStringConvertEncodingToNSStringEncoding(cfEncoding); | ||
754 | + } | ||
755 | + } | ||
756 | + } | ||
757 | + [self setResponseEncoding:encoding]; | ||
758 | + | ||
741 | // Handle cookies | 759 | // Handle cookies |
742 | NSArray *cookies = [NSHTTPCookie cookiesWithResponseHeaderFields:responseHeaders forURL:url]; | 760 | NSArray *cookies = [NSHTTPCookie cookiesWithResponseHeaderFields:responseHeaders forURL:url]; |
743 | [self setResponseCookies:cookies]; | 761 | [self setResponseCookies:cookies]; |
@@ -1182,4 +1200,6 @@ static NSError *ASIUnableToCreateRequestError; | @@ -1182,4 +1200,6 @@ static NSError *ASIUnableToCreateRequestError; | ||
1182 | @synthesize showAccurateProgress; | 1200 | @synthesize showAccurateProgress; |
1183 | @synthesize totalBytesRead; | 1201 | @synthesize totalBytesRead; |
1184 | @synthesize uploadBufferSize; | 1202 | @synthesize uploadBufferSize; |
1203 | +@synthesize defaultResponseEncoding; | ||
1204 | +@synthesize responseEncoding; | ||
1185 | @end | 1205 | @end |
@@ -53,9 +53,31 @@ | @@ -53,9 +53,31 @@ | ||
53 | STAssertTrue(success,@"Failed to generate an error for a bad host"); | 53 | STAssertTrue(success,@"Failed to generate an error for a bad host"); |
54 | } | 54 | } |
55 | 55 | ||
56 | +- (void)testCharacterEncoding | ||
57 | +{ | ||
58 | + | ||
59 | + NSArray *IANAEncodings = [NSArray arrayWithObjects:@"UTF-8",@"US-ASCII",@"ISO-8859-1",@"UTF-16",nil]; | ||
60 | + NSUInteger NSStringEncodings[] = {NSUTF8StringEncoding,NSASCIIStringEncoding,NSISOLatin1StringEncoding,NSUnicodeStringEncoding}; | ||
61 | + | ||
62 | + int i; | ||
63 | + for (i=0; i<[IANAEncodings count]; i++) { | ||
64 | + NSURL *url = [[[NSURL alloc] initWithString:[NSString stringWithFormat:@"http://allseeing-i.com/ASIHTTPRequest/tests/Character-Encoding/%@",[IANAEncodings objectAtIndex:i]]] autorelease]; | ||
65 | + ASIHTTPRequest *request = [[[ASIHTTPRequest alloc] initWithURL:url] autorelease]; | ||
66 | + [request start]; | ||
67 | + BOOL success = [request responseEncoding] == NSStringEncodings[i]; | ||
68 | + STAssertTrue(success,[NSString stringWithFormat:@"Failed to use the correct text encoding for %@i",[IANAEncodings objectAtIndex:i]]); | ||
69 | + } | ||
70 | + | ||
71 | + NSURL *url = [[[NSURL alloc] initWithString:@"http://allseeing-i.com/ASIHTTPRequest/tests/Character-Encoding/Something-else"] autorelease]; | ||
72 | + ASIHTTPRequest *request = [[[ASIHTTPRequest alloc] initWithURL:url] autorelease]; | ||
73 | + [request setDefaultResponseEncoding:NSWindowsCP1251StringEncoding]; | ||
74 | + [request start]; | ||
75 | + BOOL success = [request responseEncoding] == [request defaultResponseEncoding]; | ||
76 | + STAssertTrue(success,[NSString stringWithFormat:@"Failed to use the default string encoding"]); | ||
77 | +} | ||
78 | + | ||
56 | - (void)testTimeOut | 79 | - (void)testTimeOut |
57 | { | 80 | { |
58 | - //Grab data | ||
59 | NSURL *url = [[[NSURL alloc] initWithString:@"http://allseeing-i.com"] autorelease]; | 81 | NSURL *url = [[[NSURL alloc] initWithString:@"http://allseeing-i.com"] autorelease]; |
60 | ASIHTTPRequest *request = [[[ASIHTTPRequest alloc] initWithURL:url] autorelease]; | 82 | ASIHTTPRequest *request = [[[ASIHTTPRequest alloc] initWithURL:url] autorelease]; |
61 | [request setTimeOutSeconds:0.0001]; //It's pretty unlikely we will be able to grab the data this quickly, so the request should timeout | 83 | [request setTimeOutSeconds:0.0001]; //It's pretty unlikely we will be able to grab the data this quickly, so the request should timeout |
-
Please register or login to post a comment