react-native-windows 0.69.7 → 0.69.8

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.
@@ -19,8 +19,12 @@
19
19
 
20
20
  namespace Microsoft::ReactNative {
21
21
 
22
+ using winrt::Microsoft::ReactNative::ReactPropertyBag;
23
+
22
24
  namespace {
23
25
 
26
+ using winrt::Microsoft::ReactNative::ReactPropertyId;
27
+
24
28
  bool HasPackageIdentity() noexcept {
25
29
  static const bool hasPackageIdentity = []() noexcept {
26
30
  auto packageStatics = winrt::get_activation_factory<winrt::Windows::ApplicationModel::IPackageStatics>(
@@ -35,6 +39,13 @@ bool HasPackageIdentity() noexcept {
35
39
  return hasPackageIdentity;
36
40
  }
37
41
 
42
+ ReactPropertyId<bool> HttpUseMonolithicModuleProperty() noexcept {
43
+ static ReactPropertyId<bool> propId{
44
+ L"ReactNative.Http"
45
+ L"UseMonolithicModule"};
46
+ return propId;
47
+ }
48
+
38
49
  } // namespace
39
50
 
40
51
  std::vector<facebook::react::NativeModuleDescription> GetCoreModules(
@@ -50,11 +61,25 @@ std::vector<facebook::react::NativeModuleDescription> GetCoreModules(
50
61
  [props = context->Properties()]() { return Microsoft::React::CreateHttpModule(props); },
51
62
  jsMessageQueue);
52
63
 
64
+ if (!ReactPropertyBag(context->Properties()).Get(HttpUseMonolithicModuleProperty())) {
65
+ modules.emplace_back(
66
+ Microsoft::React::GetBlobModuleName(),
67
+ [props = context->Properties()]() { return Microsoft::React::CreateBlobModule(props); },
68
+ batchingUIMessageQueue);
69
+
70
+ modules.emplace_back(
71
+ Microsoft::React::GetFileReaderModuleName(),
72
+ [props = context->Properties()]() { return Microsoft::React::CreateFileReaderModule(props); },
73
+ batchingUIMessageQueue);
74
+ }
75
+
53
76
  modules.emplace_back(
54
77
  "Timing",
55
78
  [batchingUIMessageQueue]() { return facebook::react::CreateTimingModule(batchingUIMessageQueue); },
56
79
  batchingUIMessageQueue);
57
80
 
81
+ // Note: `context` is moved to remove the reference from the current scope.
82
+ // This should either be the last usage of `context`, or the std::move call should happen later in this method.
58
83
  modules.emplace_back(
59
84
  NativeAnimatedModule::name,
60
85
  [context = std::move(context)]() mutable { return std::make_unique<NativeAnimatedModule>(std::move(context)); },
@@ -43,7 +43,6 @@
43
43
  #include <winrt/Windows.Storage.Streams.h>
44
44
  #include <winrt/Windows.UI.ViewManagement.Core.h>
45
45
  #include <winrt/Windows.UI.ViewManagement.h>
46
- #include <winrt/Windows.Web.Http.Filters.h>
47
46
  #include <winrt/Windows.Web.Http.Headers.h>
48
47
 
49
48
  #include "Base/CxxReactIncludes.h"
@@ -24,6 +24,11 @@
24
24
  "Microsoft.SourceLink.Common": "1.0.0"
25
25
  }
26
26
  },
27
+ "boost": {
28
+ "type": "Transitive",
29
+ "resolved": "1.76.0",
30
+ "contentHash": "p+w3YvNdXL8Cu9Fzrmexssu0tZbWxuf6ywsQqHjDlKFE5ojXHof1HIyMC3zDLfLnh80dIeFcEUAuR2Asg/XHRA=="
31
+ },
27
32
  "Microsoft.Build.Tasks.Git": {
28
33
  "type": "Transitive",
29
34
  "resolved": "1.0.0",
@@ -60,14 +65,34 @@
60
65
  "resolved": "1.0.0",
61
66
  "contentHash": "G8DuQY8/DK5NN+3jm5wcMcd9QYD90UV7MiLmdljSJixi3U/vNaeBKmmXUqI4DJCOeWizIUEh4ALhSt58mR+5eg=="
62
67
  },
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
+ },
63
83
  "NETStandard.Library": {
64
84
  "type": "Transitive",
65
85
  "resolved": "2.0.3",
66
- "contentHash": "st47PosZSHrjECdjeIzZQbzivYBJFv6P2nv4cj2ypdI204DO+vZ7l5raGMiX4eXMJ53RfOIg+/s4DHVZ54Nu2A==",
86
+ "contentHash": "548M6mnBSJWxsIlkQHfbzoYxpiYFXZZSL00p4GHYv8PkiqFBnnT68mW5mGEsA/ch9fDO9GkPgkFQpWiXZN7mAQ==",
67
87
  "dependencies": {
68
88
  "Microsoft.NETCore.Platforms": "1.1.0"
69
89
  }
70
90
  },
91
+ "ReactNative.Hermes.Windows": {
92
+ "type": "Transitive",
93
+ "resolved": "0.11.0-ms.6",
94
+ "contentHash": "WAVLsSZBV4p/3hNC3W67su7xu3f/ZMSKxu0ON7g2GaKRbkJmH0Qyif1IlzcJwtvR48kuOdfgPu7Bgtz3AY+gqg=="
95
+ },
71
96
  "runtime.win10-arm.Microsoft.Net.Native.Compiler": {
72
97
  "type": "Transitive",
73
98
  "resolved": "2.2.7-rel-27913-00",
@@ -303,4 +328,4 @@
303
328
  }
304
329
  }
305
330
  }
306
- }
331
+ }
@@ -10,10 +10,10 @@
10
10
  -->
