react-native-windows 0.74.7 → 0.74.9

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.
Files changed (49) hide show
  1. package/Libraries/ReactNative/AppContainer-dev.js +3 -2
  2. package/Libraries/ReactNative/AppContainer-prod.js +2 -1
  3. package/Libraries/ReactNative/AppContainer.js +2 -0
  4. package/Libraries/ReactNative/AppRegistry.d.ts +7 -0
  5. package/Libraries/ReactNative/AppRegistry.js +8 -0
  6. package/Libraries/ReactNative/renderApplication.js +3 -0
  7. package/Microsoft.ReactNative/AsynchronousEventBeat.cpp +1 -2
  8. package/Microsoft.ReactNative/CompositionHwndHost.idl +1 -1
  9. package/Microsoft.ReactNative/Fabric/Composition/CompositionEventHandler.cpp +18 -18
  10. package/Microsoft.ReactNative/Fabric/Composition/CompositionEventHandler.h +2 -2
  11. package/Microsoft.ReactNative/Fabric/Composition/CompositionHwndHost.cpp +4 -4
  12. package/Microsoft.ReactNative/Fabric/Composition/CompositionHwndHost.h +1 -1
  13. package/Microsoft.ReactNative/Fabric/Composition/CompositionRootAutomationProvider.cpp +3 -3
  14. package/Microsoft.ReactNative/Fabric/Composition/CompositionRootAutomationProvider.h +3 -3
  15. package/Microsoft.ReactNative/Fabric/Composition/CompositionViewComponentView.cpp +5 -5
  16. package/Microsoft.ReactNative/Fabric/Composition/{CompositionRootView.cpp → ReactNativeIsland.cpp} +59 -51
  17. package/Microsoft.ReactNative/Fabric/Composition/{CompositionRootView.h → ReactNativeIsland.h} +8 -8
  18. package/Microsoft.ReactNative/Fabric/Composition/RootComponentView.cpp +7 -8
  19. package/Microsoft.ReactNative/Fabric/Composition/RootComponentView.h +2 -2
  20. package/Microsoft.ReactNative/Fabric/Composition/TextInput/WindowsTextInputComponentView.cpp +2 -2
  21. package/Microsoft.ReactNative/Fabric/Composition/UriImageManager.cpp +82 -17
  22. package/Microsoft.ReactNative/Fabric/Composition/UriImageManager.h +79 -0
  23. package/Microsoft.ReactNative/Fabric/FabricUIManagerModule.cpp +2 -2
  24. package/Microsoft.ReactNative/Fabric/FabricUIManagerModule.h +3 -3
  25. package/Microsoft.ReactNative/Fabric/WindowsImageManager.cpp +191 -119
  26. package/Microsoft.ReactNative/Fabric/WindowsImageManager.h +11 -0
  27. package/Microsoft.ReactNative/HttpSettings.idl +19 -0
  28. package/Microsoft.ReactNative/Modules/ImageViewManagerModule.cpp +15 -11
  29. package/Microsoft.ReactNative/{CompositionRootView.idl → ReactNativeIsland.idl} +10 -10
  30. package/Microsoft.ReactNative/UriImageManager.idl +35 -17
  31. package/Microsoft.ReactNative/Utils/ImageUtils.cpp +22 -3
  32. package/Microsoft.ReactNative/Utils/ImageUtils.h +3 -1
  33. package/Microsoft.ReactNative/Views/Image/ImageViewManager.cpp +1 -1
  34. package/Microsoft.ReactNative/Views/Image/ReactImage.cpp +13 -4
  35. package/Microsoft.ReactNative/Views/Image/ReactImage.h +4 -2
  36. package/PropertySheets/Generated/PackageVersion.g.props +3 -3
  37. package/Shared/Modules/FileReaderModule.cpp +3 -4
  38. package/Shared/Modules/WebSocketModule.cpp +14 -16
  39. package/Shared/Networking/DefaultBlobResource.cpp +6 -14
  40. package/Shared/Networking/NetworkPropertyIds.cpp +60 -0
  41. package/Shared/Networking/NetworkPropertyIds.h +41 -0
  42. package/Shared/Networking/RedirectHttpFilter.cpp +18 -9
  43. package/Shared/Networking/RedirectHttpFilter.h +6 -3
  44. package/Shared/Networking/WinRTHttpResource.cpp +36 -8
  45. package/Shared/Networking/WinRTHttpResource.h +17 -0
  46. package/Shared/Shared.vcxitems +6 -4
  47. package/Shared/Shared.vcxitems.filters +5 -3
  48. package/package.json +1 -1
  49. package/templates/cpp-app/windows/MyApp/MyApp.cpp +2 -2
@@ -4,6 +4,8 @@
4
4
  #include "pch.h"
5
5
  #include "ImageUtils.h"
6
6
 
7
+ #include <CppRuntimeOptions.h>
8
+ #include <Networking/NetworkPropertyIds.h>
7
9
  #include <Shared/cdebug.h>
8
10
  #include <Utils/CppWinrtLessExceptions.h>
9
11
  #include <windows.Web.Http.h>
@@ -19,7 +21,9 @@ using namespace Windows::Web::Http;
19
21
 
