Skip to content

Commit 518d48b

Browse files
committed
Updated ProcessRequestAsync
1 parent 709a821 commit 518d48b

File tree

2 files changed

+96
-35
lines changed

2 files changed

+96
-35
lines changed

windows/RNFetchBlob/RNFetchBlob.cpp

Lines changed: 66 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ RNFetchBlobConfig::RNFetchBlobConfig(winrt::Microsoft::ReactNative::JSValueObjec
131131
bool hasTrailingSlash{ filepath[fileLength - 1] == '\\' || filepath[fileLength - 1] == '/' };
132132
std::filesystem::path pathToParse{ hasTrailingSlash ? filepath.substr(0, fileLength - 1) : filepath };
133133
pathToParse.make_preferred();
134-
path = winrt::to_string(pathToParse.c_str());
134+
path = pathToParse.string();
135135
}
136136
trusty = options["trusty"].AsBoolean();
137137

@@ -230,7 +230,7 @@ try
230230
}
231231
catch (...)
232232
{
233-
promise.Reject("EEXIST: File already exists."); // TODO: Include filepath
233+
promise.Reject(winrt::Microsoft::ReactNative::ReactError{ "EEXIST", "EEXIST: File already exists; " + path });
234234
shouldExit = true;
235235
}
236236
}
@@ -245,13 +245,11 @@ catch (const hresult_error& ex)
245245
hresult result{ ex.code() };
246246
if (result == 0x80070002) // FileNotFoundException
247247
{
248-
promise.Reject("ENOENT: File does not exist and could not be created"); // TODO: Include filepath
248+
promise.Reject(winrt::Microsoft::ReactNative::ReactError{ "ENOENT", "ENOENT: File does not exist and could not be created; " + path });
249249
}
250250
else
251251
{
252-
// EUNSPECIFIED: Failed to write to file
253-
auto errorMessage{ L"EUNSPECIFIED: " + ex.message() };
254-
promise.Reject(errorMessage.c_str());
252+
promise.Reject(winrt::Microsoft::ReactNative::ReactError{ "EUNSPECIFIED", "EUNSPECIFIED: " + winrt::to_string(ex.message()) + "; " + path });
255253
}
256254
}
257255

@@ -286,16 +284,15 @@ catch (const hresult_error& ex)
286284
hresult result{ ex.code() };
287285
if (result == 0x80070002) // FileNotFoundException
288286
{
289-
promise.Reject("ENOENT: File does not exist and could not be created"); // TODO: Include filepath
287+
promise.Reject(winrt::Microsoft::ReactNative::ReactError{ "ENOENT", "ENOENT: File does not exist and could not be created; " + path });
290288
}
291289
else if (result == 0x80070050)
292290
{
293-
promise.Reject("EEXIST: File already exists.");
291+
promise.Reject(winrt::Microsoft::ReactNative::ReactError{ "EEXIST", "EEXIST: File already exists; " + path });
294292
}
295293
else
296294
{
297-
auto errorMessage{ L"EUNSPECIFIED: " + ex.message() };
298-
promise.Reject(errorMessage.c_str());
295+
promise.Reject(winrt::Microsoft::ReactNative::ReactError{ "EUNSPECIFIED", "EUNSPECIFIED: " + winrt::to_string(ex.message()) });
299296
}
300297
}
301298

@@ -353,9 +350,9 @@ try
353350
co_await stream.WriteAsync(buffer);
354351
promise.Resolve(buffer.Length());
355352
}
356-
catch (...)
353+
catch (const hresult_error& ex)
357354
{
358-
promise.Reject("Failed to write");
355+
promise.Reject(winrt::Microsoft::ReactNative::ReactError{ "EUNSPECIFIED", "EUNSPECIFIED: " + winrt::to_string(ex.message()) + "; " + path });
359356
}
360357