11
11
  <Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
12
12
  <PropertyGroup>
13
- <ReactNativeWindowsVersion>0.69.7</ReactNativeWindowsVersion>
13
+ <ReactNativeWindowsVersion>0.69.8</ReactNativeWindowsVersion>
14
14
  <ReactNativeWindowsMajor>0</ReactNativeWindowsMajor>
15
15
  <ReactNativeWindowsMinor>69</ReactNativeWindowsMinor>
16
- <ReactNativeWindowsPatch>7</ReactNativeWindowsPatch>
16
+ <ReactNativeWindowsPatch>8</ReactNativeWindowsPatch>
17
17
  <ReactNativeWindowsCanary>false</ReactNativeWindowsCanary>
18
18
  </PropertyGroup>
19
19
  </Project>
@@ -139,7 +139,7 @@ vector<module::CxxModule::Method> BlobModule::getMethods() {
139
139
  auto size = blob[sizeKey].getInt();
140
140
  auto socketID = jsArgAsInt(args, 1);
141
141
 
142
- winrt::array_view<uint8_t> data;
142
+ winrt::array_view<uint8_t const> data;
143
143
  try {
144
144
  data = persistor->ResolveMessage(std::move(blobId), offset, size);
145
145
  } catch (const std::exception &e) {
@@ -169,7 +169,7 @@ vector<module::CxxModule::Method> BlobModule::getMethods() {
169
169
  auto type = part[typeKey].asString();
170
170
  if (blobKey == type) {
171
171
  auto blob = part[dataKey];
172
- winrt::array_view<uint8_t> bufferPart;
172
+ winrt::array_view<uint8_t const> bufferPart;
173
173
  try {
174
174
  bufferPart = persistor->ResolveMessage(
175
175
  blob[blobIdKey].asString(), blob[offsetKey].asInt(), blob[sizeKey].asInt());
@@ -216,7 +216,7 @@ vector<module::CxxModule::Method> BlobModule::getMethods() {
216
216
 
217
217
  #pragma region IBlobPersistor
218
218
 
219
- winrt::array_view<uint8_t> MemoryBlobPersistor::ResolveMessage(string &&blobId, int64_t offset, int64_t size) {
219
+ winrt::array_view<uint8_t const> MemoryBlobPersistor::ResolveMessage(string &&blobId, int64_t offset, int64_t size) {
220
220
  if (size < 1)
221
221
  return {};
222
222
 
@@ -233,7 +233,7 @@ winrt::array_view<uint8_t> MemoryBlobPersistor::ResolveMessage(string &&blobId,
233
233
  if (endBound > bytes.size() || offset >= static_cast<int64_t>(bytes.size()) || offset < 0)
234
234
  throw std::out_of_range("Offset or size out of range");
235
235
 
236
- return winrt::array_view<uint8_t>(bytes.data() + offset, bytes.data() + endBound);
236
+ return winrt::array_view<uint8_t const>(bytes.data() + offset, bytes.data() + endBound);
237
237
  }
238
238
 
239
239
  void MemoryBlobPersistor::RemoveMessage(string &&blobId) noexcept {
@@ -30,7 +30,7 @@ class MemoryBlobPersistor final : public IBlobPersistor {
30
30
  public:
31
31
  #pragma region IBlobPersistor
32
32
 
33
- winrt::array_view<uint8_t> ResolveMessage(std::string &&blobId, int64_t offset, int64_t size) override;
33
+ winrt::array_view<uint8_t const> ResolveMessage(std::string &&blobId, int64_t offset, int64_t size) override;
34
34
 
35
35
  void RemoveMessage(std::string &&blobId) noexcept override;
36
36
 
@@ -71,7 +71,7 @@ std::vector<module::CxxModule::Method> FileReaderModule::getMethods() {
71
71
  auto offset = blob["offset"].asInt();
72
72
  auto size = blob["size"].asInt();
73
73
 
74
- winrt::array_view<uint8_t> bytes;
74
+ winrt::array_view<uint8_t const> bytes;
75
75
  try {
76
76
  bytes = blobPersistor->ResolveMessage(std::move(blobId), offset, size);
77
77
  } catch (const std::exception &e) {
@@ -116,7 +116,7 @@ std::vector<module::CxxModule::Method> FileReaderModule::getMethods() {
116
116
  auto offset = blob["offset"].asInt();
117
117
  auto size = blob["size"].asInt();
118
118
 
119
- winrt::array_view<uint8_t> bytes;
119
+ winrt::array_view<uint8_t const> bytes;
120
120
  try {
121
121
  bytes = blobPersistor->ResolveMessage(std::move(blobId), offset, size);
122
122
  } catch (const std::exception &e) {
@@ -72,9 +72,11 @@ static void SetUpHttpResource(
72
72
  };
73
73
  resource->SetOnData(std::move(onDataDynamic));
74
74
 
75
- resource->SetOnError([weakReactInstance](int64_t requestId, string &&message) {
75
+ resource->SetOnError([weakReactInstance](int64_t requestId, string &&message, bool isTimeout) {
76
76
  dynamic args = dynamic::array(requestId, std::move(message));
77
- // TODO: isTimeout errorArgs.push_back(true);
77
+ if (isTimeout) {
78
+ args.push_back(true);
79
+ }
78
80
 
79
81
  SendEvent(weakReactInstance, completedResponse, std::move(args));
80
82
  });
@@ -18,7 +18,7 @@ struct IBlobPersistor {
18
18
  /// When an entry for blobId cannot be found.
19
19
  /// </exception>
20
20
  ///
21
- virtual winrt::array_view<uint8_t> ResolveMessage(std::string &&blobId, int64_t offset, int64_t size) = 0;
21
+ virtual winrt::array_view<uint8_t const> ResolveMessage(std::string &&blobId, int64_t offset, int64_t size) = 0;
22
22
 
23
23
  virtual void RemoveMessage(std::string &&blobId) noexcept = 0;
24
24
 
@@ -71,6 +71,7 @@ struct IHttpResource {
71
71
  /// </param>
72
72
  /// <param name="timeout">
73
73
  /// Request timeout in miliseconds.
74
+ /// Note: A value of 0 means no timeout. The resource will await the response indefinitely.
74
75
  /// </param>
75
76
  /// <param name="withCredentials">
76
77
  /// Allow including credentials in request.
@@ -95,7 +96,7 @@ struct IHttpResource {
95
96
  virtual void SetOnData(std::function<void(int64_t requestId, std::string &&responseData)> &&handler) noexcept = 0;
96
97
  virtual void SetOnData(std::function<void(int64_t requestId, folly::dynamic &&responseData)> &&handler) noexcept = 0;
97
98
  virtual void SetOnError(
98
- std::function<void(int64_t requestId, std::string &&errorMessage /*, bool isTimeout*/)> &&handler) noexcept = 0;
99
+ std::function<void(int64_t requestId, std::string &&errorMessage, bool isTimeout)> &&handler) noexcept = 0;
99
100
  };
100
101
 
101
102
  } // namespace Microsoft::React::Networking
@@ -0,0 +1,18 @@
1
+ // Copyright (c) Microsoft Corporation.
2
+ // Licensed under the MIT License.
3
+
4
+ #pragma once
5
+
6
+ #include <winrt/Windows.Foundation.h>
7
+ #include <winrt/Windows.Web.Http.h>
8
+ #include <winrt/base.h>
9
+
10
+ namespace Microsoft::React::Networking {
11
+
12
+ struct IRedirectEventSource : winrt::implements<IRedirectEventSource, winrt::Windows::Foundation::IInspectable> {
13
+ virtual bool OnRedirecting(
14
+ winrt::Windows::Web::Http::HttpRequestMessage const &request,
15
+ winrt::Windows::Web::Http::HttpResponseMessage const &response) noexcept = 0;
16
+ };
17
+
18
+ } // namespace Microsoft::React::Networking
@@ -0,0 +1,22 @@
1
+ // Copyright (c) Microsoft Corporation.
2
+ // Licensed under the MIT License.
3
+
4
+ #pragma once
5
+
6
+ #include <winrt/Windows.Foundation.Collections.h>
7
+ #include <winrt/Windows.Foundation.h>
8
+ #include <winrt/Windows.Web.Http.h>
9
+
10
+ namespace Microsoft::React::Networking {
11
+
12
+ struct IWinRTHttpRequestFactory {
13
+ virtual ~IWinRTHttpRequestFactory() noexcept {}
14
+
15
+ virtual winrt::Windows::Foundation::IAsyncOperation<winrt::Windows::Web::Http::HttpRequestMessage> CreateRequest(
16
+ winrt::Windows::Web::Http::HttpMethod &&method,
17
+ winrt::Windows::Foundation::Uri &&uri,
18
+ winrt::Windows::Foundation::Collections::IMap<winrt::hstring, winrt::Windows::Foundation::IInspectable>
19
+ props) noexcept = 0;
20
+ };
21
+
22
+ } // namespace Microsoft::React::Networking
@@ -11,9 +11,6 @@
11
11
  #include <boost/algorithm/string.hpp>
12
12
  #include <boost/lexical_cast/try_lexical_convert.hpp>
13
13
 
14
- // Windows API
15
- #include <winrt/Windows.Web.Http.Headers.h>
16
-
17
14
  // Standard Library
18
15
  #include <queue>
19
16
  #include <regex>
@@ -27,6 +24,7 @@ using winrt::to_hstring;
27
24
  using winrt::Windows::Foundation::IInspectable;
28
25
  using winrt::Windows::Foundation::IPropertyValue;
29
26
  using winrt::Windows::Foundation::Uri;
27
+ using winrt::Windows::Foundation::Collections::IMap;
30
28
  using winrt::Windows::Web::Http::HttpMethod;
31
29
  using winrt::Windows::Web::Http::HttpRequestMessage;
32
30
  using winrt::Windows::Web::Http::HttpResponseMessage;
@@ -118,7 +116,7 @@ bool OriginPolicyHttpFilter::ConstWcharComparer::operator()(const wchar_t *a, co
118
116
  }
119
117
 
120
118
  /*static*/ bool OriginPolicyHttpFilter::IsSameOrigin(Uri const &u1, Uri const &u2) noexcept {
121
- return u1.SchemeName() == u2.SchemeName() && u1.Host() == u2.Host() && u1.Port() == u2.Port();
119
+ return (u1 && u2) && u1.SchemeName() == u2.SchemeName() && u1.Host() == u2.Host() && u1.Port() == u2.Port();
122
120
  }
123
121
 
124
122
  /*static*/ bool OriginPolicyHttpFilter::IsSimpleCorsRequest(HttpRequestMessage const &request) noexcept {
@@ -373,7 +371,7 @@ bool OriginPolicyHttpFilter::ConstWcharComparer::operator()(const wchar_t *a, co
373
371
  }
374
372
  }
375
373
 
376
- OriginPolicyHttpFilter::OriginPolicyHttpFilter(IHttpFilter &&innerFilter) : m_innerFilter{std::move(innerFilter)} {}
374
+ OriginPolicyHttpFilter::OriginPolicyHttpFilter(IHttpFilter const &innerFilter) : m_innerFilter{innerFilter} {}
377
375
 
378
376
  OriginPolicyHttpFilter::OriginPolicyHttpFilter()
379
377
  : OriginPolicyHttpFilter(winrt::Windows::Web::Http::Filters::HttpBaseProtocolFilter{}) {}
@@ -442,21 +440,24 @@ OriginPolicy OriginPolicyHttpFilter::ValidateRequest(HttpRequestMessage const &r
442
440
  void OriginPolicyHttpFilter::ValidateAllowOrigin(
443
441
  hstring const &allowedOrigin,
444
442
  hstring const &allowCredentials,
445
- IInspectable const &iRequestArgs) const {
443
+ IMap<hstring, IInspectable> props) const {
446
444
  // 4.10.1-2 - null allow origin
447
445
  if (L"null" == allowedOrigin)
448
446
  throw hresult_error{
449
447
  E_INVALIDARG,
450
448
  L"Response header Access-Control-Allow-Origin has a value of [null] which differs from the supplied origin"};
451
449
 
452
- bool withCredentials = iRequestArgs.as<RequestArgs>()->WithCredentials;
450
+ bool withCredentials = props.Lookup(L"RequestArgs").as<RequestArgs>()->WithCredentials;
453
451
  // 4.10.3 - valid wild card allow origin
454
452
  if (!withCredentials && L"*" == allowedOrigin)
455
453
  return;
456
454
 
457
455
  // We assume the source (request) origin is not "*", "null", or empty string. Valid URI is expected
458
456
  // 4.10.4 - Mismatched allow origin
459
- if (allowedOrigin.empty() || !IsSameOrigin(s_origin, Uri{allowedOrigin})) {
457
+ auto taintedOriginProp = props.TryLookup(L"TaintedOrigin");
458
+ auto taintedOrigin = taintedOriginProp && winrt::unbox_value<bool>(taintedOriginProp);
459
+ auto origin = taintedOrigin ? nullptr : s_origin;
460
+ if (allowedOrigin.empty() || !IsSameOrigin(origin, Uri{allowedOrigin})) {
460
461
  hstring errorMessage;
461
462
  if (allowedOrigin.empty())
462
463
  errorMessage = L"No valid origin in response";
@@ -510,14 +511,14 @@ void OriginPolicyHttpFilter::ValidatePreflightResponse(
510
511
 
511
512
  auto controlValues = ExtractAccessControlValues(response.Headers());
512
513
 
513
- auto iRequestArgs = request.Properties().Lookup(L"RequestArgs");
514
+ auto props = request.Properties();
514
515
  // Check if the origin is allowed in conjuction with the withCredentials flag
515
516
  // CORS preflight should always exclude credentials although the subsequent CORS request may include credentials.
516
- ValidateAllowOrigin(controlValues.AllowedOrigin, controlValues.AllowedCredentials, iRequestArgs);
517
+ ValidateAllowOrigin(controlValues.AllowedOrigin, controlValues.AllowedCredentials, props);
517
518
 
518
519
  // See https://fetch.spec.whatwg.org/#cors-preflight-fetch, section 4.8.7.5
519
520
  // Check if the request method is allowed
520
- bool withCredentials = iRequestArgs.as<RequestArgs>()->WithCredentials;
521
+ bool withCredentials = props.Lookup(L"RequestArgs").as<RequestArgs>()->WithCredentials;
521
522
  bool requestMethodAllowed = false;
522
523
  for (const auto &method : controlValues.AllowedMethods) {
523
524
  if (L"*" == method) {
@@ -578,8 +579,8 @@ void OriginPolicyHttpFilter::ValidateResponse(HttpResponseMessage const &respons
578
579
  if (originPolicy == OriginPolicy::SimpleCrossOriginResourceSharing ||
579
580
  originPolicy == OriginPolicy::CrossOriginResourceSharing) {
580
581
  auto controlValues = ExtractAccessControlValues(response.Headers());
581
- auto withCredentials =
582
- response.RequestMessage().Properties().Lookup(L"RequestArgs").try_as<RequestArgs>()->WithCredentials;
582
+ auto props = response.RequestMessage().Properties();
583
+ auto withCredentials = props.Lookup(L"RequestArgs").try_as<RequestArgs>()->WithCredentials;
583
584
 
584
585
  if (GetRuntimeOptionBool("Http.StrictOriginCheckSimpleCors") &&
585
586
  originPolicy == OriginPolicy::SimpleCrossOriginResourceSharing) {
@@ -594,8 +595,7 @@ void OriginPolicyHttpFilter::ValidateResponse(HttpResponseMessage const &respons
594
595
  throw hresult_error{E_INVALIDARG, L"The server does not support CORS or the origin is not allowed"};
595
596
  }
596
597
  } else {
597
- auto iRequestArgs = response.RequestMessage().Properties().Lookup(L"RequestArgs");
598
- ValidateAllowOrigin(controlValues.AllowedOrigin, controlValues.AllowedCredentials, iRequestArgs);
598
+ ValidateAllowOrigin(controlValues.AllowedOrigin, controlValues.AllowedCredentials, props);
599
599
  }
600
600
 
601
601
  if (originPolicy == OriginPolicy::SimpleCrossOriginResourceSharing) {
@@ -678,6 +678,38 @@ ResponseOperation OriginPolicyHttpFilter::SendPreflightAsync(HttpRequestMessage
678
678
  co_return {co_await m_innerFilter.SendRequestAsync(preflightRequest)};
679
679
  }
680
680
 
681
+ #pragma region IRedirectEventSource
682
+
683
+ bool OriginPolicyHttpFilter::OnRedirecting(
684
+ HttpRequestMessage const &request,
685
+ HttpResponseMessage const &response) noexcept {
686
+ // Consider the following scenario.
687
+ // User signs in to http://a.com and visits a page that makes CORS request to http://b.com with origin=http://a.com.
688
+ // Http://b.com reponds with a redirect to http://a.com. The browser follows the redirect to http://a.com with
689
+ // origin=http://a.com. Since the origin matches the URL, the request is authorized at http://a.com, but it actually
690
+ // allows http://b.com to bypass the CORS check at http://a.com since the redirected URL is from http://b.com.
691
+ if (!IsSameOrigin(response.Headers().Location(), request.RequestUri()) &&
692
+ !IsSameOrigin(s_origin, request.RequestUri())) {
693
+ // By masking the origin field in the request header, we make it impossible for the server to set a single value for
694
+ // the access-control-allow-origin header. It means, the only way to support redirect is that server allows access
695
+ // from all sites through wildcard.
696
+ request.Headers().Insert(L"Origin", L"null");
697
+
698
+ auto props = request.Properties();
699
+ // Look for 'RequestArgs' key to ensure we are redirecting the main request.
700
+ if (auto iReqArgs = props.TryLookup(L"RequestArgs")) {
701
+ props.Insert(L"TaintedOrigin", winrt::box_value(true));
702
+ } else {
703
+ // Abort redirection if the request is either preflight or extraneous.
704
+ return false;
705
+ }
706
+ }
707
+
708
+ return true;
709
+ }
710
+
711
+ #pragma endregion IRedirectEventSource
712
+
681
713
  #pragma region IHttpFilter
682
714
 
683
715
  ResponseOperation OriginPolicyHttpFilter::SendRequestAsync(HttpRequestMessage const &request) {
@@ -3,11 +3,14 @@
3
3
 
4
4
  #pragma once
5
5
 
6
+ #include "IRedirectEventSource.h"
6
7
  #include "OriginPolicy.h"
7
8
 
8
9
  // Windows API
10
+ #include <winrt/Windows.Foundation.Collections.h>
9
11
  #include <winrt/Windows.Foundation.h>
10
12
  #include <winrt/Windows.Web.Http.Filters.h>
13
+ #include <winrt/Windows.Web.Http.Headers.h>
11
14
  #include <winrt/Windows.Web.Http.h>
12
15
 
13
16
  // Standard Library
@@ -16,7 +19,8 @@
16
19
  namespace Microsoft::React::Networking {
17
20
 
18
21
  class OriginPolicyHttpFilter
19
- : public winrt::implements<OriginPolicyHttpFilter, winrt::Windows::Web::Http::Filters::IHttpFilter> {
22
+ : public winrt::
23
+ implements<OriginPolicyHttpFilter, winrt::Windows::Web::Http::Filters::IHttpFilter, IRedirectEventSource> {
20
24
  public:
21
25
  struct ConstWcharComparer {
22
26
  bool operator()(const wchar_t *, const wchar_t *) const;
@@ -75,7 +79,7 @@ class OriginPolicyHttpFilter
75
79
  winrt::Windows::Web::Http::HttpResponseMessage const &response,
76
80
  bool removeAll);
77
81
 
78
- OriginPolicyHttpFilter(winrt::Windows::Web::Http::Filters::IHttpFilter &&innerFilter);
82
+ OriginPolicyHttpFilter(winrt::Windows::Web::Http::Filters::IHttpFilter const &innerFilter);
79
83
 
80
84
  OriginPolicyHttpFilter();
81
85
 
@@ -92,13 +96,22 @@ class OriginPolicyHttpFilter
92
96
  void ValidateAllowOrigin(
93
97
  winrt::hstring const &allowedOrigin,
94
98
  winrt::hstring const &allowCredentials,
95
- winrt::Windows::Foundation::IInspectable const &iArgs) const;
99
+ winrt::Windows::Foundation::Collections::IMap<winrt::hstring, winrt::Windows::Foundation::IInspectable> props)
100
+ const;
96
101
 
97
102
  winrt::Windows::Foundation::IAsyncOperationWithProgress<
98
103
  winrt::Windows::Web::Http::HttpResponseMessage,
99
104
  winrt::Windows::Web::Http::HttpProgress>
100
105
  SendPreflightAsync(winrt::Windows::Web::Http::HttpRequestMessage const &request) const;
101
106
 
107
+ #pragma region IRedirectEventSource
108
+
109
+ bool OnRedirecting(
110
+ winrt::Windows::Web::Http::HttpRequestMessage const &request,
111
+ winrt::Windows::Web::Http::HttpResponseMessage const &response) noexcept override;
112
+
113
+ #pragma endregion IRedirectEventSource
114
+
102
115
  #pragma region IHttpFilter
103
116
 
104
117
  winrt::Windows::Foundation::IAsyncOperationWithProgress<