react-native-windows 0.69.14 → 0.69.15
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/Microsoft.ReactNative/Base/CoreNativeModules.cpp +9 -22
- package/PropertySheets/Generated/PackageVersion.g.props +2 -2
- package/Shared/Modules/FileReaderModule.cpp +1 -0
- package/Shared/Modules/HttpModule.cpp +87 -72
- package/Shared/Networking/IHttpResource.h +126 -0
- package/Shared/Networking/OriginPolicyHttpFilter.cpp +21 -16
- package/Shared/Networking/WinRTHttpResource.cpp +161 -32
- package/Shared/Networking/WinRTHttpResource.h +10 -0
- package/Shared/OInstance.cpp +2 -8
- package/Shared/Shared.vcxitems +3 -1
- package/package.json +1 -1
|
@@ -19,12 +19,8 @@
|
|
|
19
19
|
|
|
20
20
|
namespace Microsoft::ReactNative {
|
|
21
21
|
|
|
22
|
-
using winrt::Microsoft::ReactNative::ReactPropertyBag;
|
|
23
|
-
|
|
24
22
|
namespace {
|
|
25
23
|
|
|
26
|
-
using winrt::Microsoft::ReactNative::ReactPropertyId;
|
|
27
|
-
|
|
28
24
|
bool HasPackageIdentity() noexcept {
|
|
29
25
|
static const bool hasPackageIdentity = []() noexcept {
|
|
30
26
|
auto packageStatics = winrt::get_activation_factory<winrt::Windows::ApplicationModel::IPackageStatics>(
|
|
@@ -39,13 +35,6 @@ bool HasPackageIdentity() noexcept {
|
|
|
39
35
|
return hasPackageIdentity;
|
|
40
36
|
}
|
|
41
37
|
|
|
42
|
-
ReactPropertyId<bool> HttpUseMonolithicModuleProperty() noexcept {
|
|
43
|
-
static ReactPropertyId<bool> propId{
|
|
44
|
-
L"ReactNative.Http"
|
|
45
|
-
L"UseMonolithicModule"};
|
|
46
|
-
return propId;
|
|
47
|
-
}
|
|
48
|
-
|
|
49
38
|
} // namespace
|
|
50
39
|
|
|
51
40
|
std::vector<facebook::react::NativeModuleDescription> GetCoreModules(
|
|
@@ -61,17 +50,15 @@ std::vector<facebook::react::NativeModuleDescription> GetCoreModules(
|
|
|
61
50
|
[props = context->Properties()]() { return Microsoft::React::CreateHttpModule(props); },
|
|
62
51
|
jsMessageQueue);
|
|
63
52
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
batchingUIMessageQueue);
|
|
74
|
-
}
|
|
53
|
+
modules.emplace_back(
|
|
54
|
+
Microsoft::React::GetBlobModuleName(),
|
|
55
|
+
[props = context->Properties()]() { return Microsoft::React::CreateBlobModule(props); },
|
|
56
|
+
batchingUIMessageQueue);
|
|
57
|
+
|
|
58
|
+
modules.emplace_back(
|
|
59
|
+
Microsoft::React::GetFileReaderModuleName(),
|
|
60
|
+
[props = context->Properties()]() { return Microsoft::React::CreateFileReaderModule(props); },
|
|
61
|
+
batchingUIMessageQueue);
|
|
75
62
|
|
|
76
63
|
modules.emplace_back(
|
|
77
64
|
"Timing",
|
|
@@ -10,10 +10,10 @@
|
|
|
10
10
|
-->
|
|
11
11
|
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
|
12
12
|
<PropertyGroup>
|
|
13
|
-
<ReactNativeWindowsVersion>0.69.
|
|
13
|
+
<ReactNativeWindowsVersion>0.69.15</ReactNativeWindowsVersion>
|
|
14
14
|
<ReactNativeWindowsMajor>0</ReactNativeWindowsMajor>
|
|
15
15
|
<ReactNativeWindowsMinor>69</ReactNativeWindowsMinor>
|
|
16
|
-
<ReactNativeWindowsPatch>
|
|
16
|
+
<ReactNativeWindowsPatch>15</ReactNativeWindowsPatch>
|
|
17
17
|
<ReactNativeWindowsCanary>false</ReactNativeWindowsCanary>
|
|
18
18
|
</PropertyGroup>
|
|
19
19
|
</Project>
|
|
@@ -33,8 +33,10 @@ constexpr char moduleName[] = "Networking";
|
|
|
33
33
|
// React event names
|
|
34
34
|
constexpr char completedResponse[] = "didCompleteNetworkResponse";
|
|
35
35
|
constexpr char receivedResponse[] = "didReceiveNetworkResponse";
|
|
36
|
-
constexpr char
|
|
36
|
+
constexpr char sentData[] = "didSendNetworkData";
|
|
37
|
+
constexpr char receivedIncrementalData[] = "didReceiveNetworkIncrementalData";
|
|
37
38
|
constexpr char receivedDataProgress[] = "didReceiveNetworkDataProgress";
|
|
39
|
+
constexpr char receivedData[] = "didReceiveNetworkData";
|
|
38
40
|
|
|
39
41
|
static void SetUpHttpResource(
|
|
40
42
|
shared_ptr<IHttpResource> resource,
|
|
@@ -60,9 +62,6 @@ static void SetUpHttpResource(
|
|
|
60
62
|
|
|
61
63
|
resource->SetOnData([weakReactInstance](int64_t requestId, string &&responseData) {
|
|
62
64
|
SendEvent(weakReactInstance, receivedData, dynamic::array(requestId, std::move(responseData)));
|
|
63
|
-
|
|
64
|
-
// TODO: Move into separate method IF not executed right after onData()
|
|
65
|
-
SendEvent(weakReactInstance, completedResponse, dynamic::array(requestId));
|
|
66
65
|
});
|
|
67
66
|
|
|
68
67
|
// Explicitly declaring function type to avoid type inference ambiguity.
|
|
@@ -72,6 +71,22 @@ static void SetUpHttpResource(
|
|
|
72
71
|
};
|
|
73
72
|
resource->SetOnData(std::move(onDataDynamic));
|
|
74
73
|
|
|
74
|
+
resource->SetOnIncrementalData(
|
|
75
|
+
[weakReactInstance](int64_t requestId, string &&responseData, int64_t progress, int64_t total) {
|
|
76
|
+
SendEvent(
|
|
77
|
+
weakReactInstance,
|
|
78
|
+
receivedIncrementalData,
|
|
79
|
+
dynamic::array(requestId, std::move(responseData), progress, total));
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
resource->SetOnDataProgress([weakReactInstance](int64_t requestId, int64_t progress, int64_t total) {
|
|
83
|
+
SendEvent(weakReactInstance, receivedDataProgress, dynamic::array(requestId, progress, total));
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
resource->SetOnResponseComplete([weakReactInstance](int64_t requestId) {
|
|
87
|
+
SendEvent(weakReactInstance, completedResponse, dynamic::array(requestId));
|
|
88
|
+
});
|
|
89
|
+
|
|
75
90
|
resource->SetOnError([weakReactInstance](int64_t requestId, string &&message, bool isTimeout) {
|
|
76
91
|
dynamic args = dynamic::array(requestId, std::move(message));
|
|
77
92
|
if (isTimeout) {
|
|
@@ -108,90 +123,90 @@ std::map<string, dynamic> HttpModule::getConstants() {
|
|
|
108
123
|
}
|
|
109
124
|
|
|
110
125
|
// clang-format off
|
|
111
|
-
std::vector<facebook::xplat::module::CxxModule::Method> HttpModule::getMethods() {
|
|
126
|
+
std::vector<facebook::xplat::module::CxxModule::Method> HttpModule::getMethods() {
|
|
112
127
|
|
|
113
|
-
|
|
114
|
-
{
|
|
128
|
+
return
|
|
115
129
|
{
|
|
116
|
-
"sendRequest",
|
|
117
|
-
[weakHolder = weak_ptr<ModuleHolder>(m_holder)](dynamic args, Callback cxxCallback)
|
|
118
130
|
{
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
return;
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
auto resource = holder->Module->m_resource;
|
|
125
|
-
if (!holder->Module->m_isResourceSetup)
|
|
131
|
+
"sendRequest",
|
|
132
|
+
[weakHolder = weak_ptr<ModuleHolder>(m_holder)](dynamic args, Callback cxxCallback)
|
|
126
133
|
{
|
|
127
|
-
|
|
128
|
-
holder
|
|
129
|
-
|
|
134
|
+
auto holder = weakHolder.lock();
|
|
135
|
+
if (!holder) {
|
|
136
|
+
return;
|
|
137
|
+
}
|
|
130
138
|
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
139
|
+
auto resource = holder->Module->m_resource;
|
|
140
|
+
if (!holder->Module->m_isResourceSetup)
|
|
141
|
+
{
|
|
142
|
+
SetUpHttpResource(resource, holder->Module->getInstance(), holder->Module->m_inspectableProperties);
|
|
143
|
+
holder->Module->m_isResourceSetup = true;
|
|
144
|
+
}
|
|
136
145
|
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
params["
|
|
140
|
-
|
|
141
|
-
std::move(headers),
|
|
142
|
-
std::move(params["data"]),
|
|
143
|
-
params["responseType"].asString(),
|
|
144
|
-
params["incrementalUpdates"].asBool(),
|
|
145
|
-
static_cast<int64_t>(params["timeout"].asDouble()),
|
|
146
|
-
params["withCredentials"].asBool(),
|
|
147
|
-
[cxxCallback = std::move(cxxCallback)](int64_t requestId) {
|
|
148
|
-
cxxCallback({requestId});
|
|
146
|
+
auto params = facebook::xplat::jsArgAsObject(args, 0);
|
|
147
|
+
IHttpResource::Headers headers;
|
|
148
|
+
for (auto& header : params["headers"].items()) {
|
|
149
|
+
headers.emplace(header.first.getString(), header.second.getString());
|
|
149
150
|
}
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
151
|
+
|
|
152
|
+
resource->SendRequest(
|
|
153
|
+
params["method"].asString(),
|
|
154
|
+
params["url"].asString(),
|
|
155
|
+
params["requestId"].asInt(),
|
|
156
|
+
std::move(headers),
|
|
157
|
+
std::move(params["data"]),
|
|
158
|
+
params["responseType"].asString(),
|
|
159
|
+
params["incrementalUpdates"].asBool(),
|
|
160
|
+
static_cast<int64_t>(params["timeout"].asDouble()),
|
|
161
|
+
params["withCredentials"].asBool(),
|
|
162
|
+
[cxxCallback = std::move(cxxCallback)](int64_t requestId) {
|
|
163
|
+
cxxCallback({requestId});
|
|
164
|
+
}
|
|
165
|
+
);
|
|
166
|
+
}
|
|
167
|
+
},
|
|
156
168
|
{
|
|
157
|
-
|
|
158
|
-
|
|
169
|
+
"abortRequest",
|
|
170
|
+
[weakHolder = weak_ptr<ModuleHolder>(m_holder)](dynamic args)
|
|
159
171
|
{
|
|
160
|
-
|
|
161
|
-
|
|
172
|
+
auto holder = weakHolder.lock();
|
|
173
|
+
if (!holder)
|
|
174
|
+
{
|
|
175
|
+
return;
|
|
176
|
+
}
|
|
162
177
|
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
178
|
+
auto resource = holder->Module->m_resource;
|
|
179
|
+
if (!holder->Module->m_isResourceSetup)
|
|
180
|
+
{
|
|
181
|
+
SetUpHttpResource(resource, holder->Module->getInstance(), holder->Module->m_inspectableProperties);
|
|
182
|
+
holder->Module->m_isResourceSetup = true;
|
|
183
|
+
}
|
|
169
184
|
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
{
|
|
174
|
-
"clearCookies",
|
|
175
|
-
[weakHolder = weak_ptr<ModuleHolder>(m_holder)](dynamic args)
|
|
185
|
+
resource->AbortRequest(facebook::xplat::jsArgAsInt(args, 0));
|
|
186
|
+
}
|
|
187
|
+
},
|
|
176
188
|
{
|
|
177
|
-
|
|
178
|
-
|
|
189
|
+
"clearCookies",
|
|
190
|
+
[weakHolder = weak_ptr<ModuleHolder>(m_holder)](dynamic args)
|
|
179
191
|
{
|
|
180
|
-
|
|
181
|
-
|
|
192
|
+
auto holder = weakHolder.lock();
|
|
193
|
+
if (!holder)
|
|
194
|
+
{
|
|
195
|
+
return;
|
|
196
|
+
}
|
|
182
197
|
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
198
|
+
auto resource = holder->Module->m_resource;
|
|
199
|
+
if (!holder->Module->m_isResourceSetup)
|
|
200
|
+
{
|
|
201
|
+
SetUpHttpResource(resource, holder->Module->getInstance(), holder->Module->m_inspectableProperties);
|
|
202
|
+
holder->Module->m_isResourceSetup = true;
|
|
203
|
+
}
|
|
189
204
|
|
|
190
|
-
|
|
205
|
+
resource->ClearCookies();
|
|
206
|
+
}
|
|
191
207
|
}
|
|
192
|
-
}
|
|
193
|
-
}
|
|
194
|
-
}
|
|
208
|
+
};
|
|
209
|
+
}
|
|
195
210
|
// clang-format on
|
|
196
211
|
|
|
197
212
|
#pragma endregion CxxModule
|
|
@@ -91,10 +91,136 @@ struct IHttpResource {
|
|
|
91
91
|
|
|
92
92
|
virtual void ClearCookies() noexcept = 0;
|
|
93
93
|
|
|
94
|
+
/// <summary>
|
|
95
|
+
/// Sets a function to be invoked when a request has been successfully responded.
|
|
96
|
+
/// </summary>
|
|
97
|
+
/// <param name="handler">
|
|
98
|
+
///
|
|
99
|
+
/// Parameters:
|
|
100
|
+
/// <param name="requestId">
|
|
101
|
+
/// Unique number identifying the HTTP request
|
|
102
|
+
/// </param>
|
|
103
|
+
/// </param>
|
|
94
104
|
virtual void SetOnRequestSuccess(std::function<void(int64_t requestId)> &&handler) noexcept = 0;
|
|
105
|
+
|
|
106
|
+
/// <summary>
|
|
107
|
+
/// Sets a function to be invoked when a response arrives and its headers are received.
|
|
108
|
+
/// </summary>
|
|
109
|
+
/// <param name="handler">
|
|
110
|
+
///
|
|
111
|
+
/// Parameters:
|
|
112
|
+
/// <param name="requestId">
|
|
113
|
+
/// Unique number identifying the HTTP request
|
|
114
|
+
/// </param>
|
|
115
|
+
/// <param name="response">
|
|
116
|
+
/// Object containing basic response data
|
|
117
|
+
/// </param>
|
|
118
|
+
/// </param>
|
|
95
119
|
virtual void SetOnResponse(std::function<void(int64_t requestId, Response &&response)> &&handler) noexcept = 0;
|
|
120
|
+
|
|
121
|
+
/// <summary>
|
|
122
|
+
/// Sets a function to be invoked when response content data has been received.
|
|
123
|
+
/// </summary>
|
|
124
|
+
/// <param name="handler">
|
|
125
|
+
///
|
|
126
|
+
/// Parameters:
|
|
127
|
+
/// <param name="requestId">
|
|
128
|
+
/// Unique number identifying the HTTP request
|
|
129
|
+
/// </param>
|
|
130
|
+
/// <param name="responseData">
|
|
131
|
+
/// Response content payload (plain text or Base64-encoded)
|
|
132
|
+
/// </param>
|
|
133
|
+
/// </param>
|
|
96
134
|
virtual void SetOnData(std::function<void(int64_t requestId, std::string &&responseData)> &&handler) noexcept = 0;
|
|
135
|
+
|
|
136
|
+
/// <summary>
|
|
137
|
+
/// Sets a function to be invoked when response content data has been received.
|
|
138
|
+
/// </summary>
|
|
139
|
+
/// <param name="handler">
|
|
140
|
+
///
|
|
141
|
+
/// Parameters:
|
|
142
|
+
/// <param name="requestId">
|
|
143
|
+
/// Unique number identifying the HTTP request
|
|
144
|
+
/// </param>
|
|
145
|
+
/// <param name="responseData">
|
|
146
|
+
/// Structured response content payload (i.e. Blob data)
|
|
147
|
+
/// </param>
|
|
148
|
+
/// </param>
|
|
97
149
|
virtual void SetOnData(std::function<void(int64_t requestId, folly::dynamic &&responseData)> &&handler) noexcept = 0;
|
|
150
|
+
|
|
151
|
+
/// <summary>
|
|
152
|
+
/// Sets a function to be invoked when a response content increment has been received.
|
|
153
|
+
/// </summary>
|
|
154
|
+
/// <remarks>
|
|
155
|
+
/// The handler set by this method will only be called if the request sets the incremental updates flag.
|
|
156
|
+
/// The handler is also mutually exclusive with those set by `SetOnData`, which are used for one pass, non-incremental
|
|
157
|
+
/// updates.
|
|
158
|
+
/// </remarks>
|
|
159
|
+
/// <param name="handler">
|
|
160
|
+
///
|
|
161
|
+
/// Parameters:
|
|
162
|
+
/// <param name="requestId">
|
|
163
|
+
/// Unique number identifying the HTTP request
|
|
164
|
+
/// </param>
|
|
165
|
+
/// <param name="responseData">
|
|
166
|
+
/// Partial response content data increment (non-accumulative)
|
|
167
|
+
/// </param>
|
|
168
|
+
/// <param name="progress">
|
|
169
|
+
/// Number of bytes received so far
|
|
170
|
+
/// </param>
|
|
171
|
+
/// <param name="total">
|
|
172
|
+
/// Number of total bytes to receive
|
|
173
|
+
/// </param>
|
|
174
|
+
/// </param>
|
|
175
|
+
virtual void SetOnIncrementalData(
|
|
176
|
+
std::function<void(int64_t requestId, std::string &&responseData, int64_t progress, int64_t total)>
|
|
177
|
+
&&handler) noexcept = 0;
|
|
178
|
+
|
|
179
|
+
/// <summary>
|
|
180
|
+
/// Sets a function to be invoked when response content download progress is reported.
|
|
181
|
+
/// </summary>
|
|
182
|
+
/// <param name="handler">
|
|
183
|
+
///
|
|
184
|
+
/// Parameters:
|
|
185
|
+
/// <param name="requestId">
|
|
186
|
+
/// Unique number identifying the HTTP request
|
|
187
|
+
/// </param>
|
|
188
|
+
/// <param name="progress">
|
|
189
|
+
/// Number of bytes received so far
|
|
190
|
+
/// </param>
|
|
191
|
+
/// <param name="total">
|
|
192
|
+
/// Number of total bytes to receive
|
|
193
|
+
/// </param>
|
|
194
|
+
/// </param>
|
|
195
|
+
virtual void SetOnDataProgress(
|
|
196
|
+
std::function<void(int64_t requestId, int64_t progress, int64_t total)> &&handler) noexcept = 0;
|
|
197
|
+
|
|
198
|
+
/// <summary>
|
|
199
|
+
/// Sets a function to be invoked when a response has been fully handled (either succeeded or failed).
|
|
200
|
+
/// </summary>
|
|
201
|
+
/// <param name="handler">
|
|
202
|
+
///
|
|
203
|
+
/// Parameters:
|
|
204
|
+
/// <param name="requestId">
|
|
205
|
+
/// Unique number identifying the HTTP request
|
|
206
|
+
/// </param>
|
|
207
|
+
/// </param>
|
|
208
|
+
virtual void SetOnResponseComplete(std::function<void(int64_t requestId)> &&handler) noexcept = 0;
|
|
209
|
+
|
|
210
|
+
/// <summary>
|
|
211
|
+
/// Sets a function to be invoked when an error condition is found.
|
|
212
|
+
/// </summary>
|
|
213
|
+
/// <remarks>
|
|
214
|
+
/// The handler's purpose is not to report any given HTTP error status (i.e. 403, 501).
|
|
215
|
+
/// It is meant to report application errors when executing HTTP requests.
|
|
216
|
+
/// </remarks>
|
|
217
|
+
/// <param name="handler">
|
|
218
|
+
///
|
|
219
|
+
/// Parameters:
|
|
220
|
+
/// <param name="requestId">
|
|
221
|
+
/// Unique number identifying the HTTP request
|
|
222
|
+
/// </param>
|
|
223
|
+
/// </param>
|
|
98
224
|
virtual void SetOnError(
|
|
99
225
|
std::function<void(int64_t requestId, std::string &&errorMessage, bool isTimeout)> &&handler) noexcept = 0;
|
|
100
226
|
};
|
|
@@ -120,12 +120,12 @@ bool OriginPolicyHttpFilter::ConstWcharComparer::operator()(const wchar_t *a, co
|
|
|
120
120
|
}
|
|
121
121
|
|
|
122
122
|
/*static*/ bool OriginPolicyHttpFilter::IsSimpleCorsRequest(HttpRequestMessage const &request) noexcept {
|
|
123
|
-
// Ensure header is in Simple CORS
|
|
123
|
+
// Ensure header is in Simple CORS allowlist
|
|
124
124
|
for (const auto &header : request.Headers()) {
|
|
125
125
|
if (s_simpleCorsRequestHeaderNames.find(header.Key().c_str()) == s_simpleCorsRequestHeaderNames.cend())
|
|
126
126
|
return false;
|
|
127
127
|
|
|
128
|
-
// Ensure Content-Type value is in Simple CORS
|
|
128
|
+
// Ensure Content-Type value is in Simple CORS allowlist, if present
|
|
129
129
|
if (boost::iequals(header.Key(), L"Content-Type")) {
|
|
130
130
|
if (s_simpleCorsContentTypeValues.find(header.Value().c_str()) != s_simpleCorsContentTypeValues.cend())
|
|
131
131
|
return false;
|
|
@@ -135,12 +135,12 @@ bool OriginPolicyHttpFilter::ConstWcharComparer::operator()(const wchar_t *a, co
|
|
|
135
135
|
// WinRT separates request headers from request content headers
|
|
136
136
|
if (auto content = request.Content()) {
|
|
137
137
|
for (const auto &header : content.Headers()) {
|
|
138
|
-
// WinRT automatically appends non-
|
|
138
|
+
// WinRT automatically appends non-allowlisted header Content-Length when Content-Type is set. Skip it.
|
|
139
139
|
if (s_simpleCorsRequestHeaderNames.find(header.Key().c_str()) == s_simpleCorsRequestHeaderNames.cend() &&
|
|
140
140
|
!boost::iequals(header.Key(), "Content-Length"))
|
|
141
141
|
return false;
|
|
142
142
|
|
|
143
|
-
// Ensure Content-Type value is in Simple CORS
|
|
143
|
+
// Ensure Content-Type value is in Simple CORS allowlist, if present
|
|
144
144
|
if (boost::iequals(header.Key(), L"Content-Type")) {
|
|
145
145
|
if (s_simpleCorsContentTypeValues.find(header.Value().c_str()) == s_simpleCorsContentTypeValues.cend())
|
|
146
146
|
return false;
|
|
@@ -148,7 +148,7 @@ bool OriginPolicyHttpFilter::ConstWcharComparer::operator()(const wchar_t *a, co
|
|
|
148
148
|
}
|
|
149
149
|
}
|
|
150
150
|
|
|
151
|
-
// Ensure method is in Simple CORS
|
|
151
|
+
// Ensure method is in Simple CORS allowlist
|
|
152
152
|
return s_simpleCorsMethods.find(request.Method().ToString().c_str()) != s_simpleCorsMethods.cend();
|
|
153
153
|
}
|
|
154
154
|
|
|
@@ -599,7 +599,7 @@ void OriginPolicyHttpFilter::ValidateResponse(HttpResponseMessage const &respons
|
|
|
599
599
|
}
|
|
600
600
|
|
|
601
601
|
if (originPolicy == OriginPolicy::SimpleCrossOriginResourceSharing) {
|
|
602
|
-
// Filter out response headers that are not in the Simple CORS
|
|
602
|
+
// Filter out response headers that are not in the Simple CORS allowlist
|
|
603
603
|
std::queue<hstring> nonSimpleNames;
|
|
604
604
|
for (const auto &header : response.Headers().GetView()) {
|
|
605
605
|
if (s_simpleCorsResponseHeaderNames.find(header.Key().c_str()) == s_simpleCorsResponseHeaderNames.cend())
|
|
@@ -651,21 +651,26 @@ ResponseOperation OriginPolicyHttpFilter::SendPreflightAsync(HttpRequestMessage
|
|
|
651
651
|
preflightRequest.Headers().Insert(L"Access-Control-Request-Method", coRequest.Method().ToString());
|
|
652
652
|
|
|
653
653
|
auto headerNames = wstring{};
|
|
654
|
-
auto
|
|
655
|
-
|
|
656
|
-
|
|
654
|
+
auto writeSeparator = false;
|
|
655
|
+
for (const auto &header : coRequest.Headers()) {
|
|
656
|
+
if (writeSeparator) {
|
|
657
|
+
headerNames += L", ";
|
|
658
|
+
} else {
|
|
659
|
+
writeSeparator = true;
|
|
660
|
+
}
|
|
657
661
|
|
|
658
|
-
|
|
659
|
-
headerNames += L", " + (*headerItr).Key();
|
|
662
|
+
headerNames += header.Key();
|
|
660
663
|
}
|
|
661
664
|
|
|
662
665
|
if (coRequest.Content()) {
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
+
for (const auto &header : coRequest.Content().Headers()) {
|
|
667
|
+
if (writeSeparator) {
|
|
668
|
+
headerNames += L", ";
|
|
669
|
+
} else {
|
|
670
|
+
writeSeparator = true;
|
|
671
|
+
}
|
|
666
672
|
|
|
667
|
-
|
|
668
|
-
headerNames += L", " + (*headerItr).Key();
|
|
673
|
+
headerNames += header.Key();
|
|
669
674
|
}
|
|
670
675
|
}
|
|
671
676
|
|
|
@@ -51,8 +51,51 @@ using winrt::Windows::Web::Http::IHttpClient;
|
|
|
51
51
|
using winrt::Windows::Web::Http::IHttpContent;
|
|
52
52
|
using winrt::Windows::Web::Http::Headers::HttpMediaTypeHeaderValue;
|
|
53
53
|
|
|
54
|
+
namespace {
|
|
55
|
+
|
|
56
|
+
constexpr uint32_t operator""_KiB(unsigned long long int x) {
|
|
57
|
+
return static_cast<uint32_t>(1024 * x);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
constexpr uint32_t operator""_MiB(unsigned long long int x) {
|
|
61
|
+
return static_cast<uint32_t>(1024_KiB * x);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
constexpr char responseTypeText[] = "text";
|
|
65
|
+
constexpr char responseTypeBase64[] = "base64";
|
|
66
|
+
constexpr char responseTypeBlob[] = "blob";
|
|
67
|
+
|
|
68
|
+
} // namespace
|
|
54
69
|
namespace Microsoft::React::Networking {
|
|
55
70
|
|
|
71
|
+
// May throw winrt::hresult_error
|
|
72
|
+
void AttachMultipartHeaders(IHttpContent content, const dynamic &headers) {
|
|
73
|
+
HttpMediaTypeHeaderValue contentType{nullptr};
|
|
74
|
+
|
|
75
|
+
// Headers are generally case-insensitive
|
|
76
|
+
// https://www.ietf.org/rfc/rfc2616.txt section 4.2
|
|
77
|
+
// TODO: Consolidate with PerformRequest's header parsing.
|
|
78
|
+
for (auto &header : headers.items()) {
|
|
79
|
+
auto &name = header.first.getString();
|
|
80
|
+
auto &value = header.second.getString();
|
|
81
|
+
|
|
82
|
+
if (boost::iequals(name.c_str(), "Content-Type")) {
|
|
83
|
+
contentType = HttpMediaTypeHeaderValue::Parse(to_hstring(value));
|
|
84
|
+
} else if (boost::iequals(name.c_str(), "Authorization")) {
|
|
85
|
+
bool success = content.Headers().TryAppendWithoutValidation(to_hstring(name), to_hstring(value));
|
|
86
|
+
if (!success) {
|
|
87
|
+
throw hresult_error{E_INVALIDARG, L"Failed to append Authorization"};
|
|
88
|
+
}
|
|
89
|
+
} else {
|
|
90
|
+
content.Headers().Append(to_hstring(name), to_hstring(value));
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
if (contentType) {
|
|
95
|
+
content.Headers().ContentType(contentType);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
56
99
|
#pragma region WinRTHttpResource
|
|
57
100
|
|
|
58
101
|
WinRTHttpResource::WinRTHttpResource(IHttpClient &&client) noexcept : m_client{std::move(client)} {}
|
|
@@ -81,20 +124,23 @@ IAsyncOperation<HttpRequestMessage> WinRTHttpResource::CreateRequest(
|
|
|
81
124
|
// Headers are generally case-insensitive
|
|
82
125
|
// https://www.ietf.org/rfc/rfc2616.txt section 4.2
|
|
83
126
|
for (auto &header : reqArgs->Headers) {
|
|
84
|
-
|
|
85
|
-
|
|
127
|
+
auto &name = header.first;
|
|
128
|
+
auto &value = header.second;
|
|
129
|
+
|
|
130
|
+
if (boost::iequals(name.c_str(), "Content-Type")) {
|
|
131
|
+
bool success = HttpMediaTypeHeaderValue::TryParse(to_hstring(value), contentType);
|
|
86
132
|
if (!success) {
|
|
87
133
|
if (self->m_onError) {
|
|
88
134
|
self->m_onError(reqArgs->RequestId, "Failed to parse Content-Type", false);
|
|
89
135
|
}
|
|
90
136
|
co_return nullptr;
|
|
91
137
|
}
|
|
92
|
-
} else if (boost::iequals(
|
|
93
|
-
contentEncoding =
|
|
94
|
-
} else if (boost::iequals(
|
|
95
|
-
contentLength =
|
|
96
|
-
} else if (boost::iequals(
|
|
97
|
-
bool success = request.Headers().TryAppendWithoutValidation(to_hstring(
|
|
138
|
+
} else if (boost::iequals(name.c_str(), "Content-Encoding")) {
|
|
139
|
+
contentEncoding = value;
|
|
140
|
+
} else if (boost::iequals(name.c_str(), "Content-Length")) {
|
|
141
|
+
contentLength = value;
|
|
142
|
+
} else if (boost::iequals(name.c_str(), "Authorization")) {
|
|
143
|
+
bool success = request.Headers().TryAppendWithoutValidation(to_hstring(name), to_hstring(value));
|
|
98
144
|
if (!success) {
|
|
99
145
|
if (self->m_onError) {
|
|
100
146
|
self->m_onError(reqArgs->RequestId, "Failed to append Authorization", false);
|
|
@@ -103,7 +149,7 @@ IAsyncOperation<HttpRequestMessage> WinRTHttpResource::CreateRequest(
|
|
|
103
149
|
}
|
|
104
150
|
} else {
|
|
105
151
|
try {
|
|
106
|
-
request.Headers().Append(to_hstring(
|
|
152
|
+
request.Headers().Append(to_hstring(name), to_hstring(value));
|
|
107
153
|
} catch (hresult_error const &e) {
|
|
108
154
|
if (self->m_onError) {
|
|
109
155
|
self->m_onError(reqArgs->RequestId, Utilities::HResultToString(e), false);
|
|
@@ -146,9 +192,31 @@ IAsyncOperation<HttpRequestMessage> WinRTHttpResource::CreateRequest(
|
|
|
146
192
|
auto file = co_await StorageFile::GetFileFromApplicationUriAsync(Uri{to_hstring(data["uri"].asString())});
|
|
147
193
|
auto stream = co_await file.OpenReadAsync();
|
|
148
194
|
content = HttpStreamContent{std::move(stream)};
|
|
149
|
-
} else if (!data["
|
|
150
|
-
|
|
151
|
-
|
|
195
|
+
} else if (!data["formData"].empty()) {
|
|
196
|
+
winrt::Windows::Web::Http::HttpMultipartFormDataContent multiPartContent;
|
|
197
|
+
auto formData = data["formData"];
|
|
198
|
+
|
|
199
|
+
// #6046 - Overwriting WinRT's HttpMultipartFormDataContent implicit Content-Type clears the generated boundary
|
|
200
|
+
contentType = nullptr;
|
|
201
|
+
|
|
202
|
+
for (auto &formDataPart : formData) {
|
|
203
|
+
IHttpContent formContent{nullptr};
|
|
204
|
+
if (!formDataPart["string"].isNull()) {
|
|
205
|
+
formContent = HttpStringContent{to_hstring(formDataPart["string"].asString())};
|
|
206
|
+
} else if (!formDataPart["uri"].empty()) {
|
|
207
|
+
auto filePath = to_hstring(formDataPart["uri"].asString());
|
|
208
|
+
auto file = co_await StorageFile::GetFileFromPathAsync(filePath);
|
|
209
|
+
auto stream = co_await file.OpenReadAsync();
|
|
210
|
+
formContent = HttpStreamContent{stream};
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
if (formContent) {
|
|
214
|
+
AttachMultipartHeaders(formContent, formDataPart["headers"]);
|
|
215
|
+
multiPartContent.Add(formContent, to_hstring(formDataPart["fieldName"].asString()));
|
|
216
|
+
}
|
|
217
|
+
} // foreach form data part
|
|
218
|
+
|
|
219
|
+
content = multiPartContent;
|
|
152
220
|
}
|
|
153
221
|
}
|
|
154
222
|
|
|
@@ -205,7 +273,7 @@ void WinRTHttpResource::SendRequest(
|
|
|
205
273
|
bool withCredentials,
|
|
206
274
|
std::function<void(int64_t)> &&callback) noexcept /*override*/ {
|
|
207
275
|
// Enforce supported args
|
|
208
|
-
assert(responseType ==
|
|
276
|
+
assert(responseType == responseTypeText || responseType == responseTypeBase64 || responseType == responseTypeBlob);
|
|
209
277
|
|
|
210
278
|
if (callback) {
|
|
211
279
|
callback(requestId);
|
|
@@ -283,6 +351,22 @@ void WinRTHttpResource::SetOnData(function<void(int64_t requestId, dynamic &&res
|
|
|
283
351
|
m_onDataDynamic = std::move(handler);
|
|
284
352
|
}
|
|
285
353
|
|
|
354
|
+
void WinRTHttpResource::SetOnIncrementalData(
|
|
355
|
+
function<void(int64_t requestId, string &&responseData, int64_t progress, int64_t total)> &&handler) noexcept
|
|
356
|
+
/*override*/ {
|
|
357
|
+
m_onIncrementalData = std::move(handler);
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
void WinRTHttpResource::SetOnDataProgress(
|
|
361
|
+
function<void(int64_t requestId, int64_t progress, int64_t total)> &&handler) noexcept
|
|
362
|
+
/*override*/ {
|
|
363
|
+
m_onDataProgress = std::move(handler);
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
void WinRTHttpResource::SetOnResponseComplete(function<void(int64_t requestId)> &&handler) noexcept /*override*/ {
|
|
367
|
+
m_onComplete = std::move(handler);
|
|
368
|
+
}
|
|
369
|
+
|
|
286
370
|
void WinRTHttpResource::SetOnError(
|
|
287
371
|
function<void(int64_t requestId, string &&errorMessage, bool isTimeout)> &&handler) noexcept
|
|
288
372
|
/*override*/ {
|
|
@@ -316,11 +400,18 @@ WinRTHttpResource::PerformSendRequest(HttpMethod &&method, Uri &&rtUri, IInspect
|
|
|
316
400
|
auto props = winrt::multi_threaded_map<winrt::hstring, IInspectable>();
|
|
317
401
|
props.Insert(L"RequestArgs", coArgs);
|
|
318
402
|
|
|
319
|
-
auto
|
|
320
|
-
|
|
321
|
-
|
|
403
|
+
auto coRequestOp = CreateRequest(std::move(coMethod), std::move(coUri), props);
|
|
404
|
+
co_await lessthrow_await_adapter<IAsyncOperation<HttpRequestMessage>>{coRequestOp};
|
|
405
|
+
auto coRequestOpHR = coRequestOp.ErrorCode();
|
|
406
|
+
if (coRequestOpHR < 0) {
|
|
407
|
+
if (self->m_onError) {
|
|
408
|
+
self->m_onError(reqArgs->RequestId, Utilities::HResultToString(std::move(coRequestOpHR)), false);
|
|
409
|
+
}
|
|
410
|
+
co_return self->UntrackResponse(reqArgs->RequestId);
|
|
322
411
|
}
|
|
323
412
|
|
|
413
|
+
auto coRequest = coRequestOp.GetResults();
|
|
414
|
+
|
|
324
415
|
// If URI handler is available, it takes over request processing.
|
|
325
416
|
if (auto uriHandler = self->m_uriHandler.lock()) {
|
|
326
417
|
auto uri = winrt::to_string(coRequest.RequestUri().ToString());
|
|
@@ -332,6 +423,10 @@ WinRTHttpResource::PerformSendRequest(HttpMethod &&method, Uri &&rtUri, IInspect
|
|
|
332
423
|
self->m_onRequestSuccess(reqArgs->RequestId);
|
|
333
424
|
}
|
|
334
425
|
|
|
426
|
+
if (self->m_onComplete) {
|
|
427
|
+
self->m_onComplete(reqArgs->RequestId);
|
|
428
|
+
}
|
|
429
|
+
|
|
335
430
|
co_return;
|
|
336
431
|
}
|
|
337
432
|
} catch (const hresult_error &e) {
|
|
@@ -345,6 +440,9 @@ WinRTHttpResource::PerformSendRequest(HttpMethod &&method, Uri &&rtUri, IInspect
|
|
|
345
440
|
|
|
346
441
|
try {
|
|
347
442
|
auto sendRequestOp = self->m_client.SendRequestAsync(coRequest);
|
|
443
|
+
|
|
444
|
+
auto isText = reqArgs->ResponseType == responseTypeText;
|
|
445
|
+
|
|
348
446
|
self->TrackResponse(reqArgs->RequestId, sendRequestOp);
|
|
349
447
|
|
|
350
448
|
if (reqArgs->Timeout > 0) {
|
|
@@ -411,55 +509,86 @@ WinRTHttpResource::PerformSendRequest(HttpMethod &&method, Uri &&rtUri, IInspect
|
|
|
411
509
|
auto inputStream = co_await response.Content().ReadAsInputStreamAsync();
|
|
412
510
|
auto reader = DataReader{inputStream};
|
|
413
511
|
|
|
414
|
-
//
|
|
415
|
-
|
|
512
|
+
// Accumulate all incoming request data in 8MB chunks
|
|
513
|
+
// Note, the minimum apparent valid chunk size is 128 KB
|
|
514
|
+
// Apple's implementation appears to grab 5-8 KB chunks
|
|
515
|
+
const uint32_t segmentSize = reqArgs->IncrementalUpdates ? 128_KiB : 8_MiB;
|
|
416
516
|
|
|
417
517
|
// Let response handler take over, if set
|
|
418
518
|
if (auto responseHandler = self->m_responseHandler.lock()) {
|
|
419
519
|
if (responseHandler->Supports(reqArgs->ResponseType)) {
|
|
420
|
-
|
|
421
|
-
reader.
|
|
422
|
-
|
|
520
|
+
vector<uint8_t> responseData{};
|
|
521
|
+
while (auto loaded = co_await reader.LoadAsync(segmentSize)) {
|
|
522
|
+
auto length = reader.UnconsumedBufferLength();
|
|
523
|
+
auto data = vector<uint8_t>(length);
|
|
524
|
+
reader.ReadBytes(data);
|
|
525
|
+
|
|
526
|
+
responseData.insert(responseData.cend(), data.cbegin(), data.cend());
|
|
527
|
+
}
|
|
528
|
+
|
|
529
|
+
auto blob = responseHandler->ToResponseData(std::move(responseData));
|
|
423
530
|
|
|
424
531
|
if (self->m_onDataDynamic && self->m_onRequestSuccess) {
|
|
425
532
|
self->m_onDataDynamic(reqArgs->RequestId, std::move(blob));
|
|
426
533
|
self->m_onRequestSuccess(reqArgs->RequestId);
|
|
427
534
|
}
|
|
428
535
|
|
|
536
|
+
if (self->m_onComplete) {
|
|
537
|
+
self->m_onComplete(reqArgs->RequestId);
|
|
538
|
+
}
|
|
429
539
|
co_return;
|
|
430
540
|
}
|
|
431
541
|
}
|
|
432
542
|
|
|
433
|
-
auto isText = reqArgs->ResponseType == "text";
|
|
434
543
|
if (isText) {
|
|
435
544
|
reader.UnicodeEncoding(UnicodeEncoding::Utf8);
|
|
436
545
|
}
|
|
437
546
|
|
|
438
|
-
|
|
439
|
-
uint32_t segmentSize = 10 * 1024 * 1024;
|
|
547
|
+
int64_t receivedBytes = 0;
|
|
440
548
|
string responseData;
|
|
441
549
|
winrt::Windows::Storage::Streams::IBuffer buffer;
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
length = reader.UnconsumedBufferLength();
|
|
550
|
+
while (auto loaded = co_await reader.LoadAsync(segmentSize)) {
|
|
551
|
+
auto length = reader.UnconsumedBufferLength();
|
|
552
|
+
receivedBytes += length;
|
|
446
553
|
|
|
447
554
|
if (isText) {
|
|
448
|
-
auto data =
|
|
555
|
+
auto data = vector<uint8_t>(length);
|
|
449
556
|
reader.ReadBytes(data);
|
|
450
557
|
|
|
451
|
-
|
|
558
|
+
auto incrementData = string(Common::Utilities::CheckedReinterpretCast<char *>(data.data()), data.size());
|
|
559
|
+
// #9534 - Send incremental updates.
|
|
560
|
+
// See https://github.com/facebook/react-native/blob/v0.70.6/Libraries/Network/RCTNetworking.mm#L561
|
|
561
|
+
if (reqArgs->IncrementalUpdates) {
|
|
562
|
+
responseData = std::move(incrementData);
|
|
563
|
+
|
|
564
|
+
if (self->m_onIncrementalData) {
|
|
565
|
+
// For total, see #10849
|
|
566
|
+
self->m_onIncrementalData(reqArgs->RequestId, std::move(responseData), receivedBytes, 0 /*total*/);
|
|
567
|
+
}
|
|
568
|
+
} else {
|
|
569
|
+
responseData += std::move(incrementData);
|
|
570
|
+
}
|
|
452
571
|
} else {
|
|
453
572
|
buffer = reader.ReadBuffer(length);
|
|
454
573
|
auto data = CryptographicBuffer::EncodeToBase64String(buffer);
|
|
455
574
|
|
|
456
575
|
responseData += winrt::to_string(std::wstring_view(data));
|
|
576
|
+
|
|
577
|
+
if (self->m_onDataProgress) {
|
|
578
|
+
// For total, see #10849
|
|
579
|
+
self->m_onDataProgress(reqArgs->RequestId, receivedBytes, 0 /*total*/);
|
|
580
|
+
}
|
|
457
581
|
}
|
|
458
|
-
}
|
|
582
|
+
}
|
|
459
583
|
|
|
460
|
-
|
|
584
|
+
// If dealing with text-incremental response data, use m_onIncrementalData instead
|
|
585
|
+
if (self->m_onData && !(reqArgs->IncrementalUpdates && isText)) {
|
|
461
586
|
self->m_onData(reqArgs->RequestId, std::move(responseData));
|
|
462
587
|
}
|
|
588
|
+
|
|
589
|
+
if (self->m_onComplete) {
|
|
590
|
+
self->m_onComplete(reqArgs->RequestId);
|
|
591
|
+
}
|
|
463
592
|
} else {
|
|
464
593
|
if (self->m_onError) {
|
|
465
594
|
self->m_onError(reqArgs->RequestId, response == nullptr ? "request failed" : "No response content", false);
|
|
@@ -30,6 +30,10 @@ class WinRTHttpResource : public IHttpResource,
|
|
|
30
30
|
std::function<void(int64_t requestId, std::string &&responseData)> m_onData;
|
|
31
31
|
std::function<void(int64_t requestId, folly::dynamic &&responseData)> m_onDataDynamic;
|
|
32
32
|
std::function<void(int64_t requestId, std::string &&errorMessage, bool isTimeout)> m_onError;
|
|
33
|
+
std::function<void(int64_t requestId, std::string &&responseData, int64_t progress, int64_t total)>
|
|
34
|
+
m_onIncrementalData;
|
|
35
|
+
std::function<void(int64_t requestId, int64_t progress, int64_t total)> m_onDataProgress;
|
|
36
|
+
std::function<void(int64_t requestId)> m_onComplete;
|
|
33
37
|
|
|
34
38
|
// Used for IHttpModuleProxy
|
|
35
39
|
std::weak_ptr<IUriHandler> m_uriHandler;
|
|
@@ -80,6 +84,12 @@ class WinRTHttpResource : public IHttpResource,
|
|
|
80
84
|
void SetOnResponse(std::function<void(int64_t requestId, Response &&response)> &&handler) noexcept override;
|
|
81
85
|
void SetOnData(std::function<void(int64_t requestId, std::string &&responseData)> &&handler) noexcept override;
|
|
82
86
|
void SetOnData(std::function<void(int64_t requestId, folly::dynamic &&responseData)> &&handler) noexcept override;
|
|
87
|
+
void SetOnIncrementalData(
|
|
88
|
+
std::function<void(int64_t requestId, std::string &&responseData, int64_t progress, int64_t total)>
|
|
89
|
+
&&handler) noexcept override;
|
|
90
|
+
void SetOnDataProgress(
|
|
91
|
+
std::function<void(int64_t requestId, int64_t progress, int64_t total)> &&handler) noexcept override;
|
|
92
|
+
void SetOnResponseComplete(std::function<void(int64_t requestId)> &&handler) noexcept override;
|
|
83
93
|
void SetOnError(
|
|
84
94
|
std::function<void(int64_t requestId, std::string &&errorMessage, bool isTimeout)> &&handler) noexcept override;
|
|
85
95
|
|
package/Shared/OInstance.cpp
CHANGED
|
@@ -27,7 +27,6 @@
|
|
|
27
27
|
|
|
28
28
|
#include <Modules/ExceptionsManagerModule.h>
|
|
29
29
|
#include <Modules/HttpModule.h>
|
|
30
|
-
#include <Modules/NetworkingModule.h>
|
|
31
30
|
#include <Modules/PlatformConstantsModule.h>
|
|
32
31
|
#include <Modules/SourceCodeModule.h>
|
|
33
32
|
#include <Modules/StatusBarManagerModule.h>
|
|
@@ -73,11 +72,7 @@ namespace Microsoft::React {
|
|
|
73
72
|
|
|
74
73
|
/*extern*/ std::unique_ptr<facebook::xplat::module::CxxModule> CreateHttpModule(
|
|
75
74
|
winrt::Windows::Foundation::IInspectable const &inspectableProperties) noexcept {
|
|
76
|
-
|
|
77
|
-
return std::make_unique<NetworkingModule>();
|
|
78
|
-
} else {
|
|
79
|
-
return std::make_unique<HttpModule>(inspectableProperties);
|
|
80
|
-
}
|
|
75
|
+
return std::make_unique<HttpModule>(inspectableProperties);
|
|
81
76
|
}
|
|
82
77
|
|
|
83
78
|
} // namespace Microsoft::React
|
|
@@ -638,8 +633,7 @@ std::vector<std::unique_ptr<NativeModule>> InstanceImpl::GetDefaultNativeModules
|
|
|
638
633
|
// If this code is enabled, we will have unused module instances.
|
|
639
634
|
// Also, MSRN has a different property bag mechanism incompatible with this method's transitionalProps variable.
|
|
640
635
|
#if (defined(_MSC_VER) && !defined(WINRT))
|
|
641
|
-
if (Microsoft::React::GetRuntimeOptionBool("Blob.EnableModule")
|
|
642
|
-
!Microsoft::React::GetRuntimeOptionBool("Http.UseMonolithicModule")) {
|
|
636
|
+
if (Microsoft::React::GetRuntimeOptionBool("Blob.EnableModule")) {
|
|
643
637
|
modules.push_back(std::make_unique<CxxNativeModule>(
|
|
644
638
|
m_innerInstance,
|
|
645
639
|
Microsoft::React::GetBlobModuleName(),
|
package/Shared/Shared.vcxitems
CHANGED
|
@@ -50,7 +50,9 @@
|
|
|
50
50
|
<ClCompile Include="$(MSBuildThisFileDirectory)Modules\FileReaderModule.cpp" />
|
|
51
51
|
<ClCompile Include="$(MSBuildThisFileDirectory)Modules\HttpModule.cpp" />
|
|
52
52
|
<ClCompile Include="$(MSBuildThisFileDirectory)Modules\I18nModule.cpp" />
|
|
53
|
-
<ClCompile Include="$(MSBuildThisFileDirectory)Modules\NetworkingModule.cpp"
|
|
53
|
+
<ClCompile Include="$(MSBuildThisFileDirectory)Modules\NetworkingModule.cpp">
|
|
54
|
+
<ExcludedFromBuild>true</ExcludedFromBuild>
|
|
55
|
+
</ClCompile>
|
|
54
56
|
<ClCompile Include="$(MSBuildThisFileDirectory)Modules\PlatformConstantsModule.cpp" />
|
|
55
57
|
<ClCompile Include="$(MSBuildThisFileDirectory)Modules\SourceCodeModule.cpp" />
|
|
56
58
|
<ClCompile Include="$(MSBuildThisFileDirectory)Modules\StatusBarManagerModule.cpp" />
|