|
25 | 25 |
|
26 | 26 | #include "async_wrap-inl.h" |
27 | 27 | #include "env-inl.h" |
| 28 | +#include "llhttp.h" |
28 | 29 | #include "memory_tracker-inl.h" |
| 30 | +#include "node_external_reference.h" |
29 | 31 | #include "stream_base-inl.h" |
30 | 32 | #include "v8.h" |
31 | | -#include "llhttp.h" |
32 | 33 |
|
33 | 34 | #include <cstdlib> // free() |
34 | 35 | #include <cstring> // strdup(), strchr() |
|
47 | 48 |
|
48 | 49 |
|
49 | 50 | namespace node { |
50 | | -namespace { // NOLINT(build/namespaces) |
| 51 | +namespace http_parser { // NOLINT(build/namespaces) |
51 | 52 |
|
52 | 53 | using v8::Array; |
53 | 54 | using v8::Boolean; |
@@ -65,6 +66,7 @@ using v8::Local; |
65 | 66 | using v8::MaybeLocal; |
66 | 67 | using v8::Number; |
67 | 68 | using v8::Object; |
| 69 | +using v8::ObjectTemplate; |
68 | 70 | using v8::String; |
69 | 71 | using v8::Uint32; |
70 | 72 | using v8::Undefined; |
@@ -1243,97 +1245,59 @@ const llhttp_settings_t Parser::settings = { |
1243 | 1245 | nullptr, |
1244 | 1246 | }; |
1245 | 1247 |
|
1246 | | -void InitializeHttpParser(Local<Object> target, |
1247 | | - Local<Value> unused, |
1248 | | - Local<Context> context, |
1249 | | - void* priv) { |
1250 | | - Realm* realm = Realm::GetCurrent(context); |
1251 | | - Environment* env = realm->env(); |
1252 | | - Isolate* isolate = env->isolate(); |
1253 | | - BindingData* const binding_data = realm->AddBindingData<BindingData>(target); |
1254 | | - if (binding_data == nullptr) return; |
| 1248 | +void CreatePerIsolateProperties(IsolateData* isolate_data, |
| 1249 | + Local<ObjectTemplate> target) { |
| 1250 | + Isolate* isolate = isolate_data->isolate(); |
1255 | 1251 |
|
1256 | 1252 | Local<FunctionTemplate> t = NewFunctionTemplate(isolate, Parser::New); |
1257 | 1253 | t->InstanceTemplate()->SetInternalFieldCount(Parser::kInternalFieldCount); |
1258 | 1254 |
|
1259 | | - t->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "REQUEST"), |
1260 | | - Integer::New(env->isolate(), HTTP_REQUEST)); |
1261 | | - t->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "RESPONSE"), |
1262 | | - Integer::New(env->isolate(), HTTP_RESPONSE)); |
1263 | | - t->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "kOnMessageBegin"), |
1264 | | - Integer::NewFromUnsigned(env->isolate(), kOnMessageBegin)); |
1265 | | - t->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "kOnHeaders"), |
1266 | | - Integer::NewFromUnsigned(env->isolate(), kOnHeaders)); |
1267 | | - t->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "kOnHeadersComplete"), |
1268 | | - Integer::NewFromUnsigned(env->isolate(), kOnHeadersComplete)); |
1269 | | - t->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "kOnBody"), |
1270 | | - Integer::NewFromUnsigned(env->isolate(), kOnBody)); |
1271 | | - t->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "kOnMessageComplete"), |
1272 | | - Integer::NewFromUnsigned(env->isolate(), kOnMessageComplete)); |
1273 | | - t->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "kOnExecute"), |
1274 | | - Integer::NewFromUnsigned(env->isolate(), kOnExecute)); |
1275 | | - t->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "kOnTimeout"), |
1276 | | - Integer::NewFromUnsigned(env->isolate(), kOnTimeout)); |
1277 | | - |
1278 | | - t->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "kLenientNone"), |
1279 | | - Integer::NewFromUnsigned(env->isolate(), kLenientNone)); |
1280 | | - t->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "kLenientHeaders"), |
1281 | | - Integer::NewFromUnsigned(env->isolate(), kLenientHeaders)); |
1282 | | - t->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "kLenientChunkedLength"), |
1283 | | - Integer::NewFromUnsigned(env->isolate(), kLenientChunkedLength)); |
1284 | | - t->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "kLenientKeepAlive"), |
1285 | | - Integer::NewFromUnsigned(env->isolate(), kLenientKeepAlive)); |
1286 | | - t->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "kLenientTransferEncoding"), |
1287 | | - Integer::NewFromUnsigned(env->isolate(), kLenientTransferEncoding)); |
1288 | | - t->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "kLenientVersion"), |
1289 | | - Integer::NewFromUnsigned(env->isolate(), kLenientVersion)); |
1290 | | - t->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "kLenientDataAfterClose"), |
1291 | | - Integer::NewFromUnsigned(env->isolate(), kLenientDataAfterClose)); |
1292 | | - t->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "kLenientOptionalLFAfterCR"), |
1293 | | - Integer::NewFromUnsigned(env->isolate(), kLenientOptionalLFAfterCR)); |
1294 | | - t->Set( |
1295 | | - FIXED_ONE_BYTE_STRING(env->isolate(), "kLenientOptionalCRLFAfterChunk"), |
1296 | | - Integer::NewFromUnsigned(env->isolate(), kLenientOptionalCRLFAfterChunk)); |
1297 | | - t->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "kLenientOptionalCRBeforeLF"), |
1298 | | - Integer::NewFromUnsigned(env->isolate(), kLenientOptionalCRBeforeLF)); |
1299 | | - t->Set( |
1300 | | - FIXED_ONE_BYTE_STRING(env->isolate(), "kLenientSpacesAfterChunkSize"), |
1301 | | - Integer::NewFromUnsigned(env->isolate(), kLenientSpacesAfterChunkSize)); |
1302 | | - |
1303 | | - t->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "kLenientAll"), |
1304 | | - Integer::NewFromUnsigned(env->isolate(), kLenientAll)); |
1305 | | - |
1306 | | - Local<Array> methods = Array::New(env->isolate()); |
1307 | | - Local<Array> all_methods = Array::New(env->isolate()); |
1308 | | - size_t method_index = -1; |
1309 | | - size_t all_method_index = -1; |
1310 | | -#define V(num, name, string) \ |
1311 | | - methods \ |
1312 | | - ->Set(env->context(), \ |
1313 | | - ++method_index, \ |
1314 | | - FIXED_ONE_BYTE_STRING(env->isolate(), #string)) \ |
1315 | | - .Check(); |
1316 | | - HTTP_METHOD_MAP(V) |
1317 | | -#undef V |
1318 | | -#define V(num, name, string) \ |
1319 | | - all_methods \ |
1320 | | - ->Set(env->context(), \ |
1321 | | - ++all_method_index, \ |
1322 | | - FIXED_ONE_BYTE_STRING(env->isolate(), #string)) \ |
1323 | | - .Check(); |
1324 | | - HTTP_ALL_METHOD_MAP(V) |
1325 | | -#undef V |
1326 | | - |
1327 | | - target->Set(env->context(), |
1328 | | - FIXED_ONE_BYTE_STRING(env->isolate(), "methods"), |
1329 | | - methods).Check(); |
1330 | | - target |
1331 | | - ->Set(env->context(), |
1332 | | - FIXED_ONE_BYTE_STRING(env->isolate(), "allMethods"), |
1333 | | - all_methods) |
1334 | | - .Check(); |
1335 | | - |
1336 | | - t->Inherit(AsyncWrap::GetConstructorTemplate(env)); |
| 1255 | + t->Set(FIXED_ONE_BYTE_STRING(isolate, "REQUEST"), |
| 1256 | + Integer::New(isolate, HTTP_REQUEST)); |
| 1257 | + t->Set(FIXED_ONE_BYTE_STRING(isolate, "RESPONSE"), |
| 1258 | + Integer::New(isolate, HTTP_RESPONSE)); |
| 1259 | + t->Set(FIXED_ONE_BYTE_STRING(isolate, "kOnMessageBegin"), |
| 1260 | + Integer::NewFromUnsigned(isolate, kOnMessageBegin)); |
| 1261 | + t->Set(FIXED_ONE_BYTE_STRING(isolate, "kOnHeaders"), |
| 1262 | + Integer::NewFromUnsigned(isolate, kOnHeaders)); |
| 1263 | + t->Set(FIXED_ONE_BYTE_STRING(isolate, "kOnHeadersComplete"), |
| 1264 | + Integer::NewFromUnsigned(isolate, kOnHeadersComplete)); |
| 1265 | + t->Set(FIXED_ONE_BYTE_STRING(isolate, "kOnBody"), |
| 1266 | + Integer::NewFromUnsigned(isolate, kOnBody)); |
| 1267 | + t->Set(FIXED_ONE_BYTE_STRING(isolate, "kOnMessageComplete"), |
| 1268 | + Integer::NewFromUnsigned(isolate, kOnMessageComplete)); |
| 1269 | + t->Set(FIXED_ONE_BYTE_STRING(isolate, "kOnExecute"), |
| 1270 | + Integer::NewFromUnsigned(isolate, kOnExecute)); |
| 1271 | + t->Set(FIXED_ONE_BYTE_STRING(isolate, "kOnTimeout"), |
| 1272 | + Integer::NewFromUnsigned(isolate, kOnTimeout)); |
| 1273 | + |
| 1274 | + t->Set(FIXED_ONE_BYTE_STRING(isolate, "kLenientNone"), |
| 1275 | + Integer::NewFromUnsigned(isolate, kLenientNone)); |
| 1276 | + t->Set(FIXED_ONE_BYTE_STRING(isolate, "kLenientHeaders"), |
| 1277 | + Integer::NewFromUnsigned(isolate, kLenientHeaders)); |
| 1278 | + t->Set(FIXED_ONE_BYTE_STRING(isolate, "kLenientChunkedLength"), |
| 1279 | + Integer::NewFromUnsigned(isolate, kLenientChunkedLength)); |
| 1280 | + t->Set(FIXED_ONE_BYTE_STRING(isolate, "kLenientKeepAlive"), |
| 1281 | + Integer::NewFromUnsigned(isolate, kLenientKeepAlive)); |
| 1282 | + t->Set(FIXED_ONE_BYTE_STRING(isolate, "kLenientTransferEncoding"), |
| 1283 | + Integer::NewFromUnsigned(isolate, kLenientTransferEncoding)); |
| 1284 | + t->Set(FIXED_ONE_BYTE_STRING(isolate, "kLenientVersion"), |
| 1285 | + Integer::NewFromUnsigned(isolate, kLenientVersion)); |
| 1286 | + t->Set(FIXED_ONE_BYTE_STRING(isolate, "kLenientDataAfterClose"), |
| 1287 | + Integer::NewFromUnsigned(isolate, kLenientDataAfterClose)); |
| 1288 | + t->Set(FIXED_ONE_BYTE_STRING(isolate, "kLenientOptionalLFAfterCR"), |
| 1289 | + Integer::NewFromUnsigned(isolate, kLenientOptionalLFAfterCR)); |
| 1290 | + t->Set(FIXED_ONE_BYTE_STRING(isolate, "kLenientOptionalCRLFAfterChunk"), |
| 1291 | + Integer::NewFromUnsigned(isolate, kLenientOptionalCRLFAfterChunk)); |
| 1292 | + t->Set(FIXED_ONE_BYTE_STRING(isolate, "kLenientOptionalCRBeforeLF"), |
| 1293 | + Integer::NewFromUnsigned(isolate, kLenientOptionalCRBeforeLF)); |
| 1294 | + t->Set(FIXED_ONE_BYTE_STRING(isolate, "kLenientSpacesAfterChunkSize"), |
| 1295 | + Integer::NewFromUnsigned(isolate, kLenientSpacesAfterChunkSize)); |
| 1296 | + |
| 1297 | + t->Set(FIXED_ONE_BYTE_STRING(isolate, "kLenientAll"), |
| 1298 | + Integer::NewFromUnsigned(isolate, kLenientAll)); |
| 1299 | + |
| 1300 | + t->Inherit(AsyncWrap::GetConstructorTemplate(isolate_data)); |
1337 | 1301 | SetProtoMethod(isolate, t, "close", Parser::Close); |
1338 | 1302 | SetProtoMethod(isolate, t, "free", Parser::Free); |
1339 | 1303 | SetProtoMethod(isolate, t, "remove", Parser::Remove); |
@@ -1348,7 +1312,7 @@ void InitializeHttpParser(Local<Object> target, |
1348 | 1312 | SetProtoMethod(isolate, t, "duration", Parser::Duration); |
1349 | 1313 | SetProtoMethod(isolate, t, "headersCompleted", Parser::HeadersCompleted); |
1350 | 1314 |
|
1351 | | - SetConstructorFunction(context, target, "HTTPParser", t); |
| 1315 | + SetConstructorFunction(isolate, target, "HTTPParser", t); |
1352 | 1316 |
|
1353 | 1317 | Local<FunctionTemplate> c = |
1354 | 1318 | NewFunctionTemplate(isolate, ConnectionsList::New); |
@@ -1358,10 +1322,79 @@ void InitializeHttpParser(Local<Object> target, |
1358 | 1322 | SetProtoMethod(isolate, c, "idle", ConnectionsList::Idle); |
1359 | 1323 | SetProtoMethod(isolate, c, "active", ConnectionsList::Active); |
1360 | 1324 | SetProtoMethod(isolate, c, "expired", ConnectionsList::Expired); |
1361 | | - SetConstructorFunction(context, target, "ConnectionsList", c); |
| 1325 | + SetConstructorFunction(isolate, target, "ConnectionsList", c); |
| 1326 | +} |
| 1327 | + |
| 1328 | +void CreatePerContextProperties(Local<Object> target, |
| 1329 | + Local<Value> unused, |
| 1330 | + Local<Context> context, |
| 1331 | + void* priv) { |
| 1332 | + Realm* realm = Realm::GetCurrent(context); |
| 1333 | + Environment* env = realm->env(); |
| 1334 | + Isolate* isolate = env->isolate(); |
| 1335 | + BindingData* const binding_data = realm->AddBindingData<BindingData>(target); |
| 1336 | + if (binding_data == nullptr) return; |
| 1337 | + |
| 1338 | + std::vector<Local<Value>> methods_val; |
| 1339 | + std::vector<Local<Value>> all_methods_val; |
| 1340 | + |
| 1341 | +#define V(num, name, string) \ |
| 1342 | + methods_val.push_back(FIXED_ONE_BYTE_STRING(isolate, #string)); |
| 1343 | + HTTP_METHOD_MAP(V) |
| 1344 | +#undef V |
| 1345 | +#define V(num, name, string) \ |
| 1346 | + all_methods_val.push_back(FIXED_ONE_BYTE_STRING(isolate, #string)); |
| 1347 | + HTTP_ALL_METHOD_MAP(V) |
| 1348 | +#undef V |
| 1349 | + |
| 1350 | + Local<Array> methods = |
| 1351 | + Array::New(isolate, methods_val.data(), methods_val.size()); |
| 1352 | + Local<Array> all_methods = |
| 1353 | + Array::New(isolate, all_methods_val.data(), all_methods_val.size()); |
| 1354 | + if (!target |
| 1355 | + ->Set(env->context(), |
| 1356 | + FIXED_ONE_BYTE_STRING(isolate, "methods"), |
| 1357 | + methods) |
| 1358 | + .IsJust()) { |
| 1359 | + return; |
| 1360 | + } |
| 1361 | + if (target |
| 1362 | + ->Set(env->context(), |
| 1363 | + FIXED_ONE_BYTE_STRING(isolate, "allMethods"), |
| 1364 | + all_methods) |
| 1365 | + .IsJust()) { |
| 1366 | + return; |
| 1367 | + } |
| 1368 | +} |
| 1369 | + |
| 1370 | +void RegisterExternalReferences(ExternalReferenceRegistry* registry) { |
| 1371 | + registry->Register(Parser::New); |
| 1372 | + registry->Register(Parser::Close); |
| 1373 | + registry->Register(Parser::Free); |
| 1374 | + registry->Register(Parser::Remove); |
| 1375 | + registry->Register(Parser::Execute); |
| 1376 | + registry->Register(Parser::Finish); |
| 1377 | + registry->Register(Parser::Initialize); |
| 1378 | + registry->Register(Parser::Pause<true>); |
| 1379 | + registry->Register(Parser::Pause<false>); |
| 1380 | + registry->Register(Parser::Consume); |
| 1381 | + registry->Register(Parser::Unconsume); |
| 1382 | + registry->Register(Parser::GetCurrentBuffer); |
| 1383 | + registry->Register(Parser::Duration); |
| 1384 | + registry->Register(Parser::HeadersCompleted); |
| 1385 | + registry->Register(ConnectionsList::New); |
| 1386 | + registry->Register(ConnectionsList::All); |
| 1387 | + registry->Register(ConnectionsList::Idle); |
| 1388 | + registry->Register(ConnectionsList::Active); |
| 1389 | + registry->Register(ConnectionsList::Expired); |
1362 | 1390 | } |
1363 | 1391 |
|
1364 | | -} // anonymous namespace |
| 1392 | +} // namespace http_parser |
1365 | 1393 | } // namespace node |
1366 | 1394 |
|
1367 | | -NODE_BINDING_CONTEXT_AWARE_INTERNAL(http_parser, node::InitializeHttpParser) |
| 1395 | +NODE_BINDING_CONTEXT_AWARE_INTERNAL( |
| 1396 | + http_parser, node::http_parser::CreatePerContextProperties) |
| 1397 | +NODE_BINDING_PER_ISOLATE_INIT(http_parser, |
| 1398 | + node::http_parser::CreatePerIsolateProperties) |
| 1399 | +NODE_BINDING_EXTERNAL_REFERENCE(http_parser, |
| 1400 | + node::http_parser::RegisterExternalReferences) |