react-native-windows 0.70.0-preview.2 → 0.70.1

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 (30) hide show
  1. package/Libraries/Core/ReactNativeVersion.js +1 -1
  2. package/Microsoft.ReactNative/JSDispatcherWriter.cpp +60 -22
  3. package/Microsoft.ReactNative/JSDispatcherWriter.h +5 -3
  4. package/Microsoft.ReactNative/Pch/pch.h +0 -1
  5. package/Microsoft.ReactNative/ReactHost/ReactInstanceWin.cpp +1 -0
  6. package/Microsoft.ReactNative/TurboModulesProvider.cpp +146 -84
  7. package/Microsoft.ReactNative/TurboModulesProvider.h +5 -0
  8. package/Microsoft.ReactNative/Views/ViewManagerBase.cpp +4 -2
  9. package/Microsoft.ReactNative.Cxx/JSI/LongLivedJsiValue.h +84 -0
  10. package/Microsoft.ReactNative.Cxx/Microsoft.ReactNative.Cxx.vcxitems +1 -0
  11. package/Microsoft.ReactNative.Cxx/Microsoft.ReactNative.Cxx.vcxitems.filters +3 -0
  12. package/Mso/src/dispatchQueue/uiScheduler_winrt.cpp +6 -1
  13. package/PropertySheets/Generated/PackageVersion.g.props +2 -2
  14. package/Shared/InstanceManager.cpp +29 -0
  15. package/Shared/InstanceManager.h +14 -0
  16. package/Shared/Modules/HttpModule.cpp +4 -2
  17. package/Shared/Networking/IHttpResource.h +1 -1
  18. package/Shared/Networking/IRedirectEventSource.h +18 -0
  19. package/Shared/Networking/IWinRTHttpRequestFactory.h +22 -0
  20. package/Shared/Networking/OriginPolicyHttpFilter.cpp +47 -16
  21. package/Shared/Networking/OriginPolicyHttpFilter.h +16 -3
  22. package/Shared/Networking/RedirectHttpFilter.cpp +283 -0
  23. package/Shared/Networking/RedirectHttpFilter.h +97 -0
  24. package/Shared/Networking/WinRTHttpResource.cpp +207 -154
  25. package/Shared/Networking/WinRTHttpResource.h +17 -4
  26. package/Shared/OInstance.cpp +16 -1
  27. package/Shared/OInstance.h +4 -13
  28. package/Shared/Shared.vcxitems +4 -0
  29. package/Shared/Shared.vcxitems.filters +12 -0
  30. package/package.json +8 -8
