react-native-windows 0.72.30 → 0.72.32

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.
@@ -10,11 +10,11 @@
10
10
  -->
11
11
  <Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
12
12
  <PropertyGroup>
13
- <ReactNativeWindowsVersion>0.72.30</ReactNativeWindowsVersion>
13
+ <ReactNativeWindowsVersion>0.72.32</ReactNativeWindowsVersion>
14
14
  <ReactNativeWindowsMajor>0</ReactNativeWindowsMajor>
15
15
  <ReactNativeWindowsMinor>72</ReactNativeWindowsMinor>
16
- <ReactNativeWindowsPatch>30</ReactNativeWindowsPatch>
16
+ <ReactNativeWindowsPatch>32</ReactNativeWindowsPatch>
17
17
  <ReactNativeWindowsCanary>false</ReactNativeWindowsCanary>
18
- <ReactNativeWindowsCommitId>26ed970fceeb6617477a575238c746aadf4a6a12</ReactNativeWindowsCommitId>
18
+ <ReactNativeWindowsCommitId>5e396ba8c0e2b687eeb194d52c595cf217c7f280</ReactNativeWindowsCommitId>
19
19
  </PropertyGroup>
20
20
  </Project>
@@ -16,6 +16,7 @@
16
16
  #include <regex>
17
17
 
18
18
  using std::set;
19
+ using std::string;
19
20
  using std::wstring;
20
21
 
21
22
  using winrt::hresult_error;
