Skip to content

Commit bf25767

Browse files
committed
Implement Blob module (microsoft#9352)
* Added BlobModule and IWSModuleContHandler headers * Implement Blob module * Avoid raw self pointer in BlobModule * Implement WebSocketModule msg processing * clang format * Don't return until websocketMessage event is sent * Define CreateBlobModule() * Add DEF exports * Add Blob JS tests * Add Blob JS tests * Change files * yarn lint * Add overrides * Register BlobModule in DesktopTestRunner * Keep ignoring WebSocketBlob test by default * Add BlobModule to default modules list * Allow 'blob' responseType in HTTP module * Ensure React Instance can be accessed when using older versions of react-native * Emit error message on createFromParts failure * Remove redundant extra modules in Desktop integration tests * Declare IWebSocketModuleProxy * Remove Blob and WS module factories from DLL boundary * Implement IWebSocketModuleProxy * clang format * Update packages.lock * Use winrt::array_view directly in ResolveMessage * Define InstanceImpl::m_transitionalModuleProperties * Include CreateModules.h in projects accessing MSRN.Cxx * Define WinRT class WebSocketModuleContentHandler - Have BlobModule constructor register the content handler in transitive property bag CxxNativeModule/WebSocketModuleContentHandler * Have WebSocketModule use IInspectable as props arg * Use property bag instead of global singletons for blob helpers * Store blob helpers in prop bag as weak_ptr * Replace remaining lock_guard<mutex> in BlobModule * Define IUriHandler, IReqBodyHandler, IRespHandler. * IHttpResource::SendRequest - add folly::dynamic data arg * Add data arg to test SendRequest calls * First implementation for BlobModuleUriHandler * Remove WebSocketModuleContentHandler WinRT class * Implement IBlobPersistor, MemoryBlobPersistor * clang format * Update yarn.lock * Update RctRootVieTagGen location * Implement addNetworkingHandler * Fix createFromParts buffer persistence * Drop WebSocketModule s_sharedState in favor of property bag * Disable back WebSocketBlob test * Rename iProperties to inspectableProperties * Pass ReactContext properties to CreateHttpModule in InstanceWin * Remove WebSocketModule constructor from x86 DLL boundary * yarn lint * Update packages.lock * Make transitional property bag non-member * Use blobURIScheme wherever possible * Pass request content as folly::dynaic. - Pass request ID directly from JavaScript layer. * Use constexpr for folly indexes * Implement GetMimeTypeFromUri * Finish BlobModule handler implementations. * Remove unused includes * Ensure HttpModule::m_resource is set * clang format * clang format * Allow blob responseType * Use winrt::to_hstring instead of Utf8ToUtf16 * Pass inspectableProperties down to WinRTHttpResource * Implement IHttpModuleProxy via WinRTHttpResource * Consume URI handler - IHttpResource - Rename SetOnRequest to SetOnRequestSuccess - Declare SetOnBlobData to pass complex (non-string) response data * Consume IRequestBodyHandler * Consume IResponseHandler * Ensure properties exist in bag before using value * Update packages lock * Add missing call to Modules::SendEvent * Fix Shared filters * Rename SetOnBlobData to SetOnData (different args) * Correctly retrieve blob slices * Correctly retrieve blob slices * Clang format * Update project filters * Drop BlobModuleUriHandler * Continue handling requests when not blob-supported * Add BlobTest * Update packages.lock.json * Define FileReaderModule * Implement FileReaderModule * Complete BlobTest * Make IBlobPersistor::ResolveMessage throw std::invalid_argument * Fail on Content-Encoding parsing even if no error handler * Remove MIME mappings. Currently unused * MemoryBlobPersistor::ResolveMessage throw on out of bounds * lint * Enable BlobTest by default * Disable Blob test in CI (may hang)
1 parent 2a5fc3e commit bf25767

6 files changed

Lines changed: 678 additions & 605 deletions

File tree

vnext/Microsoft.ReactNative.Managed.UnitTests/packages.lock.json

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -81,10 +81,25 @@
8181
"resolved": "1.0.1",
8282
"contentHash": "rkn+fKobF/cbWfnnfBOQHKVKIOpxMZBvlSHkqDWgBpwGDcLRduvs3D9OLGeV6GWGvVwNlVi2CBbTjuPmtHvyNw=="
8383
},
84+
"Microsoft.UI.Xaml": {
85+
"type": "Transitive",
86+
"resolved": "2.7.0",
87+
"contentHash": "dB4im13tfmMgL/V3Ei+3kD2rUF+/lTxAmR4gjJ45l577eljHfdo/KUrxpq/3I1Vp6e5GCDG1evDaEGuDxypLMg=="
88+
},
89+
"Microsoft.Windows.CppWinRT": {
90+
"type": "Transitive",
91+
"resolved": "2.0.211028.7",
92+
"contentHash": "JBGI0c3WLoU6aYJRy9Qo0MLDQfObEp+d4nrhR95iyzf7+HOgjRunHDp/6eGFREd7xq3OI1mll9ecJrMfzBvlyg=="
93+
},
94+
"Microsoft.Windows.SDK.BuildTools": {
95+
"type": "Transitive",
96+
"resolved": "10.0.22000.194",
97+
"contentHash": "4L0P3zqut466SIqT3VBeLTNUQTxCBDOrTRymRuROCRJKazcK7ibLz9yAO1nKWRt50ttCj39oAa2Iuz9ZTDmLlg=="
98+
},
8499
"NETStandard.Library": {
85100
"type": "Transitive",
86101
"resolved": "2.0.3",
87-
"contentHash": "st47PosZSHrjECdjeIzZQbzivYBJFv6P2nv4cj2ypdI204DO+vZ7l5raGMiX4eXMJ53RfOIg+/s4DHVZ54Nu2A==",
102+
"contentHash": "548M6mnBSJWxsIlkQHfbzoYxpiYFXZZSL00p4GHYv8PkiqFBnnT68mW5mGEsA/ch9fDO9GkPgkFQpWiXZN7mAQ==",
88103
"dependencies": {
89104
"Microsoft.NETCore.Platforms": "1.1.0"
90105
}
@@ -1790,4 +1805,4 @@
17901805
}
17911806
}
17921807
}
1793-
}
1808+
}