20
22
  namespace Microsoft::ReactNative {
21
23
 
22
- winrt::IAsyncOperation<winrt::IRandomAccessStream> GetImageStreamAsync(ReactImageSource source) {
24
+ winrt::IAsyncOperation<winrt::IRandomAccessStream> GetImageStreamAsync(
25
+ winrt::Microsoft::ReactNative::IReactPropertyBag properties,
26
+ ReactImageSource source) {
23
27
  try {
24
28
  co_await winrt::resume_background();
25
29
 
@@ -66,6 +70,19 @@ winrt::IAsyncOperation<winrt::IRandomAccessStream> GetImageStreamAsync(ReactImag
66
70
 
67
71
  winrt::HttpRequestMessage request{httpMethod, uri};
68
72
 
73
+ // Ideally we'd just set m_httpClient.DefaultRequestHeaders().UserAgent().ParseAdd(m_defaultUserAgent), but when we
74
+ // do we start hitting E_STATE_CHANGED errors. Which appears to be this issue
75
+ // https://github.com/MicrosoftDocs/winrt-api/issues/2410 So instead we apply the header to each request
76
+ auto userAgent = Microsoft::React::GetRuntimeOptionString("Http.UserAgent");
77
+ if (userAgent.size() > 0) {
78
+ request.Headers().Append(L"User-Agent", winrt::to_hstring(userAgent));
79
+ } else {
80
+ if (auto userAgentProp = winrt::Microsoft::ReactNative::ReactPropertyBag(properties)
81
+ .Get(::Microsoft::React::DefaultUserAgentPropertyId())) {
82
+ request.Headers().Append(L"User-Agent", winrt::to_hstring(*userAgentProp));
83
+ }
84
+ }
85
+
69
86
  if (!source.headers.empty()) {
70
87
  for (auto &header : source.headers) {
71
88
  if (_stricmp(header.first.c_str(), "authorization") == 0) {
@@ -161,10 +178,12 @@ winrt::IAsyncOperation<winrt::IRandomAccessStream> GetImageInlineDataAsync(React
161
178
  co_return nullptr;
162
179
  }
163
180
 
164
- winrt::IAsyncOperation<winrt::IRandomAccessStream> GetImageMemoryStreamAsync(ReactImageSource source) {
181
+ winrt::IAsyncOperation<winrt::IRandomAccessStream> GetImageMemoryStreamAsync(
182
+ winrt::Microsoft::ReactNative::IReactPropertyBag properties,
183
+ ReactImageSource source) {
165
184
  switch (source.sourceType) {
166
185
  case ImageSourceType::Download:
167
- co_return co_await GetImageStreamAsync(source);
186
+ co_return co_await GetImageStreamAsync(properties, source);
168
187
  case ImageSourceType::InlineData:
169
188
  co_return co_await GetImageInlineDataAsync(source);
170
189
  default: // ImageSourceType::Uri
@@ -2,6 +2,7 @@
2
2
  // Licensed under the MIT License.
3
3
 
4
4
  #pragma once
5
+ #include <ReactContext.h>
5
6
  #include <winrt/Windows.Storage.Streams.h>
6
7
  #include <string>
7
8
 
@@ -23,9 +24,10 @@ struct ReactImageSource {
23
24
  };
24
25
 
25
26
  winrt::Windows::Foundation::IAsyncOperation<winrt::Windows::Storage::Streams::IRandomAccessStream>
26
- GetImageMemoryStreamAsync(ReactImageSource source);
27
+ GetImageMemoryStreamAsync(winrt::Microsoft::ReactNative::IReactPropertyBag properties, ReactImageSource source);
27
28
 
28
29
  winrt::Windows::Foundation::IAsyncOperation<winrt::Windows::Storage::Streams::IRandomAccessStream> GetImageStreamAsync(
30
+ winrt::Microsoft::ReactNative::IReactPropertyBag properties,
29
31
  ReactImageSource source);
30
32
 
31
33
  winrt::Windows::Foundation::IAsyncOperation<winrt::Windows::Storage::Streams::IRandomAccessStream>
@@ -114,7 +114,7 @@ const wchar_t *ImageViewManager::GetName() const {
114
114
  }
115
115
 
116
116
  XamlView ImageViewManager::CreateViewCore(int64_t /*tag*/, const winrt::Microsoft::ReactNative::JSValueObject &) {
117
- return ReactImage::Create().as<winrt::Grid>();
117
+ return ReactImage::Create(GetReactContext()).as<winrt::Grid>();
118
118
  }
119
119
 
120
120
  ShadowNode *ImageViewManager::createShadow() const {
@@ -12,6 +12,7 @@
12
12
  #include <winrt/Windows.Web.Http.Headers.h>
13
13
  #include <winrt/Windows.Web.Http.h>
14
14
 
15
+ #include <Networking/NetworkPropertyIds.h>
15
16
  #include <Views/DynamicAutomationPeer.h>
16
17
  #include "Unicode.h"
17
18
  #include "XamlView.h"
@@ -32,8 +33,10 @@ using Microsoft::Common::Unicode::Utf8ToUtf16;
32
33
 
33
34
  namespace Microsoft::ReactNative {
34
35
 
35
- /*static*/ winrt::com_ptr<ReactImage> ReactImage::Create() {
36
- auto reactImage = winrt::make_self<ReactImage>();
36
+ ReactImage::ReactImage(const Mso::React::IReactContext &context) : m_reactContext(&context) {}
37
+
38
+ /*static*/ winrt::com_ptr<ReactImage> ReactImage::Create(const Mso::React::IReactContext &context) {
39
+ auto reactImage = winrt::make_self<ReactImage>(context);
37
40
  // Grid inherits the layout direction from parent and mirrors the background image in RTL mode.
38
41
  // Forcing the container to LTR mode to avoid the unexpected mirroring behavior.
39
42
  reactImage->FlowDirection(xaml::FlowDirection::LeftToRight);
@@ -162,7 +165,12 @@ void ReactImage::Source(ReactImageSource source) {
162
165
  winrt::hstring scheme{uri ? uri.SchemeName() : L""};
163
166
  winrt::hstring ext{uri ? uri.Extension() : L""};
164
167
 
165
- if (((scheme == L"http") || (scheme == L"https")) && !source.headers.empty()) {
168
+ // Xaml default image handling can handle http/https uris. However it will not use the specified headers in its
169
+ // request. If this image is using custom headers, or if we have a custom user-agent, then we have to download the
170
+ // image manually.
171
+ bool customUserAgent = !!winrt::Microsoft::ReactNative::ReactPropertyBag(m_reactContext->Properties())
172
+ .Get(Microsoft::React::DefaultUserAgentPropertyId());
173
+ if (((scheme == L"http") || (scheme == L"https")) && (customUserAgent || !source.headers.empty())) {
166
174
  source.sourceType = ImageSourceType::Download;
167
175
  } else if (scheme == L"data") {
168
176
  source.sourceType = ImageSourceType::InlineData;
@@ -237,7 +245,8 @@ winrt::fire_and_forget ReactImage::SetBackground(bool fireLoadEndEvent) {
237
245
 
238
246
  try {
239
247
  if (fromStream) {
240
- memoryStream = co_await GetImageMemoryStreamAsync(source);
248
+ auto properties = m_reactContext->Properties();
249
+ memoryStream = co_await GetImageMemoryStreamAsync(properties, source);
241
250
 
242
251
  // Fire failed load event if we're not loading from URI and the memory stream is null.
243
252
  if (!memoryStream) {
@@ -9,6 +9,7 @@
9
9
  #include <UI.Xaml.Controls.h>
10
10
 
11
11
  #include <JSValue.h>
12
+ #include <React.h>
12
13
  #include <Utils/ImageUtils.h>
13
14
  #include <folly/dynamic.h>
14
15
 
@@ -17,10 +18,10 @@ namespace Microsoft::ReactNative {
17
18
  struct ReactImage : xaml::Controls::GridT<ReactImage> {
18
19
  using Super = xaml::Controls::GridT<ReactImage>;
19
20
 
20
- ReactImage() = default;
21
+ ReactImage(const Mso::React::IReactContext &context);
21
22
 
22
23
  public:
23
- static winrt::com_ptr<ReactImage> Create();
24
+ static winrt::com_ptr<ReactImage> Create(const Mso::React::IReactContext &context);
24
25
 
25
26
  // Overrides
26
27
  winrt::Windows::Foundation::Size ArrangeOverride(winrt::Windows::Foundation::Size finalSize);
@@ -59,6 +60,7 @@ struct ReactImage : xaml::Controls::GridT<ReactImage> {
59
60
  double GetHeight();
60
61
 
61
62
  bool m_useCompositionBrush{false};
63
+ Mso::CntPtr<const Mso::React::IReactContext> m_reactContext;
62
64
  float m_blurRadius{0};
63
65
  int m_imageSourceId{0};
64
66
  ReactImageSource m_imageSource;
@@ -10,11 +10,11 @@
10
10
  -->
11
11
  <Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
12
12
  <PropertyGroup>
13
- <ReactNativeWindowsVersion>0.74.7</ReactNativeWindowsVersion>
13
+ <ReactNativeWindowsVersion>0.74.9</ReactNativeWindowsVersion>
14
14
  <ReactNativeWindowsMajor>0</ReactNativeWindowsMajor>
15
15
  <ReactNativeWindowsMinor>74</ReactNativeWindowsMinor>
16
- <ReactNativeWindowsPatch>7</ReactNativeWindowsPatch>
16
+ <ReactNativeWindowsPatch>9</ReactNativeWindowsPatch>
17
17
  <ReactNativeWindowsCanary>false</ReactNativeWindowsCanary>
18
- <ReactNativeWindowsCommitId>92b63ecf09a8f2c61a3c972e76bfdb535707d87b</ReactNativeWindowsCommitId>
18
+ <ReactNativeWindowsCommitId>9efa2f6851a90be02d599f18a224bf6c89032409</ReactNativeWindowsCommitId>
19
19
  </PropertyGroup>
20
20
  </Project>
@@ -5,6 +5,7 @@
5
5
 
6
6
  #include <CreateModules.h>
7
7
  #include <ReactPropertyBag.h>
8
+ #include "Networking/NetworkPropertyIds.h"
8
9
 
9
10
  // React Native
10
11
  #include <cxxreact/JsArgumentHelpers.h>
@@ -113,9 +114,8 @@ std::vector<module::CxxModule::Method> FileReaderModule::getMethods() {
113
114
  #pragma region FileReaderTurboModule
114
115
 
115
116
  void FileReaderTurboModule::Initialize(msrn::ReactContext const &reactContext) noexcept {
116
- auto propId = msrn::ReactPropertyId<msrn::ReactNonAbiValue<weak_ptr<IBlobPersistor>>>{L"Blob.Persistor"};
117
117
  auto props = reactContext.Properties();
118
- auto prop = props.Get(propId);
118
+ auto prop = props.Get(BlobModulePersistorPropertyId());
119
119
  m_resource = IFileReaderResource::Make(prop.Value());
120
120
  }
121
121
 
@@ -195,10 +195,9 @@ void FileReaderTurboModule::ReadAsText(
195
195
 
196
196
  /*extern*/ std::unique_ptr<module::CxxModule> CreateFileReaderModule(
197
197
  IInspectable const &inspectableProperties) noexcept {
198
- auto propId = msrn::ReactPropertyId<msrn::ReactNonAbiValue<weak_ptr<IBlobPersistor>>>{L"Blob.Persistor"};
199
198
  auto propBag = msrn::ReactPropertyBag{inspectableProperties.try_as<msrn::IReactPropertyBag>()};
200
199
 
201
- if (auto prop = propBag.Get(propId)) {
200
+ if (auto prop = propBag.Get(BlobModulePersistorPropertyId())) {
202
201
  auto weakBlobPersistor = prop.Value();
203
202
 
204
203
  return std::make_unique<FileReaderModule>(weakBlobPersistor);
@@ -10,6 +10,7 @@
10
10
  #include <Modules/CxxModuleUtilities.h>
11
11
  #include <Modules/IWebSocketModuleContentHandler.h>
12
12
  #include <ReactPropertyBag.h>
13
+ #include "Networking/NetworkPropertyIds.h"
13
14
 
14
15
  // fmt
15
16
  #include <fmt/format.h>
@@ -52,12 +53,16 @@ using Microsoft::React::Networking::IWebSocketResource;
52
53
 
53
54
  constexpr char s_moduleName[] = "WebSocketModule";
54
55
  constexpr wchar_t s_moduleNameW[] = L"WebSocketModule";
55
- constexpr wchar_t s_proxyNameW[] = L"WebSocketModule.Proxy";
56
- constexpr wchar_t s_sharedStateNameW[] = L"WebSocketModule.SharedState";
57
- constexpr wchar_t s_contentHandlerNameW[] = L"BlobModule.ContentHandler";
58
56
 
59
57
  msrn::ReactModuleProvider s_moduleProvider = msrn::MakeTurboModuleProvider<Microsoft::React::WebSocketTurboModule>();
60
58
 
59
+ const ReactPropertyId<msrn::ReactNonAbiValue<weak_ptr<WebSocketModule::SharedState>>>
60
+ WebSocketModuleSharedStatePropertyId() noexcept {
61
+ static const ReactPropertyId<msrn::ReactNonAbiValue<weak_ptr<WebSocketModule::SharedState>>> prop{
62
+ L"WebSocketModule.SharedState"};
63
+ return prop;
64
+ }
65
+
61
66
  static shared_ptr<IWebSocketResource>
62
67
  GetOrCreateWebSocket(int64_t id, string &&url, weak_ptr<WebSocketModule::SharedState> weakState) {
63
68
  auto state = weakState.lock();
@@ -121,9 +126,7 @@ GetOrCreateWebSocket(int64_t id, string &&url, weak_ptr<WebSocketModule::SharedS
121
126
 
122
127
  auto args = msrn::JSValueObject{{"id", id}, {"type", isBinary ? "binary" : "text"}};
123
128
  shared_ptr<Microsoft::React::IWebSocketModuleContentHandler> contentHandler;
124
- auto propId = ReactPropertyId<ReactNonAbiValue<weak_ptr<Microsoft::React::IWebSocketModuleContentHandler>>>{
125
- s_contentHandlerNameW};
126
- if (auto prop = propBag.Get(propId))
129
+ if (auto prop = propBag.Get(Microsoft::React::BlobModuleContentHandlerPropertyId()))
127
130
  contentHandler = prop.Value().lock();
128
131
 
129
132
  if (contentHandler) {
@@ -174,13 +177,11 @@ WebSocketModule::WebSocketModule(winrt::Windows::Foundation::IInspectable const
174
177
 
175
178
  auto propBag = ReactPropertyBag{m_sharedState->InspectableProps.try_as<IReactPropertyBag>()};
176
179
 
177
- auto proxyPropId = ReactPropertyId<ReactNonAbiValue<weak_ptr<IWebSocketModuleProxy>>>{s_proxyNameW};
178
180
  auto proxy = weak_ptr<IWebSocketModuleProxy>{m_proxy};
179
- propBag.Set(proxyPropId, std::move(proxy));
181
+ propBag.Set(WebSocketModuleProxyPropertyId(), std::move(proxy));
180
182
 
181
- auto statePropId = ReactPropertyId<ReactNonAbiValue<weak_ptr<SharedState>>>{s_sharedStateNameW};
182
183
  auto state = weak_ptr<SharedState>{m_sharedState};
183
- propBag.Set(statePropId, std::move(state));
184
+ propBag.Set(WebSocketModuleSharedStatePropertyId(), std::move(state));
184
185
  }
185
186
 
186
187
  WebSocketModule::~WebSocketModule() noexcept /*override*/ {
@@ -314,8 +315,7 @@ WebSocketModuleProxy::WebSocketModuleProxy(IInspectable const &inspectableProper
314
315
 
315
316
  void WebSocketModuleProxy::SendBinary(string &&base64String, int64_t id) noexcept /*override*/ {
316
317
  auto propBag = ReactPropertyBag{m_inspectableProps.try_as<IReactPropertyBag>()};
317
- auto sharedPropId = ReactPropertyId<ReactNonAbiValue<weak_ptr<WebSocketModule::SharedState>>>{s_sharedStateNameW};
318
- auto state = propBag.Get(sharedPropId).Value();
318
+ auto state = propBag.Get(WebSocketModuleSharedStatePropertyId()).Value();
319
319
 
320
320
  weak_ptr weakWs = GetOrCreateWebSocket(id, {}, std::move(state));
321
321
  if (auto sharedWs = weakWs.lock()) {
@@ -355,9 +355,8 @@ shared_ptr<IWebSocketResource> WebSocketTurboModule::CreateResource(int64_t id,
355
355
  rc->SetOnMessage([id, context = m_context](size_t length, const string &message, bool isBinary) {
356
356
  auto args = msrn::JSValueObject{{"id", id}, {"type", isBinary ? "binary" : "text"}};
357
357
  shared_ptr<IWebSocketModuleContentHandler> contentHandler;
358
- auto propId = ReactPropertyId<ReactNonAbiValue<weak_ptr<IWebSocketModuleContentHandler>>>{s_contentHandlerNameW};
359
358
  auto propBag = context.Properties();
360
- if (auto prop = propBag.Get(propId))
359
+ if (auto prop = propBag.Get(BlobModuleContentHandlerPropertyId()))
361
360
  contentHandler = prop.Value().lock();
362
361
 
363
362
  if (contentHandler) {
@@ -399,9 +398,8 @@ void WebSocketTurboModule::Initialize(msrn::ReactContext const &reactContext) no
399
398
  m_context = reactContext.Handle();
400
399
  m_proxy = std::make_shared<WebSocketTurboModuleProxy>(m_resourceMap);
401
400
 
402
- auto proxyPropId = ReactPropertyId<ReactNonAbiValue<weak_ptr<IWebSocketModuleProxy>>>{s_proxyNameW};
403
401
  auto proxy = weak_ptr<IWebSocketModuleProxy>{m_proxy};
404
- m_context.Properties().Set(proxyPropId, std::move(proxy));
402
+ m_context.Properties().Set(WebSocketModuleProxyPropertyId(), std::move(proxy));
405
403
  }
406
404
 
407
405
  void WebSocketTurboModule::Connect(
@@ -6,6 +6,7 @@
6
6
  #include <Modules/IHttpModuleProxy.h>
7
7
  #include <Modules/IWebSocketModuleProxy.h>
8
8
  #include <utilities.h>
9
+ #include "NetworkPropertyIds.h"
9
10
 
10
11
  // Boost Libraries
11
12
  #include <boost/uuid/uuid_io.hpp>
@@ -63,13 +64,9 @@ DefaultBlobResource::DefaultBlobResource(
63
64
  auto requestBodyHandler = std::make_shared<BlobModuleRequestBodyHandler>(blobPersistor);
64
65
  auto responseHandler = std::make_shared<BlobModuleResponseHandler>(blobPersistor);
65
66
 
66
- auto contentHandlerPropId =
67
- ReactPropertyId<ReactNonAbiValue<weak_ptr<IWebSocketModuleContentHandler>>>{L"BlobModule.ContentHandler"};
68
- propBag.Set(contentHandlerPropId, weak_ptr<IWebSocketModuleContentHandler>{contentHandler});
67
+ propBag.Set(BlobModuleContentHandlerPropertyId(), weak_ptr<IWebSocketModuleContentHandler>{contentHandler});
69
68
 
70
- auto blobPersistorPropId = ReactPropertyId<ReactNonAbiValue<weak_ptr<IBlobPersistor>>>{L"Blob.Persistor"};
71
- ;
72
- propBag.Set(blobPersistorPropId, weak_ptr<IBlobPersistor>{blobPersistor});
69
+ propBag.Set(BlobModulePersistorPropertyId(), weak_ptr<IBlobPersistor>{blobPersistor});
73
70
 
74
71
  auto result = std::make_shared<DefaultBlobResource>(
75
72
  blobPersistor, contentHandler, requestBodyHandler, responseHandler, propBag);
@@ -79,10 +76,8 @@ DefaultBlobResource::DefaultBlobResource(
79
76
 
80
77
  void DefaultBlobResource::SendOverSocket(string &&blobId, int64_t offset, int64_t size, int64_t socketId) noexcept
81
78
  /*override*/ {
82
- auto propId =
83
- msrn::ReactPropertyId<msrn::ReactNonAbiValue<weak_ptr<IWebSocketModuleProxy>>>{L"WebSocketModule.Proxy"};
84
79
  shared_ptr<IWebSocketModuleProxy> wsProxy;
85
- if (auto prop = m_propertyBag.Get(propId)) {
80
+ if (auto prop = m_propertyBag.Get(WebSocketModuleProxyPropertyId())) {
86
81
  wsProxy = prop.Value().lock();
87
82
  }
88
83
  if (!wsProxy) {
@@ -137,10 +132,8 @@ void DefaultBlobResource::Release(string &&blobId) noexcept /*override*/ {
137
132
  }
138
133
 
139
134
  void DefaultBlobResource::AddNetworkingHandler() noexcept /*override*/ {
140
- auto propId = msrn::ReactPropertyId<msrn::ReactNonAbiValue<weak_ptr<IHttpModuleProxy>>>{L"HttpModule.Proxy"};
141
-
142
135
  bool handlerAdded = false;
143
- if (auto prop = m_propertyBag.Get(propId)) {
136
+ if (auto prop = m_propertyBag.Get(HttpModuleProxyPropertyId())) {
144
137
  if (auto httpHandler = prop.Value().lock()) {
145
138
  httpHandler->AddRequestBodyHandler(m_requestBodyHandler);
146
139
  httpHandler->AddResponseHandler(m_responseHandler);
@@ -152,8 +145,7 @@ void DefaultBlobResource::AddNetworkingHandler() noexcept /*override*/ {
152
145
  // Best-effort approach to set up the request/response handlers by exposing this interface to dependents
153
146
  // (i.e. IHttpResource).
154
147
  if (!handlerAdded) {
155
- auto propId = msrn::ReactPropertyId<msrn::ReactNonAbiValue<weak_ptr<IBlobResource>>>{L"Blob.Resource"};
156
- m_propertyBag.Set(propId, weak_ptr<IBlobResource>(shared_from_this()));
148
+ m_propertyBag.Set(BlobResourcePropertyId(), weak_ptr<IBlobResource>(shared_from_this()));
157
149
  }
158
150
  }
159
151
 
@@ -0,0 +1,60 @@
1
+ // Copyright (c) Microsoft Corporation.
2
+ // Licensed under the MIT License.
3
+
4
+ #pragma once
5
+
6
+ #include "NetworkPropertyIds.h"
7
+
8
+ namespace Microsoft::React {
9
+
10
+ const winrt::Microsoft::ReactNative::ReactPropertyId<
11
+ winrt::Microsoft::ReactNative::ReactNonAbiValue<std::weak_ptr<IWebSocketModuleContentHandler>>>
12
+ BlobModuleContentHandlerPropertyId() noexcept {
13
+ static const winrt::Microsoft::ReactNative::ReactPropertyId<
14
+ winrt::Microsoft::ReactNative::ReactNonAbiValue<std::weak_ptr<IWebSocketModuleContentHandler>>>
15
+ prop{L"BlobModule.ContentHandler"};
16
+ return prop;
17
+ }
18
+
19
+ const winrt::Microsoft::ReactNative::ReactPropertyId<
20
+ winrt::Microsoft::ReactNative::ReactNonAbiValue<std::weak_ptr<IBlobPersistor>>>
21
+ BlobModulePersistorPropertyId() noexcept {
22
+ static const winrt::Microsoft::ReactNative::ReactPropertyId<
23
+ winrt::Microsoft::ReactNative::ReactNonAbiValue<std::weak_ptr<IBlobPersistor>>>
24
+ prop{L"Blob.Persistor"};
25
+ return prop;
26
+ }
27
+
28
+ const winrt::Microsoft::ReactNative::ReactPropertyId<
29
+ winrt::Microsoft::ReactNative::ReactNonAbiValue<std::weak_ptr<IWebSocketModuleProxy>>>
30
+ WebSocketModuleProxyPropertyId() noexcept {
31
+ static const winrt::Microsoft::ReactNative::ReactPropertyId<
32
+ winrt::Microsoft::ReactNative::ReactNonAbiValue<std::weak_ptr<IWebSocketModuleProxy>>>
33
+ prop{L"WebSocketModule.Proxy"};
34
+ return prop;
35
+ }
36
+
37
+ const winrt::Microsoft::ReactNative::ReactPropertyId<
38
+ winrt::Microsoft::ReactNative::ReactNonAbiValue<std::weak_ptr<IHttpModuleProxy>>>
39
+ HttpModuleProxyPropertyId() noexcept {
40
+ static const winrt::Microsoft::ReactNative::ReactPropertyId<
41
+ winrt::Microsoft::ReactNative::ReactNonAbiValue<std::weak_ptr<IHttpModuleProxy>>>
42
+ prop{L"HttpModule.Proxy"};
43
+ return prop;
44
+ }
45
+
46
+ const winrt::Microsoft::ReactNative::ReactPropertyId<
47
+ winrt::Microsoft::ReactNative::ReactNonAbiValue<std::weak_ptr<Networking::IBlobResource>>>
48
+ BlobResourcePropertyId() noexcept {
49
+ static const winrt::Microsoft::ReactNative::ReactPropertyId<
50
+ winrt::Microsoft::ReactNative::ReactNonAbiValue<std::weak_ptr<Networking::IBlobResource>>>
51
+ prop{L"Blob.Resource"};
52
+ return prop;
53
+ }
54
+
55
+ const winrt::Microsoft::ReactNative::ReactPropertyId<winrt::hstring> DefaultUserAgentPropertyId() noexcept {
56
+ static const winrt::Microsoft::ReactNative::ReactPropertyId<winrt::hstring> prop{L"ReactNative", L"UserAgent"};
57
+ return prop;
58
+ }
59
+
60
+ } // namespace Microsoft::React
@@ -0,0 +1,41 @@
1
+ // Copyright (c) Microsoft Corporation.
2
+ // Licensed under the MIT License.
3
+
4
+ #pragma once
5
+
6
+ #include <ReactPropertyBag.h>
7
+
8
+ namespace Microsoft::React {
9
+
10
+ struct IWebSocketModuleContentHandler;
11
+ struct IBlobPersistor;
12
+ struct IWebSocketModuleProxy;
13
+ struct IHttpModuleProxy;
14
+
15
+ namespace Networking {
16
+ struct IBlobResource;
17
+ }
18
+
19
+ const winrt::Microsoft::ReactNative::ReactPropertyId<
20
+ winrt::Microsoft::ReactNative::ReactNonAbiValue<std::weak_ptr<IWebSocketModuleContentHandler>>>
21
+ BlobModuleContentHandlerPropertyId() noexcept;
22
+
23
+ const winrt::Microsoft::ReactNative::ReactPropertyId<
24
+ winrt::Microsoft::ReactNative::ReactNonAbiValue<std::weak_ptr<IBlobPersistor>>>
25
+ BlobModulePersistorPropertyId() noexcept;
26
+
27
+ const winrt::Microsoft::ReactNative::ReactPropertyId<
28
+ winrt::Microsoft::ReactNative::ReactNonAbiValue<std::weak_ptr<IWebSocketModuleProxy>>>
29
+ WebSocketModuleProxyPropertyId() noexcept;
30
+
31
+ const winrt::Microsoft::ReactNative::ReactPropertyId<
32
+ winrt::Microsoft::ReactNative::ReactNonAbiValue<std::weak_ptr<IHttpModuleProxy>>>
33
+ HttpModuleProxyPropertyId() noexcept;
34
+
35
+ const winrt::Microsoft::ReactNative::ReactPropertyId<
36
+ winrt::Microsoft::ReactNative::ReactNonAbiValue<std::weak_ptr<Networking::IBlobResource>>>
37
+ BlobResourcePropertyId() noexcept;
38
+
39
+ const winrt::Microsoft::ReactNative::ReactPropertyId<winrt::hstring> DefaultUserAgentPropertyId() noexcept;
40
+
41
+ } // namespace Microsoft::React
@@ -42,10 +42,12 @@ namespace Microsoft::React::Networking {
42
42
  RedirectHttpFilter::RedirectHttpFilter(
43
43
  size_t maxRedirects,
44
44
  IHttpFilter &&innerFilter,
45
- IHttpFilter &&innerFilterWithNoCredentials) noexcept
45
+ IHttpFilter &&innerFilterWithNoCredentials,
46
+ winrt::hstring defaultUserAgent) noexcept
46
47
  : m_maximumRedirects{maxRedirects},
47
48
  m_innerFilter{std::move(innerFilter)},
48
- m_innerFilterWithNoCredentials{std::move(innerFilterWithNoCredentials)} {
49
+ m_innerFilterWithNoCredentials{std::move(innerFilterWithNoCredentials)},
50
+ m_defaultUserAgent(defaultUserAgent) {
49
51
  // Prevent automatic redirections.
50
52
  if (auto baseFilter = m_innerFilter.try_as<IHttpBaseProtocolFilter>()) {
51
53
  baseFilter.AllowAutoRedirect(false);
@@ -57,13 +59,21 @@ RedirectHttpFilter::RedirectHttpFilter(
57
59
  }
58
60
  }
59
61
 
60
- RedirectHttpFilter::RedirectHttpFilter(IHttpFilter &&innerFilter, IHttpFilter &&innerFilterWithNoCredentials) noexcept
61
- : RedirectHttpFilter(DefaultMaxRedirects, std::move(innerFilter), std::move(innerFilterWithNoCredentials)) {}
62
+ RedirectHttpFilter::RedirectHttpFilter(
63
+ IHttpFilter &&innerFilter,
64
+ IHttpFilter &&innerFilterWithNoCredentials,
65
+ winrt::hstring defaultUserAgent) noexcept
66
+ : RedirectHttpFilter(
67
+ DefaultMaxRedirects,
68
+ std::move(innerFilter),
69
+ std::move(innerFilterWithNoCredentials),
70
+ defaultUserAgent) {}
62
71
 
63
- RedirectHttpFilter::RedirectHttpFilter() noexcept
72
+ RedirectHttpFilter::RedirectHttpFilter(winrt::hstring defaultUserAgent) noexcept
64
73
  : RedirectHttpFilter(
65
74
  winrt::Windows::Web::Http::Filters::HttpBaseProtocolFilter{},
66
- winrt::Windows::Web::Http::Filters::HttpBaseProtocolFilter{}) {}
75
+ winrt::Windows::Web::Http::Filters::HttpBaseProtocolFilter{},
76
+ defaultUserAgent) {}
67
77
 
68
78
  void RedirectHttpFilter::SetRequestFactory(std::weak_ptr<IWinRTHttpRequestFactory> factory) noexcept {
69
79
  m_requestFactory = factory;
@@ -215,9 +225,8 @@ ResponseOperation RedirectHttpFilter::SendRequestAsync(HttpRequestMessage const
215
225
  do {
216
226
  // Set User-Agent
217
227
  // See https://fetch.spec.whatwg.org/#http-network-or-cache-fetch
218
- auto userAgent = GetRuntimeOptionString("Http.UserAgent");
219
- if (userAgent.size() > 0) {
220
- coRequest.Headers().Append(L"User-Agent", winrt::to_hstring(userAgent));
228
+ if (!m_defaultUserAgent.empty()) {
229
+ coRequest.Headers().Append(L"User-Agent", m_defaultUserAgent);
221
230
  }
222
231
 
223
232
  // Send subsequent requests through the filter that doesn't have the credentials included in the first request
@@ -31,18 +31,21 @@ class RedirectHttpFilter : public winrt::implements<
31
31
  winrt::com_ptr<Microsoft::React::Networking::IRedirectEventSource> m_redirEventSrc;
32
32
  bool m_allowAutoRedirect{true};
33
33
  size_t m_maximumRedirects;
34
+ winrt::hstring m_defaultUserAgent;
34
35
 
35
36
  public:
36
37
  RedirectHttpFilter(
37
38
  size_t maxRedirects,
38
39
  winrt::Windows::Web::Http::Filters::IHttpFilter &&innerFilter,
39
- winrt::Windows::Web::Http::Filters::IHttpFilter &&innerFilterWithNoCredentials) noexcept;
40
+ winrt::Windows::Web::Http::Filters::IHttpFilter &&innerFilterWithNoCredentials,
41
+ winrt::hstring defaultUserAgent) noexcept;
40
42
 
41
43
  RedirectHttpFilter(
42
44
  winrt::Windows::Web::Http::Filters::IHttpFilter &&innerFilter,
43
- winrt::Windows::Web::Http::Filters::IHttpFilter &&innerFilterWithNoCredentials) noexcept;
45
+ winrt::Windows::Web::Http::Filters::IHttpFilter &&innerFilterWithNoCredentials,
46
+ winrt::hstring defaultUserAgent) noexcept;
44
47
 
45
- RedirectHttpFilter() noexcept;
48
+ RedirectHttpFilter(winrt::hstring defaultUserAgent) noexcept;
46
49
 
47
50
  void SetRequestFactory(std::weak_ptr<IWinRTHttpRequestFactory> factory) noexcept;
48
51
 
@@ -5,6 +5,7 @@
5
5
 
6
6
  #include "WinRTHttpResource.h"
7
7
 
8
+ #include "HttpSettings.g.cpp"
8
9
  #include <CppRuntimeOptions.h>
9
10
  #include <Networking/IBlobResource.h>
10
11
  #include <ReactPropertyBag.h>
@@ -12,6 +13,7 @@
12
13
  #include <Utils/WinRTConversions.h>
13
14
  #include <utilities.h>
14
15
  #include "IRedirectEventSource.h"
16
+ #include "Networking/NetworkPropertyIds.h"
15
17
  #include "OriginPolicyHttpFilter.h"
16
18
  #include "RedirectHttpFilter.h"
17
19
 
@@ -310,7 +312,9 @@ void WinRTHttpResource::SendRequest(
310
312
  m_onError(requestId, Utilities::HResultToString(e), false);
311
313
  }
312
314
  } catch (...) {
313
- m_onError(requestId, "Unidentified error sending HTTP request", false);
315
+ if (m_onError) {
316
+ m_onError(requestId, "Unidentified error sending HTTP request", false);
317
+ }
314
318
  }
315
319
  }
316
320
 
@@ -329,7 +333,9 @@ void WinRTHttpResource::AbortRequest(int64_t requestId) noexcept /*override*/ {
329
333
  try {
330
334
  request.Cancel();
331
335
  } catch (hresult_error const &e) {
332
- m_onError(requestId, Utilities::HResultToString(e), false);
336
+ if (m_onError) {
337
+ m_onError(requestId, Utilities::HResultToString(e), false);
338
+ }
333
339
  }
334
340
  }
335
341
 
@@ -645,7 +651,20 @@ void WinRTHttpResource::AddResponseHandler(shared_ptr<IResponseHandler> response
645
651
  using namespace winrt::Microsoft::ReactNative;
646
652
  using winrt::Windows::Web::Http::HttpClient;
647
653
 
648
- auto redirFilter = winrt::make<RedirectHttpFilter>();
654
+ winrt::hstring defaultUserAgent;
655
+ if (inspectableProperties) {
656
+ auto propBag = ReactPropertyBag{inspectableProperties.as<IReactPropertyBag>()};
657
+ if (auto userAgentProp = propBag.Get(DefaultUserAgentPropertyId())) {
658
+ defaultUserAgent = *userAgentProp;
659
+ }
660
+ }
661
+
662
+ auto userAgent = GetRuntimeOptionString("Http.UserAgent");
663
+ if (userAgent.size() > 0) {
664
+ defaultUserAgent = winrt::to_hstring(userAgent);
665
+ }
666
+
667
+ auto redirFilter = winrt::make<RedirectHttpFilter>(defaultUserAgent);
649
668
  HttpClient client;
650
669
 
651
670
  if (static_cast<OriginPolicy>(GetRuntimeOptionInt("Http.OriginPolicy")) == OriginPolicy::None) {
@@ -665,14 +684,12 @@ void WinRTHttpResource::AddResponseHandler(shared_ptr<IResponseHandler> response
665
684
 
666
685
  // Register resource as HTTP module proxy.
667
686
  if (inspectableProperties) {
668
- auto propId = ReactPropertyId<ReactNonAbiValue<weak_ptr<IHttpModuleProxy>>>{L"HttpModule.Proxy"};
669
- auto propBag = ReactPropertyBag{inspectableProperties.try_as<IReactPropertyBag>()};
687
+ auto propBag = ReactPropertyBag{inspectableProperties.as<IReactPropertyBag>()};
670
688
  auto moduleProxy = weak_ptr<IHttpModuleProxy>{result};
671
- propBag.Set(propId, std::move(moduleProxy));
689
+ propBag.Set(HttpModuleProxyPropertyId(), std::move(moduleProxy));
672
690
 
673
691
  // #11439 - Best-effort attempt to set up the HTTP handler after an initial call to addNetworkingHandler failed.
674
- auto blobRcPropId = ReactPropertyId<ReactNonAbiValue<weak_ptr<Networking::IBlobResource>>>{L"Blob.Resource"};
675
- if (auto prop = propBag.Get(blobRcPropId)) {
692
+ if (auto prop = propBag.Get(BlobResourcePropertyId())) {
676
693
  if (auto blobRc = prop.Value().lock()) {
677
694
  blobRc->AddNetworkingHandler();
678
695
  }
@@ -690,3 +707,14 @@ void WinRTHttpResource::AddResponseHandler(shared_ptr<IResponseHandler> response
690
707
  #pragma endregion IHttpResource
691
708
 
692
709
  } // namespace Microsoft::React::Networking
710
+
711
+ namespace winrt::Microsoft::ReactNative::implementation {
712
+
713
+ void HttpSettings::SetDefaultUserAgent(
714
+ const winrt::Microsoft::ReactNative::ReactInstanceSettings &settings,
715
+ const winrt::hstring &userAgent) noexcept {
716
+ winrt::Microsoft::ReactNative::ReactPropertyBag(settings.Properties())
717
+ .Set(::Microsoft::React::DefaultUserAgentPropertyId(), userAgent);
718
+ };
719
+
720
+ } // namespace winrt::Microsoft::ReactNative::implementation
@@ -5,6 +5,7 @@
5
5
 
6
6
  #include "IHttpResource.h"
7
7
 
8
+ #include "HttpSettings.g.h"
8
9
  #include <Modules/IHttpModuleProxy.h>
9
10
  #include "IWinRTHttpRequestFactory.h"
10
11
  #include "WinRTTypes.h"
@@ -108,3 +109,19 @@ class WinRTHttpResource : public IHttpResource,
108
109
  };
109
110
 
110
111
  } // namespace Microsoft::React::Networking
112
+
113
+ namespace winrt::Microsoft::ReactNative::implementation {
114
+
115
+ struct HttpSettings {
116
+ HttpSettings() = default;
117
+
118
+ static void SetDefaultUserAgent(
119
+ const winrt::Microsoft::ReactNative::ReactInstanceSettings &settings,
120
+ const winrt::hstring &userAgent) noexcept;
121
+ };
122
+
123
+ } // namespace winrt::Microsoft::ReactNative::implementation
124
+
125
+ namespace winrt::Microsoft::ReactNative::factory_implementation {
126
+ struct HttpSettings : HttpSettingsT<HttpSettings, implementation::HttpSettings> {};
127
+ } // namespace winrt::Microsoft::ReactNative::factory_implementation