Skip to content

Commit a3b3dbe

Browse files
committed
Implemented Initial timeout
1 parent 820b73e commit a3b3dbe

File tree

3 files changed

+116
-91
lines changed

3 files changed

+116
-91
lines changed

RNFetchBlobWin/App.js

Lines changed: 25 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -360,7 +360,7 @@ const App: () => React$Node = () => {
360360
})
361361
.fetch(
362362
'POST',
363-
'https://enb954aqyumba.x.pipedream.net',
363+
'https://enb954aqyumba.x.pipedream.net/',
364364
{
365365
Authorization : "Bearer access-token...",
366366
'Dropbox-API-Arg': JSON.stringify({
@@ -383,7 +383,7 @@ const App: () => React$Node = () => {
383383

384384
// uploadFileFromStorage
385385
const uploadFromStorageCall = () => {
386-
RNFetchBlob.fetch('POST', 'https://enb954aqyumba.x.pipedream.net', {
386+
RNFetchBlob.fetch('POST', 'https://enb954aqyumba.x.pipedream.net/', {
387387
Authorization : "Bearer access-token...",
388388
'Dropbox-API-Arg': JSON.stringify({
389389
path : '/img-from-react-native.png',
@@ -406,7 +406,7 @@ const App: () => React$Node = () => {
406406

407407
// uploadTextFromStorage
408408
const uploadTextFromCall = () => {
409-
RNFetchBlob.fetch('POST', 'https://enb954aqyumba.x.pipedream.net', {
409+
RNFetchBlob.fetch('POST', 'https://enb954aqyumba.x.pipedream.net/', {
410410
Authorization : "Bearer access-token...",
411411
'Dropbox-API-Arg': JSON.stringify({
412412
path : '/img-from-react-native.png',
@@ -429,7 +429,7 @@ const App: () => React$Node = () => {
429429

430430
// MultipartFileAndData
431431
const MultipartFileAndData = () => {
432-
RNFetchBlob.fetch('POST', 'https://enb954aqyumba.x.pipedream.net', {
432+
RNFetchBlob.fetch('POST', 'https://enb954aqyumba.x.pipedream.net/', {
433433
Authorization : "Bearer access-token...",
434434
'Dropbox-API-Arg': JSON.stringify({
435435
path : '/img-from-react-native.png',
@@ -461,31 +461,30 @@ const App: () => React$Node = () => {
461461
Progress: {count : 10, interval : 10},
462462
UploadProgress: {count : 10, interval : 10},
463463
fileCache : true,
464-
}).fetch('POST', 'https://enb954aqyumba.x.pipedream.net', {
465-
Authorization : "Bearer access-token",
466-
otherHeader : "foo",
467-
'Content-Type' : 'multipart/form-data',
468-
}, [
469-
// element with property `filename` will be transformed into `file` in form data
470-
{ name : 'avatar', filename : 'avatar.png', data: "Kentucky Fried Seth"},
471-
// custom content type
472-
{ name : 'avatar-png', filename : 'avatar-png.png', type:'image/png', data: "whaddup my pickles"},
473-
// part file from storage
474-
{ name : 'avatar-foo', filename : 'avatar-foo.png', type:'image/foo', data: RNFetchBlob.wrap(RNFetchBlob.fs.dirs.DocumentDir + '/temp1.txt')},
475-
// elements without property `filename` will be sent as plain text
476-
{ name : 'name', data : 'user'},
477-
{ name : 'info', data : JSON.stringify({
478-
479-
tel : '12345678'
480-
})},
481-
]).progress((received, total) => {
464+
}).fetch('POST', 'https://enb954aqyumba.x.pipedream.net/', {
465+
Authorization : "Bearer access-token",
466+
otherHeader : "foo",
467+
'Content-Type' : 'multipart/form-data',
468+
}, [
469+
// element with property `filename` will be transformed into `file` in form data
470+
{ name : 'avatar', filename : 'avatar.png', data: "Kentucky Fried Seth"},
471+
// custom content type
472+
{ name : 'avatar-png', filename : 'avatar-png.png', type:'image/png', data: "whaddup my pickles"},
473+
// part file from storage
474+
{ name : 'avatar-foo', filename : 'avatar-foo.png', type:'image/foo', data: RNFetchBlob.wrap(RNFetchBlob.fs.dirs.DocumentDir + '/temp1.txt')},
475+
// elements without property `filename` will be sent as plain text
476+
{ name : 'name', data : 'user'},
477+
{ name : 'info', data : JSON.stringify({
478+
479+
tel : '12345678'
480+
})},
481+
]).progress((received, total) => {
482482
console.log('progress', received / total)
483-
}).then((res) => {
483+
}).then((res) => {
484484
console.log(res.text());
485-
})
486-
.catch((err) => {
485+
}).catch((err) => {
487486
// error handling ..
488-
})
487+
})
489488
}
490489

491490
// App ************************************************************************

RNFetchBlobWin/windows/RNFetchBlobWin/RNFetchBlob.cpp

Lines changed: 79 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,9 @@ using namespace winrt::Windows::Foundation;
2222
using namespace winrt::Windows::Security::Cryptography;
2323
using namespace winrt::Windows::Security::Cryptography::Core;
2424

25+
26+
using namespace std::chrono_literals;
27+
2528
CancellationDisposable::CancellationDisposable(IAsyncInfo const& async, std::function<void()>&& onCancel) noexcept
2629
: m_async{ async }
2730
, m_onCancel{ std::move(onCancel) }
@@ -148,7 +151,7 @@ void RNFetchBlob::ConstantsViaConstantsProvider(winrt::Microsoft::ReactNative::R
148151
constants.Add(L"MusicDir", UserDataPaths::GetDefault().Music());
149152

150153
// RNFetchBlob.MovieDir
151-
constants.Add(L"MusicDir", UserDataPaths::GetDefault().Videos());
154+
constants.Add(L"MovieDir", UserDataPaths::GetDefault().Videos());
152155

153156
// RNFetchBlob.DownloadDirectoryPath - IMPLEMENT for convenience? (absent in iOS and deprecated in Android)
154157
constants.Add(L"DownloadDir", UserDataPaths::GetDefault().Downloads());
@@ -1063,7 +1066,7 @@ winrt::fire_and_forget RNFetchBlob::fetchBlob(
10631066
std::wstring url,
10641067
winrt::Microsoft::ReactNative::JSValueObject headers,
10651068
std::string body,
1066-
std::function<void(std::string, std::string, std::string)> callback) noexcept
1069+
std::function<void(std::string, std::string, std::string, std::string)> callback) noexcept
10671070
{
10681071
winrt::Windows::Web::Http::Filters::HttpBaseProtocolFilter filter;
10691072

@@ -1165,8 +1168,9 @@ winrt::fire_and_forget RNFetchBlob::fetchBlob(
11651168
co_return;
11661169
}
11671170

1168-
winrt::Windows::Web::Http::HttpRequestMessage requestMessage{ httpMethod, Uri{url} };
1171+
11691172

1173+
winrt::Windows::Web::Http::HttpRequestMessage requestMessage{ httpMethod, Uri{url} };
11701174
bool pathToFile{ body.rfind(prefix, 0) == 0 };
11711175
winrt::hstring fileContent;
11721176
if (pathToFile)
@@ -1202,7 +1206,7 @@ winrt::fire_and_forget RNFetchBlob::fetchBlobForm(
12021206
std::wstring url,
12031207
winrt::Microsoft::ReactNative::JSValueObject headers,
12041208
winrt::Microsoft::ReactNative::JSValueArray body,
1205-
std::function<void(std::string, std::string, std::string)> callback) noexcept
1209+
std::function<void(std::string, std::string, std::string, std::string)> callback) noexcept
12061210
{
12071211
//createBlobForm(options, taskId, method, url, headers, "", body, callback);
12081212
//co_return;
@@ -1318,6 +1322,7 @@ winrt::fire_and_forget RNFetchBlob::fetchBlobForm(
13181322
if (!requestMessage.Headers().TryAppendWithoutValidation(winrt::to_hstring(entry.first), winrt::to_hstring(entry.second.AsString())))
13191323
{
13201324
bool result = requestContent.Headers().TryAppendWithoutValidation(winrt::to_hstring(entry.first), winrt::to_hstring(entry.second.AsString()));
1325+
bool lol = true;
13211326
}
13221327
}
13231328

@@ -1476,86 +1481,107 @@ winrt::Windows::Foundation::IAsyncAction RNFetchBlob::ProcessRequestAsync(
14761481
const winrt::Windows::Web::Http::Filters::HttpBaseProtocolFilter& filter,
14771482
winrt::Windows::Web::Http::HttpRequestMessage& httpRequestMessage,
14781483
RNFetchBlobConfig& config,
1479-
std::function<void(std::string, std::string, std::string)> callback) noexcept
1484+
std::function<void(std::string, std::string, std::string, std::string)> callback) noexcept
14801485
try
14811486
{
14821487
// TODO: implement timeouts
14831488
winrt::Windows::Web::Http::HttpClient httpClient{filter};
1484-
winrt::Windows::Web::Http::HttpResponseMessage response = co_await httpClient.SendRequestAsync(httpRequestMessage, winrt::Windows::Web::Http::HttpCompletionOption::ResponseHeadersRead);
1485-
IReference<uint64_t> contentLength{ response.Content().Headers().ContentLength() };
1489+
1490+
IAsyncOperationWithProgress async{ httpClient.SendRequestAsync(httpRequestMessage, winrt::Windows::Web::Http::HttpCompletionOption::ResponseHeadersRead) };
1491+
if (async.wait_for(100s) == AsyncStatus::Completed) {
1492+
winrt::Windows::Web::Http::HttpResponseMessage response{async.get()};
1493+
IReference<uint64_t> contentLength{ response.Content().Headers().ContentLength() };
14861494

1487-
if (config.fileCache)
1488-
{
1489-
if (config.path.empty())
1495+
if (config.fileCache)
14901496
{
1491-
config.path = winrt::to_string(ApplicationData::Current().TemporaryFolder().Path()) + "\\RNFetchBlobTmp_" + config.taskId;
1492-
if (config.appendExt.length() > 0)
1497+
if (config.path.empty())
14931498
{
1494-
config.path += "." + config.appendExt;
1499+
config.path = winrt::to_string(ApplicationData::Current().TemporaryFolder().Path()) + "\\RNFetchBlobTmp_" + config.taskId;
1500+
if (config.appendExt.length() > 0)
1501+
{
1502+
config.path += "." + config.appendExt;
1503+
}
14951504
}
1496-
}
14971505

1498-
std::filesystem::path path{ config.path };
1499-
StorageFolder storageFolder{ co_await StorageFolder::GetFolderFromPathAsync(ApplicationData::Current().TemporaryFolder().Path()) };
1500-
StorageFile storageFile{ co_await storageFolder.CreateFileAsync(path.filename().wstring(), CreationCollisionOption::FailIfExists) };
1501-
IRandomAccessStream stream{ co_await storageFile.OpenAsync(FileAccessMode::ReadWrite) };
1502-
IOutputStream outputStream{ stream.GetOutputStreamAt(0) };
1506+
std::filesystem::path path{ config.path };
1507+
StorageFolder storageFolder{ co_await StorageFolder::GetFolderFromPathAsync(ApplicationData::Current().TemporaryFolder().Path()) };
1508+
StorageFile storageFile{ co_await storageFolder.CreateFileAsync(path.filename().wstring(), CreationCollisionOption::FailIfExists) };
1509+
IRandomAccessStream stream{ co_await storageFile.OpenAsync(FileAccessMode::ReadWrite) };
1510+
IOutputStream outputStream{ stream.GetOutputStreamAt(0) };
15031511

1504-
auto contentStream{ co_await response.Content().ReadAsInputStreamAsync() };
1505-
Buffer buffer{ 10 * 1024 };
1506-
uint64_t totalRead{ 0 };
1512+
auto contentStream{ co_await response.Content().ReadAsInputStreamAsync() };
1513+
Buffer buffer{ 10 * 1024 };
1514+
uint64_t totalRead{ 0 };
15071515

1508-
for (;;)
1509-
{
1510-
buffer.Length(0);
1511-
auto readBuffer = co_await contentStream.ReadAsync(buffer, buffer.Capacity(), InputStreamOptions::None);
1512-
totalRead += readBuffer.Length();
1513-
if (readBuffer.Length() == 0)
1516+
for (;;)
15141517
{
1515-
break;
1518+
buffer.Length(0);
1519+
auto readBuffer = co_await contentStream.ReadAsync(buffer, buffer.Capacity(), InputStreamOptions::None);
1520+
totalRead += readBuffer.Length();
1521+
1522+
auto it{ downloadProgressMap.find(taskId) };
1523+
if (it != downloadProgressMap.end()) {
1524+
auto var{ downloadProgressMap[taskId] };
1525+
std::string chunk{ winrt::to_string(CryptographicBuffer::ConvertBinaryToString(BinaryStringEncoding::Utf8, readBuffer)) };
1526+
m_reactContext.CallJSFunction(L"RCTDeviceEventEmitter", L"emit", L"RNFetchBlobProgress",
1527+
Microsoft::ReactNative::JSValueObject{
1528+
{ "taskId", taskId },
1529+
{ "written", totalRead },
1530+
{ "total", contentLength.Type() == PropertyType::UInt64 ?
1531+
Microsoft::ReactNative::JSValue(contentLength.Value()) :
1532+
Microsoft::ReactNative::JSValue{nullptr} },
1533+
{ "chunk", chunk },
1534+
});
1535+
}
1536+
1537+
if (readBuffer.Length() == 0)
1538+
{
1539+
break;
1540+
}
1541+
co_await outputStream.WriteAsync(readBuffer);
1542+
1543+
// condition if taskId in a table where I need to report, then emit this
1544+
// to do that, I need a map that with a mutex
1545+
// mutex for all rn fetch blob main class
1546+
// std::scoped_lock lock {m_mutex}
1547+
15161548
}
1517-
co_await outputStream.WriteAsync(readBuffer);
1549+
callback("", "path", config.path, "");
15181550

1519-
// condition if taskId in a table where I need to report, then emit this
1520-
// to do that, I need a map that with a mutex
1521-
// mutex for all rn fetch blob main class
1522-
// std::scoped_lock lock {m_mutex}
1551+
}
1552+
else {
1553+
std::string chunk{ winrt::to_string(CryptographicBuffer::ConvertBinaryToString(BinaryStringEncoding::Utf8, co_await response.Content().ReadAsBufferAsync())) };
15231554
auto it{ downloadProgressMap.find(taskId) };
15241555
if (it != downloadProgressMap.end()) {
1556+
15251557
auto var{ downloadProgressMap[taskId] };
1558+
15261559
m_reactContext.CallJSFunction(L"RCTDeviceEventEmitter", L"emit", L"RNFetchBlobProgress",
15271560
Microsoft::ReactNative::JSValueObject{
1528-
{ "recieved", totalRead },
1561+
{ "taskId", taskId },
1562+
{ "written", contentLength.Type() == PropertyType::UInt64 ?
1563+
Microsoft::ReactNative::JSValue(contentLength.Value()) :
1564+
Microsoft::ReactNative::JSValue{nullptr} },
15291565
{ "total", contentLength.Type() == PropertyType::UInt64 ?
1530-
Microsoft::ReactNative::JSValue(contentLength.Value()) :
1531-
Microsoft::ReactNative::JSValue{nullptr} },
1566+
Microsoft::ReactNative::JSValue(contentLength.Value()) :
1567+
Microsoft::ReactNative::JSValue{nullptr} },
1568+
{ "chunk", chunk },
15321569
});
15331570
}
1571+
callback(chunk, "result", config.path, "");
15341572
}
1535-
callback("", "path", config.path);
1536-
1573+
15371574
}
1538-
else {
1539-
auto it{ downloadProgressMap.find(taskId) };
1540-
if (it != downloadProgressMap.end()) {
15411575

1542-
auto var{ downloadProgressMap[taskId] };
15431576

1544-
m_reactContext.CallJSFunction(L"RCTDeviceEventEmitter", L"emit", L"RNFetchBlobProgress",
1545-
Microsoft::ReactNative::JSValueObject{
1546-
{ "recieved", 0 },
1547-
{ "total", 0},
1548-
});
1549-
}
1550-
callback(winrt::to_string(co_await response.Content().ReadAsStringAsync()), "result", config.path);
1551-
}
1552-
co_return;
1577+
15531578
}
15541579
catch (const hresult_error& ex)
15551580
{
1556-
callback(winrt::to_string(ex.message().c_str()), "error", "");
1581+
callback(winrt::to_string(ex.message().c_str()), "error", "", "");
15571582
}
15581583

1584+
15591585
RNFetchBlobStream::RNFetchBlobStream(Streams::IRandomAccessStream& _streamInstance, EncodingOptions _encoding) noexcept
15601586
: streamInstance{ std::move(_streamInstance) }
15611587
, encoding{ _encoding }

RNFetchBlobWin/windows/RNFetchBlobWin/RNFetchBlob.h

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -262,7 +262,7 @@ struct RNFetchBlob
262262
std::wstring url,
263263
winrt::Microsoft::ReactNative::JSValueObject headers,
264264
std::string body,
265-
std::function<void(std::string, std::string, std::string)> callback) noexcept;
265+
std::function<void(std::string, std::string, std::string, std::string)> callback) noexcept;
266266

267267
REACT_METHOD(fetchBlobForm);
268268
winrt::fire_and_forget fetchBlobForm(
@@ -272,7 +272,7 @@ struct RNFetchBlob
272272
std::wstring url,
273273
winrt::Microsoft::ReactNative::JSValueObject headers,
274274
winrt::Microsoft::ReactNative::JSValueArray body,
275-
std::function<void(std::string, std::string, std::string)> callback) noexcept;
275+
std::function<void(std::string, std::string, std::string, std::string)> callback) noexcept;
276276

277277
REACT_METHOD(enableProgressReport);
278278
void enableProgressReport(
@@ -319,7 +319,7 @@ struct RNFetchBlob
319319
const winrt::Windows::Web::Http::Filters::HttpBaseProtocolFilter& filter,
320320
winrt::Windows::Web::Http::HttpRequestMessage& httpRequestMessage,
321321
RNFetchBlobConfig& config,
322-
std::function<void(std::string, std::string, std::string)> callback) noexcept;
322+
std::function<void(std::string, std::string, std::string, std::string)> callback) noexcept;
323323

324324
const std::map<std::string, std::function<CryptographyCore::HashAlgorithmProvider()>> availableHashes{
325325
{"md5", []() { return CryptographyCore::HashAlgorithmProvider::OpenAlgorithm(CryptographyCore::HashAlgorithmNames::Md5()); } },
@@ -329,15 +329,15 @@ struct RNFetchBlob
329329
{"sha512", []() { return CryptographyCore::HashAlgorithmProvider::OpenAlgorithm(CryptographyCore::HashAlgorithmNames::Sha512()); } }
330330
};
331331

332-
winrt::fire_and_forget createBlobForm(
333-
const winrt::Microsoft::ReactNative::JSValueObject& options,
334-
const std::string& taskId,
335-
const std::string& method,
336-
const std::wstring& url,
337-
const winrt::Microsoft::ReactNative::JSValueObject& headers,
338-
const std::string& bodyString,
339-
const winrt::Microsoft::ReactNative::JSValueArray& bodyArray,
340-
std::function<void(std::string, std::string, std::string)> callback) noexcept;
332+
//winrt::fire_and_forget createBlobForm(
333+
// const winrt::Microsoft::ReactNative::JSValueObject& options,
334+
// const std::string& taskId,
335+
// const std::string& method,
336+
// const std::wstring& url,
337+
// const winrt::Microsoft::ReactNative::JSValueObject& headers,
338+
// const std::string& bodyString,
339+
// const winrt::Microsoft::ReactNative::JSValueArray& bodyArray,
340+
// std::function<void(std::string, std::string, std::string, std::string)> callback) noexcept;
341341

342342
void splitPath(const std::string& fullPath,
343343
winrt::hstring& directoryPath,

0 commit comments

Comments
 (0)