react-native-windows 0.72.1 → 0.72.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Libraries/Core/ReactNativeVersion.js +1 -1
- package/Libraries/Network/RCTNetworking.windows.js +10 -16
- package/Microsoft.ReactNative/Fabric/ImageRequest.cpp +11 -14
- package/Microsoft.ReactNative/Fabric/WindowsImageManager.cpp +1 -1
- package/Microsoft.ReactNative/Microsoft.ReactNative.vcxproj +1 -3
- package/Microsoft.ReactNative/Microsoft.ReactNative.vcxproj.filters +0 -7
- package/Microsoft.ReactNative/ReactHost/ReactInstanceWin.cpp +11 -10
- package/Microsoft.ReactNative.Cxx/JSValueReader.h +1 -1
- package/Microsoft.ReactNative.Cxx/JSValueWriter.h +1 -1
- package/Microsoft.ReactNative.Cxx/ModuleRegistration.h +22 -0
- package/Microsoft.ReactNative.Cxx/NativeModules.h +5 -0
- package/Microsoft.ReactNative.Cxx/StructInfo.h +4 -4
- package/Microsoft.ReactNative.Managed/packages.lock.json +2 -71
- package/PropertySheets/Generated/PackageVersion.g.props +3 -3
- package/PropertySheets/React.Cpp.props +2 -3
- package/Shared/BaseFileReaderResource.cpp +95 -0
- package/Shared/BaseFileReaderResource.h +41 -0
- package/Shared/CreateModules.h +27 -5
- package/Shared/IFileReaderResource.h +36 -0
- package/Shared/Modules/BlobModule.cpp +93 -297
- package/Shared/Modules/BlobModule.h +25 -87
- package/Shared/Modules/CxxModuleUtilities.cpp +32 -0
- package/Shared/Modules/CxxModuleUtilities.h +17 -0
- package/Shared/Modules/FileReaderModule.cpp +118 -51
- package/Shared/Modules/FileReaderModule.h +27 -1
- package/Shared/Modules/HttpModule.cpp +133 -9
- package/Shared/Modules/HttpModule.h +33 -0
- package/Shared/Modules/IRequestBodyHandler.h +6 -4
- package/Shared/Modules/IResponseHandler.h +3 -3
- package/Shared/Modules/IUriHandler.h +3 -3
- package/Shared/Modules/IWebSocketModuleContentHandler.h +6 -4
- package/Shared/Modules/WebSocketModule.cpp +190 -7
- package/Shared/Modules/WebSocketTurboModule.h +52 -0
- package/Shared/Networking/DefaultBlobResource.cpp +323 -0
- package/Shared/Networking/DefaultBlobResource.h +133 -0
- package/Shared/Networking/IBlobResource.h +56 -0
- package/Shared/Networking/IHttpResource.h +6 -5
- package/Shared/Networking/WinRTHttpResource.cpp +40 -32
- package/Shared/Networking/WinRTHttpResource.h +4 -3
- package/Shared/Networking/WinRTTypes.h +3 -3
- package/Shared/Shared.vcxitems +8 -1
- package/Shared/Shared.vcxitems.filters +24 -3
- package/package.json +13 -13
- package/types/experimental.d.ts +101 -0
- package/types/index.d.ts +216 -0
- package/types/modules/BatchedBridge.d.ts +32 -0
- package/types/modules/Codegen.d.ts +74 -0
- package/types/modules/Devtools.d.ts +31 -0
- package/types/modules/LaunchScreen.d.ts +18 -0
- package/types/modules/globals.d.ts +579 -0
- package/types/private/TimerMixin.d.ts +19 -0
- package/types/private/Utilities.d.ts +10 -0
- package/types/public/DeprecatedPropertiesAlias.d.ts +185 -0
- package/types/public/Insets.d.ts +15 -0
- package/types/public/ReactNativeRenderer.d.ts +144 -0
- package/types/public/ReactNativeTypes.d.ts +143 -0
- package/Microsoft.ReactNative/Base/CoreNativeModules.cpp +0 -44
- package/Microsoft.ReactNative/Base/CoreNativeModules.h +0 -30
- /package/Shared/{Modules/IBlobPersistor.h → IBlobPersistor.h} +0 -0
|
@@ -0,0 +1,323 @@
|
|
|
1
|
+
// Copyright (c) Microsoft Corporation.
|
|
2
|
+
// Licensed under the MIT License.
|
|
3
|
+
|
|
4
|
+
#include "DefaultBlobResource.h"
|
|
5
|
+
|
|
6
|
+
#include <Modules/IHttpModuleProxy.h>
|
|
7
|
+
#include <Modules/IWebSocketModuleProxy.h>
|
|
8
|
+
|
|
9
|
+
// Boost Libraries
|
|
10
|
+
#include <boost/uuid/uuid_io.hpp>
|
|
11
|
+
|
|
12
|
+
// Windows API
|
|
13
|
+
#include <winrt/Windows.Security.Cryptography.h>
|
|
14
|
+
|
|
15
|
+
using std::scoped_lock;
|
|
16
|
+
using std::shared_ptr;
|
|
17
|
+
using std::string;
|
|
18
|
+
using std::vector;
|
|
19
|
+
using std::weak_ptr;
|
|
20
|
+
using winrt::array_view;
|
|
21
|
+
using winrt::Windows::Security::Cryptography::CryptographicBuffer;
|
|
22
|
+
|
|
23
|
+
namespace msrn = winrt::Microsoft::ReactNative;
|
|
24
|
+
|
|
25
|
+
namespace {
|
|
26
|
+
|
|
27
|
+
constexpr Microsoft::React::Networking::IBlobResource::BlobFieldNames
|
|
28
|
+
blobKeys{"blob", "blobId", "offset", "size", "type", "data"};
|
|
29
|
+
|
|
30
|
+
} // namespace
|
|
31
|
+
|
|
32
|
+
namespace Microsoft::React::Networking {
|
|
33
|
+
|
|
34
|
+
#pragma region DefaultBlobResource
|
|
35
|
+
|
|
36
|
+
DefaultBlobResource::DefaultBlobResource(
|
|
37
|
+
shared_ptr<MemoryBlobPersistor> blobPersistor,
|
|
38
|
+
shared_ptr<BlobWebSocketModuleContentHandler> contentHandler,
|
|
39
|
+
shared_ptr<BlobModuleRequestBodyHandler> requestBodyHandler,
|
|
40
|
+
shared_ptr<BlobModuleResponseHandler> responseHandler,
|
|
41
|
+
msrn::ReactPropertyBag propertyBag)
|
|
42
|
+
: m_blobPersistor{blobPersistor},
|
|
43
|
+
m_contentHandler{contentHandler},
|
|
44
|
+
m_requestBodyHandler{requestBodyHandler},
|
|
45
|
+
m_responseHandler{responseHandler},
|
|
46
|
+
m_propertyBag{propertyBag} {}
|
|
47
|
+
|
|
48
|
+
#pragma region IBlobResource
|
|
49
|
+
|
|
50
|
+
/*static*/ const IBlobResource::BlobFieldNames &IBlobResource::FieldNames() noexcept {
|
|
51
|
+
return blobKeys;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/*static*/ shared_ptr<IBlobResource> IBlobResource::Make(
|
|
55
|
+
winrt::Windows::Foundation::IInspectable const &inspectableProperties) {
|
|
56
|
+
using namespace msrn;
|
|
57
|
+
|
|
58
|
+
auto propBag = ReactPropertyBag{inspectableProperties.try_as<IReactPropertyBag>()};
|
|
59
|
+
|
|
60
|
+
auto blobPersistor = std::make_shared<MemoryBlobPersistor>();
|
|
61
|
+
auto contentHandler = std::make_shared<BlobWebSocketModuleContentHandler>(blobPersistor);
|
|
62
|
+
auto requestBodyHanlder = std::make_shared<BlobModuleRequestBodyHandler>(blobPersistor);
|
|
63
|
+
auto responseHandler = std::make_shared<BlobModuleResponseHandler>(blobPersistor);
|
|
64
|
+
|
|
65
|
+
auto contentHandlerPropId =
|
|
66
|
+
ReactPropertyId<ReactNonAbiValue<weak_ptr<IWebSocketModuleContentHandler>>>{L"BlobModule.ContentHandler"};
|
|
67
|
+
propBag.Set(contentHandlerPropId, weak_ptr<IWebSocketModuleContentHandler>{contentHandler});
|
|
68
|
+
|
|
69
|
+
auto blobPersistorPropId = ReactPropertyId<ReactNonAbiValue<weak_ptr<IBlobPersistor>>>{L"Blob.Persistor"};
|
|
70
|
+
;
|
|
71
|
+
propBag.Set(blobPersistorPropId, weak_ptr<IBlobPersistor>{blobPersistor});
|
|
72
|
+
|
|
73
|
+
auto result = std::make_shared<DefaultBlobResource>(
|
|
74
|
+
blobPersistor, contentHandler, requestBodyHanlder, responseHandler, propBag);
|
|
75
|
+
|
|
76
|
+
return result;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
void DefaultBlobResource::SendOverSocket(string &&blobId, int64_t offset, int64_t size, int64_t socketId) noexcept
|
|
80
|
+
/*override*/ {
|
|
81
|
+
auto propId =
|
|
82
|
+
msrn::ReactPropertyId<msrn::ReactNonAbiValue<weak_ptr<IWebSocketModuleProxy>>>{L"WebSocketModule.Proxy"};
|
|
83
|
+
shared_ptr<IWebSocketModuleProxy> wsProxy;
|
|
84
|
+
if (auto prop = m_propertyBag.Get(propId)) {
|
|
85
|
+
wsProxy = prop.Value().lock();
|
|
86
|
+
}
|
|
87
|
+
if (!wsProxy) {
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
array_view<uint8_t const> data;
|
|
92
|
+
try {
|
|
93
|
+
data = m_blobPersistor->ResolveMessage(std::move(blobId), offset, size);
|
|
94
|
+
} catch (const std::exception &e) {
|
|
95
|
+
return m_callbacks.OnError(e.what());
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
auto buffer = CryptographicBuffer::CreateFromByteArray(data);
|
|
99
|
+
auto base64Hstring = CryptographicBuffer::EncodeToBase64String(std::move(buffer));
|
|
100
|
+
auto base64String = winrt::to_string(base64Hstring);
|
|
101
|
+
|
|
102
|
+
wsProxy->SendBinary(std::move(base64String), socketId);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
void DefaultBlobResource::CreateFromParts(msrn::JSValueArray &&parts, string &&blobId) noexcept /*override*/ {
|
|
106
|
+
vector<uint8_t> buffer{};
|
|
107
|
+
|
|
108
|
+
for (const auto &partItem : parts) {
|
|
109
|
+
auto &part = partItem.AsObject();
|
|
110
|
+
auto type = part.at(blobKeys.Type).AsString();
|
|
111
|
+
if (blobKeys.Blob == type) {
|
|
112
|
+
auto &blob = part.at(blobKeys.Data).AsObject();
|
|
113
|
+
array_view<uint8_t const> bufferPart;
|
|
114
|
+
try {
|
|
115
|
+
bufferPart = m_blobPersistor->ResolveMessage(
|
|
116
|
+
blob.at(blobKeys.BlobId).AsString(), blob.at(blobKeys.Offset).AsInt64(), blob.at(blobKeys.Size).AsInt64());
|
|
117
|
+
} catch (const std::exception &e) {
|
|
118
|
+
return m_callbacks.OnError(e.what());
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
buffer.reserve(buffer.size() + bufferPart.size());
|
|
122
|
+
buffer.insert(buffer.end(), bufferPart.begin(), bufferPart.end());
|
|
123
|
+
} else if ("string" == type) {
|
|
124
|
+
auto data = part.at(blobKeys.Data).AsString();
|
|
125
|
+
|
|
126
|
+
buffer.reserve(buffer.size() + data.size());
|
|
127
|
+
buffer.insert(buffer.end(), data.begin(), data.end());
|
|
128
|
+
} else {
|
|
129
|
+
return m_callbacks.OnError("Invalid type for blob: " + type);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
m_blobPersistor->StoreMessage(std::move(buffer), std::move(blobId));
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
void DefaultBlobResource::Release(string &&blobId) noexcept /*override*/ {
|
|
137
|
+
m_blobPersistor->RemoveMessage(std::move(blobId));
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
void DefaultBlobResource::AddNetworkingHandler() noexcept /*override*/ {
|
|
141
|
+
auto propId = msrn::ReactPropertyId<msrn::ReactNonAbiValue<weak_ptr<IHttpModuleProxy>>>{L"HttpModule.Proxy"};
|
|
142
|
+
|
|
143
|
+
if (auto prop = m_propertyBag.Get(propId)) {
|
|
144
|
+
if (auto httpHandler = prop.Value().lock()) {
|
|
145
|
+
httpHandler->AddRequestBodyHandler(m_requestBodyHandler);
|
|
146
|
+
httpHandler->AddResponseHandler(m_responseHandler);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
// TODO: else emit error?
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
void DefaultBlobResource::AddWebSocketHandler(int64_t id) noexcept /*override*/ {
|
|
153
|
+
m_contentHandler->Register(id);
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
void DefaultBlobResource::RemoveWebSocketHandler(int64_t id) noexcept /*override*/ {
|
|
157
|
+
m_contentHandler->Unregister(id);
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
IBlobResource::BlobCallbacks &DefaultBlobResource::Callbacks() noexcept /*override*/ {
|
|
161
|
+
return m_callbacks;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
#pragma endregion IBlobResource
|
|
165
|
+
|
|
166
|
+
#pragma endregion DefaultBlobResource
|
|
167
|
+
|
|
168
|
+
#pragma region MemoryBlobPersistor
|
|
169
|
+
|
|
170
|
+
#pragma region IBlobPersistor
|
|
171
|
+
|
|
172
|
+
array_view<uint8_t const> MemoryBlobPersistor::ResolveMessage(string &&blobId, int64_t offset, int64_t size) {
|
|
173
|
+
if (size < 1)
|
|
174
|
+
return {};
|
|
175
|
+
|
|
176
|
+
scoped_lock lock{m_mutex};
|
|
177
|
+
|
|
178
|
+
auto dataItr = m_blobs.find(std::move(blobId));
|
|
179
|
+
// Not found.
|
|
180
|
+
if (dataItr == m_blobs.cend())
|
|
181
|
+
throw std::invalid_argument("Blob object not found");
|
|
182
|
+
|
|
183
|
+
auto &bytes = (*dataItr).second;
|
|
184
|
+
auto endBound = static_cast<size_t>(offset + size);
|
|
185
|
+
// Out of bounds.
|
|
186
|
+
if (endBound > bytes.size() || offset >= static_cast<int64_t>(bytes.size()) || offset < 0)
|
|
187
|
+
throw std::out_of_range("Offset or size out of range");
|
|
188
|
+
|
|
189
|
+
return array_view<uint8_t const>(bytes.data() + offset, bytes.data() + endBound);
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
void MemoryBlobPersistor::RemoveMessage(string &&blobId) noexcept {
|
|
193
|
+
scoped_lock lock{m_mutex};
|
|
194
|
+
|
|
195
|
+
m_blobs.erase(std::move(blobId));
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
void MemoryBlobPersistor::StoreMessage(vector<uint8_t> &&message, string &&blobId) noexcept {
|
|
199
|
+
scoped_lock lock{m_mutex};
|
|
200
|
+
|
|
201
|
+
m_blobs.insert_or_assign(std::move(blobId), std::move(message));
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
string MemoryBlobPersistor::StoreMessage(vector<uint8_t> &&message) noexcept {
|
|
205
|
+
auto blobId = boost::uuids::to_string(m_guidGenerator());
|
|
206
|
+
|
|
207
|
+
scoped_lock lock{m_mutex};
|
|
208
|
+
m_blobs.insert_or_assign(blobId, std::move(message));
|
|
209
|
+
|
|
210
|
+
return blobId;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
#pragma endregion IBlobPersistor
|
|
214
|
+
|
|
215
|
+
#pragma endregion MemoryBlobPersistor
|
|
216
|
+
|
|
217
|
+
#pragma region BlobWebSocketModuleContentHandler
|
|
218
|
+
|
|
219
|
+
BlobWebSocketModuleContentHandler::BlobWebSocketModuleContentHandler(shared_ptr<IBlobPersistor> blobPersistor) noexcept
|
|
220
|
+
: m_blobPersistor{blobPersistor} {}
|
|
221
|
+
|
|
222
|
+
#pragma region IWebSocketModuleContentHandler
|
|
223
|
+
|
|
224
|
+
void BlobWebSocketModuleContentHandler::ProcessMessage(
|
|
225
|
+
string &&message,
|
|
226
|
+
msrn::JSValueObject ¶ms) noexcept /*override*/
|
|
227
|
+
{
|
|
228
|
+
params[blobKeys.Data] = std::move(message);
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
void BlobWebSocketModuleContentHandler::ProcessMessage(
|
|
232
|
+
vector<uint8_t> &&message,
|
|
233
|
+
msrn::JSValueObject ¶ms) noexcept /*override*/
|
|
234
|
+
{
|
|
235
|
+
auto blob = msrn::JSValueObject{
|
|
236
|
+
{blobKeys.Offset, 0},
|
|
237
|
+
{blobKeys.Size, message.size()},
|
|
238
|
+
{blobKeys.BlobId, m_blobPersistor->StoreMessage(std::move(message))}};
|
|
239
|
+
|
|
240
|
+
params[blobKeys.Data] = std::move(blob);
|
|
241
|
+
params[blobKeys.Type] = blobKeys.Blob;
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
#pragma endregion IWebSocketModuleContentHandler
|
|
245
|
+
|
|
246
|
+
void BlobWebSocketModuleContentHandler::Register(int64_t socketID) noexcept {
|
|
247
|
+
scoped_lock lock{m_mutex};
|
|
248
|
+
m_socketIds.insert(socketID);
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
void BlobWebSocketModuleContentHandler::Unregister(int64_t socketID) noexcept {
|
|
252
|
+
scoped_lock lock{m_mutex};
|
|
253
|
+
|
|
254
|
+
auto itr = m_socketIds.find(socketID);
|
|
255
|
+
if (itr != m_socketIds.end())
|
|
256
|
+
m_socketIds.erase(itr);
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
#pragma endregion BlobWebSocketModuleContentHandler
|
|
260
|
+
|
|
261
|
+
#pragma region BlobModuleRequestBodyHandler
|
|
262
|
+
|
|
263
|
+
BlobModuleRequestBodyHandler::BlobModuleRequestBodyHandler(shared_ptr<IBlobPersistor> blobPersistor) noexcept
|
|
264
|
+
: m_blobPersistor{blobPersistor} {}
|
|
265
|
+
|
|
266
|
+
#pragma region IRequestBodyHandler
|
|
267
|
+
|
|
268
|
+
bool BlobModuleRequestBodyHandler::Supports(msrn::JSValueObject &data) /*override*/ {
|
|
269
|
+
auto itr = data.find(blobKeys.Blob);
|
|
270
|
+
|
|
271
|
+
return itr != data.cend() && !(*itr).second.AsString().empty();
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
msrn::JSValueObject BlobModuleRequestBodyHandler::ToRequestBody(
|
|
275
|
+
msrn::JSValueObject &data,
|
|
276
|
+
string &contentType) /*override*/ {
|
|
277
|
+
auto type = contentType;
|
|
278
|
+
auto itr = data.find(blobKeys.Type);
|
|
279
|
+
if (itr != data.cend() && !(*itr).second.AsString().empty()) {
|
|
280
|
+
type = (*itr).second.AsString();
|
|
281
|
+
}
|
|
282
|
+
if (type.empty()) {
|
|
283
|
+
type = "application/octet-stream";
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
auto &blob = data[blobKeys.Blob].AsObject();
|
|
287
|
+
auto blobId = blob[blobKeys.BlobId].AsString();
|
|
288
|
+
auto bytes = m_blobPersistor->ResolveMessage(
|
|
289
|
+
std::move(blobId), blob[blobKeys.Offset].AsInt64(), blob[blobKeys.Size].AsInt64());
|
|
290
|
+
|
|
291
|
+
return {
|
|
292
|
+
{blobKeys.Type, type},
|
|
293
|
+
{blobKeys.Size, bytes.size()},
|
|
294
|
+
{"bytes", msrn::JSValueArray(bytes.cbegin(), bytes.cend())}};
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
#pragma endregion IRequestBodyHandler
|
|
298
|
+
|
|
299
|
+
#pragma endregion BlobModuleRequestBodyHandler
|
|
300
|
+
|
|
301
|
+
#pragma region BlobModuleResponseHandler
|
|
302
|
+
|
|
303
|
+
BlobModuleResponseHandler::BlobModuleResponseHandler(shared_ptr<IBlobPersistor> blobPersistor) noexcept
|
|
304
|
+
: m_blobPersistor{blobPersistor} {}
|
|
305
|
+
|
|
306
|
+
#pragma region IResponseHandler
|
|
307
|
+
|
|
308
|
+
bool BlobModuleResponseHandler::Supports(string &responseType) /*override*/ {
|
|
309
|
+
return blobKeys.Blob == responseType;
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
msrn::JSValueObject BlobModuleResponseHandler::ToResponseData(vector<uint8_t> &&content) /*override*/ {
|
|
313
|
+
return {
|
|
314
|
+
{blobKeys.Offset, 0},
|
|
315
|
+
{blobKeys.Size, content.size()},
|
|
316
|
+
{blobKeys.BlobId, m_blobPersistor->StoreMessage(std::move(content))}};
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
#pragma endregion IResponseHandler
|
|
320
|
+
|
|
321
|
+
#pragma endregion BlobModuleResponseHandler
|
|
322
|
+
|
|
323
|
+
} // namespace Microsoft::React::Networking
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
// Copyright (c) Microsoft Corporation.
|
|
2
|
+
// Licensed under the MIT License.
|
|
3
|
+
|
|
4
|
+
#pragma once
|
|
5
|
+
|
|
6
|
+
#include "IBlobResource.h"
|
|
7
|
+
|
|
8
|
+
#include <IBlobPersistor.h>
|
|
9
|
+
#include <Modules/IRequestBodyHandler.h>
|
|
10
|
+
#include <Modules/IResponseHandler.h>
|
|
11
|
+
#include <Modules/IWebSocketModuleContentHandler.h>
|
|
12
|
+
|
|
13
|
+
// React Native Windows
|
|
14
|
+
#include <ReactPropertyBag.h>
|
|
15
|
+
|
|
16
|
+
// Boost Libraries
|
|
17
|
+
#include <boost/uuid/uuid_generators.hpp>
|
|
18
|
+
|
|
19
|
+
// Standard Library
|
|
20
|
+
#include <mutex>
|
|
21
|
+
#include <unordered_set>
|
|
22
|
+
|
|
23
|
+
namespace Microsoft::React::Networking {
|
|
24
|
+
|
|
25
|
+
class MemoryBlobPersistor final : public IBlobPersistor {
|
|
26
|
+
std::unordered_map<std::string, std::vector<uint8_t>> m_blobs;
|
|
27
|
+
std::mutex m_mutex;
|
|
28
|
+
boost::uuids::random_generator m_guidGenerator;
|
|
29
|
+
|
|
30
|
+
public:
|
|
31
|
+
#pragma region IBlobPersistor
|
|
32
|
+
|
|
33
|
+
winrt::array_view<uint8_t const> ResolveMessage(std::string &&blobId, int64_t offset, int64_t size) override;
|
|
34
|
+
|
|
35
|
+
void RemoveMessage(std::string &&blobId) noexcept override;
|
|
36
|
+
|
|
37
|
+
void StoreMessage(std::vector<uint8_t> &&message, std::string &&blobId) noexcept override;
|
|
38
|
+
|
|
39
|
+
std::string StoreMessage(std::vector<uint8_t> &&message) noexcept override;
|
|
40
|
+
|
|
41
|
+
#pragma endregion IBlobPersistor
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
class BlobWebSocketModuleContentHandler final : public IWebSocketModuleContentHandler {
|
|
45
|
+
std::unordered_set<int64_t> m_socketIds;
|
|
46
|
+
std::mutex m_mutex;
|
|
47
|
+
std::shared_ptr<IBlobPersistor> m_blobPersistor;
|
|
48
|
+
|
|
49
|
+
public:
|
|
50
|
+
BlobWebSocketModuleContentHandler(std::shared_ptr<IBlobPersistor> blobPersistor) noexcept;
|
|
51
|
+
|
|
52
|
+
#pragma region IWebSocketModuleContentHandler
|
|
53
|
+
|
|
54
|
+
void ProcessMessage(std::string &&message, winrt::Microsoft::ReactNative::JSValueObject ¶ms) noexcept override;
|
|
55
|
+
|
|
56
|
+
void ProcessMessage(std::vector<uint8_t> &&message, winrt::Microsoft::ReactNative::JSValueObject ¶ms) noexcept
|
|
57
|
+
override;
|
|
58
|
+
|
|
59
|
+
#pragma endregion IWebSocketModuleContentHandler
|
|
60
|
+
|
|
61
|
+
void Register(int64_t socketID) noexcept;
|
|
62
|
+
|
|
63
|
+
void Unregister(int64_t socketID) noexcept;
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
class BlobModuleRequestBodyHandler final : public IRequestBodyHandler {
|
|
67
|
+
std::shared_ptr<IBlobPersistor> m_blobPersistor;
|
|
68
|
+
|
|
69
|
+
public:
|
|
70
|
+
BlobModuleRequestBodyHandler(std::shared_ptr<IBlobPersistor> blobPersistor) noexcept;
|
|
71
|
+
|
|
72
|
+
#pragma region IRequestBodyHandler
|
|
73
|
+
|
|
74
|
+
bool Supports(winrt::Microsoft::ReactNative::JSValueObject &data) override;
|
|
75
|
+
|
|
76
|
+
winrt::Microsoft::ReactNative::JSValueObject ToRequestBody(
|
|
77
|
+
winrt::Microsoft::ReactNative::JSValueObject &data,
|
|
78
|
+
std::string &contentType) override;
|
|
79
|
+
|
|
80
|
+
#pragma endregion IRequestBodyHandler
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
class BlobModuleResponseHandler final : public IResponseHandler {
|
|
84
|
+
std::shared_ptr<IBlobPersistor> m_blobPersistor;
|
|
85
|
+
|
|
86
|
+
public:
|
|
87
|
+
BlobModuleResponseHandler(std::shared_ptr<IBlobPersistor> blobPersistor) noexcept;
|
|
88
|
+
|
|
89
|
+
#pragma region IResponseHandler
|
|
90
|
+
|
|
91
|
+
bool Supports(std::string &responseType) override;
|
|
92
|
+
|
|
93
|
+
winrt::Microsoft::ReactNative::JSValueObject ToResponseData(std::vector<uint8_t> &&content) override;
|
|
94
|
+
|
|
95
|
+
#pragma endregion IResponseHandler
|
|
96
|
+
};
|
|
97
|
+
|
|
98
|
+
class DefaultBlobResource : public IBlobResource, public std::enable_shared_from_this<DefaultBlobResource> {
|
|
99
|
+
std::shared_ptr<MemoryBlobPersistor> m_blobPersistor;
|
|
100
|
+
std::shared_ptr<BlobWebSocketModuleContentHandler> m_contentHandler;
|
|
101
|
+
std::shared_ptr<BlobModuleRequestBodyHandler> m_requestBodyHandler;
|
|
102
|
+
std::shared_ptr<BlobModuleResponseHandler> m_responseHandler;
|
|
103
|
+
winrt::Microsoft::ReactNative::ReactPropertyBag m_propertyBag;
|
|
104
|
+
BlobCallbacks m_callbacks;
|
|
105
|
+
|
|
106
|
+
public:
|
|
107
|
+
DefaultBlobResource(
|
|
108
|
+
std::shared_ptr<MemoryBlobPersistor> blobPersistor,
|
|
109
|
+
std::shared_ptr<BlobWebSocketModuleContentHandler> contentHandler,
|
|
110
|
+
std::shared_ptr<BlobModuleRequestBodyHandler> requestBodyHandler,
|
|
111
|
+
std::shared_ptr<BlobModuleResponseHandler> responseHandler,
|
|
112
|
+
winrt::Microsoft::ReactNative::ReactPropertyBag propertyBag);
|
|
113
|
+
|
|
114
|
+
#pragma region IBlobResource
|
|
115
|
+
|
|
116
|
+
void SendOverSocket(std::string &&blobId, int64_t offset, int64_t size, int64_t socketId) noexcept override;
|
|
117
|
+
|
|
118
|
+
void CreateFromParts(winrt::Microsoft::ReactNative::JSValueArray &&parts, std::string &&blobId) noexcept override;
|
|
119
|
+
|
|
120
|
+
void Release(std::string &&blobId) noexcept override;
|
|
121
|
+
|
|
122
|
+
void AddNetworkingHandler() noexcept override;
|
|
123
|
+
|
|
124
|
+
void AddWebSocketHandler(int64_t id) noexcept override;
|
|
125
|
+
|
|
126
|
+
void RemoveWebSocketHandler(int64_t id) noexcept override;
|
|
127
|
+
|
|
128
|
+
BlobCallbacks &Callbacks() noexcept override;
|
|
129
|
+
|
|
130
|
+
#pragma endregion IBlobResource
|
|
131
|
+
};
|
|
132
|
+
|
|
133
|
+
} // namespace Microsoft::React::Networking
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
// Copyright (c) Microsoft Corporation.
|
|
2
|
+
// Licensed under the MIT License.
|
|
3
|
+
|
|
4
|
+
#pragma once
|
|
5
|
+
|
|
6
|
+
#include <IBlobPersistor.h>
|
|
7
|
+
|
|
8
|
+
// React Native Windows
|
|
9
|
+
#include <JSValue.h>
|
|
10
|
+
|
|
11
|
+
// Windows API
|
|
12
|
+
#include <winrt/Windows.Foundation.h>
|
|
13
|
+
|
|
14
|
+
// Standard Library
|
|
15
|
+
#include <functional>
|
|
16
|
+
#include <memory>
|
|
17
|
+
#include <string>
|
|
18
|
+
|
|
19
|
+
namespace Microsoft::React::Networking {
|
|
20
|
+
|
|
21
|
+
struct IBlobResource {
|
|
22
|
+
struct BlobCallbacks {
|
|
23
|
+
std::function<void(std::string &&errorText)> OnError;
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
struct BlobFieldNames {
|
|
27
|
+
const char *Blob;
|
|
28
|
+
const char *BlobId;
|
|
29
|
+
const char *Offset;
|
|
30
|
+
const char *Size;
|
|
31
|
+
const char *Type;
|
|
32
|
+
const char *Data;
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
static std::shared_ptr<IBlobResource> Make(winrt::Windows::Foundation::IInspectable const &inspectableProperties);
|
|
36
|
+
|
|
37
|
+
static const BlobFieldNames &FieldNames() noexcept;
|
|
38
|
+
|
|
39
|
+
virtual ~IBlobResource() noexcept {}
|
|
40
|
+
|
|
41
|
+
virtual void SendOverSocket(std::string &&blobId, int64_t offset, int64_t size, int64_t socketId) noexcept = 0;
|
|
42
|
+
|
|
43
|
+
virtual void CreateFromParts(winrt::Microsoft::ReactNative::JSValueArray &&parts, std::string &&blobId) noexcept = 0;
|
|
44
|
+
|
|
45
|
+
virtual void Release(std::string &&blobId) noexcept = 0;
|
|
46
|
+
|
|
47
|
+
virtual void AddNetworkingHandler() noexcept = 0;
|
|
48
|
+
|
|
49
|
+
virtual void AddWebSocketHandler(int64_t id) noexcept = 0;
|
|
50
|
+
|
|
51
|
+
virtual void RemoveWebSocketHandler(int64_t id) noexcept = 0;
|
|
52
|
+
|
|
53
|
+
virtual BlobCallbacks &Callbacks() noexcept = 0;
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
} // namespace Microsoft::React::Networking
|
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
|
|
4
4
|
#pragma once
|
|
5
5
|
|
|
6
|
-
//
|
|
7
|
-
#include <
|
|
6
|
+
// React Native Windows
|
|
7
|
+
#include <JSValue.h>
|
|
8
8
|
|
|
9
9
|
// Windows API
|
|
10
10
|
#include <winrt/Windows.Foundation.h>
|
|
@@ -20,7 +20,6 @@ namespace Microsoft::React::Networking {
|
|
|
20
20
|
struct IHttpResource {
|
|
21
21
|
typedef std::unordered_map<std::string, std::string> Headers;
|
|
22
22
|
|
|
23
|
-
// TODO: Implement Form data
|
|
24
23
|
struct BodyData {
|
|
25
24
|
enum class Type : size_t { Empty, String, Base64, Uri, Form } Type = Type::Empty;
|
|
26
25
|
std::string Data;
|
|
@@ -81,7 +80,7 @@ struct IHttpResource {
|
|
|
81
80
|
std::string &&url,
|
|
82
81
|
int64_t requestId,
|
|
83
82
|
Headers &&headers,
|
|
84
|
-
|
|
83
|
+
winrt::Microsoft::ReactNative::JSValueObject &&data,
|
|
85
84
|
std::string &&responseType,
|
|
86
85
|
bool useIncrementalUpdates,
|
|
87
86
|
int64_t timeout,
|
|
@@ -146,7 +145,9 @@ struct IHttpResource {
|
|
|
146
145
|
/// Structured response content payload (i.e. Blob data)
|
|
147
146
|
/// </param>
|
|
148
147
|
/// </param>
|
|
149
|
-
virtual void SetOnData(
|
|
148
|
+
virtual void SetOnData(
|
|
149
|
+
std::function<void(int64_t requestId, winrt::Microsoft::ReactNative::JSValueObject &&responseData)>
|
|
150
|
+
&&handler) noexcept = 0;
|
|
150
151
|
|
|
151
152
|
/// <summary>
|
|
152
153
|
/// Sets a function to be invoked when a response content increment has been received.
|