vnext/Microsoft.ReactNative.Managed/packages.lock.json

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,11 @@
2424
"Microsoft.SourceLink.Common": "1.0.0"
2525
}
2626
},
27+
"boost": {
28+
"type": "Transitive",
29+
"resolved": "1.76.0",
30+
"contentHash": "p+w3YvNdXL8Cu9Fzrmexssu0tZbWxuf6ywsQqHjDlKFE5ojXHof1HIyMC3zDLfLnh80dIeFcEUAuR2Asg/XHRA=="
31+
},
2732
"Microsoft.Build.Tasks.Git": {
2833
"type": "Transitive",
2934
"resolved": "1.0.0",
@@ -60,14 +65,34 @@
6065
"resolved": "1.0.0",
6166
"contentHash": "G8DuQY8/DK5NN+3jm5wcMcd9QYD90UV7MiLmdljSJixi3U/vNaeBKmmXUqI4DJCOeWizIUEh4ALhSt58mR+5eg=="
6267
},
68+
"Microsoft.UI.Xaml": {
69+
"type": "Transitive",
70+
"resolved": "2.7.0",
71+
"contentHash": "dB4im13tfmMgL/V3Ei+3kD2rUF+/lTxAmR4gjJ45l577eljHfdo/KUrxpq/3I1Vp6e5GCDG1evDaEGuDxypLMg=="
72+
},
73+
"Microsoft.Windows.CppWinRT": {
74+
"type": "Transitive",
75+
"resolved": "2.0.211028.7",
76+
"contentHash": "JBGI0c3WLoU6aYJRy9Qo0MLDQfObEp+d4nrhR95iyzf7+HOgjRunHDp/6eGFREd7xq3OI1mll9ecJrMfzBvlyg=="
77+
},
78+
"Microsoft.Windows.SDK.BuildTools": {
79+
"type": "Transitive",
80+
"resolved": "10.0.22000.194",
81+
"contentHash": "4L0P3zqut466SIqT3VBeLTNUQTxCBDOrTRymRuROCRJKazcK7ibLz9yAO1nKWRt50ttCj39oAa2Iuz9ZTDmLlg=="
82+
},
6383
"NETStandard.Library": {
6484
"type": "Transitive",
6585
"resolved": "2.0.3",
66-
"contentHash": "st47PosZSHrjECdjeIzZQbzivYBJFv6P2nv4cj2ypdI204DO+vZ7l5raGMiX4eXMJ53RfOIg+/s4DHVZ54Nu2A==",
86+
"contentHash": "548M6mnBSJWxsIlkQHfbzoYxpiYFXZZSL00p4GHYv8PkiqFBnnT68mW5mGEsA/ch9fDO9GkPgkFQpWiXZN7mAQ==",
6787
"dependencies": {
6888
"Microsoft.NETCore.Platforms": "1.1.0"
6989
}
7090
},
91+
"ReactNative.Hermes.Windows": {
92+
"type": "Transitive",
93+
"resolved": "0.11.0-ms.6",
94+
"contentHash": "WAVLsSZBV4p/3hNC3W67su7xu3f/ZMSKxu0ON7g2GaKRbkJmH0Qyif1IlzcJwtvR48kuOdfgPu7Bgtz3AY+gqg=="
95+
},
7196
"runtime.win10-arm.Microsoft.Net.Native.Compiler": {
7297
"type": "Transitive",
7398
"resolved": "2.2.7-rel-27913-00",
@@ -303,4 +328,4 @@
303328
}
304329
}
305330
}
306-
}
331+
}

