-
Notifications
You must be signed in to change notification settings - Fork 544
Expand file tree
/
Copy pathHTTPRequestManagerModuleFactory.cpp
More file actions
125 lines (100 loc) · 4.77 KB
/
HTTPRequestManagerModuleFactory.cpp
File metadata and controls
125 lines (100 loc) · 4.77 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
//
// HTTPRequestManagerModuleFactory.cpp
// valdi-pc
//
// Created by Simon Corsin on 10/14/20.
//
#include "HTTPRequestManagerModuleFactory.hpp"
#include "valdi/runtime/Runtime.hpp"
#include "valdi/runtime/Utils/HTTPRequestManagerUtils.hpp"
#include "valdi_core/Cancelable.hpp"
#include "valdi_core/HTTPRequest.hpp"
#include "valdi_core/HTTPResponse.hpp"
#include "valdi_core/cpp/JavaScript/ModuleFactoryRegistry.hpp"
#include "valdi_core/cpp/Utils/ValueFunctionWithCallable.hpp"
#include "valdi_core/cpp/Utils/ValueTypedArray.hpp"
namespace Valdi {
HTTPRequestManagerModuleFactory::HTTPRequestManagerModuleFactory() = default;
HTTPRequestManagerModuleFactory::~HTTPRequestManagerModuleFactory() = default;
StringBox HTTPRequestManagerModuleFactory::getModulePath() {
return STRING_LITERAL("valdi_http/src/NativeHTTPClient");
}
static Shared<snap::valdi_core::HTTPRequestManager> getRequestManager() {
auto runtime = Runtime::currentRuntime();
if (runtime == nullptr) {
return nullptr;
}
return runtime->getRequestManager();
}
Value HTTPRequestManagerModuleFactory::loadModule() {
Value out;
auto strongSelf = strongSmallRef(this);
out.setMapValue(
"performRequest",
Value(makeShared<ValueFunctionWithCallable>([strongSelf](const ValueFunctionCallContext& callContext) -> Value {
auto requestManager = getRequestManager();
if (requestManager == nullptr) {
callContext.getExceptionTracker().onError(Error("No RequestManager set"));
return Value::undefined();
}
const auto& requestObject = callContext.getParameter(0);
auto url = requestObject.getMapValue("url").toStringBox();
// Validate URL to prevent SSRF attacks
if (!HTTPRequestManagerUtils::isUrlAllowed(url)) {
callContext.getExceptionTracker().onError(
Error("URL not allowed!"));
return Value::undefined();
}
auto method = requestObject.getMapValue("method").toStringBox();
auto headers = requestObject.getMapValue("headers");
auto body = requestObject.getMapValue("body").getTypedArrayRef();
auto priority = requestObject.getMapValue("priority").toInt();
std::optional<BytesView> convertedBody;
if (body != nullptr) {
convertedBody = {body->getBuffer()};
}
auto completion =
callContext.getParameter(1).checkedTo<Ref<ValueFunction>>(callContext.getExceptionTracker());
if (!callContext.getExceptionTracker()) {
return Value::undefined();
}
auto requestCompletion = HTTPRequestManagerUtils::makeRequestCompletion(
[completion = std::move(completion)](const Result<snap::valdi_core::HTTPResponse>& result) {
std::array<Value, 2> parameters;
if (result) {
const auto& response = result.value();
Value convertedResponse;
convertedResponse.setMapValue("headers", response.headers);
convertedResponse.setMapValue("statusCode", Value(response.statusCode));
if (response.body) {
convertedResponse.setMapValue(
"body",
Value(makeShared<ValueTypedArray>(TypedArrayType::Uint8Array, response.body.value())));
}
parameters[0] = std::move(convertedResponse);
parameters[1] = Value::undefined();
} else {
parameters[0] = Value::undefined();
parameters[1] = Value(result.error());
}
(*completion)(parameters.data(), parameters.size());
});
auto cancellable = requestManager->performRequest(
snap::valdi_core::HTTPRequest(
std::move(url), std::move(method), std::move(headers), std::move(convertedBody), priority),
requestCompletion);
Value out;
out.setMapValue("cancel",
Value(makeShared<ValueFunctionWithCallable>(
[cancellable](const ValueFunctionCallContext& /*callContext*/) -> Value {
cancellable->cancel();
return Value::undefined();
})));
return out;
})));
return out;
}
static Valdi::RegisterModuleFactory kRegisterModule([]() {
return std::make_shared<HTTPRequestManagerModuleFactory>();
});
} // namespace Valdi