react-native-windows 0.70.0 → 0.70.2
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.
- package/Libraries/Network/RCTNetworking.windows.js +117 -1
- package/Microsoft.ReactNative/Pch/pch.h +0 -1
- package/Microsoft.ReactNative/Views/ViewManagerBase.cpp +4 -2
- package/Microsoft.ReactNative.Managed/Microsoft.ReactNative.Managed.csproj +1 -3
- package/PropertySheets/External/Microsoft.ReactNative.Common.props +0 -9
- package/PropertySheets/External/Microsoft.ReactNative.Uwp.CSharpApp.props +1 -0
- package/PropertySheets/External/Microsoft.ReactNative.Uwp.CSharpLib.props +1 -0
- package/PropertySheets/External/Microsoft.ReactNative.Uwp.CppApp.props +1 -0
- package/PropertySheets/External/Microsoft.ReactNative.Uwp.CppLib.props +1 -0
- package/PropertySheets/External/Microsoft.ReactNative.WinAppSDK.CSharpApp.props +1 -0
- package/PropertySheets/Generated/PackageVersion.g.props +2 -2
- package/PropertySheets/NuGet.CSharp.props +15 -0
- package/PropertySheets/NuGet.Cpp.props +31 -0
- package/PropertySheets/React.Cpp.props +1 -15
- package/Scripts/OfficeReact.Win32.nuspec +1 -0
- package/Shared/Modules/HttpModule.cpp +4 -2
- package/Shared/Modules/HttpModule.h +1 -1
- package/Shared/Networking/IHttpResource.h +1 -1
- package/Shared/Networking/IRedirectEventSource.h +18 -0
- package/Shared/Networking/IWinRTHttpRequestFactory.h +22 -0
- package/Shared/Networking/OriginPolicy.h +1 -1
- package/Shared/Networking/OriginPolicyHttpFilter.cpp +47 -16
- package/Shared/Networking/OriginPolicyHttpFilter.h +16 -3
- package/Shared/Networking/RedirectHttpFilter.cpp +283 -0
- package/Shared/Networking/RedirectHttpFilter.h +97 -0
- package/Shared/Networking/WinRTHttpResource.cpp +207 -154
- package/Shared/Networking/WinRTHttpResource.h +17 -4
- package/Shared/Shared.vcxitems +4 -0
- package/Shared/Shared.vcxitems.filters +12 -0
- package/package.json +1 -1
- package/template/cpp-app/proj/MyApp.vcxproj +0 -3
- package/template/cpp-lib/proj/MyLib.vcxproj +0 -3
- package/template/cs-app/proj/MyApp.csproj +0 -3
- package/template/cs-lib/proj/MyLib.csproj +0 -3
- package/Libraries/Network/RCTNetworkingWinShared.js +0 -117
|
@@ -1 +1,117 @@
|
|
|
1
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) Microsoft Corporation.
|
|
3
|
+
* Licensed under the MIT License.
|
|
4
|
+
*
|
|
5
|
+
* @flow strict-local
|
|
6
|
+
* @format
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
'use strict';
|
|
10
|
+
|
|
11
|
+
import RCTDeviceEventEmitter from '../EventEmitter/RCTDeviceEventEmitter';
|
|
12
|
+
const RCTNetworkingNative =
|
|
13
|
+
require('../BatchedBridge/NativeModules').Networking; // [Windows]
|
|
14
|
+
import {type NativeResponseType} from './XMLHttpRequest';
|
|
15
|
+
import convertRequestBody, {type RequestBody} from './convertRequestBody';
|
|
16
|
+
import {type EventSubscription} from '../vendor/emitter/EventEmitter';
|
|
17
|
+
|
|
18
|
+
type RCTNetworkingEventDefinitions = $ReadOnly<{
|
|
19
|
+
didSendNetworkData: [
|
|
20
|
+
[
|
|
21
|
+
number, // requestId
|
|
22
|
+
number, // progress
|
|
23
|
+
number, // total
|
|
24
|
+
],
|
|
25
|
+
],
|
|
26
|
+
didReceiveNetworkResponse: [
|
|
27
|
+
[
|
|
28
|
+
number, // requestId
|
|
29
|
+
number, // status
|
|
30
|
+
?{[string]: string}, // responseHeaders
|
|
31
|
+
?string, // responseURL
|
|
32
|
+
],
|
|
33
|
+
],
|
|
34
|
+
didReceiveNetworkData: [
|
|
35
|
+
[
|
|
36
|
+
number, // requestId
|
|
37
|
+
string, // response
|
|
38
|
+
],
|
|
39
|
+
],
|
|
40
|
+
didReceiveNetworkIncrementalData: [
|
|
41
|
+
[
|
|
42
|
+
number, // requestId
|
|
43
|
+
string, // responseText
|
|
44
|
+
number, // progress
|
|
45
|
+
number, // total
|
|
46
|
+
],
|
|
47
|
+
],
|
|
48
|
+
didReceiveNetworkDataProgress: [
|
|
49
|
+
[
|
|
50
|
+
number, // requestId
|
|
51
|
+
number, // loaded
|
|
52
|
+
number, // total
|
|
53
|
+
],
|
|
54
|
+
],
|
|
55
|
+
didCompleteNetworkResponse: [
|
|
56
|
+
[
|
|
57
|
+
number, // requestId
|
|
58
|
+
string, // error
|
|
59
|
+
boolean, // timeOutError
|
|
60
|
+
],
|
|
61
|
+
],
|
|
62
|
+
}>;
|
|
63
|
+
|
|
64
|
+
let _requestId = 1;
|
|
65
|
+
function generateRequestId(): number {
|
|
66
|
+
return _requestId++;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
const RCTNetworking = {
|
|
70
|
+
addListener<K: $Keys<RCTNetworkingEventDefinitions>>(
|
|
71
|
+
eventType: K,
|
|
72
|
+
listener: (...$ElementType<RCTNetworkingEventDefinitions, K>) => mixed,
|
|
73
|
+
context?: mixed,
|
|
74
|
+
): EventSubscription {
|
|
75
|
+
return RCTDeviceEventEmitter.addListener(eventType, listener, context);
|
|
76
|
+
},
|
|
77
|
+
|
|
78
|
+
sendRequest(
|
|
79
|
+
method: string,
|
|
80
|
+
trackingName: string,
|
|
81
|
+
url: string,
|
|
82
|
+
headers: {...},
|
|
83
|
+
data: RequestBody,
|
|
84
|
+
responseType: NativeResponseType,
|
|
85
|
+
incrementalUpdates: boolean,
|
|
86
|
+
timeout: number,
|
|
87
|
+
callback: (requestId: number) => void,
|
|
88
|
+
withCredentials: boolean,
|
|
89
|
+
) {
|
|
90
|
+
const requestId = generateRequestId();
|
|
91
|
+
const body = convertRequestBody(data);
|
|
92
|
+
RCTNetworkingNative.sendRequest(
|
|
93
|
+
{
|
|
94
|
+
method,
|
|
95
|
+
url,
|
|
96
|
+
requestId,
|
|
97
|
+
data: {...body, trackingName},
|
|
98
|
+
headers,
|
|
99
|
+
responseType,
|
|
100
|
+
incrementalUpdates,
|
|
101
|
+
timeout,
|
|
102
|
+
withCredentials,
|
|
103
|
+
},
|
|
104
|
+
callback,
|
|
105
|
+
);
|
|
106
|
+
},
|
|
107
|
+
|
|
108
|
+
abortRequest(requestId: number) {
|
|
109
|
+
RCTNetworkingNative.abortRequest(requestId);
|
|
110
|
+
},
|
|
111
|
+
|
|
112
|
+
clearCookies(callback: (result: boolean) => void) {
|
|
113
|
+
RCTNetworkingNative.clearCookies(callback);
|
|
114
|
+
},
|
|
115
|
+
};
|
|
116
|
+
|
|
117
|
+
module.exports = RCTNetworking;
|
|
@@ -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"
|
|
@@ -271,9 +271,11 @@ bool ViewManagerBase::UpdateProperty(
|
|
|
271
271
|
const auto iter = pointerEventsMap.find(propertyValue.AsString());
|
|
272
272
|
if (iter != pointerEventsMap.end()) {
|
|
273
273
|
nodeToUpdate->m_pointerEvents = iter->second;
|
|
274
|
-
if (nodeToUpdate->
|
|
275
|
-
if (
|
|
274
|
+
if (const auto uiElement = nodeToUpdate->GetView().try_as<xaml::UIElement>()) {
|
|
275
|
+
if (nodeToUpdate->m_pointerEvents == PointerEventsKind::None) {
|
|
276
276
|
uiElement.IsHitTestVisible(false);
|
|
277
|
+
} else {
|
|
278
|
+
uiElement.ClearValue(xaml::UIElement::IsHitTestVisibleProperty());
|
|
277
279
|
}
|
|
278
280
|
}
|
|
279
281
|
} else {
|
|
@@ -25,9 +25,6 @@
|
|
|
25
25
|
<NoWarn>$(NoWarn);1591</NoWarn>
|
|
26
26
|
<!-- Missing XML comment for publicly visible type or member -->
|
|
27
27
|
</PropertyGroup>
|
|
28
|
-
<PropertyGroup Label="NuGet">
|
|
29
|
-
<AssetTargetFallback>$(AssetTargetFallback);native</AssetTargetFallback>
|
|
30
|
-
</PropertyGroup>
|
|
31
28
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
|
|
32
29
|
<PlatformTarget>x86</PlatformTarget>
|
|
33
30
|
<DebugSymbols>true</DebugSymbols>
|
|
@@ -80,6 +77,7 @@
|
|
|
80
77
|
<RestoreProjectStyle>PackageReference</RestoreProjectStyle>
|
|
81
78
|
<RestorePackagesWithLockFile>true</RestorePackagesWithLockFile>
|
|
82
79
|
</PropertyGroup>
|
|
80
|
+
<Import Project="..\PropertySheets\NuGet.CSharp.props" />
|
|
83
81
|
<Import Project="..\PropertySheets\WinUI.props" />
|
|
84
82
|
<ItemGroup>
|
|
85
83
|
<Compile Include="AttributedViewManager.cs" />
|
|
@@ -37,14 +37,5 @@
|
|
|
37
37
|
<HermesNoDLLCopy Condition="'$(UseHermes)' != 'true'">true</HermesNoDLLCopy>
|
|
38
38
|
</PropertyGroup>
|
|
39
39
|
|
|
40
|
-
<!-- Should match entry in $(ReactNativeWindowsDir)vnext\Directory.Build.props -->
|
|
41
|
-
<PropertyGroup Label="NuGet" Condition="'$(MSBuildProjectExtension)' == '.vcxproj'">
|
|
42
|
-
<!--See https://docs.microsoft.com/en-us/nuget/reference/msbuild-targets#restore-target-->
|
|
43
|
-
<RestoreUseStaticGraphEvaluation Condition="'$(BuildingInsideVisualStudio)' == 'true'">true</RestoreUseStaticGraphEvaluation>
|
|
44
|
-
|
|
45
|
-
<!-- Ensure PackageReference compatibility for any consuming projects/apps -->
|
|
46
|
-
<ResolveNuGetPackages>false</ResolveNuGetPackages>
|
|
47
|
-
</PropertyGroup>
|
|
48
|
-
|
|
49
40
|
<Import Project="$(ReactNativeWindowsDir)\PropertySheets\Generated\PackageVersion.g.props" />
|
|
50
41
|
</Project>
|
|
@@ -20,5 +20,6 @@
|
|
|
20
20
|
<Import Project="$(MSBuildThisFileDirectory)Microsoft.ReactNative.Uwp.Common.props" />
|
|
21
21
|
<Import Project="$(ReactNativeWindowsDir)\PropertySheets\Appx.props" />
|
|
22
22
|
<Import Project="$(ReactNativeWindowsDir)\PropertySheets\Autolink.props" />
|
|
23
|
+
<Import Project="$(ReactNativeWindowsDir)\PropertySheets\NuGet.CSharp.props" />
|
|
23
24
|
<Import Project="$(ReactNativeWindowsDir)\PropertySheets\WinUI.props" />
|
|
24
25
|
</Project>
|
|
@@ -16,6 +16,7 @@
|
|
|
16
16
|
<Import Project="$(MSBuildThisFileDirectory)Microsoft.ReactNative.Uwp.Common.props" />
|
|
17
17
|
<Import Project="$(ReactNativeWindowsDir)\PropertySheets\Appx.props" />
|
|
18
18
|
<Import Project="$(ReactNativeWindowsDir)\PropertySheets\Autolink.props" />
|
|
19
|
+
<Import Project="$(ReactNativeWindowsDir)\PropertySheets\NuGet.Cpp.props" />
|
|
19
20
|
<Import Project="$(ReactNativeWindowsDir)\PropertySheets\WinUI.props" />
|
|
20
21
|
<Import Project="$(ReactNativeWindowsDir)\PropertySheets\CppAppConsumeCSharpModule.props" />
|
|
21
22
|
<Import Project="$(ReactNativeWindowsDir)\PropertySheets\PackageVersionDefinitions.props" />
|
|
@@ -17,6 +17,7 @@
|
|
|
17
17
|
<GenerateLibraryLayout>false</GenerateLibraryLayout>
|
|
18
18
|
</PropertyGroup>
|
|
19
19
|
<Import Project="$(MSBuildThisFileDirectory)Microsoft.ReactNative.Uwp.Common.props" />
|
|
20
|
+
<Import Project="$(ReactNativeWindowsDir)\PropertySheets\NuGet.Cpp.props" />
|
|
20
21
|
<Import Project="$(ReactNativeWindowsDir)\PropertySheets\WinUI.props" />
|
|
21
22
|
<Import Project="$(ReactNativeWindowsDir)\PropertySheets\PackageVersionDefinitions.props" />
|
|
22
23
|
</Project>
|
|
@@ -22,5 +22,6 @@
|
|
|
22
22
|
<Import Project="$(MSBuildThisFileDirectory)Microsoft.ReactNative.WinAppSDK.Common.props" />
|
|
23
23
|
<Import Project="$(ReactNativeWindowsDir)\PropertySheets\Appx.props" />
|
|
24
24
|
<Import Project="$(ReactNativeWindowsDir)\PropertySheets\Autolink.props" />
|
|
25
|
+
<Import Project="$(ReactNativeWindowsDir)\PropertySheets\NuGet.CSharp.props" />
|
|
25
26
|
<Import Project="$(ReactNativeWindowsDir)\PropertySheets\WinUI.props" />
|
|
26
27
|
</Project>
|
|
@@ -10,10 +10,10 @@
|
|
|
10
10
|
-->
|
|
11
11
|
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
|
12
12
|
<PropertyGroup>
|
|
13
|
-
<ReactNativeWindowsVersion>0.70.
|
|
13
|
+
<ReactNativeWindowsVersion>0.70.2</ReactNativeWindowsVersion>
|
|
14
14
|
<ReactNativeWindowsMajor>0</ReactNativeWindowsMajor>
|
|
15
15
|
<ReactNativeWindowsMinor>70</ReactNativeWindowsMinor>
|
|
16
|
-
<ReactNativeWindowsPatch>
|
|
16
|
+
<ReactNativeWindowsPatch>2</ReactNativeWindowsPatch>
|
|
17
17
|
<ReactNativeWindowsCanary>false</ReactNativeWindowsCanary>
|
|
18
18
|
</PropertyGroup>
|
|
19
19
|
</Project>
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="utf-8"?>
|
|
2
|
+
<!--
|
|
3
|
+
Copyright (c) Microsoft Corporation. All rights reserved.
|
|
4
|
+
Licensed under the MIT License.
|
|
5
|
+
|
|
6
|
+
Defines NuGet-related properties for C# projects using PackageReference.
|
|
7
|
+
-->
|
|
8
|
+
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
|
9
|
+
|
|
10
|
+
<PropertyGroup Label="NuGet">
|
|
11
|
+
<!-- https://github.com/NuGet/Home/issues/10511#issuecomment-778400668 -->
|
|
12
|
+
<AssetTargetFallback>$(AssetTargetFallback);native</AssetTargetFallback>
|
|
13
|
+
</PropertyGroup>
|
|
14
|
+
|
|
15
|
+
</Project>
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="utf-8"?>
|
|
2
|
+
<!--
|
|
3
|
+
Copyright (c) Microsoft Corporation. All rights reserved.
|
|
4
|
+
Licensed under the MIT License.
|
|
5
|
+
|
|
6
|
+
Defines NuGet-related properties for C++ projects using PackageReference.
|
|
7
|
+
-->
|
|
8
|
+
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
|
9
|
+
|
|
10
|
+
<PropertyGroup Label="NuGet">
|
|
11
|
+
<!-- Should match entry in $(ReactNativeWindowsDir)vnext\Directory.Build.props -->
|
|
12
|
+
<!--See https://docs.microsoft.com/en-us/nuget/reference/msbuild-targets#restore-target-->
|
|
13
|
+
<RestoreUseStaticGraphEvaluation Condition="'$(BuildingInsideVisualStudio)' == 'true'">true</RestoreUseStaticGraphEvaluation>
|
|
14
|
+
|
|
15
|
+
<!-- Ensure PackageReference compatibility for any consuming projects/apps -->
|
|
16
|
+
<ResolveNuGetPackages>false</ResolveNuGetPackages>
|
|
17
|
+
|
|
18
|
+
<!-- https://github.com/NuGet/Home/issues/10511#issuecomment-778400668 -->
|
|
19
|
+
<AssetTargetFallback>$(AssetTargetFallback);uap10.0.16299</AssetTargetFallback>
|
|
20
|
+
|
|
21
|
+
<!--
|
|
22
|
+
Avoid Visual Studio error message:
|
|
23
|
+
"The project '$(MSBuildProjectName)' ran into a problem during the last operation: The value of the
|
|
24
|
+
'TargetFrameworkMoniker' and 'NuGetTargetMoniker' properties in the '$(Configuration)|$(Platform)' configuration are both
|
|
25
|
+
empty. This configuration will not contribute to NuGet restore, which may result in restore and build errors. You may
|
|
26
|
+
need to reload the solution after fixing the problem."
|
|
27
|
+
-->
|
|
28
|
+
<TargetFrameworkMoniker>native,Version=v0.0</TargetFrameworkMoniker>
|
|
29
|
+
</PropertyGroup>
|
|
30
|
+
|
|
31
|
+
</Project>
|
|
@@ -17,21 +17,7 @@
|
|
|
17
17
|
<EnableWinRtLeanAndMean Condition="'$(EnableWinRtLeanAndMean)' == ''">true</EnableWinRtLeanAndMean>
|
|
18
18
|
</PropertyGroup>
|
|
19
19
|
|
|
20
|
-
<
|
|
21
|
-
<ResolveNuGetPackages>false</ResolveNuGetPackages>
|
|
22
|
-
|
|
23
|
-
<!-- https://github.com/NuGet/Home/issues/10511#issuecomment-778400668 -->
|
|
24
|
-
<AssetTargetFallback>$(AssetTargetFallback);native</AssetTargetFallback>
|
|
25
|
-
|
|
26
|
-
<!--
|
|
27
|
-
Avoid Visual Studio error message:
|
|
28
|
-
"The project '$(MSBuildProjectName)' ran into a problem during the last operation: The value of the
|
|
29
|
-
'TargetFrameworkMoniker' and 'NuGetTargetMoniker' properties in the '$(Configuration)|$(Platform)' configuration are both
|
|
30
|
-
empty. This configuration will not contribute to NuGet restore, which may result in restore and build errors. You may
|
|
31
|
-
need to reload the solution after fixing the problem."
|
|
32
|
-
-->
|
|
33
|
-
<TargetFrameworkMoniker>native,Version=v0.0</TargetFrameworkMoniker>
|
|
34
|
-
</PropertyGroup>
|
|
20
|
+
<Import Project="$(MSBuildThisFileDirectory)NuGet.Cpp.props" />
|
|
35
21
|
|
|
36
22
|
<PropertyGroup Label="Desktop">
|
|
37
23
|
<!-- See https://docs.microsoft.com/en-us/cpp/porting/modifying-winver-and-win32-winnt -->
|
|
@@ -56,6 +56,7 @@
|
|
|
56
56
|
<file src="$nugetroot$\inc\Shared\Modules\I18nModule.h" target="inc"/>
|
|
57
57
|
<file src="$nugetroot$\inc\Shared\NativeModuleProvider.h" target="inc"/>
|
|
58
58
|
<file src="$nugetroot$\inc\Shared\Networking\IWebSocketResource.h" target="inc"/>
|
|
59
|
+
<file src="$nugetroot$\inc\Shared\Networking\OriginPolicy.h" target="inc"/>
|
|
59
60
|
<file src="$nugetroot$\inc\Shared\RuntimeOptions.h" target="inc"/>
|
|
60
61
|
<file src="$nugetroot$\inc\Shared\Tracing.h" target="inc"/>
|
|
61
62
|
|
|
@@ -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
|
-
|
|
77
|
+
if (isTimeout) {
|
|
78
|
+
args.push_back(true);
|
|
79
|
+
}
|
|
78
80
|
|
|
79
81
|
SendEvent(weakReactInstance, completedResponse, std::move(args));
|
|
80
82
|
});
|
|
@@ -15,7 +15,7 @@ namespace Microsoft::React {
|
|
|
15
15
|
|
|
16
16
|
///
|
|
17
17
|
/// Realizes <c>NativeModules</c> projection.
|
|
18
|
-
/// <remarks>See src\Libraries\Network\
|
|
18
|
+
/// <remarks>See src\Libraries\Network\RCTNetworking.windows.js</remarks>
|
|
19
19
|
///
|
|
20
20
|
class HttpModule : public facebook::xplat::module::CxxModule {
|
|
21
21
|
public:
|
|
@@ -96,7 +96,7 @@ struct IHttpResource {
|
|
|
96
96
|
virtual void SetOnData(std::function<void(int64_t requestId, std::string &&responseData)> &&handler) noexcept = 0;
|
|
97
97
|
virtual void SetOnData(std::function<void(int64_t requestId, folly::dynamic &&responseData)> &&handler) noexcept = 0;
|
|
98
98
|
virtual void SetOnError(
|
|
99
|
-
std::function<void(int64_t requestId, std::string &&errorMessage
|
|
99
|
+
std::function<void(int64_t requestId, std::string &&errorMessage, bool isTimeout)> &&handler) noexcept = 0;
|
|
100
100
|
};
|
|
101
101
|
|
|
102
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
|
|
@@ -9,7 +9,7 @@ enum class OriginPolicy : size_t {
|
|
|
9
9
|
None = 0,
|
|
10
10
|
SameOrigin = 1,
|
|
11
11
|
SimpleCrossOriginResourceSharing = 2,
|
|
12
|
-
CrossOriginResourceSharing = 3,
|
|
12
|
+
CrossOriginResourceSharing = 3,
|
|
13
13
|
};
|
|
14
14
|
|
|
15
15
|
} // namespace Microsoft::React::Networking
|
|
@@ -11,10 +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.Foundation.Collections.h>
|
|
16
|
-
#include <winrt/Windows.Web.Http.Headers.h>
|
|
17
|
-
|
|
18
14
|
// Standard Library
|
|
19
15
|
#include <queue>
|
|
20
16
|
#include <regex>
|
|
@@ -28,6 +24,7 @@ using winrt::to_hstring;
|
|
|
28
24
|
using winrt::Windows::Foundation::IInspectable;
|
|
29
25
|
using winrt::Windows::Foundation::IPropertyValue;
|
|
30
26
|
using winrt::Windows::Foundation::Uri;
|
|
27
|
+
using winrt::Windows::Foundation::Collections::IMap;
|
|
31
28
|
using winrt::Windows::Web::Http::HttpMethod;
|
|
32
29
|
using winrt::Windows::Web::Http::HttpRequestMessage;
|
|
33
30
|
using winrt::Windows::Web::Http::HttpResponseMessage;
|
|
@@ -119,7 +116,7 @@ bool OriginPolicyHttpFilter::ConstWcharComparer::operator()(const wchar_t *a, co
|
|
|
119
116
|
}
|
|
120
117
|
|
|
121
118
|
/*static*/ bool OriginPolicyHttpFilter::IsSameOrigin(Uri const &u1, Uri const &u2) noexcept {
|
|
122
|
-
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();
|
|
123
120
|
}
|
|
124
121
|
|
|
125
122
|
/*static*/ bool OriginPolicyHttpFilter::IsSimpleCorsRequest(HttpRequestMessage const &request) noexcept {
|
|
@@ -374,7 +371,7 @@ bool OriginPolicyHttpFilter::ConstWcharComparer::operator()(const wchar_t *a, co
|
|
|
374
371
|
}
|
|
375
372
|
}
|
|
376
373
|
|
|
377
|
-
OriginPolicyHttpFilter::OriginPolicyHttpFilter(IHttpFilter
|
|
374
|
+
OriginPolicyHttpFilter::OriginPolicyHttpFilter(IHttpFilter const &innerFilter) : m_innerFilter{innerFilter} {}
|
|
378
375
|
|
|
379
376
|
OriginPolicyHttpFilter::OriginPolicyHttpFilter()
|
|
380
377
|
: OriginPolicyHttpFilter(winrt::Windows::Web::Http::Filters::HttpBaseProtocolFilter{}) {}
|
|
@@ -443,21 +440,24 @@ OriginPolicy OriginPolicyHttpFilter::ValidateRequest(HttpRequestMessage const &r
|
|
|
443
440
|
void OriginPolicyHttpFilter::ValidateAllowOrigin(
|
|
444
441
|
hstring const &allowedOrigin,
|
|
445
442
|
hstring const &allowCredentials,
|
|
446
|
-
IInspectable
|
|
443
|
+
IMap<hstring, IInspectable> props) const {
|
|
447
444
|
// 4.10.1-2 - null allow origin
|
|
448
445
|
if (L"null" == allowedOrigin)
|
|
449
446
|
throw hresult_error{
|
|
450
447
|
E_INVALIDARG,
|
|
451
448
|
L"Response header Access-Control-Allow-Origin has a value of [null] which differs from the supplied origin"};
|
|
452
449
|
|
|
453
|
-
bool withCredentials =
|
|
450
|
+
bool withCredentials = props.Lookup(L"RequestArgs").as<RequestArgs>()->WithCredentials;
|
|
454
451
|
// 4.10.3 - valid wild card allow origin
|
|
455
452
|
if (!withCredentials && L"*" == allowedOrigin)
|
|
456
453
|
return;
|
|
457
454
|
|
|
458
455
|
// We assume the source (request) origin is not "*", "null", or empty string. Valid URI is expected
|
|
459
456
|
// 4.10.4 - Mismatched allow origin
|
|
460
|
-
|
|
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})) {
|
|
461
461
|
hstring errorMessage;
|
|
462
462
|
if (allowedOrigin.empty())
|
|
463
463
|
errorMessage = L"No valid origin in response";
|
|
@@ -511,14 +511,14 @@ void OriginPolicyHttpFilter::ValidatePreflightResponse(
|
|
|
511
511
|
|
|
512
512
|
auto controlValues = ExtractAccessControlValues(response.Headers());
|
|
513
513
|
|
|
514
|
-
auto
|
|
514
|
+
auto props = request.Properties();
|
|
515
515
|
// Check if the origin is allowed in conjuction with the withCredentials flag
|
|
516
516
|
// CORS preflight should always exclude credentials although the subsequent CORS request may include credentials.
|
|
517
|
-
ValidateAllowOrigin(controlValues.AllowedOrigin, controlValues.AllowedCredentials,
|
|
517
|
+
ValidateAllowOrigin(controlValues.AllowedOrigin, controlValues.AllowedCredentials, props);
|
|
518
518
|
|
|
519
519
|
// See https://fetch.spec.whatwg.org/#cors-preflight-fetch, section 4.8.7.5
|
|
520
520
|
// Check if the request method is allowed
|
|
521
|
-
bool withCredentials =
|
|
521
|
+
bool withCredentials = props.Lookup(L"RequestArgs").as<RequestArgs>()->WithCredentials;
|
|
522
522
|
bool requestMethodAllowed = false;
|
|
523
523
|
for (const auto &method : controlValues.AllowedMethods) {
|
|
524
524
|
if (L"*" == method) {
|
|
@@ -579,8 +579,8 @@ void OriginPolicyHttpFilter::ValidateResponse(HttpResponseMessage const &respons
|
|
|
579
579
|
if (originPolicy == OriginPolicy::SimpleCrossOriginResourceSharing ||
|
|
580
580
|
originPolicy == OriginPolicy::CrossOriginResourceSharing) {
|
|
581
581
|
auto controlValues = ExtractAccessControlValues(response.Headers());
|
|
582
|
-
auto
|
|
583
|
-
|
|
582
|
+
auto props = response.RequestMessage().Properties();
|
|
583
|
+
auto withCredentials = props.Lookup(L"RequestArgs").try_as<RequestArgs>()->WithCredentials;
|
|
584
584
|
|
|
585
585
|
if (GetRuntimeOptionBool("Http.StrictOriginCheckSimpleCors") &&
|
|
586
586
|
originPolicy == OriginPolicy::SimpleCrossOriginResourceSharing) {
|
|
@@ -595,8 +595,7 @@ void OriginPolicyHttpFilter::ValidateResponse(HttpResponseMessage const &respons
|
|
|
595
595
|
throw hresult_error{E_INVALIDARG, L"The server does not support CORS or the origin is not allowed"};
|
|
596
596
|
}
|
|
597
597
|
} else {
|
|
598
|
-
|
|
599
|
-
ValidateAllowOrigin(controlValues.AllowedOrigin, controlValues.AllowedCredentials, iRequestArgs);
|
|
598
|
+
ValidateAllowOrigin(controlValues.AllowedOrigin, controlValues.AllowedCredentials, props);
|
|
600
599
|
}
|
|
601
600
|
|
|
602
601
|
if (originPolicy == OriginPolicy::SimpleCrossOriginResourceSharing) {
|
|
@@ -684,6 +683,38 @@ ResponseOperation OriginPolicyHttpFilter::SendPreflightAsync(HttpRequestMessage
|
|
|
684
683
|
co_return {co_await m_innerFilter.SendRequestAsync(preflightRequest)};
|
|
685
684
|
}
|
|
686
685
|
|
|
686
|
+
#pragma region IRedirectEventSource
|
|
687
|
+
|
|
688
|
+
bool OriginPolicyHttpFilter::OnRedirecting(
|
|
689
|
+
HttpRequestMessage const &request,
|
|
690
|
+
HttpResponseMessage const &response) noexcept {
|
|
691
|
+
// Consider the following scenario.
|
|
692
|
+
// User signs in to http://a.com and visits a page that makes CORS request to http://b.com with origin=http://a.com.
|
|
693
|
+
// Http://b.com reponds with a redirect to http://a.com. The browser follows the redirect to http://a.com with
|
|
694
|
+
// origin=http://a.com. Since the origin matches the URL, the request is authorized at http://a.com, but it actually
|
|
695
|
+
// allows http://b.com to bypass the CORS check at http://a.com since the redirected URL is from http://b.com.
|
|
696
|
+
if (!IsSameOrigin(response.Headers().Location(), request.RequestUri()) &&
|
|
697
|
+
!IsSameOrigin(s_origin, request.RequestUri())) {
|
|
698
|
+
// By masking the origin field in the request header, we make it impossible for the server to set a single value for
|
|
699
|
+
// the access-control-allow-origin header. It means, the only way to support redirect is that server allows access
|
|
700
|
+
// from all sites through wildcard.
|
|
701
|
+
request.Headers().Insert(L"Origin", L"null");
|
|
702
|
+
|
|
703
|
+
auto props = request.Properties();
|
|
704
|
+
// Look for 'RequestArgs' key to ensure we are redirecting the main request.
|
|
705
|
+
if (auto iReqArgs = props.TryLookup(L"RequestArgs")) {
|
|
706
|
+
props.Insert(L"TaintedOrigin", winrt::box_value(true));
|
|
707
|
+
} else {
|
|
708
|
+
// Abort redirection if the request is either preflight or extraneous.
|
|
709
|
+
return false;
|
|
710
|
+
}
|
|
711
|
+
}
|
|
712
|
+
|
|
713
|
+
return true;
|
|
714
|
+
}
|
|
715
|
+
|
|
716
|
+
#pragma endregion IRedirectEventSource
|
|
717
|
+
|
|
687
718
|
#pragma region IHttpFilter
|
|
688
719
|
|
|
689
720
|
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::
|
|
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
|
|
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
|
|
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<
|