Skip to content

Commit d7fa9d6

Browse files
committed
Implement capacity for get request with fetchBlob()
1 parent dae3909 commit d7fa9d6

File tree

3 files changed

+154
-18
lines changed

3 files changed

+154
-18
lines changed

RNFetchBlobWin/App.js

Lines changed: 42 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -338,18 +338,34 @@ const App: () => React$Node = () => {
338338

339339
// readStream
340340
const readStreamCall = () => {
341-
RNFetchBlob.fs.readStream(RNFetchBlob.fs.dirs.DocumentDir + '/' + readStreamParam, 'utf8')
341+
RNFetchBlob.fs.readStream(RNFetchBlob.fs.dirs.DocumentDir + '/' + readStreamParam, readEncodeStreamParam, 4000, 200)
342342
.then((stream) => {
343343
let data = '';
344344
stream.open();
345345
stream.onData((chunk) => {
346346
data += chunk;
347347
})
348348
stream.onEnd(() => {
349-
console.log('data:' + data);
349+
console.log('data: ' + data);
350350
})
351-
});
352-
}
351+
});
352+
}
353+
354+
// fetchCall
355+
const fetchCall = () => {
356+
RNFetchBlob.config({
357+
// add this option that makes response data to be stored as a file,
358+
// this is much more performant.
359+
fileCache : true,
360+
})
361+
.fetch('GET', 'https://enag6ppx4ilaf.x.pipedream.net/', {
362+
'Content-Type' : 'multipart/form-data'
363+
}, "Hello World!")
364+
.then((res) => {
365+
// the temp file path
366+
console.log('The file saved to ', res.path())
367+
});
368+
}
353369

