@@ -1044,6 +1044,10 @@ catch (...)
1044
1044
}
1045
1045
1046
1046
1047
+ IAsyncAction setTimeout (std::chrono::seconds time) {
1048
+ co_await time ;
1049
+ }
1050
+
1047
1051
winrt::fire_and_forget RNFetchBlob::fetchBlob (
1048
1052
winrt::Microsoft::ReactNative::JSValueObject options,
1049
1053
std::string taskId,
@@ -1186,9 +1190,38 @@ winrt::fire_and_forget RNFetchBlob::fetchBlob(
1186
1190
}
1187
1191
}
1188
1192
}
1193
+
1194
+ std::string error;
1195
+ auto cancellationTimer{ setTimeout (config.timeout ) };
1196
+ cancellationTimer.Completed ([weak_this = weak_from_this (), taskId, error](IAsyncAction const & action, AsyncStatus status) {
1197
+ if (status == AsyncStatus::Completed) {
1198
+ auto strong_this{ weak_this.lock () };
1199
+ if (strong_this) {
1200
+ strong_this->m_tasks .Cancel (taskId);
1201
+ {
1202
+ std::scoped_lock lock{ strong_this->m_mutex };
1203
+ strong_this->uploadProgressMap .extract (taskId);
1204
+ strong_this->downloadProgressMap .extract (taskId);
1205
+ }
1206
+ }
1207
+ }
1208
+ });
1209
+ try {
1210
+ co_await m_tasks.Add (taskId, ProcessRequestAsync (taskId, filter, requestMessage, config, callback, error));
1211
+ }
1212
+ catch (...) {
1213
+
1214
+ }
1215
+ if (!error.empty ()) {
1216
+ if (cancellationTimer.Status () != AsyncStatus::Completed) {
1217
+ callback (error, " error" , " " );
1218
+ }
1219
+ else {
1220
+ callback (" RNFetchBlob request timed out" , " error" , " " );
1221
+ }
1222
+ }
1189
1223
1190
- co_await m_tasks.Add (taskId, ProcessRequestAsync (taskId, filter, requestMessage, config, callback, eventState));
1191
-
1224
+ cancellationTimer.Cancel ();
1192
1225
m_tasks.Cancel (taskId);
1193
1226
{
1194
1227
std::scoped_lock lock{ m_mutex };
@@ -1211,14 +1244,7 @@ winrt::fire_and_forget RNFetchBlob::fetchBlobForm(
1211
1244
1212
1245
RNFetchBlobConfig config{ options };
1213
1246
1214
- if (config.followRedirect == true )
1215
- {
1216
- filter.AllowAutoRedirect (true );
1217
- }
1218
- else
1219
- {
1220
- filter.AllowAutoRedirect (false );
1221
- }
1247
+ filter.AllowAutoRedirect (false );
1222
1248
1223
1249
if (config.trusty )
1224
1250
{
@@ -1375,11 +1401,37 @@ winrt::fire_and_forget RNFetchBlob::fetchBlobForm(
1375
1401
}
1376
1402
}
1377
1403
1378
- RNFetchBlobState eventState;
1379
-
1380
- co_await m_tasks.Add (taskId, ProcessRequestAsync (taskId, filter, requestMessage, config, callback, eventState));
1404
+ std::string error;
1405
+ auto cancellationTimer{ setTimeout (config.timeout ) };
1406
+ cancellationTimer.Completed ([weak_this = weak_from_this (), taskId, error](IAsyncAction const & action, AsyncStatus status) {
1407
+ if (status == AsyncStatus::Completed) {
1408
+ auto strong_this{ weak_this.lock () };
1409
+ if (strong_this) {
1410
+ strong_this->m_tasks .Cancel (taskId);
1411
+ {
1412
+ std::scoped_lock lock{ strong_this->m_mutex };
1413
+ strong_this->uploadProgressMap .extract (taskId);
1414
+ strong_this->downloadProgressMap .extract (taskId);
1415
+ }
1416
+ }
1417
+ }
1418
+ });
1419
+ try {
1420
+ co_await m_tasks.Add (taskId, ProcessRequestAsync (taskId, filter, requestMessage, config, callback, error));
1421
+ }
1422
+ catch (...) {
1381
1423
1424
+ }
1425
+ if (!error.empty ()) {
1426
+ if (cancellationTimer.Status () != AsyncStatus::Completed) {
1427
+ callback (error, " error" , " " );
1428
+ }
1429
+ else {
1430
+ callback (" RNFetchBlob request timed out" , " error" , " " );
1431
+ }
1432
+ }
1382
1433
1434
+ cancellationTimer.Cancel ();
1383
1435
m_tasks.Cancel (taskId);
1384
1436
{
1385
1437
std::scoped_lock lock{ m_mutex };
@@ -1480,13 +1532,15 @@ winrt::Windows::Foundation::IAsyncAction RNFetchBlob::ProcessRequestAsync(
1480
1532
winrt::Windows::Web::Http::HttpRequestMessage& httpRequestMessage,
1481
1533
RNFetchBlobConfig& config,
1482
1534
std::function<void (std::string, std::string, std::string)> callback,
1483
- RNFetchBlobState& eventState ) noexcept
1535
+ std::string& error ) noexcept
1484
1536
try
1485
1537
{
1486
1538
winrt::Windows::Web::Http::HttpClient httpClient{filter};
1487
-
1539
+
1488
1540
winrt::Windows::Web::Http::HttpResponseMessage response{ co_await httpClient.SendRequestAsync (httpRequestMessage, winrt::Windows::Web::Http::HttpCompletionOption::ResponseHeadersRead) };
1489
1541
1542
+ RNFetchBlobState eventState;
1543
+
1490
1544
auto status{ static_cast <int >(response.StatusCode ()) };
1491
1545
if (config.followRedirect ) {
1492
1546
while (status >= 300 && status < 400 ) {
@@ -1620,11 +1674,11 @@ try
1620
1674
else {
1621
1675
callback (" " , " result" , resultOutput.str ());
1622
1676
}
1623
- // callback("RNFetchBlob request timed out", "error", "");
1624
1677
}
1625
1678
catch (const hresult_error& ex)
1626
1679
{
1627
- callback (winrt::to_string (ex.message ().c_str ()), " error" , " " );
1680
+ error = winrt::to_string (ex.message ().c_str ());
1681
+ // callback(winrt::to_string(ex.message().c_str()), "error", "");
1628
1682
}
1629
1683
catch (...) {
1630
1684
co_return ;
0 commit comments