vnext/Shared/Networking/WinRTHttpResource.cpp

Lines changed: 31 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ namespace Microsoft::React::Networking {
6868
bool withCredentials,
6969
std::function<void(int64_t)>&& callback) noexcept /*override*/ {
7070
// Enforce supported args
71-
assert(responseType == "text" || responseType == "base64" || responseType == "blob");
71+
assert(responseType == "text" || responseType == "base64" | responseType == "blob");
7272

7373
if (callback) {
7474
callback(requestId);
@@ -131,8 +131,8 @@ namespace Microsoft::React::Networking {
131131
// NOT IMPLEMENTED
132132
}
133133

134-
void WinRTHttpResource::SetOnRequestSuccess(function<void(int64_t requestId)>&& handler) noexcept /*override*/ {
135-
m_onRequestSuccess = std::move(handler);
134+
void WinRTHttpResource::SetOnRequestSuccessSuccess(function<void(int64_t requestId)>&& handler) noexcept /*override*/ {
135+
m_onRequestSuccessSuccess = std::move(handler);
136136
}
137137

138138
void WinRTHttpResource::SetOnResponse(function<void(int64_t requestId, Response&& response)>&& handler) noexcept
@@ -151,6 +151,12 @@ namespace Microsoft::React::Networking {
151151
m_onDataDynamic = std::move(handler);
152152
}
153153

154+
void WinRTHttpResource::SetOnData(function<void(int64_t requestId, dynamic&& responseData)>&& handler) noexcept
155+
/*override*/
156+
{
157+
m_onDataDynamic = std::move(handler);
158+
}
159+
154160
void WinRTHttpResource::SetOnError(function<void(int64_t requestId, string&& errorMessage)>&& handler) noexcept
155161
/*override*/ {
156162
m_onError = std::move(handler);
@@ -349,7 +355,27 @@ namespace Microsoft::React::Networking {
349355
auto inputStream = co_await response.Content().ReadAsInputStreamAsync();
350356
auto reader = DataReader{ inputStream };
351357

352-
if (coReqArgs->IsText) {
358+
// #9510 - 10mb limit on fetch
359+
co_await reader.LoadAsync(10 * 1024 * 1024);
360+
361+
// Let response handler take over, if set
362+
if (auto responseHandler = self->m_responseHandler.lock()) {
363+
if (responseHandler->Supports(coReqArgs->ResponseType)) {
364+
auto bytes = vector<uint8_t>(reader.UnconsumedBufferLength());
365+
reader.ReadBytes(bytes);
366+
auto blob = responseHandler->ToResponseData(std::move(bytes));
367+
368+
if (self->m_onDataDynamic && self->m_onRequestSuccess) {
369+
self->m_onDataDynamic(coReqArgs->RequestId, std::move(blob));
370+
self->m_onRequestSuccess(coReqArgs->RequestId);
371+
}
372+
373+
co_return;
374+
}
375+
}
376+
377+
auto isText = coReqArgs->ResponseType == "text";
378+
if (isText) {
353379
reader.UnicodeEncoding(UnicodeEncoding::Utf8);
354380
}
355381

@@ -362,7 +388,7 @@ namespace Microsoft::React::Networking {
362388
co_await reader.LoadAsync(segmentSize);
363389
length = reader.UnconsumedBufferLength();
364390

365-
if (coReqArgs->IsText) {
391+
if (isText) {
366392
auto data = std::vector<uint8_t>(length);
367393
reader.ReadBytes(data);
368394

0 commit comments

Comments
 (0)