react-native-windows 0.67.7 → 0.67.10
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/CHANGELOG.json +162 -0
- package/CHANGELOG.md +68 -8
- package/Chakra/ChakraHelpers.cpp +0 -1
- package/Directory.Build.props +4 -0
- package/Folly/Folly.vcxproj +4 -5
- package/Libraries/Network/RCTNetworkingWinShared.js +7 -0
- package/Microsoft.ReactNative/Base/CoreNativeModules.cpp +2 -3
- package/Microsoft.ReactNative/IReactContext.cpp +17 -0
- package/Microsoft.ReactNative/IReactContext.h +2 -0
- package/Microsoft.ReactNative/IReactContext.idl +27 -0
- package/Microsoft.ReactNative/Modules/CreateModules.cpp +3 -3
- package/Microsoft.ReactNative/packages.config +1 -1
- package/Microsoft.ReactNative.Cxx/JSI/NodeApiJsiRuntime.cpp +26 -16
- package/Microsoft.ReactNative.Cxx/JSI/NodeApiJsiRuntime.h +52 -0
- package/Microsoft.ReactNative.Cxx/NativeModules.h +2 -2
- package/Mso/src/dispatchQueue/threadPoolScheduler_win.cpp +96 -4
- package/PropertySheets/Generated/PackageVersion.g.props +2 -2
- package/PropertySheets/JSEngine.props +1 -1
- package/Scripts/OfficeReact.Win32.nuspec +1 -1
- package/Shared/BaseScriptStoreImpl.cpp +1 -1
- package/Shared/CppRuntimeOptions.h +50 -0
- package/Shared/CreateModules.h +20 -1
- package/Shared/InspectorPackagerConnection.cpp +7 -5
- package/Shared/InspectorPackagerConnection.h +2 -2
- package/Shared/JSI/ChakraApi.cpp +0 -1
- package/Shared/JSI/ChakraRuntime.cpp +0 -1
- package/Shared/JSI/NapiJsiV8RuntimeHolder.cpp +72 -2
- package/Shared/JSI/NapiJsiV8RuntimeHolder.h +3 -1
- package/Shared/Modules/BlobModule.cpp +376 -0
- package/Shared/Modules/BlobModule.h +153 -0
- package/Shared/Modules/CxxModuleUtilities.cpp +19 -0
- package/Shared/Modules/CxxModuleUtilities.h +23 -0
- package/Shared/Modules/FileReaderModule.cpp +156 -0
- package/Shared/Modules/FileReaderModule.h +54 -0
- package/Shared/Modules/HttpModule.cpp +201 -0
- package/Shared/Modules/HttpModule.h +60 -0
- package/Shared/Modules/IBlobPersistor.h +30 -0
- package/Shared/Modules/IHttpModuleProxy.h +30 -0
- package/Shared/Modules/IRequestBodyHandler.h +52 -0
- package/Shared/Modules/IResponseHandler.h +27 -0
- package/Shared/Modules/IUriHandler.h +37 -0
- package/Shared/Modules/IWebSocketModuleContentHandler.h +26 -0
- package/Shared/Modules/IWebSocketModuleProxy.h +22 -0
- package/Shared/Modules/NetworkingModule.cpp +1 -1
- package/Shared/Modules/WebSocketModule.cpp +97 -23
- package/Shared/Modules/WebSocketModule.h +35 -6
- package/Shared/Networking/IHttpResource.h +101 -0
- package/Shared/{IWebSocketResource.h → Networking/IWebSocketResource.h} +3 -3
- package/Shared/Networking/OriginPolicy.h +15 -0
- package/Shared/Networking/OriginPolicyHttpFilter.cpp +747 -0
- package/Shared/Networking/OriginPolicyHttpFilter.h +112 -0
- package/Shared/Networking/WinRTHttpResource.cpp +465 -0
- package/Shared/Networking/WinRTHttpResource.h +86 -0
- package/Shared/Networking/WinRTTypes.h +33 -0
- package/Shared/{WinRTWebSocketResource.cpp → Networking/WinRTWebSocketResource.cpp} +31 -22
- package/Shared/{WinRTWebSocketResource.h → Networking/WinRTWebSocketResource.h} +3 -3
- package/Shared/OInstance.cpp +41 -4
- package/Shared/OInstance.h +8 -4
- package/Shared/RuntimeOptions.cpp +96 -15
- package/Shared/RuntimeOptions.h +32 -8
- package/Shared/Shared.vcxitems +28 -5
- package/Shared/Shared.vcxitems.filters +93 -15
- package/Shared/Utils/WinRTConversions.cpp +22 -0
- package/Shared/Utils/WinRTConversions.h +15 -0
- package/fmt/fmt.vcxproj +4 -5
- package/package.json +1 -1
- package/Shared/IHttpResource.h +0 -34
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
// Copyright (c) Microsoft Corporation.
|
|
2
|
+
// Licensed under the MIT License.
|
|
3
|
+
|
|
4
|
+
#include "FileReaderModule.h"
|
|
5
|
+
|
|
6
|
+
#include <ReactPropertyBag.h>
|
|
7
|
+
|
|
8
|
+
// Boost Library
|
|
9
|
+
#include <boost/archive/iterators/base64_from_binary.hpp>
|
|
10
|
+
#include <boost/archive/iterators/ostream_iterator.hpp>
|
|
11
|
+
#include <boost/archive/iterators/transform_width.hpp>
|
|
12
|
+
|
|
13
|
+
// React Native
|
|
14
|
+
#include <cxxreact/JsArgumentHelpers.h>
|
|
15
|
+
|
|
16
|
+
// Windows API
|
|
17
|
+
#include <winrt/Windows.Foundation.h>
|
|
18
|
+
|
|
19
|
+
using namespace facebook::xplat;
|
|
20
|
+
|
|
21
|
+
using folly::dynamic;
|
|
22
|
+
using std::string;
|
|
23
|
+
using std::weak_ptr;
|
|
24
|
+
using winrt::Microsoft::ReactNative::IReactPropertyBag;
|
|
25
|
+
using winrt::Microsoft::ReactNative::ReactNonAbiValue;
|
|
26
|
+
using winrt::Microsoft::ReactNative::ReactPropertyBag;
|
|
27
|
+
using winrt::Microsoft::ReactNative::ReactPropertyId;
|
|
28
|
+
using winrt::Windows::Foundation::IInspectable;
|
|
29
|
+
|
|
30
|
+
namespace {
|
|
31
|
+
constexpr char moduleName[] = "FileReaderModule";
|
|
32
|
+
} // namespace
|
|
33
|
+
|
|
34
|
+
namespace Microsoft::React {
|
|
35
|
+
|
|
36
|
+
#pragma region FileReaderModule
|
|
37
|
+
|
|
38
|
+
FileReaderModule::FileReaderModule(weak_ptr<IBlobPersistor> weakBlobPersistor) noexcept
|
|
39
|
+
: m_weakBlobPersistor{weakBlobPersistor} {}
|
|
40
|
+
|
|
41
|
+
FileReaderModule::~FileReaderModule() noexcept /*override*/
|
|
42
|
+
{}
|
|
43
|
+
|
|
44
|
+
#pragma region CxxModule
|
|
45
|
+
|
|
46
|
+
string FileReaderModule::getName() {
|
|
47
|
+
return moduleName;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
std::map<string, dynamic> FileReaderModule::getConstants() {
|
|
51
|
+
return {};
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
std::vector<module::CxxModule::Method> FileReaderModule::getMethods() {
|
|
55
|
+
return {
|
|
56
|
+
{///
|
|
57
|
+
/// <param name="args">
|
|
58
|
+
/// Array of arguments passed from the JavaScript layer.
|
|
59
|
+
/// [0] - dynamic blob object { blobId, offset, size[, type] }
|
|
60
|
+
/// </param>
|
|
61
|
+
///
|
|
62
|
+
"readAsDataURL",
|
|
63
|
+
[blobPersistor = m_weakBlobPersistor.lock()](dynamic args, Callback resolve, Callback reject) {
|
|
64
|
+
if (!blobPersistor) {
|
|
65
|
+
return reject({"Could not find Blob persistor"});
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
auto blob = jsArgAsObject(args, 0);
|
|
69
|
+
|
|
70
|
+
auto blobId = blob["blobId"].asString();
|
|
71
|
+
auto offset = blob["offset"].asInt();
|
|
72
|
+
auto size = blob["size"].asInt();
|
|
73
|
+
|
|
74
|
+
winrt::array_view<uint8_t> bytes;
|
|
75
|
+
try {
|
|
76
|
+
bytes = blobPersistor->ResolveMessage(std::move(blobId), offset, size);
|
|
77
|
+
} catch (const std::exception &e) {
|
|
78
|
+
return reject({e.what()});
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
auto result = string{"data:"};
|
|
82
|
+
auto typeItr = blob.find("type");
|
|
83
|
+
if (typeItr == blob.items().end()) {
|
|
84
|
+
result += "application/octet-stream";
|
|
85
|
+
} else {
|
|
86
|
+
result += (*typeItr).second.asString();
|
|
87
|
+
}
|
|
88
|
+
result += ";base64,";
|
|
89
|
+
|
|
90
|
+
// https://www.boost.org/doc/libs/1_76_0/libs/serialization/doc/dataflow.html
|
|
91
|
+
using namespace boost::archive::iterators;
|
|
92
|
+
typedef base64_from_binary<transform_width<const char *, 6, 8>> encode_base64;
|
|
93
|
+
std::ostringstream oss;
|
|
94
|
+
std::copy(encode_base64(bytes.cbegin()), encode_base64(bytes.cend()), ostream_iterator<char>(oss));
|
|
95
|
+
result += oss.str();
|
|
96
|
+
|
|
97
|
+
resolve({std::move(result)});
|
|
98
|
+
}},
|
|
99
|
+
{///
|
|
100
|
+
/// <param name="args">
|
|
101
|
+
/// Array of arguments passed from the JavaScript layer.
|
|
102
|
+
/// [0] - dynamic blob object { blobId, offset, size }
|
|
103
|
+
/// [1] - string encoding
|
|
104
|
+
/// </param>
|
|
105
|
+
///
|
|
106
|
+
"readAsText",
|
|
107
|
+
[blobPersistor = m_weakBlobPersistor.lock()](dynamic args, Callback resolve, Callback reject) {
|
|
108
|
+
if (!blobPersistor) {
|
|
109
|
+
return reject({"Could not find Blob persistor"});
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
auto blob = jsArgAsObject(args, 0);
|
|
113
|
+
auto encoding = jsArgAsString(args, 1); // Default: "UTF-8"
|
|
114
|
+
|
|
115
|
+
auto blobId = blob["blobId"].asString();
|
|
116
|
+
auto offset = blob["offset"].asInt();
|
|
117
|
+
auto size = blob["size"].asInt();
|
|
118
|
+
|
|
119
|
+
winrt::array_view<uint8_t> bytes;
|
|
120
|
+
try {
|
|
121
|
+
bytes = blobPersistor->ResolveMessage(std::move(blobId), offset, size);
|
|
122
|
+
} catch (const std::exception &e) {
|
|
123
|
+
return reject({e.what()});
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
// #9982 - Handle non-UTF8 encodings
|
|
127
|
+
// See https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/nio/charset/Charset.html
|
|
128
|
+
auto result = string{bytes.cbegin(), bytes.cend()};
|
|
129
|
+
|
|
130
|
+
resolve({std::move(result)});
|
|
131
|
+
}}};
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
#pragma endregion CxxModule
|
|
135
|
+
|
|
136
|
+
#pragma endregion FileReaderModule
|
|
137
|
+
|
|
138
|
+
/*extern*/ const char *GetFileReaderModuleName() noexcept {
|
|
139
|
+
return moduleName;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
/*extern*/ std::unique_ptr<module::CxxModule> CreateFileReaderModule(
|
|
143
|
+
IInspectable const &inspectableProperties) noexcept {
|
|
144
|
+
auto propId = ReactPropertyId<ReactNonAbiValue<weak_ptr<IBlobPersistor>>>{L"Blob.Persistor"};
|
|
145
|
+
auto propBag = ReactPropertyBag{inspectableProperties.try_as<IReactPropertyBag>()};
|
|
146
|
+
|
|
147
|
+
if (auto prop = propBag.Get(propId)) {
|
|
148
|
+
auto weakBlobPersistor = prop.Value();
|
|
149
|
+
|
|
150
|
+
return std::make_unique<FileReaderModule>(weakBlobPersistor);
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
return nullptr;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
} // namespace Microsoft::React
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
// Copyright (c) Microsoft Corporation.
|
|
2
|
+
// Licensed under the MIT License.
|
|
3
|
+
|
|
4
|
+
#pragma once
|
|
5
|
+
|
|
6
|
+
#include "IBlobPersistor.h"
|
|
7
|
+
|
|
8
|
+
// React Native
|
|
9
|
+
#include <cxxreact/CxxModule.h>
|
|
10
|
+
|
|
11
|
+
// Folly
|
|
12
|
+
#include <folly/dynamic.h>
|
|
13
|
+
|
|
14
|
+
// Standard Library
|
|
15
|
+
#include <map>
|
|
16
|
+
#include <memory>
|
|
17
|
+
#include <string>
|
|
18
|
+
#include <vector>
|
|
19
|
+
|
|
20
|
+
namespace Microsoft::React {
|
|
21
|
+
|
|
22
|
+
class FileReaderModule : public facebook::xplat::module::CxxModule {
|
|
23
|
+
public:
|
|
24
|
+
enum class MethodId { ReadAsDataURL = 0, ReadAsText = 1, SIZE = 2 };
|
|
25
|
+
|
|
26
|
+
FileReaderModule(std::weak_ptr<IBlobPersistor> weakBlobPersistor) noexcept;
|
|
27
|
+
|
|
28
|
+
~FileReaderModule() noexcept override;
|
|
29
|
+
|
|
30
|
+
#pragma region CxxModule
|
|
31
|
+
|
|
32
|
+
/// <summary>
|
|
33
|
+
/// <see cref="facebook::xplat::module::CxxModule::getName" />
|
|
34
|
+
/// </summary>
|
|
35
|
+
std::string getName() override;
|
|
36
|
+
|
|
37
|
+
/// <summary>
|
|
38
|
+
/// <see cref="facebook::xplat::module::CxxModule::getConstants" />
|
|
39
|
+
/// </summary>
|
|
40
|
+
std::map<std::string, folly::dynamic> getConstants() override;
|
|
41
|
+
|
|
42
|
+
/// <summary>
|
|
43
|
+
/// <see cref="facebook::xplat::module::CxxModule::getMethods" />
|
|
44
|
+
/// </summary>
|
|
45
|
+
/// <remarks>See See react-native/Libraries/WebSocket/WebSocket.js</remarks>
|
|
46
|
+
std::vector<Method> getMethods() override;
|
|
47
|
+
|
|
48
|
+
#pragma endregion CxxModule
|
|
49
|
+
|
|
50
|
+
private:
|
|
51
|
+
std::weak_ptr<IBlobPersistor> m_weakBlobPersistor;
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
} // namespace Microsoft::React
|
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
// Copyright (c) Microsoft Corporation.
|
|
2
|
+
// Licensed under the MIT License.
|
|
3
|
+
|
|
4
|
+
#include "pch.h"
|
|
5
|
+
|
|
6
|
+
#include "HttpModule.h"
|
|
7
|
+
|
|
8
|
+
#include <Modules/CxxModuleUtilities.h>
|
|
9
|
+
#include <ReactPropertyBag.h>
|
|
10
|
+
|
|
11
|
+
// React Native
|
|
12
|
+
#include <cxxreact/Instance.h>
|
|
13
|
+
#include <cxxreact/JsArgumentHelpers.h>
|
|
14
|
+
|
|
15
|
+
using facebook::react::Instance;
|
|
16
|
+
using folly::dynamic;
|
|
17
|
+
using std::shared_ptr;
|
|
18
|
+
using std::string;
|
|
19
|
+
using std::weak_ptr;
|
|
20
|
+
using winrt::Microsoft::ReactNative::IReactPropertyBag;
|
|
21
|
+
using winrt::Microsoft::ReactNative::ReactNonAbiValue;
|
|
22
|
+
using winrt::Microsoft::ReactNative::ReactPropertyBag;
|
|
23
|
+
using winrt::Microsoft::ReactNative::ReactPropertyId;
|
|
24
|
+
using winrt::Windows::Foundation::IInspectable;
|
|
25
|
+
|
|
26
|
+
namespace {
|
|
27
|
+
|
|
28
|
+
using Microsoft::React::Modules::SendEvent;
|
|
29
|
+
using Microsoft::React::Networking::IHttpResource;
|
|
30
|
+
|
|
31
|
+
constexpr char moduleName[] = "Networking";
|
|
32
|
+
|
|
33
|
+
// React event names
|
|
34
|
+
constexpr char completedResponse[] = "didCompleteNetworkResponse";
|
|
35
|
+
constexpr char receivedResponse[] = "didReceiveNetworkResponse";
|
|
36
|
+
constexpr char receivedData[] = "didReceiveNetworkData";
|
|
37
|
+
constexpr char receivedDataProgress[] = "didReceiveNetworkDataProgress";
|
|
38
|
+
|
|
39
|
+
static void SetUpHttpResource(
|
|
40
|
+
shared_ptr<IHttpResource> resource,
|
|
41
|
+
weak_ptr<Instance> weakReactInstance,
|
|
42
|
+
IInspectable &inspectableProperties) {
|
|
43
|
+
resource->SetOnRequestSuccess([weakReactInstance](int64_t requestId) {
|
|
44
|
+
auto args = dynamic::array(requestId);
|
|
45
|
+
|
|
46
|
+
SendEvent(weakReactInstance, completedResponse, std::move(args));
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
resource->SetOnResponse([weakReactInstance](int64_t requestId, IHttpResource::Response &&response) {
|
|
50
|
+
dynamic headers = dynamic::object();
|
|
51
|
+
for (auto &header : response.Headers) {
|
|
52
|
+
headers[header.first] = header.second;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// TODO: Test response content.
|
|
56
|
+
dynamic args = dynamic::array(requestId, response.StatusCode, headers, response.Url);
|
|
57
|
+
|
|
58
|
+
SendEvent(weakReactInstance, receivedResponse, std::move(args));
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
resource->SetOnData([weakReactInstance](int64_t requestId, string &&responseData) {
|
|
62
|
+
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
|
+
});
|
|
67
|
+
|
|
68
|
+
// Explicitly declaring function type to avoid type inference ambiguity.
|
|
69
|
+
std::function<void(int64_t, dynamic &&)> onDataDynamic = [weakReactInstance](
|
|
70
|
+
int64_t requestId, dynamic &&responseData) {
|
|
71
|
+
SendEvent(weakReactInstance, receivedData, dynamic::array(requestId, std::move(responseData)));
|
|
72
|
+
};
|
|
73
|
+
resource->SetOnData(std::move(onDataDynamic));
|
|
74
|
+
|
|
75
|
+
resource->SetOnError([weakReactInstance](int64_t requestId, string &&message) {
|
|
76
|
+
dynamic args = dynamic::array(requestId, std::move(message));
|
|
77
|
+
// TODO: isTimeout errorArgs.push_back(true);
|
|
78
|
+
|
|
79
|
+
SendEvent(weakReactInstance, completedResponse, std::move(args));
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
} // namespace
|
|
84
|
+
|
|
85
|
+
namespace Microsoft::React {
|
|
86
|
+
|
|
87
|
+
HttpModule::HttpModule(IInspectable const &inspectableProperties) noexcept
|
|
88
|
+
: m_holder{std::make_shared<ModuleHolder>()},
|
|
89
|
+
m_inspectableProperties{inspectableProperties},
|
|
90
|
+
m_resource{IHttpResource::Make(inspectableProperties)} {
|
|
91
|
+
m_holder->Module = this;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
HttpModule::~HttpModule() noexcept /*override*/ {
|
|
95
|
+
m_holder->Module = nullptr;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
#pragma region CxxModule
|
|
99
|
+
|
|
100
|
+
string HttpModule::getName() /*override*/ {
|
|
101
|
+
return moduleName;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
std::map<string, dynamic> HttpModule::getConstants() {
|
|
105
|
+
return {};
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
// clang-format off
|
|
109
|
+
std::vector<facebook::xplat::module::CxxModule::Method> HttpModule::getMethods() {
|
|
110
|
+
|
|
111
|
+
return
|
|
112
|
+
{
|
|
113
|
+
{
|
|
114
|
+
"sendRequest",
|
|
115
|
+
[weakHolder = weak_ptr<ModuleHolder>(m_holder)](dynamic args, Callback cxxCallback)
|
|
116
|
+
{
|
|
117
|
+
auto holder = weakHolder.lock();
|
|
118
|
+
if (!holder) {
|
|
119
|
+
return;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
auto resource = holder->Module->m_resource;
|
|
123
|
+
if (!holder->Module->m_isResourceSetup)
|
|
124
|
+
{
|
|
125
|
+
SetUpHttpResource(resource, holder->Module->getInstance(), holder->Module->m_inspectableProperties);
|
|
126
|
+
holder->Module->m_isResourceSetup = true;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
auto params = facebook::xplat::jsArgAsObject(args, 0);
|
|
130
|
+
IHttpResource::Headers headers;
|
|
131
|
+
for (auto& header : params["headers"].items()) {
|
|
132
|
+
headers.emplace(header.first.getString(), header.second.getString());
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
resource->SendRequest(
|
|
136
|
+
params["method"].asString(),
|
|
137
|
+
params["url"].asString(),
|
|
138
|
+
params["requestId"].asInt(),
|
|
139
|
+
std::move(headers),
|
|
140
|
+
std::move(params["data"]),
|
|
141
|
+
params["responseType"].asString(),
|
|
142
|
+
params["incrementalUpdates"].asBool(),
|
|
143
|
+
static_cast<int64_t>(params["timeout"].asDouble()),
|
|
144
|
+
params["withCredentials"].asBool(),
|
|
145
|
+
[cxxCallback = std::move(cxxCallback)](int64_t requestId) {
|
|
146
|
+
cxxCallback({requestId});
|
|
147
|
+
}
|
|
148
|
+
);
|
|
149
|
+
}
|
|
150
|
+
},
|
|
151
|
+
{
|
|
152
|
+
"abortRequest",
|
|
153
|
+
[weakHolder = weak_ptr<ModuleHolder>(m_holder)](dynamic args)
|
|
154
|
+
{
|
|
155
|
+
auto holder = weakHolder.lock();
|
|
156
|
+
if (!holder)
|
|
157
|
+
{
|
|
158
|
+
return;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
auto resource = holder->Module->m_resource;
|
|
162
|
+
if (!holder->Module->m_isResourceSetup)
|
|
163
|
+
{
|
|
164
|
+
SetUpHttpResource(resource, holder->Module->getInstance(), holder->Module->m_inspectableProperties);
|
|
165
|
+
holder->Module->m_isResourceSetup = true;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
resource->AbortRequest(facebook::xplat::jsArgAsInt(args, 0));
|
|
169
|
+
}
|
|
170
|
+
},
|
|
171
|
+
{
|
|
172
|
+
"clearCookies",
|
|
173
|
+
[weakHolder = weak_ptr<ModuleHolder>(m_holder)](dynamic args)
|
|
174
|
+
{
|
|
175
|
+
auto holder = weakHolder.lock();
|
|
176
|
+
if (!holder)
|
|
177
|
+
{
|
|
178
|
+
return;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
auto resource = holder->Module->m_resource;
|
|
182
|
+
if (!holder->Module->m_isResourceSetup)
|
|
183
|
+
{
|
|
184
|
+
SetUpHttpResource(resource, holder->Module->getInstance(), holder->Module->m_inspectableProperties);
|
|
185
|
+
holder->Module->m_isResourceSetup = true;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
resource->ClearCookies();
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
};
|
|
192
|
+
}
|
|
193
|
+
// clang-format on
|
|
194
|
+
|
|
195
|
+
#pragma endregion CxxModule
|
|
196
|
+
|
|
197
|
+
/*extern*/ const char *GetHttpModuleName() noexcept {
|
|
198
|
+
return moduleName;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
} // namespace Microsoft::React
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
// Copyright (c) Microsoft Corporation.
|
|
2
|
+
// Licensed under the MIT License.
|
|
3
|
+
|
|
4
|
+
#pragma once
|
|
5
|
+
|
|
6
|
+
#include <Networking/IHttpResource.h>
|
|
7
|
+
|
|
8
|
+
// React Native
|
|
9
|
+
#include <cxxreact/CxxModule.h>
|
|
10
|
+
|
|
11
|
+
// Windows API
|
|
12
|
+
#include <winrt/Windows.Foundation.h>
|
|
13
|
+
|
|
14
|
+
namespace Microsoft::React {
|
|
15
|
+
|
|
16
|
+
///
|
|
17
|
+
/// Realizes <c>NativeModules</c> projection.
|
|
18
|
+
/// <remarks>See src\Libraries\Network\RCTNetworkingWinShared.js</remarks>
|
|
19
|
+
///
|
|
20
|
+
class HttpModule : public facebook::xplat::module::CxxModule {
|
|
21
|
+
public:
|
|
22
|
+
enum MethodId { SendRequest = 0, AbortRequest = 1, ClearCookies = 2, LAST = ClearCookies };
|
|
23
|
+
|
|
24
|
+
HttpModule(winrt::Windows::Foundation::IInspectable const &inspectableProperties) noexcept;
|
|
25
|
+
|
|
26
|
+
~HttpModule() noexcept override;
|
|
27
|
+
|
|
28
|
+
#pragma region CxxModule
|
|
29
|
+
|
|
30
|
+
/// <summary>
|
|
31
|
+
/// <see cref="facebook::xplat::module::CxxModule::getName" />
|
|
32
|
+
/// </summary>
|
|
33
|
+
std::string getName() override;
|
|
34
|
+
|
|
35
|
+
/// <summary>
|
|
36
|
+
/// <see cref="facebook::xplat::module::CxxModule::getConstants" />
|
|
37
|
+
/// </summary>
|
|
38
|
+
std::map<std::string, folly::dynamic> getConstants() override;
|
|
39
|
+
|
|
40
|
+
/// <summary>
|
|
41
|
+
/// <see cref="facebook::xplat::module::CxxModule::getMethods" />
|
|
42
|
+
/// </summary>
|
|
43
|
+
/// <remarks>See See react-native/Libraries/WebSocket/WebSocket.js</remarks>
|
|
44
|
+
std::vector<Method> getMethods() override;
|
|
45
|
+
|
|
46
|
+
#pragma endregion CxxModule
|
|
47
|
+
|
|
48
|
+
private:
|
|
49
|
+
struct ModuleHolder {
|
|
50
|
+
HttpModule *Module{nullptr};
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
std::shared_ptr<Networking::IHttpResource> m_resource;
|
|
54
|
+
std::shared_ptr<ModuleHolder> m_holder;
|
|
55
|
+
bool m_isResourceSetup{false};
|
|
56
|
+
|
|
57
|
+
// Property bag high level reference.
|
|
58
|
+
winrt::Windows::Foundation::IInspectable m_inspectableProperties;
|
|
59
|
+
};
|
|
60
|
+
} // namespace Microsoft::React
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
// Copyright (c) Microsoft Corporation.
|
|
2
|
+
// Licensed under the MIT License.
|
|
3
|
+
|
|
4
|
+
#pragma once
|
|
5
|
+
|
|
6
|
+
// Windows API
|
|
7
|
+
#include <winrt/base.h>
|
|
8
|
+
|
|
9
|
+
// Standard Library
|
|
10
|
+
#include <string>
|
|
11
|
+
#include <vector>
|
|
12
|
+
|
|
13
|
+
namespace Microsoft::React {
|
|
14
|
+
|
|
15
|
+
struct IBlobPersistor {
|
|
16
|
+
///
|
|
17
|
+
/// <exception cref="std::invalid_argument">
|
|
18
|
+
/// When an entry for blobId cannot be found.
|
|
19
|
+
/// </exception>
|
|
20
|
+
///
|
|
21
|
+
virtual winrt::array_view<uint8_t> ResolveMessage(std::string &&blobId, int64_t offset, int64_t size) = 0;
|
|
22
|
+
|
|
23
|
+
virtual void RemoveMessage(std::string &&blobId) noexcept = 0;
|
|
24
|
+
|
|
25
|
+
virtual void StoreMessage(std::vector<uint8_t> &&message, std::string &&blobId) noexcept = 0;
|
|
26
|
+
|
|
27
|
+
virtual std::string StoreMessage(std::vector<uint8_t> &&message) noexcept = 0;
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
} // namespace Microsoft::React
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
// Copyright (c) Microsoft Corporation.
|
|
2
|
+
// Licensed under the MIT License.
|
|
3
|
+
|
|
4
|
+
#pragma once
|
|
5
|
+
|
|
6
|
+
#include "IRequestBodyHandler.h"
|
|
7
|
+
#include "IResponseHandler.h"
|
|
8
|
+
#include "IUriHandler.h"
|
|
9
|
+
|
|
10
|
+
// Standard Library
|
|
11
|
+
#include <functional>
|
|
12
|
+
|
|
13
|
+
namespace Microsoft::React {
|
|
14
|
+
|
|
15
|
+
/// <summary>
|
|
16
|
+
/// Provides partial access to HttpModule methods directly to other native modules
|
|
17
|
+
/// without switching to the JavaScript queue thread.
|
|
18
|
+
/// </summary>
|
|
19
|
+
struct IHttpModuleProxy {
|
|
20
|
+
virtual ~IHttpModuleProxy() noexcept {}
|
|
21
|
+
|
|
22
|
+
// TODO: Implement custom URI handlers.
|
|
23
|
+
virtual void AddUriHandler(std::shared_ptr<IUriHandler> uriHandler) noexcept = 0;
|
|
24
|
+
|
|
25
|
+
virtual void AddRequestBodyHandler(std::shared_ptr<IRequestBodyHandler> requestBodyHandler) noexcept = 0;
|
|
26
|
+
|
|
27
|
+
virtual void AddResponseHandler(std::shared_ptr<IResponseHandler> responseHandler) noexcept = 0;
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
} // namespace Microsoft::React
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
// Copyright (c) Microsoft Corporation.
|
|
2
|
+
// Licensed under the MIT License.
|
|
3
|
+
|
|
4
|
+
#pragma once
|
|
5
|
+
|
|
6
|
+
// Folly
|
|
7
|
+
#include <folly/dynamic.h>
|
|
8
|
+
|
|
9
|
+
// Standard Library
|
|
10
|
+
#include <string>
|
|
11
|
+
|
|
12
|
+
namespace Microsoft::React {
|
|
13
|
+
|
|
14
|
+
/// <summary>
|
|
15
|
+
/// Allows adding custom handling to build the {@link RequestBody} from the JS body payload.
|
|
16
|
+
/// </summary>
|
|
17
|
+
struct IRequestBodyHandler {
|
|
18
|
+
/// <summary>
|
|
19
|
+
/// Returns if the handler should be used for a JS body payload.
|
|
20
|
+
/// </summary>
|
|
21
|
+
/// <param name="data">
|
|
22
|
+
/// folly object potentially containing a blob reference.
|
|
23
|
+
/// "blob" - folly object holding blob metadata. Optional.
|
|
24
|
+
/// </param>
|
|
25
|
+
/// <returns>
|
|
26
|
+
/// true - <paramref name="data" /> contains a blob reference.
|
|
27
|
+
/// false - <paramref name="data" /> does not contain a blob reference.
|
|
28
|
+
/// </returns>
|
|
29
|
+
virtual bool Supports(folly::dynamic &data) = 0;
|
|
30
|
+
|
|
31
|
+
/// <summary>
|
|
32
|
+
/// Returns the {@link RequestBody} for the JS body payload.
|
|
33
|
+
/// </summary>
|
|
34
|
+
/// <param name="data">
|
|
35
|
+
/// Incoming folly object containing the blob metadada.
|
|
36
|
+
/// Structure:
|
|
37
|
+
/// "blob" - folly object info
|
|
38
|
+
/// "blobId" - Blob unique identifier
|
|
39
|
+
/// "offset" - Start index to read the blob
|
|
40
|
+
/// "size" - Amount of bytes to read from the blob
|
|
41
|
+
/// </param>
|
|
42
|
+
/// <returns>
|
|
43
|
+
/// folly::dynamic object with the following entries:
|
|
44
|
+
/// "type" - Request content type
|
|
45
|
+
/// "size" - Amount of bytes
|
|
46
|
+
/// "bytes" - Raw body content
|
|
47
|
+
/// NOTE: This is an arbitrary key. Pending non-folly structured object to model request body.
|
|
48
|
+
/// </returns>
|
|
49
|
+
virtual folly::dynamic ToRequestBody(folly::dynamic &data, std::string &contentType) = 0;
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
} // namespace Microsoft::React
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
#pragma once
|
|
2
|
+
|
|
3
|
+
// Folly
|
|
4
|
+
#include <folly/dynamic.h>
|
|
5
|
+
|
|
6
|
+
// Standard Library
|
|
7
|
+
#include <string>
|
|
8
|
+
#include <vector>
|
|
9
|
+
|
|
10
|
+
namespace Microsoft::React {
|
|
11
|
+
|
|
12
|
+
/// <summary>
|
|
13
|
+
/// Allows adding custom handling to build the JS body payload from the {@link ResponseBody}.
|
|
14
|
+
/// </summary>
|
|
15
|
+
struct IResponseHandler {
|
|
16
|
+
/// <summary>
|
|
17
|
+
/// Returns if the handler should be used for a response type.
|
|
18
|
+
/// </summary>
|
|
19
|
+
virtual bool Supports(std::string &responseType) = 0;
|
|
20
|
+
|
|
21
|
+
/// <summary>
|
|
22
|
+
/// Returns the JS body payload for the {@link ResponseBody}.
|
|
23
|
+
/// </summary>
|
|
24
|
+
virtual folly::dynamic ToResponseData(std::vector<uint8_t> &&content) = 0;
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
} // namespace Microsoft::React
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
// Copyright (c) Microsoft Corporation.
|
|
2
|
+
// Licensed under the MIT License.
|
|
3
|
+
|
|
4
|
+
#pragma once
|
|
5
|
+
|
|
6
|
+
// Folly
|
|
7
|
+
#include <folly/dynamic.h>
|
|
8
|
+
|
|
9
|
+
// Standard Library
|
|
10
|
+
#include <string>
|
|
11
|
+
|
|
12
|
+
namespace Microsoft::React {
|
|
13
|
+
|
|
14
|
+
/// <summary>
|
|
15
|
+
/// Allows to implement a custom fetching process for specific URIs. It is the handler's job to
|
|
16
|
+
/// fetch the URI and return the JS body payload.
|
|
17
|
+
/// </summary>
|
|
18
|
+
struct IUriHandler {
|
|
19
|
+
/// <summary>
|
|
20
|
+
/// Returns whether the handler should be used for a given URI.
|
|
21
|
+
/// </summary>
|
|
22
|
+
virtual bool Supports(std::string &uri, std::string &responseType) = 0;
|
|
23
|
+
|
|
24
|
+
/// <summary>
|
|
25
|
+
/// Fetch the URI and return the JS body payload.
|
|
26
|
+
/// </summary>
|
|
27
|
+
/// <returns>
|
|
28
|
+
/// Blob representation in a dynamic object with the folliwing structure:
|
|
29
|
+
/// "blobId" - Blob unique identifier
|
|
30
|
+
/// "offset" - Blob segment starting offset
|
|
31
|
+
/// "size" - Number of bytes fetched from blob
|
|
32
|
+
/// "name" - File name obtained from the URI
|
|
33
|
+
/// "lastModified - Last write to local file in milliseconds
|
|
34
|
+
virtual folly::dynamic Fetch(std::string &uri) = 0;
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
} // namespace Microsoft::React
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
// Copyright (c) Microsoft Corporation.
|
|
2
|
+
// Licensed under the MIT License.
|
|
3
|
+
|
|
4
|
+
#pragma once
|
|
5
|
+
|
|
6
|
+
// React Native
|
|
7
|
+
#include <folly/dynamic.h>
|
|
8
|
+
|
|
9
|
+
// Standard Library
|
|
10
|
+
#include <string>
|
|
11
|
+
#include <vector>
|
|
12
|
+
|
|
13
|
+
namespace Microsoft::React {
|
|
14
|
+
|
|
15
|
+
/// <summary>
|
|
16
|
+
/// See https://github.com/facebook/react-native/blob/v0.63.2/React/CoreModules/RCTWebSocketModule.h#L12
|
|
17
|
+
/// </summary>
|
|
18
|
+
struct IWebSocketModuleContentHandler {
|
|
19
|
+
virtual ~IWebSocketModuleContentHandler() noexcept {}
|
|
20
|
+
|
|
21
|
+
virtual void ProcessMessage(std::string &&message, folly::dynamic ¶ms) = 0;
|
|
22
|
+
|
|
23
|
+
virtual void ProcessMessage(std::vector<uint8_t> &&message, folly::dynamic ¶ms) = 0;
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
} // namespace Microsoft::React
|