@@ -0,0 +1,283 @@
1
+ // Copyright (c) Microsoft Corporation.
2
+ // Licensed under the MIT License.
3
+
4
+ #undef WINRT_LEAN_AND_MEAN
5
+
6
+ #include "RedirectHttpFilter.h"
7
+
8
+ #include "WinRTTypes.h"
9
+
10
+ // Windows API
11
+ #include <winapifamily.h>
12
+ #include <winrt/Windows.Web.Http.Headers.h>
13
+ #if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
14
+ #include <WinInet.h>
15
+ #else
16
+ #define INTERNET_ERROR_BASE 12000
17
+ #define ERROR_HTTP_REDIRECT_FAILED (INTERNET_ERROR_BASE + 156)
18
+ #endif
19
+
20
+ namespace {
21
+ constexpr size_t DefaultMaxRedirects = 20;
22
+ } // namespace
23
+
24
+ using winrt::Windows::Foundation::Uri;
25
+ using winrt::Windows::Foundation::Collections::IVector;
26
+ using winrt::Windows::Security::Credentials::PasswordCredential;
27
+ using winrt::Windows::Security::Cryptography::Certificates::Certificate;
28
+ using winrt::Windows::Security::Cryptography::Certificates::ChainValidationResult;
29
+ using winrt::Windows::Web::Http::HttpMethod;
30
+ using winrt::Windows::Web::Http::HttpRequestMessage;
31
+ using winrt::Windows::Web::Http::HttpResponseMessage;
32
+ using winrt::Windows::Web::Http::HttpStatusCode;
33
+ using winrt::Windows::Web::Http::Filters::IHttpBaseProtocolFilter;
34
+ using winrt::Windows::Web::Http::Filters::IHttpFilter;
35
+
36
+ namespace Microsoft::React::Networking {
37
+
38
+ #pragma region RedirectHttpFilter
39
+
40
+ RedirectHttpFilter::RedirectHttpFilter(
41
+ size_t maxRedirects,
42
+ IHttpFilter &&innerFilter,
43
+ IHttpFilter &&innerFilterWithNoCredentials) noexcept
44
+ : m_maximumRedirects{maxRedirects},
45
+ m_innerFilter{std::move(innerFilter)},
46
+ m_innerFilterWithNoCredentials{std::move(innerFilterWithNoCredentials)} {
47
+ // Prevent automatic redirections.
48
+ if (auto baseFilter = m_innerFilter.try_as<IHttpBaseProtocolFilter>()) {
49
+ baseFilter.AllowAutoRedirect(false);
50
+ baseFilter.AllowUI(false);
51
+ }
52
+ if (auto baseFilter = m_innerFilterWithNoCredentials.try_as<IHttpBaseProtocolFilter>()) {
53
+ baseFilter.AllowAutoRedirect(false);
54
+ baseFilter.AllowUI(false);
55
+ }
56
+ }
57
+
58
+ RedirectHttpFilter::RedirectHttpFilter(IHttpFilter &&innerFilter, IHttpFilter &&innerFilterWithNoCredentials) noexcept
59
+ : RedirectHttpFilter(DefaultMaxRedirects, std::move(innerFilter), std::move(innerFilterWithNoCredentials)) {}
60
+
61
+ RedirectHttpFilter::RedirectHttpFilter() noexcept
62
+ : RedirectHttpFilter(
63
+ winrt::Windows::Web::Http::Filters::HttpBaseProtocolFilter{},
64
+ winrt::Windows::Web::Http::Filters::HttpBaseProtocolFilter{}) {}
65
+
66
+ void RedirectHttpFilter::SetRequestFactory(std::weak_ptr<IWinRTHttpRequestFactory> factory) noexcept {
67
+ m_requestFactory = factory;
68
+ }
69
+
70
+ void RedirectHttpFilter::SetRedirectSource(
71
+ winrt::com_ptr<Microsoft::React::Networking::IRedirectEventSource> const &eventSrc) noexcept {
72
+ m_redirEventSrc = eventSrc;
73
+ }
74
+
75
+ #pragma region IHttpBaseProtocolFilter
76
+
77
+ bool RedirectHttpFilter::AllowAutoRedirect() const {
78
+ return m_allowAutoRedirect;
79
+ }
80
+
81
+ void RedirectHttpFilter::AllowAutoRedirect(bool value) {
82
+ m_allowAutoRedirect = value;
83
+ }
84
+
85
+ bool RedirectHttpFilter::AllowUI() const {
86
+ return false;
87
+ }
88
+ void RedirectHttpFilter::AllowUI(bool /*value*/) const {
89
+ throw winrt::hresult_error{HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED)};
90
+ }
91
+
92
+ bool RedirectHttpFilter::AutomaticDecompression() const {
93
+ if (auto baseFilter = m_innerFilter.try_as<IHttpBaseProtocolFilter>()) {
94
+ return baseFilter.AutomaticDecompression();
95
+ }
96
+
97
+ return false;
98
+ }
99
+ void RedirectHttpFilter::AutomaticDecompression(bool value) const {
100
+ if (auto baseFilter = m_innerFilter.try_as<IHttpBaseProtocolFilter>()) {
101
+ baseFilter.AutomaticDecompression(value);
102
+ }
103
+ }
104
+
105
+ winrt::Windows::Web::Http::Filters::HttpCacheControl RedirectHttpFilter::CacheControl() const {
106
+ if (auto baseFilter = m_innerFilter.try_as<IHttpBaseProtocolFilter>()) {
107
+ return baseFilter.CacheControl();
108
+ }
109
+
110
+ return nullptr;
111
+ }
112
+
113
+ winrt::Windows::Web::Http::HttpCookieManager RedirectHttpFilter::CookieManager() const {
114
+ if (auto baseFilter = m_innerFilter.try_as<IHttpBaseProtocolFilter>()) {
115
+ return baseFilter.CookieManager();
116
+ }
117
+
118
+ return nullptr;
119
+ }
120
+
121
+ Certificate RedirectHttpFilter::ClientCertificate() const {
122
+ if (auto baseFilter = m_innerFilter.try_as<IHttpBaseProtocolFilter>()) {
123
+ return baseFilter.ClientCertificate();
124
+ }
125
+
126
+ return nullptr;
127
+ }
128
+ void RedirectHttpFilter::ClientCertificate(Certificate const &value) const {
129
+ if (auto baseFilter = m_innerFilter.try_as<IHttpBaseProtocolFilter>()) {
130
+ baseFilter.ClientCertificate(value);
131
+ }
132
+ }
133
+
134
+ IVector<ChainValidationResult> RedirectHttpFilter::IgnorableServerCertificateErrors() const {
135
+ if (auto baseFilter = m_innerFilter.try_as<IHttpBaseProtocolFilter>()) {
136
+ return baseFilter.IgnorableServerCertificateErrors();
137
+ }
138
+
139
+ return nullptr;
140
+ }
141
+
142
+ uint32_t RedirectHttpFilter::MaxConnectionsPerServer() const {
143
+ if (auto baseFilter = m_innerFilter.try_as<IHttpBaseProtocolFilter>()) {
144
+ return baseFilter.MaxConnectionsPerServer();
145
+ }
146
+
147
+ return 0;
148
+ }
149
+ void RedirectHttpFilter::MaxConnectionsPerServer(uint32_t value) const {
150
+ if (auto baseFilter = m_innerFilter.try_as<IHttpBaseProtocolFilter>()) {
151
+ baseFilter.MaxConnectionsPerServer(value);
152
+ }
153
+ }
154
+
155
+ PasswordCredential RedirectHttpFilter::ProxyCredential() const {
156
+ if (auto baseFilter = m_innerFilter.try_as<IHttpBaseProtocolFilter>()) {
157
+ return baseFilter.ProxyCredential();
158
+ }
159
+
160
+ return nullptr;
161
+ }
162
+ void RedirectHttpFilter::ProxyCredential(PasswordCredential const &value) const {
163
+ if (auto baseFilter = m_innerFilter.try_as<IHttpBaseProtocolFilter>()) {
164
+ baseFilter.ProxyCredential(value);
165
+ }
166
+ }
167
+
168
+ PasswordCredential RedirectHttpFilter::ServerCredential() const {
169
+ if (auto baseFilter = m_innerFilter.try_as<IHttpBaseProtocolFilter>()) {
170
+ return baseFilter.ServerCredential();
171
+ }
172
+
173
+ return nullptr;
174
+ }
175
+ void RedirectHttpFilter::ServerCredential(PasswordCredential const &value) const {
176
+ if (auto baseFilter = m_innerFilter.try_as<IHttpBaseProtocolFilter>()) {
177
+ baseFilter.ServerCredential(value);
178
+ }
179
+ }
180
+
181
+ bool RedirectHttpFilter::UseProxy() const {
182
+ if (auto baseFilter = m_innerFilter.try_as<IHttpBaseProtocolFilter>()) {
183
+ return baseFilter.UseProxy();
184
+ }
185
+
186
+ return false;
187
+ }
188
+ void RedirectHttpFilter::UseProxy(bool value) const {
189
+ if (auto baseFilter = m_innerFilter.try_as<IHttpBaseProtocolFilter>()) {
190
+ baseFilter.UseProxy(value);
191
+ }
192
+ }
193
+
194
+ #pragma endregion IHttpBaseProtocolFilter
195
+
196
+ #pragma region IHttpFilter
197
+
198
+ ///
199
+ /// See https://github.com/dotnet/corefx/pull/22702
200
+ ResponseOperation RedirectHttpFilter::SendRequestAsync(HttpRequestMessage const &request) {
201
+ size_t redirectCount = 0;
202
+ HttpMethod method{nullptr};
203
+ HttpResponseMessage response{nullptr};
204
+
205
+ auto coRequest = request;
206
+ auto coAllowAutoRedirect = m_allowAutoRedirect;
207
+ auto coMaxRedirects = m_maximumRedirects;
208
+ auto coRequestFactory = m_requestFactory;
209
+ auto coEventSrc = m_redirEventSrc;
210
+
211
+ method = coRequest.Method();
212
+
213
+ do {
214
+ // Send subsequent requests through the filter that doesn't have the credentials included in the first request
215
+ response =
216
+ co_await (redirectCount > 0 ? m_innerFilterWithNoCredentials : m_innerFilter).SendRequestAsync(coRequest);
217
+
218
+ // Stop redirecting when a non-redirect status is responded.
219
+ if (response.StatusCode() != HttpStatusCode::MultipleChoices &&
220
+ response.StatusCode() != HttpStatusCode::MovedPermanently &&
221
+ response.StatusCode() != HttpStatusCode::Found && // Redirect
222
+ response.StatusCode() != HttpStatusCode::SeeOther && // RedirectMethod
223
+ response.StatusCode() != HttpStatusCode::TemporaryRedirect && // RedirectKeepVerb
224
+ response.StatusCode() != HttpStatusCode::PermanentRedirect) {
225
+ break;
226
+ }
227
+
228
+ redirectCount++;
229
+ if (redirectCount > coMaxRedirects) {
230
+ throw winrt::hresult_error{HRESULT_FROM_WIN32(ERROR_HTTP_REDIRECT_FAILED), L"Too many redirects"};
231
+ }
232
+
233
+ // Call event source's OnRedirecting before modifying request parameters.
234
+ if (coEventSrc && !coEventSrc->OnRedirecting(coRequest, response)) {
235
+ break;
236
+ }
237
+
238
+ if (auto requestFactory = coRequestFactory.lock()) {
239
+ coRequest =
240
+ co_await requestFactory->CreateRequest(HttpMethod{method}, coRequest.RequestUri(), coRequest.Properties());
241
+
242
+ if (!coRequest) {
243
+ throw winrt::hresult_error{E_INVALIDARG, L"Invalid request handle"};
244
+ }
245
+ }
246
+
247
+ auto redirectUri = Uri{response.Headers().Location().AbsoluteUri()};
248
+ if (!redirectUri) {
249
+ break;
250
+ }
251
+
252
+ if (redirectUri.SchemeName() != L"http" && redirectUri.SchemeName() != L"https") {
253
+ break;
254
+ }
255
+
256
+ // Do not "downgrade" from HTTPS to HTTP
257
+ if (coRequest.RequestUri().SchemeName() == L"https" && redirectUri.SchemeName() == L"http") {
258
+ break;
259
+ }
260
+
261
+ /// See https://github.com/dotnet/corefx/blob/v3.1.28/src/System.Net.Http/src/uap/System/Net/HttpClientHandler.cs
262
+ // Follow HTTP RFC 7231 rules. In general, 3xx responses
263
+ // except for 307 and 308 will keep verb except POST becomes GET.
264
+ // 307 and 308 responses have all verbs stay the same.
265
+ // https://tools.ietf.org/html/rfc7231#section-6.4
266
+ if (response.StatusCode() != HttpStatusCode::TemporaryRedirect &&
267
+ response.StatusCode() != HttpStatusCode::PermanentRedirect && method != HttpMethod::Post()) {
268
+ method = HttpMethod::Get();
269
+ }
270
+
271
+ coRequest.RequestUri(redirectUri);
272
+ } while (coAllowAutoRedirect);
273
+
274
+ response.RequestMessage(coRequest);
275
+
276
+ co_return response;
277
+ }
278
+
279
+ #pragma endregion IHttpFilter
280
+
281
+ #pragma endregion RedirectHttpFilter
282
+
283
+ } // namespace Microsoft::React::Networking
@@ -0,0 +1,97 @@
1
+ // Copyright (c) Microsoft Corporation.
2
+ // Licensed under the MIT License.
3
+
4
+ #pragma once
5
+
6
+ #include <winrt/base.h>
7
+ #include "IRedirectEventSource.h"
8
+ #include "IWinRTHttpRequestFactory.h"
9
+
10
+ // Windows API
11
+ #include <winrt/Windows.Foundation.Collections.h>
12
+ #include <winrt/Windows.Security.Credentials.h>
13
+ #include <winrt/Windows.Security.Cryptography.Certificates.h>
14
+ #include <winrt/Windows.Web.Http.Filters.h>
15
+ #include <winrt/Windows.Web.Http.h>
16
+
17
+ namespace Microsoft::React::Networking {
18
+
19
+ class RedirectHttpFilter : public winrt::implements<
20
+ RedirectHttpFilter,
21
+ winrt::Windows::Web::Http::Filters::IHttpFilter,
22
+ winrt::Windows::Web::Http::Filters::IHttpBaseProtocolFilter> {
23
+ // See
24
+ // https://github.com/dotnet/corefx/pull/22702/files#diff-53f0c1940c6bec8054a95caac33680306aa6ab13ac48c9a8c9df013d3bc29d15R30
25
+ // We need two different WinRT filters because we need to remove credentials during redirection requests
26
+ // and WinRT doesn't allow changing the filter properties after the first request.
27
+ winrt::Windows::Web::Http::Filters::IHttpFilter m_innerFilter;
28
+ winrt::Windows::Web::Http::Filters::IHttpFilter m_innerFilterWithNoCredentials;
29
+
30
+ std::weak_ptr<IWinRTHttpRequestFactory> m_requestFactory;
31
+ winrt::com_ptr<Microsoft::React::Networking::IRedirectEventSource> m_redirEventSrc;
32
+ bool m_allowAutoRedirect{true};
33
+ size_t m_maximumRedirects;
34
+
35
+ public:
36
+ RedirectHttpFilter(
37
+ size_t maxRedirects,
38
+ winrt::Windows::Web::Http::Filters::IHttpFilter &&innerFilter,
39
+ winrt::Windows::Web::Http::Filters::IHttpFilter &&innerFilterWithNoCredentials) noexcept;
40
+
41
+ RedirectHttpFilter(
42
+ winrt::Windows::Web::Http::Filters::IHttpFilter &&innerFilter,
43
+ winrt::Windows::Web::Http::Filters::IHttpFilter &&innerFilterWithNoCredentials) noexcept;
44
+
45
+ RedirectHttpFilter() noexcept;
46
+
47
+ void SetRequestFactory(std::weak_ptr<IWinRTHttpRequestFactory> factory) noexcept;
48
+
49
+ void SetRedirectSource(winrt::com_ptr<Microsoft::React::Networking::IRedirectEventSource> const &eventSrc) noexcept;
50
+
51
+ #pragma region IHttpFilter
52
+
53
+ winrt::Windows::Foundation::IAsyncOperationWithProgress<
54
+ winrt::Windows::Web::Http::HttpResponseMessage,
55
+ winrt::Windows::Web::Http::HttpProgress>
56
+ SendRequestAsync(winrt::Windows::Web::Http::HttpRequestMessage const &request);
57
+
58
+ #pragma endregion IHttpFilter
59
+
60
+ #pragma region IHttpBaseProtocolFilter
61
+
62
+ bool AllowAutoRedirect() const;
63
+ void AllowAutoRedirect(bool value);
64
+
65
+ bool AllowUI() const;
66
+ void AllowUI(bool value) const;
67
+
68
+ bool AutomaticDecompression() const;
69
+ void AutomaticDecompression(bool value) const;
70
+
71
+ winrt::Windows::Web::Http::Filters::HttpCacheControl CacheControl() const;
72
+
73
+ winrt::Windows::Web::Http::HttpCookieManager CookieManager() const;
74
+
75
+ winrt::Windows::Security::Cryptography::Certificates::Certificate ClientCertificate() const;
76
+ void ClientCertificate(winrt::Windows::Security::Cryptography::Certificates::Certificate const &value) const;
77
+
78
+ winrt::Windows::Foundation::Collections::IVector<
79
+ winrt::Windows::Security::Cryptography::Certificates::ChainValidationResult>
80
+ IgnorableServerCertificateErrors() const;
81
+
82
+ uint32_t MaxConnectionsPerServer() const;
83
+ void MaxConnectionsPerServer(uint32_t value) const;
84
+
85
+ winrt::Windows::Security::Credentials::PasswordCredential ProxyCredential() const;
86
+ void ProxyCredential(winrt::Windows::Security::Credentials::PasswordCredential const &value) const;
87
+
88
+ winrt::Windows::Security::Credentials::PasswordCredential ServerCredential() const;
89
+ void ServerCredential(winrt::Windows::Security::Credentials::PasswordCredential const &value) const;
90
+
91
+ bool UseProxy() const;
92
+ void UseProxy(bool value) const;
93
+
94
+ #pragma endregion IHttpBaseProtocolFilter
95
+ };
96
+
97
+ } // namespace Microsoft::React::Networking