354370
// App ************************************************************************
355371
return (
@@ -747,6 +763,28 @@ const App: () => React$Node = () => {
747763
</View>
748764
</View>
749765

766+
767+
<View style={styles.body}>
768+
<View style={styles.sectionContainer}>
769+
<Text style={styles.sectionTitle}>
770+
{"FetchBlobTest"}
771+
</Text>
772+
<View style={styles.sectionDescription}>
773+
<TextInput style = {styles.input}
774+
placeholder = "Source path"
775+
onChangeText={readStreamParam => setReadStreamParam(readStreamParam)}
776+
placeholderTextColor = "#9a73ef"
777+
autoCapitalize = "none"
778+
/>
779+
</View>
780+
<Button
781+
title="Attempt Fetch"
782+
color="#9a73ef"
783+
onPress={fetchCall}
784+
/>
785+
</View>
786+
</View>
787+
750788
</ScrollView>
751789
</SafeAreaView>
752790
</>

RNFetchBlobWin/windows/RNFetchBlobWin/RNFetchBlob.cpp

Lines changed: 92 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@
77
#include <winrt/Windows.Storage.Streams.h>
88
#include <winrt/Windows.Storage.h>
99

10+
#include <winrt/Windows.Web.Http.h>
11+
#include <winrt/Windows.Web.Http.Headers.h>
12+
1013
#include <filesystem>
1114

1215
using namespace winrt;
@@ -58,7 +61,6 @@ winrt::fire_and_forget RNFetchBlob::createFile(
5861
winrt::Microsoft::ReactNative::ReactPromise<std::string> promise) noexcept
5962
try
6063
{
61-
bool isUTF8{ encoding.compare("utf8") == 0 };
6264
bool shouldExit{ false };
6365
Streams::IBuffer buffer;
6466
if (encoding.compare("uri") == 0)
@@ -448,11 +450,13 @@ try
448450
// TODO: Investigate returning wstrings as parameters
449451
winrt::hstring base64Content{ Cryptography::CryptographicBuffer::EncodeToBase64String(readBuffer) };
450452
//m_reactContext.CallJSFunction(L"RCTDeviceEventEmitter", L"emit", [&streamId, &base64Content](React::IJSValueWriter const& argWriter) {
453+
// argWriter.WriteArrayBegin();
451454
// WriteValue(argWriter, streamId);
452455
// argWriter.WriteObjectBegin();
453-
// React::WriteProperty(argWriter, "event", L"data");
456+
// React::WriteProperty(argWriter, "event", "data");
454457
// React::WriteProperty(argWriter, "detail", base64Content);
455458
// argWriter.WriteObjectEnd();
459+
// argWriter.WriteArrayEnd();
456460
// });
457461
m_reactContext.CallJSFunction(L"RCTDeviceEventEmitter", L"emit", streamId,
458462
winrt::Microsoft::ReactNative::JSValueObject{
@@ -825,7 +829,7 @@ winrt::fire_and_forget RNFetchBlob::lstat(
825829

826830
callback("", resultsArray);
827831
}
828-
catch (const hresult_error& ex)
832+
catch (...)
829833
{
830834
// "Failed to read directory."
831835
winrt::Microsoft::ReactNative::JSValueArray emptyArray;
@@ -948,35 +952,110 @@ catch (...)
948952
}
949953

950954

951-
void RNFetchBlob::fetchBlob(
955+
winrt::fire_and_forget RNFetchBlob::fetchBlob(
952956
winrt::Microsoft::ReactNative::JSValueObject options,
953957
std::string taskId,
954958
std::string method,
955-
std::string url,
959+
std::wstring url,
956960
winrt::Microsoft::ReactNative::JSValueObject headers,
957961
std::string body,
958962
std::function<void(std::string, std::string, std::string)> callback) noexcept
959963
{
964+
//winrt::Windows::Web::Http::HttpMethod::Hea
965+
// Delete, Patch, Post, Put, Get, Options, Head
966+
// Method
967+
RNFetchBlobConfig config;
968+
config.appendExt = options["appendExt"].AsString();
969+
config.fileCache = options["fileCache"].AsBoolean();
970+
config.followRedirect = options["followRedirect"].IsNull() ? true : options["followRedirect"].AsBoolean();
971+
config.overwrite = options["overwrite"].AsBoolean();
972+
config.path = options["path"].AsString();
973+
config.timeout = options["timeout"].AsInt32();
974+
config.trusty = options["trusty"].AsBoolean();;
960975

976+
977+
winrt::Windows::Web::Http::HttpMethod httpMethod{ winrt::Windows::Web::Http::HttpMethod::Post() };
978+
std::string methodUpperCase{ method };
979+
for (auto& c : methodUpperCase)
980+
{
981+
toupper(c);
982+
}
983+
984+
if (methodUpperCase.compare("DELETE") == 0)
985+
{
986+
httpMethod = winrt::Windows::Web::Http::HttpMethod::Delete();
987+
}
988+
else if (methodUpperCase.compare("PATCH") == 0)
989+
{
990+
httpMethod = winrt::Windows::Web::Http::HttpMethod::Patch();
991+
}
992+
else if (methodUpperCase.compare("PUT") == 0)
993+
{
994+
httpMethod = winrt::Windows::Web::Http::HttpMethod::Put();
995+
}
996+
else if (methodUpperCase.compare("GET") == 0)
997+
{
998+
httpMethod = winrt::Windows::Web::Http::HttpMethod::Get();
999+
}
1000+
else if (methodUpperCase.compare("OPTIONS") == 0)
1001+
{
1002+
httpMethod = winrt::Windows::Web::Http::HttpMethod::Options();
1003+
}
1004+
else if (methodUpperCase.compare("HEAD") == 0)
1005+
{
1006+
httpMethod = winrt::Windows::Web::Http::HttpMethod::Head();
1007+
}
1008+
else if (methodUpperCase.compare("POST") != 0)
1009+
{
1010+
// Method not supported by winrt
1011+
co_return;
1012+
}
1013+
1014+
winrt::Windows::Web::Http::HttpRequestMessage requestMessage{ httpMethod, Uri{url} };
1015+
winrt::Windows::Web::Http::HttpMultipartFormDataContent requestContent{ L"-----" };
1016+
1017+
//co_await requestMessage.Content().;
1018+
1019+
for (auto const& entry : headers)
1020+
{
1021+
if (!requestMessage.Headers().TryAppendWithoutValidation(winrt::to_hstring(entry.first), winrt::to_hstring(entry.second.AsString())))
1022+
{
1023+
requestContent.Headers().TryAppendWithoutValidation(winrt::to_hstring(entry.first), winrt::to_hstring(entry.second.AsString()));
1024+
}
1025+
}
1026+
1027+
std::string temp{ body };
1028+
if (body.length() > 0) {
1029+
winrt::Windows::Web::Http::HttpBufferContent content{ CryptographicBuffer::ConvertStringToBinary(winrt::to_hstring(body), BinaryStringEncoding::Utf8) };
1030+
requestMessage.Content(content);
1031+
}
1032+
1033+
1034+
winrt::Windows::Web::Http::HttpResponseMessage response = co_await m_httpClient.SendRequestAsync(requestMessage, winrt::Windows::Web::Http::HttpCompletionOption::ResponseHeadersRead);
1035+
1036+
co_return;
9611037
}
9621038

9631039
void RNFetchBlob::fetchBlobForm(
9641040
winrt::Microsoft::ReactNative::JSValueObject options,
9651041
std::string taskId,
9661042
std::string method,
967-
std::string url,
1043+
std::wstring url,
9681044
winrt::Microsoft::ReactNative::JSValueObject headers,
9691045
winrt::Microsoft::ReactNative::JSValueArray body,
9701046
std::function<void(std::string)> callback) noexcept
9711047
{
972-
1048+
return;
9731049
}
9741050

1051+
1052+
9751053
void RNFetchBlob::enableProgressReport(
9761054
std::string taskId,
9771055
int interval,
9781056
int count) noexcept
9791057
{
1058+
return;
9801059
}
9811060

9821061
// enableUploadProgressReport
@@ -985,20 +1064,22 @@ void RNFetchBlob::enableUploadProgressReport(
9851064
int interval,
9861065
int count) noexcept
9871066
{
1067+
return;
9881068
}
9891069

9901070
// cancelRequest
9911071
void RNFetchBlob::cancelRequest(
9921072
std::string taskId,
9931073
std::function<void(std::string)> callback) noexcept
9941074
{
1075+
return;
9951076
}
9961077

9971078
void RNFetchBlob::removeSession(
9981079
winrt::Microsoft::ReactNative::JSValueObject paths,
9991080
std::function<void(std::string)> callback) noexcept
10001081
{
1001-
1082+
return;
10021083
}
10031084

10041085
void RNFetchBlob::closeStream(
@@ -1009,10 +1090,11 @@ try
10091090
auto stream{ m_streamMap.find(streamId)->second };
10101091
stream.streamInstance.Close();
10111092
m_streamMap.extract(streamId);
1093+
callback("");
10121094
}
1013-
catch (...)
1095+
catch (const hresult_error& ex)
10141096
{
1015-
1097+
callback(winrt::to_string(ex.message()).c_str());
10161098
}
10171099

10181100

RNFetchBlobWin/windows/RNFetchBlobWin/RNFetchBlob.h

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,25 @@ enum struct EncodingOptions { UTF8, BASE64, ASCII, URI };
1313
struct RNFetchBlobStream
1414
{
1515
public:
16-
RNFetchBlobStream::RNFetchBlobStream(winrt::Windows::Storage::Streams::IRandomAccessStream& _streamInstance, EncodingOptions _encoding) noexcept;
16+
RNFetchBlobStream(winrt::Windows::Storage::Streams::IRandomAccessStream& _streamInstance, EncodingOptions _encoding) noexcept;
1717
winrt::Windows::Storage::Streams::IRandomAccessStream streamInstance;
1818
const EncodingOptions encoding;
1919
};
2020

21+
struct RNFetchBlobConfig
22+
{
23+
public:
24+
RNFetchBlobConfig() = default;
25+
26+
bool overwrite;
27+
int timeout;
28+
bool trusty;
29+
bool fileCache;
30+
std::string appendExt;
31+
std::string path;
32+
bool followRedirect;
33+
};
34+
2135

2236
REACT_MODULE(RNFetchBlob, L"RNFetchBlob");
2337
struct RNFetchBlob
@@ -188,11 +202,11 @@ struct RNFetchBlob
188202
winrt::Microsoft::ReactNative::ReactPromise<std::string> promise) noexcept;
189203

190204
REACT_METHOD(fetchBlob);
191-
void fetchBlob(
205+
winrt::fire_and_forget fetchBlob(
192206
winrt::Microsoft::ReactNative::JSValueObject options,
193207
std::string taskId,
194208
std::string method,
195-
std::string url,
209+
std::wstring url,
196210
winrt::Microsoft::ReactNative::JSValueObject headers,
197211
std::string body,
198212
std::function<void(std::string, std::string, std::string)> callback) noexcept;
@@ -202,7 +216,7 @@ struct RNFetchBlob
202216
winrt::Microsoft::ReactNative::JSValueObject options,
203217
std::string taskId,
204218
std::string method,
205-
std::string url,
219+
std::wstring url,
206220
winrt::Microsoft::ReactNative::JSValueObject headers,
207221
winrt::Microsoft::ReactNative::JSValueArray body,
208222
std::function<void(std::string)> callback) noexcept;
@@ -238,6 +252,8 @@ struct RNFetchBlob
238252

239253
// Helper methods
240254
private:
255+
winrt::Windows::Web::Http::HttpClient m_httpClient;
256+
241257
constexpr static int64_t UNIX_EPOCH_IN_WINRT_SECONDS = 11644473600;
242258

243259
std::map<StreamId, RNFetchBlobStream> m_streamMap;

0 commit comments

Comments
 (0)