From f5207ba9c764f33ef83fa897f6014d67193be0e2 Mon Sep 17 00:00:00 2001 From: Janic Duplessis Date: Tue, 27 Mar 2018 10:34:09 -0700 Subject: [PATCH] Fix blob response parsing for empty body on iOS Summary: We currently handle empty body poorly in the iOS blob implementation, this happens because of an early return that cause the blob response to not be processed by the blob module, resulting in an empty string as the body instead of a blob object. We also need to make sure to create an empty blob object when data is nil (empty body) as per the XMLHttpRequest spec. The Android implementation was already handling this properly. Fixes #18223 Send a HEAD request ```js fetch('https://apipre.monkimun.com/whoami', { body: null, method: 'HEAD', headers: { Accept: 'application/json', 'Content-Type': 'application/json', }, }) ``` [IOS][BUGFIX][Blob] - Fix blob response parsing for empty body Closes https://github.com/facebook/react-native/pull/18547 Differential Revision: D7415950 Pulled By: hramos fbshipit-source-id: 56860532c6171255869f02a0960f55d155184a46 --- Libraries/Blob/RCTBlobManager.mm | 3 +++ Libraries/Network/RCTNetworking.mm | 8 ++++---- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/Libraries/Blob/RCTBlobManager.mm b/Libraries/Blob/RCTBlobManager.mm index 56235ee04b6dfe..7c0cbb8673f064 100755 --- a/Libraries/Blob/RCTBlobManager.mm +++ b/Libraries/Blob/RCTBlobManager.mm @@ -258,6 +258,9 @@ - (BOOL)canHandleNetworkingResponse:(NSString *)responseType - (id)handleNetworkingResponse:(NSURLResponse *)response data:(NSData *)data { + // An empty body will have nil for data, in this case we need to return + // an empty blob as per the XMLHttpRequest spec. + data = data ?: [NSData new]; return @{ @"blobId": [self store:data], @"offset": @0, diff --git a/Libraries/Network/RCTNetworking.mm b/Libraries/Network/RCTNetworking.mm index fe86d31e67e0ff..f8de23abf0127f 100644 --- a/Libraries/Network/RCTNetworking.mm +++ b/Libraries/Network/RCTNetworking.mm @@ -439,10 +439,6 @@ - (void)sendData:(NSData *)data { RCTAssertThread(_methodQueue, @"sendData: must be called on method queue"); - if (data.length == 0) { - return; - } - id responseData = nil; for (id handler in _responseHandlers) { if ([handler canHandleNetworkingResponse:responseType]) { @@ -452,6 +448,10 @@ - (void)sendData:(NSData *)data } if (!responseData) { + if (data.length == 0) { + return; + } + if ([responseType isEqualToString:@"text"]) { // No carry storage is required here because the entire data has been loaded. responseData = [RCTNetworking decodeTextData:data fromResponse:task.response withCarryData:nil];