2015-09-14 17:35:58 +03:00
/ * *
2018-09-12 01:27:47 +03:00
* Copyright ( c ) Facebook , Inc . and its affiliates .
2015-09-14 17:35:58 +03:00
*
2018-02-17 05:24:55 +03:00
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree .
2015-09-14 17:35:58 +03:00
*
2018-05-11 05:06:46 +03:00
* @ format
2018-08-08 20:39:16 +03:00
* @ flow
2015-09-14 17:35:58 +03:00
* /
2018-05-11 05:06:46 +03:00
2015-09-14 17:35:58 +03:00
// Do not require the native RCTNetworking module directly! Use this wrapper module instead.
// It will add the necessary requestId, so that you don't have to generate it yourself.
2020-06-27 12:15:58 +03:00
import NativeEventEmitter from '../EventEmitter/NativeEventEmitter' ;
2019-08-23 18:43:08 +03:00
import NativeNetworkingAndroid from './NativeNetworkingAndroid' ;
2020-06-27 12:15:58 +03:00
import convertRequestBody from './convertRequestBody' ;
2019-05-08 18:44:25 +03:00
import type { RequestBody } from './convertRequestBody' ;
2021-04-12 16:23:53 +03:00
import Platform from '../Utilities/Platform' ;
2015-09-14 17:35:58 +03:00
2016-05-25 14:17:35 +03:00
type Header = [ string , string ] ;
2017-01-21 05:40:28 +03:00
// Convert FormData headers to arrays, which are easier to consume in
// native on Android.
2016-05-25 14:17:35 +03:00
function convertHeadersMapToArray ( headers : Object ) : Array < Header > {
const headerArray = [ ] ;
for ( const name in headers ) {
headerArray . push ( [ name , headers [ name ] ] ) ;
}
return headerArray ;
}
let _requestId = 1 ;
2016-07-12 03:53:35 +03:00
function generateRequestId ( ) : number {
2015-09-14 17:35:58 +03:00
return _requestId ++ ;
2016-05-25 14:17:35 +03:00
}
2015-09-14 17:35:58 +03:00
/ * *
* This class is a wrapper around the native RCTNetworking module . It adds a necessary unique
* requestId to each network request that can be used to abort that request later on .
* /
2021-01-07 14:16:31 +03:00
// FIXME: use typed events
2021-01-04 14:52:18 +03:00
class RCTNetworking extends NativeEventEmitter < $FlowFixMe > {
2016-05-25 14:17:35 +03:00
constructor ( ) {
2021-04-12 16:23:53 +03:00
super (
// T88715063: NativeEventEmitter only used this parameter on iOS. Now it uses it on all platforms, so this code was modified automatically to preserve its behavior
// If you want to use the native module on other platforms, please remove this condition and test its behavior
Platform . OS !== 'ios' ? null : NativeNetworkingAndroid ,
) ;
2016-05-25 14:17:35 +03:00
}
2015-09-14 17:35:58 +03:00
2016-07-12 03:53:35 +03:00
sendRequest (
Add responseType as a concept to RCTNetworking, send binary data as base64
Summary:
In preparation for Blob support (wherein binary XHR and WebSocket responses can be retained as native data blobs on the native side and JS receives a web-like opaque Blob object), this change makes RCTNetworking aware of the responseType that JS requests. A `xhr.responseType` of `''` or `'text'` translates to a native response type of `'text'`. A `xhr.responseType` of `arraybuffer` translates to a native response type of `base64`, as we currently lack an API to transmit TypedArrays directly to JS. This is analogous to how the WebSocket module already works, and it's a lot more versatile and much less brittle than converting a JS *string* back to a TypedArray, which is what's currently going on.
Now that we don't always send text down to JS, JS consumers might still want to get progress updates about a binary download. This is what the `'progress'` event is designed for, so this change also implements that. This change also follows the XHR spec with regards to `xhr.response` and `xhr.responseText`:
- if the response type is `'text'`, `xhr.responseText` can be peeked at by the JS consumer. It will be updated periodically as the download progresses, so long as there's either an `onreadystatechange` or `onprogress` handler on the XHR.
- if the response type is not `'text'`, `xhr.responseText` can't be accessed and `xhr.response` remains `null` until the response is fully received. `'progress'` events containing response details (total bytes, downloaded so far) are dispatched if there's an `onprogress` handler.
Once Blobs are landed, `xhr.responseType` of `'blob'` will correspond to the same native response type, which will cause RCTNetworking to only send a blob ID down to JS, which can then create a `Blob` object from that for consumers.
Closes https://github.com/facebook/react-native/pull/8324
Reviewed By: javache
Differential Revision: D3508822
Pulled By: davidaurelio
fbshipit-source-id: 441b2d4d40265b6036559c3ccb9fa962999fa5df
2016-07-13 14:53:54 +03:00
method : string ,
2016-07-12 03:53:35 +03:00
trackingName : string ,
Add responseType as a concept to RCTNetworking, send binary data as base64
Summary:
In preparation for Blob support (wherein binary XHR and WebSocket responses can be retained as native data blobs on the native side and JS receives a web-like opaque Blob object), this change makes RCTNetworking aware of the responseType that JS requests. A `xhr.responseType` of `''` or `'text'` translates to a native response type of `'text'`. A `xhr.responseType` of `arraybuffer` translates to a native response type of `base64`, as we currently lack an API to transmit TypedArrays directly to JS. This is analogous to how the WebSocket module already works, and it's a lot more versatile and much less brittle than converting a JS *string* back to a TypedArray, which is what's currently going on.
Now that we don't always send text down to JS, JS consumers might still want to get progress updates about a binary download. This is what the `'progress'` event is designed for, so this change also implements that. This change also follows the XHR spec with regards to `xhr.response` and `xhr.responseText`:
- if the response type is `'text'`, `xhr.responseText` can be peeked at by the JS consumer. It will be updated periodically as the download progresses, so long as there's either an `onreadystatechange` or `onprogress` handler on the XHR.
- if the response type is not `'text'`, `xhr.responseText` can't be accessed and `xhr.response` remains `null` until the response is fully received. `'progress'` events containing response details (total bytes, downloaded so far) are dispatched if there's an `onprogress` handler.
Once Blobs are landed, `xhr.responseType` of `'blob'` will correspond to the same native response type, which will cause RCTNetworking to only send a blob ID down to JS, which can then create a `Blob` object from that for consumers.
Closes https://github.com/facebook/react-native/pull/8324
Reviewed By: javache
Differential Revision: D3508822
Pulled By: davidaurelio
fbshipit-source-id: 441b2d4d40265b6036559c3ccb9fa962999fa5df
2016-07-13 14:53:54 +03:00
url : string ,
2016-07-12 03:53:35 +03:00
headers : Object ,
2017-01-21 05:40:28 +03:00
data : RequestBody ,
Add responseType as a concept to RCTNetworking, send binary data as base64
Summary:
In preparation for Blob support (wherein binary XHR and WebSocket responses can be retained as native data blobs on the native side and JS receives a web-like opaque Blob object), this change makes RCTNetworking aware of the responseType that JS requests. A `xhr.responseType` of `''` or `'text'` translates to a native response type of `'text'`. A `xhr.responseType` of `arraybuffer` translates to a native response type of `base64`, as we currently lack an API to transmit TypedArrays directly to JS. This is analogous to how the WebSocket module already works, and it's a lot more versatile and much less brittle than converting a JS *string* back to a TypedArray, which is what's currently going on.
Now that we don't always send text down to JS, JS consumers might still want to get progress updates about a binary download. This is what the `'progress'` event is designed for, so this change also implements that. This change also follows the XHR spec with regards to `xhr.response` and `xhr.responseText`:
- if the response type is `'text'`, `xhr.responseText` can be peeked at by the JS consumer. It will be updated periodically as the download progresses, so long as there's either an `onreadystatechange` or `onprogress` handler on the XHR.
- if the response type is not `'text'`, `xhr.responseText` can't be accessed and `xhr.response` remains `null` until the response is fully received. `'progress'` events containing response details (total bytes, downloaded so far) are dispatched if there's an `onprogress` handler.
Once Blobs are landed, `xhr.responseType` of `'blob'` will correspond to the same native response type, which will cause RCTNetworking to only send a blob ID down to JS, which can then create a `Blob` object from that for consumers.
Closes https://github.com/facebook/react-native/pull/8324
Reviewed By: javache
Differential Revision: D3508822
Pulled By: davidaurelio
fbshipit-source-id: 441b2d4d40265b6036559c3ccb9fa962999fa5df
2016-07-13 14:53:54 +03:00
responseType : 'text' | 'base64' ,
2016-07-12 03:53:35 +03:00
incrementalUpdates : boolean ,
timeout : number ,
2019-05-30 04:23:47 +03:00
callback : ( requestId : number ) => mixed ,
2018-05-11 05:06:46 +03:00
withCredentials : boolean ,
2016-07-12 03:53:35 +03:00
) {
2017-01-21 05:40:28 +03:00
const body = convertRequestBody ( data ) ;
if ( body && body . formData ) {
2020-03-25 07:35:58 +03:00
body . formData = body . formData . map ( part => ( {
2017-01-21 05:40:28 +03:00
... part ,
headers : convertHeadersMapToArray ( part . headers ) ,
} ) ) ;
}
2016-05-25 14:17:35 +03:00
const requestId = generateRequestId ( ) ;
2019-05-30 04:23:47 +03:00
NativeNetworkingAndroid . sendRequest (
2015-09-14 17:35:58 +03:00
method ,
url ,
requestId ,
2016-05-25 14:17:35 +03:00
convertHeadersMapToArray ( headers ) ,
Add responseType as a concept to RCTNetworking, send binary data as base64
Summary:
In preparation for Blob support (wherein binary XHR and WebSocket responses can be retained as native data blobs on the native side and JS receives a web-like opaque Blob object), this change makes RCTNetworking aware of the responseType that JS requests. A `xhr.responseType` of `''` or `'text'` translates to a native response type of `'text'`. A `xhr.responseType` of `arraybuffer` translates to a native response type of `base64`, as we currently lack an API to transmit TypedArrays directly to JS. This is analogous to how the WebSocket module already works, and it's a lot more versatile and much less brittle than converting a JS *string* back to a TypedArray, which is what's currently going on.
Now that we don't always send text down to JS, JS consumers might still want to get progress updates about a binary download. This is what the `'progress'` event is designed for, so this change also implements that. This change also follows the XHR spec with regards to `xhr.response` and `xhr.responseText`:
- if the response type is `'text'`, `xhr.responseText` can be peeked at by the JS consumer. It will be updated periodically as the download progresses, so long as there's either an `onreadystatechange` or `onprogress` handler on the XHR.
- if the response type is not `'text'`, `xhr.responseText` can't be accessed and `xhr.response` remains `null` until the response is fully received. `'progress'` events containing response details (total bytes, downloaded so far) are dispatched if there's an `onprogress` handler.
Once Blobs are landed, `xhr.responseType` of `'blob'` will correspond to the same native response type, which will cause RCTNetworking to only send a blob ID down to JS, which can then create a `Blob` object from that for consumers.
Closes https://github.com/facebook/react-native/pull/8324
Reviewed By: javache
Differential Revision: D3508822
Pulled By: davidaurelio
fbshipit-source-id: 441b2d4d40265b6036559c3ccb9fa962999fa5df
2016-07-13 14:53:54 +03:00
{ ... body , trackingName } ,
responseType ,
2016-05-25 14:17:35 +03:00
incrementalUpdates ,
2017-04-11 08:32:38 +03:00
timeout ,
2018-05-11 05:06:46 +03:00
withCredentials ,
2016-05-25 14:17:35 +03:00
) ;
callback ( requestId ) ;
2015-09-14 17:35:58 +03:00
}
2016-07-12 03:53:35 +03:00
abortRequest ( requestId : number ) {
2019-05-30 04:23:47 +03:00
NativeNetworkingAndroid . abortRequest ( requestId ) ;
2015-09-14 17:35:58 +03:00
}
2015-11-23 13:16:51 +03:00
Add responseType as a concept to RCTNetworking, send binary data as base64
Summary:
In preparation for Blob support (wherein binary XHR and WebSocket responses can be retained as native data blobs on the native side and JS receives a web-like opaque Blob object), this change makes RCTNetworking aware of the responseType that JS requests. A `xhr.responseType` of `''` or `'text'` translates to a native response type of `'text'`. A `xhr.responseType` of `arraybuffer` translates to a native response type of `base64`, as we currently lack an API to transmit TypedArrays directly to JS. This is analogous to how the WebSocket module already works, and it's a lot more versatile and much less brittle than converting a JS *string* back to a TypedArray, which is what's currently going on.
Now that we don't always send text down to JS, JS consumers might still want to get progress updates about a binary download. This is what the `'progress'` event is designed for, so this change also implements that. This change also follows the XHR spec with regards to `xhr.response` and `xhr.responseText`:
- if the response type is `'text'`, `xhr.responseText` can be peeked at by the JS consumer. It will be updated periodically as the download progresses, so long as there's either an `onreadystatechange` or `onprogress` handler on the XHR.
- if the response type is not `'text'`, `xhr.responseText` can't be accessed and `xhr.response` remains `null` until the response is fully received. `'progress'` events containing response details (total bytes, downloaded so far) are dispatched if there's an `onprogress` handler.
Once Blobs are landed, `xhr.responseType` of `'blob'` will correspond to the same native response type, which will cause RCTNetworking to only send a blob ID down to JS, which can then create a `Blob` object from that for consumers.
Closes https://github.com/facebook/react-native/pull/8324
Reviewed By: javache
Differential Revision: D3508822
Pulled By: davidaurelio
fbshipit-source-id: 441b2d4d40265b6036559c3ccb9fa962999fa5df
2016-07-13 14:53:54 +03:00
clearCookies ( callback : ( result : boolean ) => any ) {
2019-05-30 04:23:47 +03:00
NativeNetworkingAndroid . clearCookies ( callback ) ;
2015-11-23 13:16:51 +03:00
}
2015-09-14 17:35:58 +03:00
}
2019-08-23 18:43:08 +03:00
module . exports = ( new RCTNetworking ( ) : RCTNetworking ) ;