corecdtl 0.1.6 → 0.1.8
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/dist/hypernode.js +1 -1
- package/package.json +12 -8
- package/prebuilds/darwin-arm64/corecdtl.node +0 -0
- package/prebuilds/linux-x64/corecdtl.node +0 -0
- package/prebuilds/win32-x64/corecdtl.node +0 -0
- package/binding.gyp +0 -42
- package/native/http/core/http_core.cpp +0 -395
- package/native/http/core/http_core.h +0 -90
- package/native/http/core/http_scanner.cpp +0 -1502
- package/native/http/core/http_scanner.h +0 -474
- package/native/http/cpool/cpool.cpp +0 -284
- package/native/http/cpool/cpool.h +0 -39
- package/native/http/parser/asset_meta.cpp +0 -31
- package/native/http/parser/asset_meta.h +0 -53
- package/native/http/parser/asset_parser.cpp +0 -52
- package/native/http/parser/asset_parser.h +0 -20
- package/native/http/routes/route.h +0 -85
- package/native/http/routes/route_builder.cpp +0 -161
- package/native/http/routes/route_matching.cpp +0 -266
- package/native/http/routes/route_print.cpp +0 -20
- package/native/main.cpp +0 -54
|
@@ -1,161 +0,0 @@
|
|
|
1
|
-
//===----------------------------------------------------------------------===//
|
|
2
|
-
// RouteBuilder - Builder Implementation
|
|
3
|
-
//===----------------------------------------------------------------------===//
|
|
4
|
-
|
|
5
|
-
#include "route.h"
|
|
6
|
-
|
|
7
|
-
#include <algorithm>
|
|
8
|
-
#include <map>
|
|
9
|
-
#include <string>
|
|
10
|
-
|
|
11
|
-
using namespace RouteBuilder;
|
|
12
|
-
|
|
13
|
-
namespace {
|
|
14
|
-
|
|
15
|
-
constexpr char kParamMarker = ':'; ///< marker for parameters in the pattern
|
|
16
|
-
constexpr char kWildcardMarker = '*'; ///< marker for wildcard all path names in the pattern
|
|
17
|
-
constexpr int kMaxPacked = 8; ///< maximum bytes to pack into a u64 for comparison
|
|
18
|
-
|
|
19
|
-
// Pack up to 8 bytes from `str` into a u64. If len < 8, fill high bytes with 0xFF
|
|
20
|
-
// to maintain inequality for short vs longer sequences.
|
|
21
|
-
inline static uint64_t packU64Safe(const char* str, int len) {
|
|
22
|
-
if (len <= 0) return 0;
|
|
23
|
-
if (len > 8) len = 8;
|
|
24
|
-
uint64_t val = 0;
|
|
25
|
-
for (int i = 0; i < len; ++i) {
|
|
26
|
-
uint8_t c = static_cast<uint8_t>(str[i]);
|
|
27
|
-
val |= (uint64_t)c << (8 * i);
|
|
28
|
-
}
|
|
29
|
-
for (int i = len; i < 8; ++i) {
|
|
30
|
-
val |= (uint64_t)0xFF << (8 * i);
|
|
31
|
-
}
|
|
32
|
-
return val;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
// Helper factory functions to make nodes
|
|
36
|
-
std::shared_ptr<RouteNode> makeParamNode() {
|
|
37
|
-
auto n = std::make_shared<RouteNode>();
|
|
38
|
-
n->is_param = true;
|
|
39
|
-
n->is_wildcard = false;
|
|
40
|
-
return n;
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
std::shared_ptr<RouteNode> makeStaticNode() {
|
|
44
|
-
auto n = std::make_shared<RouteNode>();
|
|
45
|
-
n->is_param = false;
|
|
46
|
-
n->is_wildcard = false;
|
|
47
|
-
return n;
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
std::shared_ptr<RouteNode> makeWildcardNode() {
|
|
51
|
-
auto n = std::make_shared<RouteNode>();
|
|
52
|
-
n->is_wildcard = true;
|
|
53
|
-
n->is_param = false;
|
|
54
|
-
return n;
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
// offset -> index into the url char array
|
|
58
|
-
static void buildSubRouteTree(std::shared_ptr<RouteNode> node, const std::vector<Endpoint>& eps, int offset) {
|
|
59
|
-
if (!node) return;
|
|
60
|
-
if (eps.empty()) return;
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
for (auto &ep : eps) {
|
|
64
|
-
if (ep.url[offset] == '\0') {
|
|
65
|
-
// conflict resolution: if multiple endpoints end here, pick one or handle collision
|
|
66
|
-
node->vptr_table_index = ep.vptr_table_index;
|
|
67
|
-
// not removing; it's OK to leave them (they represent same path)
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
std::vector<Endpoint> param_eps;
|
|
72
|
-
std::vector<Endpoint> static_eps;
|
|
73
|
-
Endpoint wildcard_ep;
|
|
74
|
-
|
|
75
|
-
for (auto &ep : eps) {
|
|
76
|
-
char c = ep.url[offset];
|
|
77
|
-
if (c == '\0') continue;
|
|
78
|
-
|
|
79
|
-
if (c == kWildcardMarker) wildcard_ep = ep;
|
|
80
|
-
else if (c == kParamMarker && ep.url[offset + 1] == '/') param_eps.push_back(ep);
|
|
81
|
-
else static_eps.push_back(ep);
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
// 3) Handle static prefix group (build common prefix up to MAX_VALUE_EXP)
|
|
85
|
-
if (!static_eps.empty()) {
|
|
86
|
-
// Build common prefix character-by-character
|
|
87
|
-
std::string prefix;
|
|
88
|
-
for (int p = 0; p < kMaxPacked; ++p) {
|
|
89
|
-
char ch = static_eps[0].url[offset + p];
|
|
90
|
-
if (ch == '\0' || ch == kParamMarker || ch == kWildcardMarker) break;
|
|
91
|
-
|
|
92
|
-
bool all_match = true;
|
|
93
|
-
for (auto &se : static_eps) {
|
|
94
|
-
if (se.url[offset + p] != ch) { all_match = false; break; }
|
|
95
|
-
}
|
|
96
|
-
if (!all_match) break;
|
|
97
|
-
prefix.push_back(ch);
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
if (!prefix.empty()) {
|
|
101
|
-
auto static_node = makeStaticNode();
|
|
102
|
-
static_node->value_length = static_cast<size_t>(prefix.size());
|
|
103
|
-
static_node->value = packU64Safe(prefix.c_str(), static_node->value_length);
|
|
104
|
-
node->children.push_back(static_node);
|
|
105
|
-
|
|
106
|
-
// recursion on static group with advanced offset
|
|
107
|
-
int next_offset = offset + static_node->value_length;
|
|
108
|
-
// pass by reference: note static_eps is a copy local vector
|
|
109
|
-
buildSubRouteTree(static_node, static_eps, next_offset);
|
|
110
|
-
} else {
|
|
111
|
-
// No common multi-char prefix: group by first char and create one child per first character
|
|
112
|
-
// This reduces worst-case behavior: split by single char
|
|
113
|
-
// collect buckets
|
|
114
|
-
std::map<char, std::vector<Endpoint>> buckets;
|
|
115
|
-
for (auto &se : static_eps) buckets[se.url[offset]].push_back(se);
|
|
116
|
-
for (auto &kv : buckets) {
|
|
117
|
-
char first = kv.first;
|
|
118
|
-
std::string onechar(1, first);
|
|
119
|
-
auto child = makeStaticNode();
|
|
120
|
-
child->value_length = 1;
|
|
121
|
-
child->value = packU64Safe(onechar.c_str(), 1);
|
|
122
|
-
node->children.push_back(child);
|
|
123
|
-
buildSubRouteTree(child, kv.second, offset + 1);
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
// 4) Handle param group (there should be at most one param child, but if multiple different param names,
|
|
129
|
-
// we might need to disambiguate; here we take the first's metadata)
|
|
130
|
-
if (!param_eps.empty()) {
|
|
131
|
-
auto param_node = makeParamNode();
|
|
132
|
-
// Use the first endpoint's param meta
|
|
133
|
-
if (!param_eps[0].params.empty()) {
|
|
134
|
-
param_node->param_name = param_eps[0].params[0].name;
|
|
135
|
-
param_node->param_type = param_eps[0].params[0].type;
|
|
136
|
-
}
|
|
137
|
-
node->children.push_back(param_node);
|
|
138
|
-
// skip the ":/" marker -> offset + 2
|
|
139
|
-
buildSubRouteTree(param_node, param_eps, offset + 2);
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
// 5) Wildcard route (terminal matcher)
|
|
143
|
-
// Only one wildcard is allowed per route level.
|
|
144
|
-
// Wildcard consumes the rest of the URL and must NOT recurse further.
|
|
145
|
-
// It acts as a final fallback when no static or param routes match.
|
|
146
|
-
if (wildcard_ep) {
|
|
147
|
-
auto wildcard_node = makeWildcardNode();
|
|
148
|
-
wildcard_node->vptr_table_index = wildcard_ep.vptr_table_index;
|
|
149
|
-
node->children.push_back(wildcard_node);
|
|
150
|
-
}
|
|
151
|
-
}
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
// Public API
|
|
155
|
-
std::shared_ptr<RouteNode> RouteBuilder::buildRouteTree(const std::vector<Endpoint>& eps) noexcept {
|
|
156
|
-
if (eps.size() == 0) return nullptr;
|
|
157
|
-
|
|
158
|
-
auto root = std::make_shared<RouteNode>();
|
|
159
|
-
buildSubRouteTree(root, eps, 0);
|
|
160
|
-
return root;
|
|
161
|
-
}
|
|
@@ -1,266 +0,0 @@
|
|
|
1
|
-
//===----------------------------------------------------------------------===//
|
|
2
|
-
// RouteBuilder - Matcher Implementation
|
|
3
|
-
//===----------------------------------------------------------------------===//
|
|
4
|
-
|
|
5
|
-
#include "route.h"
|
|
6
|
-
|
|
7
|
-
#include <cassert>
|
|
8
|
-
#include <cstring>
|
|
9
|
-
#include <memory>
|
|
10
|
-
|
|
11
|
-
using namespace RouteBuilder;
|
|
12
|
-
|
|
13
|
-
namespace {
|
|
14
|
-
|
|
15
|
-
//===------------------------------------------------------------------===//
|
|
16
|
-
// Helper Functions
|
|
17
|
-
//===------------------------------------------------------------------===//
|
|
18
|
-
|
|
19
|
-
[[gnu::always_inline]] constexpr static uint64_t packedU64FromString(const char* __restrict src, size_t start, size_t end) {
|
|
20
|
-
size_t len = end - start;
|
|
21
|
-
if (len > 8) len = 8;
|
|
22
|
-
|
|
23
|
-
uint64_t value = 0;
|
|
24
|
-
|
|
25
|
-
switch(len) {
|
|
26
|
-
case 8: value |= (uint64_t)(uint8_t)src[start+7] << 56; [[fallthrough]];
|
|
27
|
-
case 7: value |= (uint64_t)(uint8_t)src[start+6] << 48; [[fallthrough]];
|
|
28
|
-
case 6: value |= (uint64_t)(uint8_t)src[start+5] << 40; [[fallthrough]];
|
|
29
|
-
case 5: value |= (uint64_t)(uint8_t)src[start+4] << 32; [[fallthrough]];
|
|
30
|
-
case 4: value |= (uint64_t)(uint8_t)src[start+3] << 24; [[fallthrough]];
|
|
31
|
-
case 3: value |= (uint64_t)(uint8_t)src[start+2] << 16; [[fallthrough]];
|
|
32
|
-
case 2: value |= (uint64_t)(uint8_t)src[start+1] << 8; [[fallthrough]];
|
|
33
|
-
case 1: value |= (uint64_t)(uint8_t)src[start+0]; break;
|
|
34
|
-
default: break;
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
switch(len) {
|
|
38
|
-
case 0: value |= (uint64_t)0xFF << 0; [[fallthrough]];
|
|
39
|
-
case 1: value |= (uint64_t)0xFF << 8; [[fallthrough]];
|
|
40
|
-
case 2: value |= (uint64_t)0xFF << 16; [[fallthrough]];
|
|
41
|
-
case 3: value |= (uint64_t)0xFF << 24; [[fallthrough]];
|
|
42
|
-
case 4: value |= (uint64_t)0xFF << 32; [[fallthrough]];
|
|
43
|
-
case 5: value |= (uint64_t)0xFF << 40; [[fallthrough]];
|
|
44
|
-
case 6: value |= (uint64_t)0xFF << 48; [[fallthrough]];
|
|
45
|
-
case 7: value |= (uint64_t)0xFF << 56; break;
|
|
46
|
-
default: break;
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
return value;
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
inline static bool nodeStaticMatches(const std::shared_ptr<RouteNode>& node,
|
|
53
|
-
const char* __restrict url,
|
|
54
|
-
uint32_t* offset) {
|
|
55
|
-
uint64_t value_buffer = packedU64FromString(url, *offset, *offset + node->value_length);
|
|
56
|
-
|
|
57
|
-
return (value_buffer == node->value);
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
inline static constexpr char hex_to_char(char h) noexcept {
|
|
61
|
-
return (h >= '0' && h <= '9') ? (h - '0')
|
|
62
|
-
: (h >= 'A' && h <= 'F') ? (h - 'A' + 10)
|
|
63
|
-
: (h >= 'a' && h <= 'f') ? (h - 'a' + 10)
|
|
64
|
-
: 0;
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
inline static std::string url_decode(const char* __restrict start, const char* __restrict end) {
|
|
68
|
-
std::string out;
|
|
69
|
-
out.reserve(end - start);
|
|
70
|
-
|
|
71
|
-
const char* p = start;
|
|
72
|
-
while (p < end) {
|
|
73
|
-
char c = *p;
|
|
74
|
-
if (c == '%') {
|
|
75
|
-
if (p + 2 < end) {
|
|
76
|
-
char hi = hex_to_char(*(p + 1));
|
|
77
|
-
char lo = hex_to_char(*(p + 2));
|
|
78
|
-
out.push_back((hi << 4) | lo);
|
|
79
|
-
p += 3;
|
|
80
|
-
continue;
|
|
81
|
-
}
|
|
82
|
-
} else if (c == '+') {
|
|
83
|
-
out.push_back(' ');
|
|
84
|
-
++p;
|
|
85
|
-
continue;
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
out.push_back(c);
|
|
89
|
-
++p;
|
|
90
|
-
}
|
|
91
|
-
return out;
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
inline static bool parse_query_params(
|
|
95
|
-
Napi::Env env,
|
|
96
|
-
const char* __restrict url,
|
|
97
|
-
uint32_t* __restrict offset,
|
|
98
|
-
Napi::Object* query_params,
|
|
99
|
-
uint32_t query_limit
|
|
100
|
-
) noexcept
|
|
101
|
-
{
|
|
102
|
-
const char* p = url + *offset;
|
|
103
|
-
|
|
104
|
-
if (*p == '?') p++;
|
|
105
|
-
|
|
106
|
-
uint32_t scanned = 0;
|
|
107
|
-
|
|
108
|
-
const char* key_start = p;
|
|
109
|
-
const char* val_start = nullptr;
|
|
110
|
-
|
|
111
|
-
while (*p != '\0') {
|
|
112
|
-
|
|
113
|
-
// ---- LAST POINT CONTROLLERS ----
|
|
114
|
-
if (*p == ' ' || *p == '\r' || *p == '\n' || *p == '#') {
|
|
115
|
-
break;
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
scanned++;
|
|
119
|
-
|
|
120
|
-
if (scanned > query_limit) {
|
|
121
|
-
return false; // QUERY LIMIT EXCEEDED
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
if (*p == '=') {
|
|
125
|
-
val_start = p + 1;
|
|
126
|
-
}
|
|
127
|
-
else if (*p == '&') {
|
|
128
|
-
|
|
129
|
-
const char* key_end = val_start ? (val_start - 1) : p;
|
|
130
|
-
const char* val_end = val_start ? p : p;
|
|
131
|
-
|
|
132
|
-
auto key = url_decode(key_start, key_end);
|
|
133
|
-
auto value = val_start ? url_decode(val_start, val_end) : "";
|
|
134
|
-
|
|
135
|
-
query_params->Set(key, value);
|
|
136
|
-
|
|
137
|
-
key_start = p + 1;
|
|
138
|
-
val_start = nullptr;
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
p++;
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
if (key_start && key_start < p) {
|
|
145
|
-
const char* key_end = val_start ? (val_start - 1) : p;
|
|
146
|
-
const char* val_end = val_start ? p : p;
|
|
147
|
-
|
|
148
|
-
auto key = url_decode(key_start, key_end);
|
|
149
|
-
auto value = val_start ? url_decode(val_start, val_end) : "";
|
|
150
|
-
|
|
151
|
-
query_params->Set(key, value);
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
*offset += scanned;
|
|
155
|
-
|
|
156
|
-
return true;
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
} // namespace
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
//===----------------------------------------------------------------------===//
|
|
163
|
-
// matchUrl Implementation
|
|
164
|
-
//===----------------------------------------------------------------------===//
|
|
165
|
-
int RouteBuilder::matchUrl(
|
|
166
|
-
Napi::Env env,
|
|
167
|
-
const std::shared_ptr<RouteNode>& root,
|
|
168
|
-
const char* url,
|
|
169
|
-
size_t urlLen,
|
|
170
|
-
uint32_t* offset,
|
|
171
|
-
Napi::Array* path_params,
|
|
172
|
-
Napi::Object* query_params,
|
|
173
|
-
uint32_t query_limit
|
|
174
|
-
) noexcept
|
|
175
|
-
{
|
|
176
|
-
auto node = root;
|
|
177
|
-
|
|
178
|
-
if (!node) return -1;
|
|
179
|
-
|
|
180
|
-
if (!node->is_param && node->value_length > 0) {
|
|
181
|
-
if (!nodeStaticMatches(node, url, offset)) {
|
|
182
|
-
return -1;
|
|
183
|
-
}
|
|
184
|
-
*offset += node->value_length;
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
uint32_t path_index = 0;
|
|
188
|
-
bool matched = false;
|
|
189
|
-
|
|
190
|
-
while (true) {
|
|
191
|
-
matched = false;
|
|
192
|
-
|
|
193
|
-
#pragma clang loop vectorize(disable)
|
|
194
|
-
#pragma clang loop unroll(disable)
|
|
195
|
-
for (auto& child : node->children) {
|
|
196
|
-
if (!child) continue;
|
|
197
|
-
// Line caches Opt
|
|
198
|
-
// __builtin_prefetch(child.get(), 0, 1);
|
|
199
|
-
|
|
200
|
-
if (child->is_param) [[unlikely]] {
|
|
201
|
-
const char* p = url + *offset;
|
|
202
|
-
size_t start = *offset;
|
|
203
|
-
|
|
204
|
-
while (*p && *p != '/' && *p != '?' && *p != ' ') p++;
|
|
205
|
-
__builtin_assume(p >= url && p <= url + urlLen);
|
|
206
|
-
|
|
207
|
-
size_t param_len = p - (url + start);
|
|
208
|
-
std::string param_value(url + start, param_len);
|
|
209
|
-
|
|
210
|
-
path_params->Set(path_index++, Napi::String::New(env, param_value));
|
|
211
|
-
|
|
212
|
-
*offset += param_len;
|
|
213
|
-
|
|
214
|
-
node = child;
|
|
215
|
-
matched = true;
|
|
216
|
-
|
|
217
|
-
if (__builtin_expect((child->vptr_table_index != -1) && (url[*offset] == ' ' || url[*offset] == '?'), 1)) {
|
|
218
|
-
if (url[*offset] == '?') {
|
|
219
|
-
if (!parse_query_params(env, url, offset, query_params, query_limit)) return -2;
|
|
220
|
-
*offset += 1;
|
|
221
|
-
}
|
|
222
|
-
return child->vptr_table_index;
|
|
223
|
-
}
|
|
224
|
-
*offset += 1;
|
|
225
|
-
break;
|
|
226
|
-
}
|
|
227
|
-
else [[likely]] {
|
|
228
|
-
if (child->is_wildcard) [[unlikely]] {
|
|
229
|
-
#pragma clang loop vectorize(disable)
|
|
230
|
-
#pragma clang loop unroll(disable)
|
|
231
|
-
while (url[*offset] != ' ') {
|
|
232
|
-
if (*offset > 1000) return -3;
|
|
233
|
-
if (url[*offset] == '?') {
|
|
234
|
-
if(!parse_query_params(env, url, offset, query_params, query_limit)) return -2;
|
|
235
|
-
*offset += 1;
|
|
236
|
-
break;
|
|
237
|
-
}
|
|
238
|
-
*offset += 1;
|
|
239
|
-
}
|
|
240
|
-
return child->vptr_table_index;
|
|
241
|
-
}
|
|
242
|
-
|
|
243
|
-
if (nodeStaticMatches(child, url, offset)) {
|
|
244
|
-
*offset += child->value_length;
|
|
245
|
-
|
|
246
|
-
node = child;
|
|
247
|
-
matched = true;
|
|
248
|
-
|
|
249
|
-
if (child->vptr_table_index != -1 && (url[*offset] == ' ' || url[*offset] == '?')) {
|
|
250
|
-
// Parse Query
|
|
251
|
-
if (url[*offset] == '?') {
|
|
252
|
-
if(!parse_query_params(env, url, offset, query_params, query_limit)) return -2;
|
|
253
|
-
*offset += 1;
|
|
254
|
-
}
|
|
255
|
-
return child->vptr_table_index;
|
|
256
|
-
}
|
|
257
|
-
break;
|
|
258
|
-
}
|
|
259
|
-
}
|
|
260
|
-
}
|
|
261
|
-
|
|
262
|
-
if (!matched) break;
|
|
263
|
-
}
|
|
264
|
-
|
|
265
|
-
return -1;
|
|
266
|
-
}
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
#include <iostream>
|
|
2
|
-
|
|
3
|
-
#include "route.h"
|
|
4
|
-
|
|
5
|
-
void RouteBuilder::printRouteTree(const std::shared_ptr<RouteNode>& node, int depth) noexcept {
|
|
6
|
-
if (!node) return;
|
|
7
|
-
for (int i = 0; i < depth; ++i) std::cout << " ";
|
|
8
|
-
if (node->is_param) {
|
|
9
|
-
std::cout << "PARAM(" << node->param_name << ")";
|
|
10
|
-
} else if (node->value_length > 0) {
|
|
11
|
-
std::cout << "STATIC(len=" << node->value_length << ", hex=" << std::hex << node->value << std::dec << ")";
|
|
12
|
-
} else {
|
|
13
|
-
std::cout << "ROOT";
|
|
14
|
-
}
|
|
15
|
-
if (node->vptr_table_index != -1)
|
|
16
|
-
std::cout << " -> ENDPOINT_IDX=" << node->vptr_table_index;
|
|
17
|
-
std::cout << "\n";
|
|
18
|
-
|
|
19
|
-
for (auto &c : node->children) printRouteTree(c, depth + 1);
|
|
20
|
-
}
|
package/native/main.cpp
DELETED
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
#include <napi.h>
|
|
2
|
-
|
|
3
|
-
#include "http_scanner.h"
|
|
4
|
-
#include <asset_parser.h>
|
|
5
|
-
#include <cpool.h>
|
|
6
|
-
#include <asset_parser.h>
|
|
7
|
-
|
|
8
|
-
inline const char* scan_url(
|
|
9
|
-
const char* __restrict curl,
|
|
10
|
-
uint32_t* __restrict offset
|
|
11
|
-
) {
|
|
12
|
-
uint32_t i = *offset;
|
|
13
|
-
const char* url_start = curl + i;
|
|
14
|
-
|
|
15
|
-
while (true) {
|
|
16
|
-
char c = curl[i];
|
|
17
|
-
|
|
18
|
-
if (c == ' ' || c == '?') {
|
|
19
|
-
*offset = i;
|
|
20
|
-
return url_start;
|
|
21
|
-
}
|
|
22
|
-
++i;
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
Napi::Value ScanUrl(const Napi::CallbackInfo& info) {
|
|
27
|
-
Napi::Env env = info.Env();
|
|
28
|
-
|
|
29
|
-
if (info.Length() < 2 || !info[0].IsBuffer() || !info[1].IsNumber()) [[unlikely]] {
|
|
30
|
-
Napi::TypeError::New(env, "Expected (curl: Buffer, offset: number)").ThrowAsJavaScriptException();
|
|
31
|
-
return env.Undefined();
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
auto buf = info[0].As<Napi::Buffer<char>>();
|
|
35
|
-
const char* curl = buf.Data();
|
|
36
|
-
uint32_t offset = info[1].As<Napi::Number>().Uint32Value();
|
|
37
|
-
|
|
38
|
-
const char* url = scan_url(curl, &offset);
|
|
39
|
-
|
|
40
|
-
return Napi::String::New(env, url);
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
Napi::Object Init(Napi::Env env, Napi::Object exports) {
|
|
45
|
-
exports.Set("HttpCore", HttpCore::GetClass(env));
|
|
46
|
-
exports.Set("PublicAssetParser", PublicAssetParser::GetClass(env));
|
|
47
|
-
|
|
48
|
-
exports.Set("scanUrl", Napi::Function::New(env, ScanUrl));
|
|
49
|
-
|
|
50
|
-
exports.Set("CPool", CPool::GetClass(env));
|
|
51
|
-
return exports;
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
NODE_API_MODULE(hypernode, Init)
|