From b1850f8fcaf9ca6b9fe4e3739ab23b00e2360c57 Mon Sep 17 00:00:00 2001 From: Mike Driver Date: Thu, 9 Apr 2015 20:18:31 -0700 Subject: [PATCH] Implemented response headers when using `XMLHttpRequest` Summary: I think perhaps these were left out by mistake? Closes https://github.com/facebook/react-native/pull/382 Github Author: Mike Driver Test Plan: Imported from GitHub, without a `Test Plan:` line. --- Libraries/Network/RCTDataManager.m | 45 +++++++++++++------------ Libraries/Network/XMLHttpRequest.ios.js | 5 +-- React/Base/RCTConvert.h | 1 + React/Base/RCTConvert.m | 6 ++++ 4 files changed, 33 insertions(+), 24 deletions(-) diff --git a/Libraries/Network/RCTDataManager.m b/Libraries/Network/RCTDataManager.m index 6aa2842a3..634d325e9 100644 --- a/Libraries/Network/RCTDataManager.m +++ b/Libraries/Network/RCTDataManager.m @@ -10,6 +10,7 @@ #import "RCTDataManager.h" #import "RCTAssert.h" +#import "RCTConvert.h" #import "RCTLog.h" #import "RCTUtils.h" @@ -22,27 +23,18 @@ RCT_EXPORT_MODULE() * The responseSender block won't be called on same thread as called. */ RCT_EXPORT_METHOD(queryData:(NSString *)queryType - withQuery:(id)query + withQuery:(NSDictionary *)query queryHash:(__unused NSString *)queryHash responseSender:(RCTResponseSenderBlock)responseSender) { if ([queryType isEqualToString:@"http"]) { - // Parse query - NSDictionary *queryDict = query; - if ([query isKindOfClass:[NSString class]]) { - // TODO: it would be more efficient just to send a dictionary - queryDict = RCTJSONParse(query, NULL); - } - // Build request - NSURL *url = [NSURL URLWithString:queryDict[@"url"]]; - NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url]; - request.HTTPMethod = queryDict[@"method"] ?: @"GET"; - request.allHTTPHeaderFields = queryDict[@"headers"]; - if ([queryDict[@"data"] isKindOfClass:[NSString class]]) { - request.HTTPBody = [queryDict[@"data"] dataUsingEncoding:NSUTF8StringEncoding]; - } + NSURL *URL = [RCTConvert NSURL:query[@"url"]]; + NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:URL]; + request.HTTPMethod = [RCTConvert NSString:query[@"method"]] ?: @"GET"; + request.allHTTPHeaderFields = [RCTConvert NSDictionary:query[@"headers"]]; + request.HTTPBody = [RCTConvert NSData:query[@"data"]]; // Build data task NSURLSessionDataTask *task = [[NSURLSession sharedSession] dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *connectionError) { @@ -50,18 +42,27 @@ RCT_EXPORT_METHOD(queryData:(NSString *)queryType // Build response NSDictionary *responseJSON; if (connectionError == nil) { - NSStringEncoding encoding; + NSStringEncoding encoding = NSUTF8StringEncoding; if (response.textEncodingName) { CFStringEncoding cfEncoding = CFStringConvertIANACharSetNameToEncoding((CFStringRef)response.textEncodingName); encoding = CFStringConvertEncodingToNSStringEncoding(cfEncoding); - } else { - encoding = NSUTF8StringEncoding; } - int responseCode = (int)[((NSHTTPURLResponse *)response) statusCode]; - NSString *returnData = [[NSString alloc] initWithData:data encoding:encoding]; - responseJSON = @{@"status": @(responseCode), @"responseText": returnData}; + NSHTTPURLResponse *httpResponse = nil; + if ([response isKindOfClass:[NSHTTPURLResponse class]]) { + // Might be a local file request + httpResponse = (NSHTTPURLResponse *)response; + } + responseJSON = @{ + @"status": @([httpResponse statusCode] ?: 200), + @"responseHeaders": [httpResponse allHeaderFields] ?: @{}, + @"responseText": [[NSString alloc] initWithData:data encoding:encoding] ?: @"" + }; } else { - responseJSON = @{@"status": @0, @"responseText": [connectionError localizedDescription]}; + responseJSON = @{ + @"status": @0, + @"responseHeaders": @{}, + @"responseText": [connectionError localizedDescription] + }; } // Send response (won't be sent on same thread as caller) diff --git a/Libraries/Network/XMLHttpRequest.ios.js b/Libraries/Network/XMLHttpRequest.ios.js index 2287ee7b2..6c7367c18 100644 --- a/Libraries/Network/XMLHttpRequest.ios.js +++ b/Libraries/Network/XMLHttpRequest.ios.js @@ -22,12 +22,13 @@ class XMLHttpRequest extends XMLHttpRequestBase { sendImpl(method: ?string, url: ?string, headers: Object, data: any): void { RCTDataManager.queryData( 'http', - JSON.stringify({ + { method: method, url: url, data: data, headers: headers, - }), + }, + // TODO: Do we need this? is it used anywhere? 'h' + crc32(method + '|' + url + '|' + data), (result) => { result = JSON.parse(result); diff --git a/React/Base/RCTConvert.h b/React/Base/RCTConvert.h index ff5fb970b..2c1c84ee8 100644 --- a/React/Base/RCTConvert.h +++ b/React/Base/RCTConvert.h @@ -38,6 +38,7 @@ + (NSDictionary *)NSDictionary:(id)json; + (NSString *)NSString:(id)json; + (NSNumber *)NSNumber:(id)json; ++ (NSData *)NSData:(id)json; + (NSURL *)NSURL:(id)json; + (NSURLRequest *)NSURLRequest:(id)json; diff --git a/React/Base/RCTConvert.m b/React/Base/RCTConvert.m index a46379ae8..6fa1c2227 100644 --- a/React/Base/RCTConvert.m +++ b/React/Base/RCTConvert.m @@ -50,6 +50,12 @@ RCT_CONVERTER(NSString *, NSString, description) return nil; } ++ (NSData *)NSData:(id)json +{ + // TODO: should we automatically decode base64 data? Probably not... + return [[self NSString:json] dataUsingEncoding:NSUTF8StringEncoding]; +} + + (NSURL *)NSURL:(id)json { if (![json isKindOfClass:[NSString class]]) {