@@ -37,22 +38,26 @@ namespace Microsoft::React::Networking {
37
38
 
38
39
  #pragma region OriginPolicyHttpFilter
39
40
 
40
- #pragma region ConstWcharComparer
41
+ #pragma region CaseInsensitiveComparer
41
42
 
42
- bool OriginPolicyHttpFilter::ConstWcharComparer::operator()(const wchar_t *a, const wchar_t *b) const {
43
+ bool OriginPolicyHttpFilter::CaseInsensitiveComparer::operator()(const wchar_t *a, const wchar_t *b) const {
43
44
  return _wcsicmp(a, b) < 0;
44
45
  }
45
46
 
46
- #pragma endregion ConstWcharComparer
47
+ bool OriginPolicyHttpFilter::CaseInsensitiveComparer::operator()(const wstring &a, const wstring &b) const {
48
+ return _wcsicmp(a.c_str(), b.c_str()) < 0;
49
+ }
50
+
51
+ #pragma endregion CaseInsensitiveComparer
47
52
 
48
53
  // https://fetch.spec.whatwg.org/#forbidden-method
49
- /*static*/ set<const wchar_t *, OriginPolicyHttpFilter::ConstWcharComparer> OriginPolicyHttpFilter::s_forbiddenMethods =
50
- {L"CONNECT", L"TRACE", L"TRACK"};
54
+ /*static*/ set<const wchar_t *, OriginPolicyHttpFilter::CaseInsensitiveComparer>
55
+ OriginPolicyHttpFilter::s_forbiddenMethods = {L"CONNECT", L"TRACE", L"TRACK"};
51
56
 
52
- /*static*/ set<const wchar_t *, OriginPolicyHttpFilter::ConstWcharComparer>
57
+ /*static*/ set<const wchar_t *, OriginPolicyHttpFilter::CaseInsensitiveComparer>
53
58
  OriginPolicyHttpFilter::s_simpleCorsMethods = {L"GET", L"HEAD", L"POST"};
54
59
 
55
- /*static*/ set<const wchar_t *, OriginPolicyHttpFilter::ConstWcharComparer>
60
+ /*static*/ set<const wchar_t *, OriginPolicyHttpFilter::CaseInsensitiveComparer>
56
61
  OriginPolicyHttpFilter::s_simpleCorsRequestHeaderNames = {
57
62
  L"Accept",
58
63
  L"Accept-Language",
@@ -64,11 +69,11 @@ bool OriginPolicyHttpFilter::ConstWcharComparer::operator()(const wchar_t *a, co
64
69
  L"Viewport-Width",
65
70
  L"Width"};
66
71
 
67
- /*static*/ set<const wchar_t *, OriginPolicyHttpFilter::ConstWcharComparer>
72
+ /*static*/ set<const wchar_t *, OriginPolicyHttpFilter::CaseInsensitiveComparer>
68
73
  OriginPolicyHttpFilter::s_simpleCorsResponseHeaderNames =
69
74
  {L"Cache-Control", L"Content-Language", L"Content-Type", L"Expires", L"Last-Modified", L"Pragma"};
70
75
 
71
- /*static*/ set<const wchar_t *, OriginPolicyHttpFilter::ConstWcharComparer>
76
+ /*static*/ set<const wchar_t *, OriginPolicyHttpFilter::CaseInsensitiveComparer>
72
77
  OriginPolicyHttpFilter::s_simpleCorsContentTypeValues = {
73
78
  L"application/x-www-form-urlencoded",
74
79
  L"multipart/form-data",
@@ -76,7 +81,7 @@ bool OriginPolicyHttpFilter::ConstWcharComparer::operator()(const wchar_t *a, co
76
81
 
77
82
  // https://fetch.spec.whatwg.org/#forbidden-header-name
78
83
  // Chromium still bans "User-Agent" due to https://crbug.com/571722
79
- /*static*/ set<const wchar_t *, OriginPolicyHttpFilter::ConstWcharComparer>
84
+ /*static*/ set<const wchar_t *, OriginPolicyHttpFilter::CaseInsensitiveComparer>
80
85
  OriginPolicyHttpFilter::s_corsForbiddenRequestHeaderNames = {
81
86
  L"Accept-Charset",
82
87
  L"Accept-Encoding",
@@ -99,24 +104,15 @@ bool OriginPolicyHttpFilter::ConstWcharComparer::operator()(const wchar_t *a, co
99
104
  L"Upgrade",
100
105
  L"Via"};
101
106
 
102
- /*static*/ set<const wchar_t *, OriginPolicyHttpFilter::ConstWcharComparer>
107
+ /*static*/ set<const wchar_t *, OriginPolicyHttpFilter::CaseInsensitiveComparer>
103
108
  OriginPolicyHttpFilter::s_cookieSettingResponseHeaders = {
104
109
  L"Set-Cookie",
105
110
  L"Set-Cookie2", // Deprecated by the spec, but probably still used
106
111
  };
107
112
 
108
- /*static*/ set<const wchar_t *, OriginPolicyHttpFilter::ConstWcharComparer>
113
+ /*static*/ set<const wchar_t *, OriginPolicyHttpFilter::CaseInsensitiveComparer>
109
114
  OriginPolicyHttpFilter::s_corsForbiddenRequestHeaderNamePrefixes = {L"Proxy-", L"Sec-"};
110
115
 
111
- /*static*/ Uri OriginPolicyHttpFilter::s_origin{nullptr};
112
-
113
- /*static*/ void OriginPolicyHttpFilter::SetStaticOrigin(std::string &&url) {
114
- if (!url.empty())
115
- s_origin = Uri{to_hstring(url)};
116
- else
117
- s_origin = nullptr;
118
- }
119
-
120
116
  /*static*/ bool OriginPolicyHttpFilter::IsSameOrigin(Uri const &u1, Uri const &u2) noexcept {
121
117
  return (u1 && u2) && u1.SchemeName() == u2.SchemeName() && u1.Host() == u2.Host() && u1.Port() == u2.Port();
122
118
  }
@@ -154,8 +150,16 @@ bool OriginPolicyHttpFilter::ConstWcharComparer::operator()(const wchar_t *a, co
154
150
  return s_simpleCorsMethods.find(request.Method().ToString().c_str()) != s_simpleCorsMethods.cend();
155
151
  }
156
152
 
157
- /*static*/ Uri OriginPolicyHttpFilter::GetOrigin(Uri const &uri) noexcept {
158
- return Uri{uri.SchemeName() + L"://" + uri.Host() + L":" + to_hstring(uri.Port())};
153
+ /*static*/ const hstring OriginPolicyHttpFilter::GetOrigin(Uri const &uri) noexcept {
154
+ auto const &scheme = uri.SchemeName();
155
+ auto port = uri.Port();
156
+
157
+ hstring result = scheme + L"://" + uri.Host();
158
+ if (!(port == 80 && scheme == L"http") && !(port == 443 && scheme == L"https")) {
159
+ result = result + L":" + to_hstring(port);
160
+ }
161
+
162
+ return result;
159
163
  }
160
164
 
161
165
  /*static*/ bool OriginPolicyHttpFilter::AreSafeRequestHeaders(
@@ -293,7 +297,7 @@ bool OriginPolicyHttpFilter::ConstWcharComparer::operator()(const wchar_t *a, co
293
297
  }
294
298
 
295
299
  /*static*/ OriginPolicyHttpFilter::AccessControlValues OriginPolicyHttpFilter::ExtractAccessControlValues(
296
- winrt::Windows::Foundation::Collections::IMap<hstring, hstring> const &headers) {
300
+ IMap<hstring, hstring> const &headers) {
297
301
  using std::wregex;
298
302
  using std::wsregex_token_iterator;
299
303
 
@@ -373,10 +377,14 @@ bool OriginPolicyHttpFilter::ConstWcharComparer::operator()(const wchar_t *a, co
373
377
  }
374
378
  }
375
379
 
376
- OriginPolicyHttpFilter::OriginPolicyHttpFilter(IHttpFilter const &innerFilter) : m_innerFilter{innerFilter} {}
380
+ OriginPolicyHttpFilter::OriginPolicyHttpFilter(string &&origin, IHttpFilter const &innerFilter)
381
+ : m_origin{nullptr}, m_innerFilter{innerFilter} {
382
+ if (!origin.empty())
383
+ m_origin = Uri{to_hstring(origin)};
384
+ }
377
385
 
378
- OriginPolicyHttpFilter::OriginPolicyHttpFilter()
379
- : OriginPolicyHttpFilter(winrt::Windows::Web::Http::Filters::HttpBaseProtocolFilter{}) {}
386
+ OriginPolicyHttpFilter::OriginPolicyHttpFilter(string &&origin)
387
+ : OriginPolicyHttpFilter(std::move(origin), winrt::Windows::Web::Http::Filters::HttpBaseProtocolFilter{}) {}
380
388
 
381
389
  OriginPolicy OriginPolicyHttpFilter::ValidateRequest(HttpRequestMessage const &request) {
382
390
  auto effectiveOriginPolicy =
@@ -386,17 +394,17 @@ OriginPolicy OriginPolicyHttpFilter::ValidateRequest(HttpRequestMessage const &r
386
394
  return effectiveOriginPolicy;
387
395
 
388
396
  case OriginPolicy::SameOrigin:
389
- if (!IsSameOrigin(s_origin, request.RequestUri()))
397
+ if (!IsSameOrigin(m_origin, request.RequestUri()))
390
398
  throw hresult_error{E_INVALIDARG, L"SOP (same-origin policy) is enforced"};
391
399
  break;
392
400
 
393
401
  case OriginPolicy::SimpleCrossOriginResourceSharing:
394
402
  // Check for disallowed mixed content
395
403
  if (GetRuntimeOptionBool("Http.BlockMixedContentSimpleCors") &&
396
- s_origin.SchemeName() != request.RequestUri().SchemeName())
404
+ m_origin.SchemeName() != request.RequestUri().SchemeName())
397
405
  throw hresult_error{E_INVALIDARG, L"The origin and request URLs must have the same scheme"};
398
406
 
399
- if (IsSameOrigin(s_origin, request.RequestUri()))
407
+ if (IsSameOrigin(m_origin, request.RequestUri()))
400
408
  // Same origin. Therefore, skip Cross-Origin handling.
401
409
  effectiveOriginPolicy = OriginPolicy::SameOrigin;
402
410
  else if (!IsSimpleCorsRequest(request))
@@ -412,7 +420,7 @@ OriginPolicy OriginPolicyHttpFilter::ValidateRequest(HttpRequestMessage const &r
412
420
  // Example: On the Edge browser, an XHR request with the "Host" header set gets rejected as unsafe.
413
421
  // https://fetch.spec.whatwg.org/#forbidden-header-name
414
422
 
415
- if (s_origin.SchemeName() != request.RequestUri().SchemeName())
423
+ if (m_origin.SchemeName() != request.RequestUri().SchemeName())
416
424
  throw hresult_error{E_INVALIDARG, L"The origin and request URLs must have the same scheme"};
417
425
 
418
426
  if (!AreSafeRequestHeaders(request.Headers()))
@@ -421,7 +429,7 @@ OriginPolicy OriginPolicyHttpFilter::ValidateRequest(HttpRequestMessage const &r
421
429
  if (s_forbiddenMethods.find(request.Method().ToString().c_str()) != s_forbiddenMethods.cend())
422
430
  throw hresult_error{E_INVALIDARG, L"Request method not allowed in cross-origin resource sharing"};
423
431
 
424
- if (IsSameOrigin(s_origin, request.RequestUri()))
432
+ if (IsSameOrigin(m_origin, request.RequestUri()))
425
433
  effectiveOriginPolicy = OriginPolicy::SameOrigin;
426
434
  else if (IsSimpleCorsRequest(request))
427
435
  effectiveOriginPolicy = OriginPolicy::SimpleCrossOriginResourceSharing;
@@ -458,7 +466,7 @@ void OriginPolicyHttpFilter::ValidateAllowOrigin(
458
466
  // 4.10.4 - Mismatched allow origin
459
467
  auto taintedOriginProp = props.TryLookup(L"TaintedOrigin");
460
468
  auto taintedOrigin = taintedOriginProp && winrt::unbox_value<bool>(taintedOriginProp);
461
- auto origin = taintedOrigin ? nullptr : s_origin;
469
+ auto origin = taintedOrigin ? nullptr : m_origin;
462
470
  if (allowedOrigin.empty() || !IsSameOrigin(origin, Uri{allowedOrigin})) {
463
471
  hstring errorMessage;
464
472
  if (allowedOrigin.empty())
@@ -589,7 +597,7 @@ void OriginPolicyHttpFilter::ValidateResponse(HttpResponseMessage const &respons
589
597
  bool originAllowed = false;
590
598
  for (const auto &header : response.Headers()) {
591
599
  if (boost::iequals(header.Key(), L"Access-Control-Allow-Origin")) {
592
- originAllowed |= L"*" == header.Value() || s_origin == Uri{header.Value()};
600
+ originAllowed |= L"*" == header.Value() || m_origin == Uri{header.Value()};
593
601
  }
594
602
  }
595
603
 
@@ -677,7 +685,7 @@ ResponseOperation OriginPolicyHttpFilter::SendPreflightAsync(HttpRequestMessage
677
685
  }
678
686
 
679
687
  preflightRequest.Headers().Insert(L"Access-Control-Request-Headers", headerNames);
680
- preflightRequest.Headers().Insert(L"Origin", s_origin.AbsoluteCanonicalUri());
688
+ preflightRequest.Headers().Insert(L"Origin", GetOrigin(m_origin));
681
689
  preflightRequest.Headers().Insert(L"Sec-Fetch-Mode", L"CORS");
682
690
 
683
691
  co_return {co_await m_innerFilter.SendRequestAsync(preflightRequest)};
@@ -694,7 +702,7 @@ bool OriginPolicyHttpFilter::OnRedirecting(
694
702
  // origin=http://a.com. Since the origin matches the URL, the request is authorized at http://a.com, but it actually
695
703
  // allows http://b.com to bypass the CORS check at http://a.com since the redirected URL is from http://b.com.
696
704
  if (!IsSameOrigin(response.Headers().Location(), request.RequestUri()) &&
697
- !IsSameOrigin(s_origin, request.RequestUri())) {
705
+ !IsSameOrigin(m_origin, request.RequestUri())) {
698
706
  // By masking the origin field in the request header, we make it impossible for the server to set a single value for
699
707
  // the access-control-allow-origin header. It means, the only way to support redirect is that server allows access
700
708
  // from all sites through wildcard.
@@ -726,7 +734,7 @@ ResponseOperation OriginPolicyHttpFilter::SendRequestAsync(HttpRequestMessage co
726
734
  // Allow only HTTP or HTTPS schemes
727
735
  if (GetRuntimeOptionBool("Http.StrictScheme") && coRequest.RequestUri().SchemeName() != L"https" &&
728
736
  coRequest.RequestUri().SchemeName() != L"http")
729
- throw hresult_error{E_INVALIDARG, L"Invalid URL scheme: [" + s_origin.SchemeName() + L"]"};
737
+ throw hresult_error{E_INVALIDARG, L"Invalid URL scheme: [" + m_origin.SchemeName() + L"]"};
730
738
 
731
739
  if (!GetRuntimeOptionBool("Http.OmitCredentials")) {
732
740
  coRequest.Properties().Lookup(L"RequestArgs").as<RequestArgs>()->WithCredentials = false;
@@ -763,7 +771,7 @@ ResponseOperation OriginPolicyHttpFilter::SendRequestAsync(HttpRequestMessage co
763
771
 
764
772
  if (originPolicy == OriginPolicy::SimpleCrossOriginResourceSharing ||
765
773
  originPolicy == OriginPolicy::CrossOriginResourceSharing) {
766
- coRequest.Headers().Insert(L"Origin", s_origin.AbsoluteCanonicalUri());
774
+ coRequest.Headers().Insert(L"Origin", GetOrigin(m_origin));
767
775
  }
768
776
 
769
777
  auto response = co_await m_innerFilter.SendRequestAsync(coRequest);
@@ -22,42 +22,40 @@ class OriginPolicyHttpFilter
22
22
  : public winrt::
23
23
  implements<OriginPolicyHttpFilter, winrt::Windows::Web::Http::Filters::IHttpFilter, IRedirectEventSource> {
24
24
  public:
25
- struct ConstWcharComparer {
25
+ struct CaseInsensitiveComparer {
26
26
  bool operator()(const wchar_t *, const wchar_t *) const;
27
+ bool operator()(const std::wstring &, const std::wstring &) const;
27
28
  };
28
29
 
29
30
  private:
30
- static std::set<const wchar_t *, ConstWcharComparer> s_forbiddenMethods;
31
- static std::set<const wchar_t *, ConstWcharComparer> s_simpleCorsMethods;
32
- static std::set<const wchar_t *, ConstWcharComparer> s_simpleCorsRequestHeaderNames;
33
- static std::set<const wchar_t *, ConstWcharComparer> s_simpleCorsResponseHeaderNames;
34
- static std::set<const wchar_t *, ConstWcharComparer> s_simpleCorsContentTypeValues;
35
- static std::set<const wchar_t *, ConstWcharComparer> s_corsForbiddenRequestHeaderNames;
36
- static std::set<const wchar_t *, ConstWcharComparer> s_corsForbiddenRequestHeaderNamePrefixes;
37
- static std::set<const wchar_t *, ConstWcharComparer> s_cookieSettingResponseHeaders;
38
-
39
- // NOTE: Assumes static origin through owning client/resource/module/(React) instance's lifetime.
40
- static winrt::Windows::Foundation::Uri s_origin;
31
+ static std::set<const wchar_t *, CaseInsensitiveComparer> s_forbiddenMethods;
32
+ static std::set<const wchar_t *, CaseInsensitiveComparer> s_simpleCorsMethods;
33
+ static std::set<const wchar_t *, CaseInsensitiveComparer> s_simpleCorsRequestHeaderNames;
34
+ static std::set<const wchar_t *, CaseInsensitiveComparer> s_simpleCorsResponseHeaderNames;
35
+ static std::set<const wchar_t *, CaseInsensitiveComparer> s_simpleCorsContentTypeValues;
36
+ static std::set<const wchar_t *, CaseInsensitiveComparer> s_corsForbiddenRequestHeaderNames;
37
+ static std::set<const wchar_t *, CaseInsensitiveComparer> s_corsForbiddenRequestHeaderNamePrefixes;
38
+ static std::set<const wchar_t *, CaseInsensitiveComparer> s_cookieSettingResponseHeaders;
41
39
 
42
40
  struct AccessControlValues {
43
41
  winrt::hstring AllowedOrigin;
44
42
  winrt::hstring AllowedCredentials;
45
- std::set<std::wstring> AllowedHeaders;
43
+ std::set<std::wstring, CaseInsensitiveComparer> AllowedHeaders;
46
44
  std::set<std::wstring> AllowedMethods;
47
- std::set<std::wstring> ExposedHeaders;
45
+ std::set<std::wstring, CaseInsensitiveComparer> ExposedHeaders;
48
46
  size_t MaxAge;
49
47
  };
50
48
 
49
+ winrt::Windows::Foundation::Uri m_origin;
50
+
51
51
  winrt::Windows::Web::Http::Filters::IHttpFilter m_innerFilter;
52
52
 
53
53
  public:
54
- static void SetStaticOrigin(std::string &&url);
55
-
56
54
  static bool IsSameOrigin(
57
55
  winrt::Windows::Foundation::Uri const &u1,
58
56
  winrt::Windows::Foundation::Uri const &u2) noexcept;
59
57
 
60
- static winrt::Windows::Foundation::Uri GetOrigin(winrt::Windows::Foundation::Uri const &uri) noexcept;
58
+ static const winrt::hstring GetOrigin(winrt::Windows::Foundation::Uri const &uri) noexcept;
61
59
 
62
60
  static bool IsSimpleCorsRequest(winrt::Windows::Web::Http::HttpRequestMessage const &request) noexcept;
63
61
 
@@ -79,9 +77,9 @@ class OriginPolicyHttpFilter
79
77
  winrt::Windows::Web::Http::HttpResponseMessage const &response,
80
78
  bool removeAll);
81
79
 
82
- OriginPolicyHttpFilter(winrt::Windows::Web::Http::Filters::IHttpFilter const &innerFilter);
80
+ OriginPolicyHttpFilter(std::string &&origin, winrt::Windows::Web::Http::Filters::IHttpFilter const &innerFilter);
83
81
 
84
- OriginPolicyHttpFilter();
82
+ OriginPolicyHttpFilter(std::string &&origin);
85
83
 
86
84
  OriginPolicy ValidateRequest(winrt::Windows::Web::Http::HttpRequestMessage const &request);
87
85
 
@@ -641,8 +641,7 @@ void WinRTHttpResource::AddResponseHandler(shared_ptr<IResponseHandler> response
641
641
 
642
642
  #pragma region IHttpResource
643
643
 
644
- /*static*/ shared_ptr<IHttpResource> IHttpResource::Make(
645
- winrt::Windows::Foundation::IInspectable const &inspectableProperties) noexcept {
644
+ /*static*/ shared_ptr<IHttpResource> IHttpResource::Make(IInspectable const &inspectableProperties) noexcept {
646
645
  using namespace winrt::Microsoft::ReactNative;
647
646
  using winrt::Windows::Web::Http::HttpClient;
648
647
 
@@ -653,8 +652,7 @@ void WinRTHttpResource::AddResponseHandler(shared_ptr<IResponseHandler> response
653
652
  client = HttpClient{redirFilter};
654
653
  } else {
655
654
  auto globalOrigin = GetRuntimeOptionString("Http.GlobalOrigin");
656
- OriginPolicyHttpFilter::SetStaticOrigin(std::move(globalOrigin));
657
- auto opFilter = winrt::make<OriginPolicyHttpFilter>(redirFilter);
655
+ auto opFilter = winrt::make<OriginPolicyHttpFilter>(std::move(globalOrigin), redirFilter);
658
656
  redirFilter.as<RedirectHttpFilter>()->SetRedirectSource(opFilter.as<IRedirectEventSource>());
659
657
 
660
658
  client = HttpClient{opFilter};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-windows",
3
- "version": "0.72.30",
3
+ "version": "0.72.32",
4
4
  "license": "MIT",
5
5
  "repository": {
6
6
  "type": "git",