361358
winrt::fire_and_forget RNFetchBlob::writeFileArray(
@@ -396,9 +393,9 @@ winrt::fire_and_forget RNFetchBlob::writeFileArray(
396393

397394
co_return;
398395
}
399-
catch (...)
396+
catch (const hresult_error& ex)
400397
{
401-
promise.Reject("Failed to write");
398+
promise.Reject(winrt::Microsoft::ReactNative::ReactError{ "EUNSPECIFIED", "EUNSPECIFIED: " + winrt::to_string(ex.message()) + "; " + path });
402399
}
403400

404401

@@ -1058,15 +1055,7 @@ winrt::fire_and_forget RNFetchBlob::fetchBlob(
10581055
{
10591056
winrt::Windows::Web::Http::Filters::HttpBaseProtocolFilter filter;
10601057
RNFetchBlobConfig config{ options };
1061-
if (config.followRedirect == true)
1062-
{
1063-
filter.AllowAutoRedirect(true);
1064-
}
1065-
else
1066-
{
1067-
filter.AllowAutoRedirect(false);
1068-
}
1069-
1058+
filter.AllowAutoRedirect(false);
10701059
if (config.trusty)
10711060
{
10721061
filter.IgnorableServerCertificateErrors().Append(Cryptography::Certificates::ChainValidationResult::Untrusted);
@@ -1197,7 +1186,10 @@ winrt::fire_and_forget RNFetchBlob::fetchBlob(
11971186
}
11981187
}
11991188

1200-
co_await m_tasks.Add(taskId, ProcessRequestAsync(taskId, filter, requestMessage, config, callback));
1189+
RNFetchBlobState eventState;
1190+
1191+
co_await m_tasks.Add(taskId, ProcessRequestAsync(taskId, filter, requestMessage, config, callback, eventState));
1192+
12011193
m_tasks.Cancel(taskId);
12021194
{
12031195
std::scoped_lock lock{ m_mutex };
@@ -1215,8 +1207,6 @@ winrt::fire_and_forget RNFetchBlob::fetchBlobForm(
12151207
winrt::Microsoft::ReactNative::JSValueArray body,
12161208
std::function<void(std::string, std::string, std::string)> callback) noexcept
12171209
{
1218-
//createBlobForm(options, taskId, method, url, headers, "", body, callback);
1219-
//co_return;
12201210
winrt::hstring boundary{ L"-----" };
12211211
winrt::Windows::Web::Http::Filters::HttpBaseProtocolFilter filter;
12221212

@@ -1387,7 +1377,23 @@ winrt::fire_and_forget RNFetchBlob::fetchBlobForm(
13871377
}
13881378

13891379
// TODO, set a timeout for cancellation
1390-
co_await m_tasks.Add(taskId, ProcessRequestAsync(taskId, filter, requestMessage, config, callback));
1380+
1381+
//Create EVENT_STATE_CHANGE
1382+
/*
1383+
taskId, // DO NOT STORE
1384+
@"state": @"2", // store
1385+
@"headers": headers, // store
1386+
@"redirects": redirects, //check how to track
1387+
@"respType" : respType, // store
1388+
@"timeout" : @NO, // do not store
1389+
@"status": [NSNumber numberWithInteger:statusCode] // store
1390+
*/
1391+
1392+
RNFetchBlobState eventState;
1393+
1394+
co_await m_tasks.Add(taskId, ProcessRequestAsync(taskId, filter, requestMessage, config, callback, eventState));
1395+
1396+
13911397
m_tasks.Cancel(taskId);
13921398
{
13931399
std::scoped_lock lock{ m_mutex };
@@ -1487,19 +1493,32 @@ winrt::Windows::Foundation::IAsyncAction RNFetchBlob::ProcessRequestAsync(
14871493
const winrt::Windows::Web::Http::Filters::HttpBaseProtocolFilter& filter,
14881494
winrt::Windows::Web::Http::HttpRequestMessage& httpRequestMessage,
14891495
RNFetchBlobConfig& config,
1490-
std::function<void(std::string, std::string, std::string)> callback) noexcept
1496+
std::function<void(std::string, std::string, std::string)> callback,
1497+
RNFetchBlobState& eventState) noexcept
14911498
try
14921499
{
14931500
winrt::Windows::Web::Http::HttpClient httpClient{filter};
14941501

14951502
winrt::Windows::Web::Http::HttpResponseMessage response{ co_await httpClient.SendRequestAsync(httpRequestMessage, winrt::Windows::Web::Http::HttpCompletionOption::ResponseHeadersRead) };
1503+
1504+
auto status{ static_cast<int>(response.StatusCode()) };
1505+
if (config.followRedirect) {
1506+
while (status >= 300 && status < 400) {
1507+
auto redirect{ response.Headers().Location().ToString() };
1508+
eventState.redirects.push_back(winrt::to_string(redirect));
1509+
httpRequestMessage.RequestUri(Uri{ redirect });
1510+
response = co_await httpClient.SendRequestAsync(httpRequestMessage, winrt::Windows::Web::Http::HttpCompletionOption::ResponseHeadersRead);
1511+
status = static_cast<int>(response.StatusCode());
1512+
}
1513+
}
1514+
14961515
IReference<uint64_t> contentLength{ response.Content().Headers().ContentLength() };
14971516

14981517
IOutputStream outputStream;
1518+
bool writeToFile{ config.fileCache || !config.path.empty() };
14991519

1500-
if (config.fileCache)
1520+
if (writeToFile)
15011521
{
1502-
15031522
if (config.path.empty())
15041523
{
15051524
config.path = winrt::to_string(ApplicationData::Current().TemporaryFolder().Path()) + "\\RNFetchBlobTmp_" + taskId;
@@ -1508,7 +1527,6 @@ try
15081527
config.path += "." + config.appendExt;
15091528
}
15101529
}
1511-
15121530
std::filesystem::path path{ config.path };
15131531
StorageFolder storageFolder{ co_await StorageFolder::GetFolderFromPathAsync( path.parent_path().wstring()) };
15141532
StorageFile storageFile{ co_await storageFolder.CreateFileAsync(path.filename().wstring(), CreationCollisionOption::FailIfExists) };
@@ -1546,7 +1564,6 @@ try
15461564
buffer.Length(0);
15471565
auto readBuffer{ co_await contentStream.ReadAsync(buffer, buffer.Capacity(), InputStreamOptions::None) };
15481566

1549-
//
15501567
read += readBuffer.Length();
15511568
totalRead += read;
15521569

@@ -1557,7 +1574,7 @@ try
15571574

15581575
readContents = winrt::to_string(CryptographicBuffer::EncodeToBase64String(readBuffer));
15591576

1560-
if (config.fileCache) {
1577+
if (writeToFile) {
15611578
co_await outputStream.WriteAsync(readBuffer);
15621579
}
15631580
else {
@@ -1587,8 +1604,20 @@ try
15871604
}
15881605
}
15891606
}
1607+
1608+
eventState.status = static_cast<int>(response.StatusCode());
15901609

1591-
if (config.fileCache) {
1610+
for (const auto header : response.Content().Headers().GetView()) {
1611+
eventState.headers[winrt::to_string(header.Key())] = winrt::to_string(header.Value());
1612+
}
1613+
1614+
if (response.Content().Headers().ContentType() != nullptr) {
1615+
eventState.respType = winrt::to_string(response.Content().Headers().ContentType().ToString());
1616+
}
1617+
1618+
eventState.state = winrt::to_string(response.ReasonPhrase());
1619+
1620+
if (writeToFile) {
15921621
callback("", "path", config.path);
15931622
}
15941623
else {
@@ -1600,6 +1629,9 @@ catch (const hresult_error& ex)
16001629
{
16011630
callback(winrt::to_string(ex.message().c_str()), "error", "");
16021631
}
1632+
catch (...) {
1633+
co_return;
1634+
}
16031635

16041636

16051637
RNFetchBlobStream::RNFetchBlobStream(Streams::IRandomAccessStream& _streamInstance, EncodingOptions _encoding) noexcept

windows/RNFetchBlob/RNFetchBlob.h

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,34 @@ struct TaskCancellationManager
4848
std::map<TaskId, CancellationDisposable> m_pendingTasks;
4949
};
5050

51+
struct RNFetchBlobState
52+
{
53+
/*
54+
55+
@"state": @"2", // store
56+
@"headers": headers, // store
57+
@"redirects": redirects, //check how to track, store
58+
@"respType" : respType, // store
59+
@"status": [NSNumber numberWithInteger : statusCode] // store
60+
*/
61+
std::string state;
62+
winrt::Microsoft::ReactNative::JSValueObject headers;
63+
std::vector<std::string> redirects;
64+
std::string respType;
65+
int status = 0;
66+
67+
/*
68+
taskId: string;
69+
state: string;
70+
headers: any;
71+
redirects: string[];
72+
status: number;
73+
respType: "text" | "blob" | "" | "json";
74+
rnfbEncode: "path" | "base64" | "ascii" | "utf8";
75+
timeout: boolean;
76+
*/
77+
};
78+
5179

5280
struct RNFetchBlobStream
5381
{
@@ -308,7 +336,8 @@ struct RNFetchBlob
308336
const winrt::Windows::Web::Http::Filters::HttpBaseProtocolFilter& filter,
309337
winrt::Windows::Web::Http::HttpRequestMessage& httpRequestMessage,
310338
RNFetchBlobConfig& config,
311-
std::function<void(std::string, std::string, std::string)> callback) noexcept;
339+
std::function<void(std::string, std::string, std::string)> callback,
340+
RNFetchBlobState& eventState) noexcept;
312341

313342
const std::map<std::string, std::function<CryptographyCore::HashAlgorithmProvider()>> availableHashes{
314343
{"md5", []() { return CryptographyCore::HashAlgorithmProvider::OpenAlgorithm(CryptographyCore::HashAlgorithmNames::Md5()); } },

0 commit comments

Comments
 (0)