From b7b1d7eb8842a18f187eedbba5b4ff2d30999df6 Mon Sep 17 00:00:00 2001
From: Anna Henningsen
Date: Wed, 26 Dec 2018 13:21:57 +0100
Subject: [PATCH 001/246] test: fix test-repl-envvars
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
In 180f86507d496b11aa35b2df4594629a92cce329, the test was changed
so that the `env` argument of `createInternalRepl()` also contained
external environment variables, because keeping them can be necessary
for spawning processes on some systems.
However, this test does not spawn new processes, and relies on the
fact that the environment variables it tests are not already set
(and fails otherwise); therefore, reverting to the original state
should fix this.
Fixes: https://github.com/nodejs/node/issues/21451
Fixes: https://github.com/nodejs/build/issues/1377
Refs: https://github.com/nodejs/node/pull/25219
PR-URL: https://github.com/nodejs/node/pull/25226
Reviewed-By: Rich Trott
Reviewed-By: Tobias Nießen
Reviewed-By: Benjamin Gruenbaum
Reviewed-By: Denys Otrishko
Reviewed-By: Colin Ihrig
Reviewed-By: Luigi Pinca
---
test/parallel/test-repl-envvars.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/test/parallel/test-repl-envvars.js b/test/parallel/test-repl-envvars.js
index 5606efc26ed031..6679cd6cd73a31 100644
--- a/test/parallel/test-repl-envvars.js
+++ b/test/parallel/test-repl-envvars.js
@@ -36,7 +36,7 @@ const tests = [
];
function run(test) {
- const env = Object.assign({}, process.env, test.env);
+ const env = test.env;
const expected = test.expected;
const opts = {
terminal: true,
From 2c50bcda8a472587c257baea7364a1462385adf5 Mon Sep 17 00:00:00 2001
From: Philipp Renoth
Date: Tue, 25 Dec 2018 13:01:20 +0100
Subject: [PATCH 002/246] doc: fix NAPI typo
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
PR-URL: https://github.com/nodejs/node/pull/25216
Reviewed-By: Richard Lau
Reviewed-By: Benjamin Gruenbaum
Reviewed-By: Vse Mozhet Byt
Reviewed-By: Tobias Nießen
Reviewed-By: Colin Ihrig
---
doc/api/n-api.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/doc/api/n-api.md b/doc/api/n-api.md
index c84b2f245adf34..1a02711f8e106e 100644
--- a/doc/api/n-api.md
+++ b/doc/api/n-api.md
@@ -60,7 +60,7 @@ if (status != napi_ok) {
return;
}
-status = napi_crate_string_utf8(env, "bar", NAPI_AUTO_LENGTH, &string);
+status = napi_create_string_utf8(env, "bar", NAPI_AUTO_LENGTH, &string);
if (status != napi_ok) {
napi_throw_error(env, ...);
return;
From 91d1aea311fd40ad791370fe381d1083e00f6b58 Mon Sep 17 00:00:00 2001
From: Rich Trott
Date: Tue, 18 Dec 2018 16:05:06 -0800
Subject: [PATCH 003/246] test: refactor test-esm-namespace.mjs
Remove unused `name` argument that is different from a subsequent `name`
argument in a different but nearby function. This was mildly confusing
to me at first, so hopefully this change clarifies things for others
reading the test.
PR-URL: https://github.com/nodejs/node/pull/25117
Reviewed-By: James M Snell
---
test/es-module/test-esm-namespace.mjs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/test/es-module/test-esm-namespace.mjs b/test/es-module/test-esm-namespace.mjs
index dcd159f6c8729a..da1286d0f40e67 100644
--- a/test/es-module/test-esm-namespace.mjs
+++ b/test/es-module/test-esm-namespace.mjs
@@ -6,7 +6,7 @@ import Module from 'module';
const keys = Object.entries(
Object.getOwnPropertyDescriptors(new Module().require('fs')))
- .filter(([name, d]) => d.enumerable)
+ .filter(([ , d]) => d.enumerable)
.map(([name]) => name)
.concat('default')
.sort();
From 9ac8d41925f72d8667afb656defad58c13cfa1ff Mon Sep 17 00:00:00 2001
From: David Halls
Date: Thu, 13 Dec 2018 23:47:32 +0000
Subject: [PATCH 004/246] net: check for close on stream, not parent
'close' event isn't emitted on a TLS connection if it's been written to
(but 'end' and 'finish' events are).
PR-URL: https://github.com/nodejs/node/pull/25026
Fixes: https://github.com/nodejs/node/issues/24984
Reviewed-By: Luigi Pinca
Reviewed-By: Anna Henningsen
---
lib/net.js | 4 +-
.../test-tls-close-event-after-write.js | 41 +++++++++++++++++++
2 files changed, 43 insertions(+), 2 deletions(-)
create mode 100644 test/parallel/test-tls-close-event-after-write.js
diff --git a/lib/net.js b/lib/net.js
index c5ff6182989efd..df68be4067c481 100644
--- a/lib/net.js
+++ b/lib/net.js
@@ -368,8 +368,8 @@ Socket.prototype._final = function(cb) {
};
-function afterShutdown(status, handle) {
- var self = handle[owner_symbol];
+function afterShutdown(status) {
+ var self = this.handle[owner_symbol];
debug('afterShutdown destroyed=%j', self.destroyed,
self._readableState);
diff --git a/test/parallel/test-tls-close-event-after-write.js b/test/parallel/test-tls-close-event-after-write.js
new file mode 100644
index 00000000000000..31ebc897b14758
--- /dev/null
+++ b/test/parallel/test-tls-close-event-after-write.js
@@ -0,0 +1,41 @@
+'use strict';
+const common = require('../common');
+
+if (!common.hasCrypto)
+ common.skip('missing crypto');
+
+// Issue #24984
+// 'close' event isn't emitted on a TLS connection if it's been written to
+// (but 'end' and 'finish' events are). Without a fix, this test won't exit.
+
+const tls = require('tls');
+const fixtures = require('../common/fixtures');
+let cconn = null;
+let sconn = null;
+
+function test() {
+ if (cconn && sconn) {
+ cconn.resume();
+ sconn.resume();
+ sconn.end(Buffer.alloc(1024 * 1024));
+ cconn.end();
+ }
+}
+
+const server = tls.createServer({
+ key: fixtures.readKey('agent1-key.pem'),
+ cert: fixtures.readKey('agent1-cert.pem')
+}, function(c) {
+ c.on('close', function() {
+ server.close();
+ });
+ sconn = c;
+ test();
+}).listen(0, common.mustCall(function() {
+ tls.connect(this.address().port, {
+ rejectUnauthorized: false
+ }, common.mustCall(function() {
+ cconn = this;
+ test();
+ }));
+}));
From c13e5be74014124caa428f05875b2df08f79bcd7 Mon Sep 17 00:00:00 2001
From: Rich Trott
Date: Sun, 23 Dec 2018 21:59:19 -0800
Subject: [PATCH 005/246] net: use decodeStrings public API for writable stream
Instead of using an undocumented underscore-prefixed property to
configure the writable stream instance to not encode strings as buffers,
use the public API which is an options property passed to the
constructor.
Refs: https://github.com/nodejs/node/issues/445
PR-URL: https://github.com/nodejs/node/pull/25201
Reviewed-By: Ben Noordhuis
Reviewed-By: Ruben Bridgewater
Reviewed-By: Anto Aravinth
Reviewed-By: Colin Ihrig
Reviewed-By: Luigi Pinca
Reviewed-By: Anna Henningsen
---
lib/net.js | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/lib/net.js b/lib/net.js
index df68be4067c481..eb5fae76fa17de 100644
--- a/lib/net.js
+++ b/lib/net.js
@@ -255,6 +255,8 @@ function Socket(options) {
options.allowHalfOpen = true;
// For backwards compat do not emit close on destroy.
options.emitClose = false;
+ // Handle strings directly.
+ options.decodeStrings = false;
stream.Duplex.call(this, options);
// Default to *not* allowing half open sockets.
@@ -308,9 +310,6 @@ function Socket(options) {
this._pendingData = null;
this._pendingEncoding = '';
- // handle strings directly
- this._writableState.decodeStrings = false;
-
// If we have a handle, then start the flow of data into the
// buffer. if not, then this will happen when we connect
if (this._handle && options.readable !== false) {
From 5b4fab1a404f8eb46e96107d7cc30fe8abea7aa3 Mon Sep 17 00:00:00 2001
From: Anna Henningsen
Date: Sat, 22 Dec 2018 21:18:13 +0100
Subject: [PATCH 006/246] dns: fix TTL value for AAAA replies to `resolveAny()`
We were previously reading from the wrong offset, namely
the one into the final results array, not the one for the
AAAA results itself, which could have lead to reading
uninitialized or out-of-bounds data.
Also, adjust the test accordingly; TTL values are not
modified by c-ares, but are only exposed for a subset
of all DNS record types.
PR-URL: https://github.com/nodejs/node/pull/25187
Reviewed-By: Luigi Pinca
Reviewed-By: James M Snell
Reviewed-By: Khaidi Chu
Reviewed-By: Ben Noordhuis
Reviewed-By: Ruben Bridgewater
---
src/cares_wrap.cc | 4 +++-
test/parallel/test-dns-resolveany.js | 13 +++++++++----
2 files changed, 12 insertions(+), 5 deletions(-)
diff --git a/src/cares_wrap.cc b/src/cares_wrap.cc
index a3bcdf89535935..9d7af47dcdbbaf 100644
--- a/src/cares_wrap.cc
+++ b/src/cares_wrap.cc
@@ -1265,6 +1265,7 @@ class QueryAnyWrap: public QueryWrap {
}
CHECK_EQ(aaaa_count, naddr6ttls);
+ CHECK_EQ(ret->Length(), a_count + aaaa_count);
for (uint32_t i = a_count; i < ret->Length(); i++) {
Local obj = Object::New(env()->isolate());
obj->Set(context,
@@ -1272,7 +1273,8 @@ class QueryAnyWrap: public QueryWrap {
ret->Get(context, i).ToLocalChecked()).FromJust();
obj->Set(context,
env()->ttl_string(),
- Integer::New(env()->isolate(), addr6ttls[i].ttl)).FromJust();
+ Integer::New(env()->isolate(), addr6ttls[i - a_count].ttl))
+ .FromJust();
obj->Set(context,
env()->type_string(),
env()->dns_aaaa_string()).FromJust();
diff --git a/test/parallel/test-dns-resolveany.js b/test/parallel/test-dns-resolveany.js
index 46694f240336cf..bb15b1a38b4ad3 100644
--- a/test/parallel/test-dns-resolveany.js
+++ b/test/parallel/test-dns-resolveany.js
@@ -53,8 +53,13 @@ server.bind(0, common.mustCall(async () => {
}));
function validateResults(res) {
- // Compare copies with ttl removed, c-ares fiddles with that value.
- assert.deepStrictEqual(
- res.map((r) => Object.assign({}, r, { ttl: null })),
- answers.map((r) => Object.assign({}, r, { ttl: null })));
+ // TTL values are only provided for A and AAAA entries.
+ assert.deepStrictEqual(res.map(maybeRedactTTL), answers.map(maybeRedactTTL));
+}
+
+function maybeRedactTTL(r) {
+ const ret = { ...r };
+ if (!['A', 'AAAA'].includes(r.type))
+ delete ret.ttl;
+ return ret;
}
From 7365b009298c7452e52cbd701ab2ae579afba27c Mon Sep 17 00:00:00 2001
From: Anna Henningsen
Date: Sat, 22 Dec 2018 03:01:28 +0100
Subject: [PATCH 007/246] src: do not leak NodeTraceStateObserver
This would otherwise be reported as a memory leak by automated tools.
PR-URL: https://github.com/nodejs/node/pull/25180
Reviewed-By: Richard Lau
Reviewed-By: Joyee Cheung
---
src/node.cc | 9 ++++++---
1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/src/node.cc b/src/node.cc
index 4e88d05510fad1..e8710bef22d3d7 100644
--- a/src/node.cc
+++ b/src/node.cc
@@ -211,7 +211,6 @@ class NodeTraceStateObserver :
// This only runs the first time tracing is enabled
controller_->RemoveTraceStateObserver(this);
- delete this;
}
void OnTraceDisabled() override {
@@ -233,8 +232,10 @@ static struct {
void Initialize(int thread_pool_size) {
tracing_agent_.reset(new tracing::Agent());
node::tracing::TraceEventHelper::SetAgent(tracing_agent_.get());
- auto controller = tracing_agent_->GetTracingController();
- controller->AddTraceStateObserver(new NodeTraceStateObserver(controller));
+ node::tracing::TracingController* controller =
+ tracing_agent_->GetTracingController();
+ trace_state_observer_.reset(new NodeTraceStateObserver(controller));
+ controller->AddTraceStateObserver(trace_state_observer_.get());
StartTracingAgent();
// Tracing must be initialized before platform threads are created.
platform_ = new NodePlatform(thread_pool_size, controller);
@@ -248,6 +249,7 @@ static struct {
// Destroy tracing after the platform (and platform threads) have been
// stopped.
tracing_agent_.reset(nullptr);
+ trace_state_observer_.reset(nullptr);
}
void DrainVMTasks(Isolate* isolate) {
@@ -300,6 +302,7 @@ static struct {
return platform_;
}
+ std::unique_ptr trace_state_observer_;
std::unique_ptr tracing_agent_;
tracing::AgentWriterHandle tracing_file_writer_;
NodePlatform* platform_;
From 73ccfc81c91779a68df6c5b74fad0de0a0e8ea2c Mon Sep 17 00:00:00 2001
From: cjihrig
Date: Mon, 24 Dec 2018 11:03:11 -0500
Subject: [PATCH 008/246] src: fix compiler warnings in node_crypto.cc
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
During the time between https://github.com/nodejs/node/pull/24234
being opened and it landing, a V8 update occurred that deprecated
several APIs. This commit fixes the following compiler warnings:
../src/node_crypto.cc:3342:11:
warning: 'Set' is deprecated: Use maybe version
../src/node_crypto.cc:3345:13:
warning: 'GetFunction' is deprecated: Use maybe version
PR-URL: https://github.com/nodejs/node/pull/25205
Reviewed-By: Tobias Nießen
Reviewed-By: Daniel Bevenius
---
src/node_crypto.cc | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/src/node_crypto.cc b/src/node_crypto.cc
index c1a87de70986b6..7967d6a40be191 100644
--- a/src/node_crypto.cc
+++ b/src/node_crypto.cc
@@ -3312,10 +3312,12 @@ Local KeyObject::Initialize(Environment* env, Local target) {
GetAsymmetricKeyType);
env->SetProtoMethod(t, "export", Export);
- target->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "KeyObject"),
- t->GetFunction(env->context()).ToLocalChecked());
+ auto function = t->GetFunction(env->context()).ToLocalChecked();
+ target->Set(env->context(),
+ FIXED_ONE_BYTE_STRING(env->isolate(), "KeyObject"),
+ function).FromJust();
- return t->GetFunction();
+ return function;
}
Local KeyObject::Create(Environment* env,
From 39b3fd1b6108186425c919f810fa7ed5a97c3b65 Mon Sep 17 00:00:00 2001
From: Rich Trott
Date: Sat, 22 Dec 2018 19:49:31 -0800
Subject: [PATCH 009/246] doc: revise "Breaking Changes to Internal Elements"
Revise the "Breaking Changes to Internal Elements" section of
COLLABORATOR_GUIDE.md. Simplify wording, shorten sentences, and remove
redundant material.
PR-URL: https://github.com/nodejs/node/pull/25190
Reviewed-By: Colin Ihrig
Reviewed-By: Luigi Pinca
Reviewed-By: James M Snell
Reviewed-By: Anto Aravinth
---
COLLABORATOR_GUIDE.md | 21 +++++++--------------
1 file changed, 7 insertions(+), 14 deletions(-)
diff --git a/COLLABORATOR_GUIDE.md b/COLLABORATOR_GUIDE.md
index 71cb741e989367..c3805d4a2c05f9 100644
--- a/COLLABORATOR_GUIDE.md
+++ b/COLLABORATOR_GUIDE.md
@@ -269,20 +269,13 @@ For more information, see [Deprecations](#deprecations).
#### Breaking Changes to Internal Elements
-Breaking changes to internal elements are permitted in semver-patch or
-semver-minor commits but Collaborators should take significant care when
-making and reviewing such changes. Before landing such commits, an effort
-must be made to determine the potential impact of the change in the ecosystem
-by analyzing current use and by validating such changes through ecosystem
-testing using the [Canary in the Goldmine](https://github.com/nodejs/citgm)
-tool. If a change cannot be made without ecosystem breakage, then TSC review is
-required before landing the change as anything less than semver-major.
-
-If a determination is made that a particular internal API (for instance, an
-underscore `_` prefixed property) is sufficiently relied upon by the ecosystem
-such that any changes may break user code, then serious consideration should be
-given to providing an alternative Public API for that functionality before any
-breaking changes are made.
+Breaking changes to internal elements may occur in semver-patch or semver-minor
+commits. Collaborators should take significant care when making and reviewing
+such changes. An effort must be made to determine the potential impact of the
+change in the ecosystem. Use
+[Canary in the Goldmine](https://github.com/nodejs/citgm) to test such changes.
+If a change will cause ecosystem breakage, then it is semver-major. Consider
+providing a Public API in such cases.
#### When Breaking Changes Actually Break Things
From e2a01ca061a5630b2014a111d20444057b67212d Mon Sep 17 00:00:00 2001
From: cjihrig
Date: Mon, 24 Dec 2018 12:10:35 -0500
Subject: [PATCH 010/246] src: use DCHECK_* macros where possible
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
PR-URL: https://github.com/nodejs/node/pull/25207
Reviewed-By: Michaël Zasso
Reviewed-By: Anna Henningsen
Reviewed-By: Ruben Bridgewater
Reviewed-By: Tobias Nießen
Reviewed-By: Luigi Pinca
---
src/aliased_buffer.h | 12 ++++--------
src/base_object-inl.h | 2 +-
src/debug_utils.h | 4 +---
src/string_decoder.cc | 10 +++-------
src/string_search.h | 4 +---
5 files changed, 10 insertions(+), 22 deletions(-)
diff --git a/src/aliased_buffer.h b/src/aliased_buffer.h
index fa610a97744840..0bae974af7a52c 100644
--- a/src/aliased_buffer.h
+++ b/src/aliased_buffer.h
@@ -198,9 +198,7 @@ class AliasedBuffer {
* Set position index to given value.
*/
inline void SetValue(const size_t index, NativeT value) {
-#if defined(DEBUG) && DEBUG
- CHECK_LT(index, count_);
-#endif
+ DCHECK_LT(index, count_);
buffer_[index] = value;
}
@@ -208,9 +206,7 @@ class AliasedBuffer {
* Get value at position index
*/
inline const NativeT GetValue(const size_t index) const {
-#if defined(DEBUG) && DEBUG
- CHECK_LT(index, count_);
-#endif
+ DCHECK_LT(index, count_);
return buffer_[index];
}
@@ -233,9 +229,9 @@ class AliasedBuffer {
// Should only be used on an owning array, not one created as a sub array of
// an owning `AliasedBuffer`.
void reserve(size_t new_capacity) {
+ DCHECK_GE(new_capacity, count_);
+ DCHECK_EQ(byte_offset_, 0);
#if defined(DEBUG) && DEBUG
- CHECK_GE(new_capacity, count_);
- CHECK_EQ(byte_offset_, 0);
CHECK(free_buffer_);
#endif
const v8::HandleScope handle_scope(isolate_);
diff --git a/src/base_object-inl.h b/src/base_object-inl.h
index cce872739381cf..84c449a30814e2 100644
--- a/src/base_object-inl.h
+++ b/src/base_object-inl.h
@@ -115,8 +115,8 @@ BaseObject::MakeLazilyInitializedJSTemplate(Environment* env) {
auto constructor = [](const v8::FunctionCallbackInfo& args) {
#ifdef DEBUG
CHECK(args.IsConstructCall());
- CHECK_GT(args.This()->InternalFieldCount(), 0);
#endif
+ DCHECK_GT(args.This()->InternalFieldCount(), 0);
args.This()->SetAlignedPointerInInternalField(0, nullptr);
};
diff --git a/src/debug_utils.h b/src/debug_utils.h
index 034d8a9ab331dc..ed5e42fcbe8e6e 100644
--- a/src/debug_utils.h
+++ b/src/debug_utils.h
@@ -68,9 +68,7 @@ template
inline void FORCE_INLINE Debug(AsyncWrap* async_wrap,
const char* format,
Args&&... args) {
-#ifdef DEBUG
- CHECK_NOT_NULL(async_wrap);
-#endif
+ DCHECK_NOT_NULL(async_wrap);
DebugCategory cat =
static_cast(async_wrap->provider_type());
if (!UNLIKELY(async_wrap->env()->debug_enabled(cat)))
diff --git a/src/string_decoder.cc b/src/string_decoder.cc
index a83d6623b4b4bb..96c6baa4d815e4 100644
--- a/src/string_decoder.cc
+++ b/src/string_decoder.cc
@@ -123,11 +123,9 @@ MaybeLocal StringDecoder::DecodeData(Isolate* isolate,
body = !prepend.IsEmpty() ? prepend : String::Empty(isolate);
prepend = Local();
} else {
-#ifdef DEBUG
// If not, that means is no character left to finish at this point.
- CHECK_EQ(MissingBytes(), 0);
- CHECK_EQ(BufferedBytes(), 0);
-#endif
+ DCHECK_EQ(MissingBytes(), 0);
+ DCHECK_EQ(BufferedBytes(), 0);
// See whether there is a character that we may have to cut off and
// finish when receiving the next chunk.
@@ -136,9 +134,7 @@ MaybeLocal StringDecoder::DecodeData(Isolate* isolate,
// This means we'll need to figure out where the character to which
// the byte belongs begins.
for (size_t i = nread - 1; ; --i) {
-#ifdef DEBUG
- CHECK_LT(i, nread);
-#endif
+ DCHECK_LT(i, nread);
state_[kBufferedBytes]++;
if ((data[i] & 0xC0) == 0x80) {
// This byte does not start a character (a "trailing" byte).
diff --git a/src/string_search.h b/src/string_search.h
index 358a4c1b024e67..7d59d89df78329 100644
--- a/src/string_search.h
+++ b/src/string_search.h
@@ -37,9 +37,7 @@ class Vector {
// Access individual vector elements - checks bounds in debug mode.
T& operator[](size_t index) const {
-#ifdef DEBUG
- CHECK(index < length_);
-#endif
+ DCHECK_LT(index, length_);
return start_[is_forward_ ? index : (length_ - index - 1)];
}
From 99a5af65df5d87b209f5722c55a3566722067e61 Mon Sep 17 00:00:00 2001
From: cjihrig
Date: Mon, 24 Dec 2018 12:24:08 -0500
Subject: [PATCH 011/246] src: introduce DCHECK macro
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
This commit adds a DCHECK macro for consistency with the
other DCHECK_* macros.
PR-URL: https://github.com/nodejs/node/pull/25207
Reviewed-By: Michaël Zasso
Reviewed-By: Anna Henningsen
Reviewed-By: Ruben Bridgewater
Reviewed-By: Tobias Nießen
Reviewed-By: Luigi Pinca
---
src/aliased_buffer.h | 4 +---
src/base_object-inl.h | 4 +---
src/inspector/node_string.h | 4 ----
src/string_decoder.cc | 4 +---
src/util.h | 2 ++
5 files changed, 5 insertions(+), 13 deletions(-)
diff --git a/src/aliased_buffer.h b/src/aliased_buffer.h
index 0bae974af7a52c..eae60f4d93a9c0 100644
--- a/src/aliased_buffer.h
+++ b/src/aliased_buffer.h
@@ -231,9 +231,7 @@ class AliasedBuffer {
void reserve(size_t new_capacity) {
DCHECK_GE(new_capacity, count_);
DCHECK_EQ(byte_offset_, 0);
-#if defined(DEBUG) && DEBUG
- CHECK(free_buffer_);
-#endif
+ DCHECK(free_buffer_);
const v8::HandleScope handle_scope(isolate_);
const size_t old_size_in_bytes = sizeof(NativeT) * count_;
diff --git a/src/base_object-inl.h b/src/base_object-inl.h
index 84c449a30814e2..f1f1498e6c6128 100644
--- a/src/base_object-inl.h
+++ b/src/base_object-inl.h
@@ -113,9 +113,7 @@ void BaseObject::ClearWeak() {
v8::Local
BaseObject::MakeLazilyInitializedJSTemplate(Environment* env) {
auto constructor = [](const v8::FunctionCallbackInfo& args) {
-#ifdef DEBUG
- CHECK(args.IsConstructCall());
-#endif
+ DCHECK(args.IsConstructCall());
DCHECK_GT(args.This()->InternalFieldCount(), 0);
args.This()->SetAlignedPointerInInternalField(0, nullptr);
};
diff --git a/src/inspector/node_string.h b/src/inspector/node_string.h
index 4588364ab12196..504798853675a5 100644
--- a/src/inspector/node_string.h
+++ b/src/inspector/node_string.h
@@ -73,8 +73,4 @@ extern size_t kNotFound;
} // namespace inspector
} // namespace node
-#ifndef DCHECK
- #define DCHECK CHECK
- #define DCHECK_LT CHECK_LT
-#endif // DCHECK
#endif // SRC_INSPECTOR_NODE_STRING_H_
diff --git a/src/string_decoder.cc b/src/string_decoder.cc
index 96c6baa4d815e4..ceee1c9d762060 100644
--- a/src/string_decoder.cc
+++ b/src/string_decoder.cc
@@ -44,9 +44,7 @@ MaybeLocal MakeString(Isolate* isolate,
isolate->ThrowException(error);
}
-#ifdef DEBUG
- CHECK(ret.IsEmpty() || ret.ToLocalChecked()->IsString());
-#endif
+ DCHECK(ret.IsEmpty() || ret.ToLocalChecked()->IsString());
return ret.FromMaybe(Local()).As();
}
diff --git a/src/util.h b/src/util.h
index 36a2ec9e3a6270..d3835c7e692b7d 100644
--- a/src/util.h
+++ b/src/util.h
@@ -130,6 +130,7 @@ void DumpBacktrace(FILE* fp);
#define CHECK_IMPLIES(a, b) CHECK(!(a) || (b))
#ifdef DEBUG
+ #define DCHECK(expr) CHECK(expr)
#define DCHECK_EQ(a, b) CHECK((a) == (b))
#define DCHECK_GE(a, b) CHECK((a) >= (b))
#define DCHECK_GT(a, b) CHECK((a) > (b))
@@ -140,6 +141,7 @@ void DumpBacktrace(FILE* fp);
#define DCHECK_NOT_NULL(val) CHECK((val) != nullptr)
#define DCHECK_IMPLIES(a, b) CHECK(!(a) || (b))
#else
+ #define DCHECK(expr)
#define DCHECK_EQ(a, b)
#define DCHECK_GE(a, b)
#define DCHECK_GT(a, b)
From 58af085d9f299d2e0da69483840902f664f1d917 Mon Sep 17 00:00:00 2001
From: Richard Lau
Date: Fri, 21 Dec 2018 13:20:21 -0500
Subject: [PATCH 012/246] test: refactor stdio handling in test-esm-cjs-main
Set encoding on the stderr/stdout streams instead of calling
data.toString(). Don't assume the complete expected messages arrive in
a single event.
PR-URL: https://github.com/nodejs/node/pull/25169
Reviewed-By: Colin Ihrig
Reviewed-By: Daniel Bevenius
---
test/es-module/test-esm-cjs-main.js | 19 +++++++++----------
1 file changed, 9 insertions(+), 10 deletions(-)
diff --git a/test/es-module/test-esm-cjs-main.js b/test/es-module/test-esm-cjs-main.js
index 8577eccb9a0f65..8308308a2dce72 100644
--- a/test/es-module/test-esm-cjs-main.js
+++ b/test/es-module/test-esm-cjs-main.js
@@ -8,21 +8,20 @@ const assert = require('assert');
const entry = fixtures.path('/es-modules/cjs.js');
const child = spawn(process.execPath, ['--experimental-modules', entry]);
-let experimentalWarning = false;
-let validatedExecution = false;
+let stderr = '';
+child.stderr.setEncoding('utf8');
child.stderr.on('data', (data) => {
- if (!experimentalWarning) {
- experimentalWarning = true;
- return;
- }
- throw new Error(data.toString());
+ stderr += data;
});
+let stdout = '';
+child.stdout.setEncoding('utf8');
child.stdout.on('data', (data) => {
- assert.strictEqual(data.toString(), 'executed\n');
- validatedExecution = true;
+ stdout += data;
});
child.on('close', common.mustCall((code, signal) => {
- assert.strictEqual(validatedExecution, true);
assert.strictEqual(code, 0);
assert.strictEqual(signal, null);
+ assert.strictEqual(stdout, 'executed\n');
+ assert.strictEqual(stderr, `(node:${child.pid}) ` +
+ 'ExperimentalWarning: The ESM module loader is experimental.\n');
}));
From 73f3a1c4e632ec4a2eb5915b924094e538316d33 Mon Sep 17 00:00:00 2001
From: Ruben Bridgewater
Date: Sun, 23 Dec 2018 17:16:14 +0100
Subject: [PATCH 013/246] util: make inspect aware of RegExp subclasses and
null prototype
This adds support for inspect to distinguish regular expression
subclasses and ones with null prototype from "normal" regular
expressions.
PR-URL: https://github.com/nodejs/node/pull/25192
Reviewed-By: Anto Aravinth
Reviewed-By: James M Snell
---
lib/internal/util/inspect.js | 7 +++--
test/parallel/test-assert-deep.js | 2 +-
test/parallel/test-util-inspect.js | 43 +++++++++++++++++++++++-------
3 files changed, 39 insertions(+), 13 deletions(-)
diff --git a/lib/internal/util/inspect.js b/lib/internal/util/inspect.js
index 256a4a8b06904b..b47ed5411f46fb 100644
--- a/lib/internal/util/inspect.js
+++ b/lib/internal/util/inspect.js
@@ -634,9 +634,12 @@ function formatRaw(ctx, value, recurseTimes) {
base = `[${name}]`;
} else if (isRegExp(value)) {
// Make RegExps say that they are RegExps
+ base = regExpToString(constructor !== null ? value : new RegExp(value));
+ const prefix = getPrefix(constructor, tag, 'RegExp');
+ if (prefix !== 'RegExp ')
+ base = `${prefix}${base}`;
if (keys.length === 0 || recurseTimes < 0)
- return ctx.stylize(regExpToString(value), 'regexp');
- base = `${regExpToString(value)}`;
+ return ctx.stylize(base, 'regexp');
} else if (isDate(value)) {
// Make dates with properties first say the date
if (keys.length === 0) {
diff --git a/test/parallel/test-assert-deep.js b/test/parallel/test-assert-deep.js
index 68b3ee5497db6a..b16b0f3ffcb911 100644
--- a/test/parallel/test-assert-deep.js
+++ b/test/parallel/test-assert-deep.js
@@ -149,7 +149,7 @@ assert.throws(
{
code: 'ERR_ASSERTION',
message: `${defaultMsgStartFull}\n\n` +
- "+ /test/\n- /test/ {\n- '0': '1'\n- }"
+ "+ /test/\n- MyRegExp /test/ {\n- '0': '1'\n- }"
}
);
diff --git a/test/parallel/test-util-inspect.js b/test/parallel/test-util-inspect.js
index 0d9cbdbe9d25fe..9ee02720897505 100644
--- a/test/parallel/test-util-inspect.js
+++ b/test/parallel/test-util-inspect.js
@@ -1580,15 +1580,7 @@ assert.strictEqual(util.inspect('"\''), '`"\'`');
// eslint-disable-next-line no-template-curly-in-string
assert.strictEqual(util.inspect('"\'${a}'), "'\"\\'${a}'");
-{
- assert.strictEqual(
- util.inspect(Object.setPrototypeOf(/a/, null)),
- '/undefined/undefined'
- );
-}
-
-// Verify that throwing in valueOf and having no prototype still produces nice
-// results.
+// Verify that throwing in valueOf and toString still produces nice results.
[
[new String(55), "[String: '55']"],
[new Boolean(true), '[Boolean: true]'],
@@ -1609,6 +1601,7 @@ assert.strictEqual(util.inspect('"\'${a}'), "'\"\\'${a}'");
[new Promise((resolve) => setTimeout(resolve, 10)), 'Promise { }'],
[new WeakSet(), 'WeakSet { }'],
[new WeakMap(), 'WeakMap { }'],
+ [/foobar/g, '/foobar/g']
].forEach(([value, expected]) => {
Object.defineProperty(value, 'valueOf', {
get() {
@@ -1628,6 +1621,7 @@ assert.strictEqual(util.inspect('"\'${a}'), "'\"\\'${a}'");
assert.notStrictEqual(util.inspect(value), expected);
});
+// Verify that having no prototype still produces nice results.
[
[[1, 3, 4], '[Array: null prototype] [ 1, 3, 4 ]'],
[new Set([1, 2]), '[Set: null prototype] { 1, 2 }'],
@@ -1652,7 +1646,8 @@ assert.strictEqual(util.inspect('"\'${a}'), "'\"\\'${a}'");
'[DataView: null prototype] {\n byteLength: undefined,\n ' +
'byteOffset: undefined,\n buffer: undefined }'],
[new SharedArrayBuffer(2), '[SharedArrayBuffer: null prototype] ' +
- '{ byteLength: undefined }']
+ '{ byteLength: undefined }'],
+ [/foobar/, '[RegExp: null prototype] /foobar/']
].forEach(([value, expected]) => {
assert.strictEqual(
util.inspect(Object.setPrototypeOf(value, null)),
@@ -1665,6 +1660,34 @@ assert.strictEqual(util.inspect('"\'${a}'), "'\"\\'${a}'");
assert.notStrictEqual(util.inspect(value), expected);
});
+// Verify that subclasses with and without prototype produce nice results.
+[
+ [RegExp, ['foobar', 'g'], '/foobar/g']
+].forEach(([base, input, rawExpected]) => {
+ class Foo extends base {}
+ const value = new Foo(...input);
+ const symbol = value[Symbol.toStringTag];
+ const expected = `Foo ${symbol ? `[${symbol}] ` : ''}${rawExpected}`;
+ const expectedWithoutProto = `[${base.name}: null prototype] ${rawExpected}`;
+ assert.strictEqual(util.inspect(value), expected);
+ value.foo = 'bar';
+ assert.notStrictEqual(util.inspect(value), expected);
+ delete value.foo;
+ assert.strictEqual(
+ util.inspect(Object.setPrototypeOf(value, null)),
+ expectedWithoutProto
+ );
+ value.foo = 'bar';
+ let res = util.inspect(value);
+ assert.notStrictEqual(res, expectedWithoutProto);
+ assert(/foo: 'bar'/.test(res), res);
+ delete value.foo;
+ value[Symbol('foo')] = 'yeah';
+ res = util.inspect(value);
+ assert.notStrictEqual(res, expectedWithoutProto);
+ assert(/\[Symbol\(foo\)]: 'yeah'/.test(res), res);
+});
+
assert.strictEqual(inspect(1n), '1n');
assert.strictEqual(inspect(Object(-1n)), '[BigInt: -1n]');
assert.strictEqual(inspect(Object(13n)), '[BigInt: 13n]');
From e182ca9bdcc47c0a8b0045bf0f574fe4613291d2 Mon Sep 17 00:00:00 2001
From: Ruben Bridgewater
Date: Sun, 23 Dec 2018 17:42:27 +0100
Subject: [PATCH 014/246] test: add more inspect subclassing tests
So far we do not test all data types for subclasses and this extends
the existing tests for WeakSet, WeakMap and BigInt64Array.
PR-URL: https://github.com/nodejs/node/pull/25192
Reviewed-By: Anto Aravinth
Reviewed-By: James M Snell
---
test/parallel/test-util-inspect.js | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/test/parallel/test-util-inspect.js b/test/parallel/test-util-inspect.js
index 9ee02720897505..66887a10f48cd3 100644
--- a/test/parallel/test-util-inspect.js
+++ b/test/parallel/test-util-inspect.js
@@ -1662,7 +1662,10 @@ assert.strictEqual(util.inspect('"\'${a}'), "'\"\\'${a}'");
// Verify that subclasses with and without prototype produce nice results.
[
- [RegExp, ['foobar', 'g'], '/foobar/g']
+ [RegExp, ['foobar', 'g'], '/foobar/g'],
+ [WeakSet, [[{}]], '{ }'],
+ [WeakMap, [[[{}, {}]]], '{ }'],
+ [BigInt64Array, [10], '[ 0n, 0n, 0n, 0n, 0n, 0n, 0n, 0n, 0n, 0n ]']
].forEach(([base, input, rawExpected]) => {
class Foo extends base {}
const value = new Foo(...input);
From 561c2689efd7996b46ac3e5fcff5a2176a81b746 Mon Sep 17 00:00:00 2001
From: Ruben Bridgewater
Date: Thu, 20 Dec 2018 17:36:57 +0100
Subject: [PATCH 015/246] console: use spread notation instead of Object.assign
PR-URL: https://github.com/nodejs/node/pull/25149
Reviewed-By: Anna Henningsen
Reviewed-By: Luigi Pinca
Reviewed-By: James M Snell
Reviewed-By: Denys Otrishko
---
lib/internal/console/constructor.js | 14 +++++++++-----
1 file changed, 9 insertions(+), 5 deletions(-)
diff --git a/lib/internal/console/constructor.js b/lib/internal/console/constructor.js
index 1090f8fde68d1f..dcfb5f4a70a826 100644
--- a/lib/internal/console/constructor.js
+++ b/lib/internal/console/constructor.js
@@ -411,11 +411,15 @@ Console.prototype.table = function(tabularData, properties) {
const final = (k, v) => this.log(cliTable(k, v));
const inspect = (v) => {
- const opt = { depth: 0, maxArrayLength: 3 };
- if (v !== null && typeof v === 'object' &&
- !isArray(v) && ObjectKeys(v).length > 2)
- opt.depth = -1;
- Object.assign(opt, this[kGetInspectOptions](this._stdout));
+ const depth = v !== null &&
+ typeof v === 'object' &&
+ !isArray(v) &&
+ ObjectKeys(v).length > 2 ? -1 : 0;
+ const opt = {
+ depth,
+ maxArrayLength: 3,
+ ...this[kGetInspectOptions](this._stdout)
+ };
return util.inspect(v, opt);
};
const getIndexArray = (length) => ArrayFrom({ length }, (_, i) => inspect(i));
From 88e73862ca432759345a93e92ee1ee633cdd6a6c Mon Sep 17 00:00:00 2001
From: Kazushi Kitaya
Date: Fri, 21 Dec 2018 18:32:02 +0900
Subject: [PATCH 016/246] util: simplify code
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Simplify code by using return value of Object.defineProperty directly.
PR-URL: https://github.com/nodejs/node/pull/25162
Reviewed-By: Vladimir de Turckheim
Reviewed-By: Masashi Hirano
Reviewed-By: James M Snell
Reviewed-By: Tobias Nießen
Reviewed-By: Ruben Bridgewater
---
lib/internal/util.js | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/lib/internal/util.js b/lib/internal/util.js
index 3aa00fed35957f..c393e44d5d6258 100644
--- a/lib/internal/util.js
+++ b/lib/internal/util.js
@@ -267,10 +267,9 @@ function promisify(original) {
if (typeof fn !== 'function') {
throw new ERR_INVALID_ARG_TYPE('util.promisify.custom', 'Function', fn);
}
- Object.defineProperty(fn, kCustomPromisifiedSymbol, {
+ return Object.defineProperty(fn, kCustomPromisifiedSymbol, {
value: fn, enumerable: false, writable: false, configurable: true
});
- return fn;
}
// Names to create an object from in case the callback receives multiple
From 3af173df003036ccc7721b14bc25a2f93be5d32a Mon Sep 17 00:00:00 2001
From: Sam Roberts
Date: Fri, 21 Dec 2018 08:25:17 -0800
Subject: [PATCH 017/246] doc: link and expand --tls-cipher-list docs
Link to the cli docs for --tls-cipher-list, and link to and mention that
NODE_OPTIONS can also be used.
PR-URL: https://github.com/nodejs/node/pull/25174
Reviewed-By: Luigi Pinca
Reviewed-By: James M Snell
Reviewed-By: Vse Mozhet Byt
---
doc/api/tls.md | 14 ++++++++++----
1 file changed, 10 insertions(+), 4 deletions(-)
diff --git a/doc/api/tls.md b/doc/api/tls.md
index d16af379e12f82..634b45e37802dc 100644
--- a/doc/api/tls.md
+++ b/doc/api/tls.md
@@ -169,12 +169,16 @@ HIGH:
!CAMELLIA
```
-This default can be replaced entirely using the `--tls-cipher-list` command
-line switch. For instance, the following makes
-`ECDHE-RSA-AES128-GCM-SHA256:!RC4` the default TLS cipher suite:
+This default can be replaced entirely using the [`--tls-cipher-list`][] command line
+switch (directly, or via the [`NODE_OPTIONS`][] environment variable). For
+instance, the following makes `ECDHE-RSA-AES128-GCM-SHA256:!RC4` the default
+TLS cipher suite:
```sh
-node --tls-cipher-list="ECDHE-RSA-AES128-GCM-SHA256:!RC4"
+node --tls-cipher-list="ECDHE-RSA-AES128-GCM-SHA256:!RC4" server.js
+
+export NODE_OPTIONS=--tls-cipher-list="ECDHE-RSA-AES128-GCM-SHA256:!RC4"
+node server.js
```
The default can also be replaced on a per client or server basis using the
@@ -1412,6 +1416,8 @@ where `secureSocket` has the same API as `pair.cleartext`.
[`'secureConnect'`]: #tls_event_secureconnect
[`'secureConnection'`]: #tls_event_secureconnection
+[`--tls-cipher-list`]: cli.html#cli_tls_cipher_list_list
+[`NODE_OPTIONS`]: cli.html#cli_node_options_options
[`SSL_CTX_set_timeout`]: https://www.openssl.org/docs/man1.1.0/ssl/SSL_CTX_set_timeout.html
[`crypto.getCurves()`]: crypto.html#crypto_crypto_getcurves
[`dns.lookup()`]: dns.html#dns_dns_lookup_hostname_options_callback
From e6da77b12c8f8cde88fc0a21b8aa3773da9dc063 Mon Sep 17 00:00:00 2001
From: Sam Roberts
Date: Fri, 21 Dec 2018 14:16:19 -0800
Subject: [PATCH 018/246] doc: describe TLS session resumption
PR-URL: https://github.com/nodejs/node/pull/25174
Reviewed-By: Luigi Pinca
Reviewed-By: James M Snell
Reviewed-By: Vse Mozhet Byt
---
doc/api/tls.md | 186 ++++++++++++++++++++++++++++++++++++++-----------
1 file changed, 147 insertions(+), 39 deletions(-)
diff --git a/doc/api/tls.md b/doc/api/tls.md
index 634b45e37802dc..ec7af9f14f8b11 100644
--- a/doc/api/tls.md
+++ b/doc/api/tls.md
@@ -140,6 +140,94 @@ To test the renegotiation limits on a server, connect to it using the OpenSSL
command-line client (`openssl s_client -connect address:port`) then input
`R` (i.e., the letter `R` followed by a carriage return) multiple times.
+### Session Resumption
+
+Establishing a TLS session can be relatively slow. The process can be sped
+up by saving and later reusing the session state. There are several mechanisms
+to do so, discussed here from oldest to newest (and preferred).
+
+***Session Identifiers*** Servers generate a unique ID for new connections and
+send it to the client. Clients and servers save the session state. When
+reconnecting, clients send the ID of their saved session state and if the server
+also has the state for that ID, it can agree to use it. Otherwise, the server
+will create a new session. See [RFC 2246][] for more information, page 23 and
+30.
+
+Resumption using session identifiers is supported by most web browsers when
+making HTTPS requests.
+
+For Node.js, clients must call [`tls.TLSSocket.getSession()`][] after the
+[`'secureConnect'`][] event to get the session data, and provide the data to the
+`session` option of [`tls.connect()`][] to reuse the session. Servers must
+implement handlers for the [`'newSession'`][] and [`'resumeSession'`][] events
+to save and restore the session data using the session ID as the lookup key to
+reuse sessions. To reuse sessions across load balancers or cluster workers,
+servers must use a shared session cache (such as Redis) in their session
+handlers.
+
+***Session Tickets*** The servers encrypt the entire session state and send it
+to the client as a "ticket". When reconnecting, the state is sent to the server
+in the initial connection. This mechanism avoids the need for server-side
+session cache. If the server doesn't use the ticket, for any reason (failure
+to decrypt it, it's too old, etc.), it will create a new session and send a new
+ticket. See [RFC 5077][] for more information.
+
+Resumption using session tickets is becoming commonly supported by many web
+browsers when making HTTPS requests.
+
+For Node.js, clients use the same APIs for resumption with session identifiers
+as for resumption with session tickets. For debugging, if
+[`tls.TLSSocket.getTLSTicket()`][] returns a value, the session data contains a
+ticket, otherwise it contains client-side session state.
+
+Single process servers need no specific implementation to use session tickets.
+To use session tickets across server restarts or load balancers, servers must
+all have the same ticket keys. There are three 16-byte keys internally, but the
+tls API exposes them as a single 48-byte buffer for convenience.
+
+Its possible to get the ticket keys by calling [`server.getTicketKeys()`][] on
+one server instance and then distribute them, but it is more reasonable to
+securely generate 48 bytes of secure random data and set them with the
+`ticketKeys` option of [`tls.createServer()`][]. The keys should be regularly
+regenerated and server's keys can be reset with
+[`server.setTicketKeys()`][].
+
+Session ticket keys are cryptographic keys, and they ***must be stored
+securely***. With TLS 1.2 and below, if they are compromised all sessions that
+used tickets encrypted with them can be decrypted. They should not be stored
+on disk, and they should be regenerated regularly.
+
+If clients advertise support for tickets, the server will send them. The
+server can disable tickets by supplying
+`require('constants').SSL_OP_NO_TICKET` in `secureOptions`.
+
+Both session identifiers and session tickets timeout, causing the server to
+create new sessions. The timeout can be configured with the `sessionTimeout`
+option of [`tls.createServer()`][].
+
+For all the mechanisms, when resumption fails, servers will create new sessions.
+Since failing to resume the session does not cause TLS/HTTPS connection
+failures, it is easy to not notice unnecessarily poor TLS performance. The
+OpenSSL CLI can be used to verify that servers are resuming sessions. Use the
+`-reconnect` option to `openssl s_client`, for example:
+
+```sh
+$ openssl s_client -connect localhost:443 -reconnect
+```
+
+Read through the debug output. The first connection should say "New", for
+example:
+
+```text
+New, TLSv1.2, Cipher is ECDHE-RSA-AES128-GCM-SHA256
+```
+
+Subsequent connections should say "Reused", for example:
+
+```text
+Reused, TLSv1.2, Cipher is ECDHE-RSA-AES128-GCM-SHA256
+```
+
## Modifying the Default TLS Cipher suite
Node.js is built with a default suite of enabled and disabled TLS ciphers.
@@ -169,10 +257,10 @@ HIGH:
!CAMELLIA
```
-This default can be replaced entirely using the [`--tls-cipher-list`][] command line
-switch (directly, or via the [`NODE_OPTIONS`][] environment variable). For
-instance, the following makes `ECDHE-RSA-AES128-GCM-SHA256:!RC4` the default
-TLS cipher suite:
+This default can be replaced entirely using the [`--tls-cipher-list`][] command
+line switch (directly, or via the [`NODE_OPTIONS`][] environment variable). For
+instance, the following makes `ECDHE-RSA-AES128-GCM-SHA256:!RC4` the default TLS
+cipher suite:
```sh
node --tls-cipher-list="ECDHE-RSA-AES128-GCM-SHA256:!RC4" server.js
@@ -221,11 +309,13 @@ added: v0.9.2
-->
The `'newSession'` event is emitted upon creation of a new TLS session. This may
-be used to store sessions in external storage. The listener callback is passed
-three arguments when called:
+be used to store sessions in external storage. The data should be provided to
+the [`'resumeSession'`][] callback.
+
+The listener callback is passed three arguments when called:
-* `sessionId` - The TLS session identifier
-* `sessionData` - The TLS session data
+* `sessionId` {Buffer} The TLS session identifier
+* `sessionData` {Buffer} The TLS session data
* `callback` {Function} A callback function taking no arguments that must be
invoked in order for data to be sent or received over the secure connection.
@@ -288,15 +378,19 @@ The `'resumeSession'` event is emitted when the client requests to resume a
previous TLS session. The listener callback is passed two arguments when
called:
-* `sessionId` - The TLS/SSL session identifier
+* `sessionId` {Buffer} The TLS session identifier
* `callback` {Function} A callback function to be called when the prior session
- has been recovered.
-
-When called, the event listener may perform a lookup in external storage using
-the given `sessionId` and invoke `callback(null, sessionData)` once finished. If
-the session cannot be resumed (i.e., doesn't exist in storage) the callback may
-be invoked as `callback(null, null)`. Calling `callback(err)` will terminate the
-incoming connection and destroy the socket.
+ has been recovered: `callback([err[, sessionData]])`
+ * `err` {Error}
+ * `sessionData` {Buffer}
+
+The event listener should perform a lookup in external storage for the
+`sessionData` saved by the [`'newSession'`][] event handler using the given
+`sessionId`. If found, call `callback(null, sessionData)` to resume the session.
+If not found, the session cannot be resumed. `callback()` must be called
+without `sessionData` so that the handshake can continue and a new session can
+be created. It is possible to call `callback(err)` to terminate the incoming
+connection and destroy the socket.
Listening for this event will have an effect only on connections established
after the addition of the event listener.
@@ -406,10 +500,11 @@ Returns the current number of concurrent connections on the server.
added: v3.0.0
-->
-* Returns: {Buffer}
+* Returns: {Buffer} A 48-byte buffer containing the session ticket keys.
-Returns a `Buffer` instance holding the keys currently used for
-encryption/decryption of the [TLS Session Tickets][].
+Returns the session ticket keys.
+
+See [Session Resumption][] for more information.
### server.listen()
@@ -433,17 +528,15 @@ existing server. Existing connections to the server are not interrupted.
added: v3.0.0
-->
-* `keys` {Buffer} The keys used for encryption/decryption of the
- [TLS Session Tickets][].
-
-Updates the keys for encryption/decryption of the [TLS Session Tickets][].
+* `keys` {Buffer} A 48-byte buffer containing the session ticket keys.
-The key's `Buffer` should be 48 bytes long. See `ticketKeys` option in
-[`tls.createServer()`] for more information on how it is used.
+Sets the session ticket keys.
Changes to the ticket keys are effective only for future server connections.
Existing or currently pending server connections will use the previous keys.
+See [Session Resumption][] for more information.
+
## Class: tls.TLSSocket
-Returns the ASN.1 encoded TLS session or `undefined` if no session was
-negotiated. Can be used to speed up handshake establishment when reconnecting
-to the server.
+* {Buffer}
+
+Returns the TLS session data or `undefined` if no session was
+negotiated. On the client, the data can be provided to the `session` option of
+[`tls.connect()`][] to resume the connection. On the server, it may be useful
+for debugging.
+
+See [Session Resumption][] for more information.
### tlsSocket.getTLSTicket()
-Returns the TLS session ticket or `undefined` if no session was negotiated.
+* {Buffer}
+
+For a client, returns the TLS session ticket if one is available, or
+`undefined`. For a server, always returns `undefined`.
+
+It may be useful for debugging.
-This only works with client TLS sockets. Useful only for debugging, for session
-reuse provide `session` option to [`tls.connect()`][].
+See [Session Resumption][] for more information.
### tlsSocket.localAddress
ironfreddiskwentsoilputs/js/holyT22:ISBNT20:adamseesjson', 'contT21: RSSloopasiamoon
soulLINEfortcartT14:80px!--<9px;T04:mike:46ZniceinchYorkricezh:'));puremageparatonebond:37Z_of_']);000,zh:tankyardbowlbush:56ZJava30px
+|}
+%C3%:34ZjeffEXPIcashvisagolfsnowzh:quer.csssickmeatmin.binddellhirepicsrent:36ZHTTP-201fotowolfEND xbox:54ZBODYdick;
+}
+exit:35Zvarsbeat'});diet999;anne}}[i].Langkm²wiretoysaddssealalex;
+ }echonine.org005)tonyjewssandlegsroof000) 200winegeardogsbootgarycutstyletemption.xmlcockgang$('.50pxPh.Dmiscalanloandeskmileryanunixdisc);}
+dustclip).
+
+70px-200DVDs7]>sonyguysfuckpipe|-
+!002)ndow[1];[];
+Log salt
+ bangtrimbath){
+00px
+});ko:feesad>
s:// [];tollplug(){
+{
+ .js'200pdualboat.JPG);
+}quot);
+
+');
+
+}
201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037201320122011201020092008200720062005200420032002200120001999199819971996199519941993199219911990198919881987198619851984198319821981198019791978197719761975197419731972197119701969196819671966196519641963196219611960195919581957195619551954195319521951195010001024139400009999comomásesteestaperotodohacecadaañobiendíaasívidacasootroforosolootracualdijosidograntipotemadebealgoquéestonadatrespococasabajotodasinoaguapuesunosantediceluisellamayozonaamorpisoobraclicellodioshoracasiзанаомрарутанепоотизнодотожеонихНаеебымыВысовывоНообПолиниРФНеМытыОнимдаЗаДаНуОбтеИзейнуммТыужفيأنمامعكلأورديافىهولملكاولهبسالإنهيأيقدهلثمبهلوليبلايبكشيامأمنتبيلنحبهممشوشfirstvideolightworldmediawhitecloseblackrightsmallbooksplacemusicfieldorderpointvalueleveltableboardhousegroupworksyearsstatetodaywaterstartstyledeathpowerphonenighterrorinputabouttermstitletoolseventlocaltimeslargewordsgamesshortspacefocusclearmodelblockguideradiosharewomenagainmoneyimagenamesyounglineslatercolorgreenfront&watchforcepricerulesbeginaftervisitissueareasbelowindextotalhourslabelprintpressbuiltlinksspeedstudytradefoundsenseundershownformsrangeaddedstillmovedtakenaboveflashfixedoftenotherviewschecklegalriveritemsquickshapehumanexistgoingmoviethirdbasicpeacestagewidthloginideaswrotepagesusersdrivestorebreaksouthvoicesitesmonthwherebuildwhichearthforumthreesportpartyClicklowerlivesclasslayerentrystoryusagesoundcourtyour birthpopuptypesapplyImagebeinguppernoteseveryshowsmeansextramatchtrackknownearlybegansuperpapernorthlearngivennamedendedTermspartsGroupbrandusingwomanfalsereadyaudiotakeswhile.com/livedcasesdailychildgreatjudgethoseunitsneverbroadcoastcoverapplefilescyclesceneplansclickwritequeenpieceemailframeolderphotolimitcachecivilscaleenterthemetheretouchboundroyalaskedwholesincestock namefaithheartemptyofferscopeownedmightalbumthinkbloodarraymajortrustcanonunioncountvalidstoneStyleLoginhappyoccurleft:freshquitefilmsgradeneedsurbanfightbasishoverauto;route.htmlmixedfinalYour slidetopicbrownalonedrawnsplitreachRightdatesmarchquotegoodsLinksdoubtasyncthumballowchiefyouthnovel10px;serveuntilhandsCheckSpacequeryjamesequaltwice0,000Startpanelsongsroundeightshiftworthpostsleadsweeksavoidthesemilesplanesmartalphaplantmarksratesplaysclaimsalestextsstarswrongthing.org/multiheardPowerstandtokensolid(thisbringshipsstafftriedcallsfullyfactsagentThis //-->adminegyptEvent15px;Emailtrue"crossspentblogsbox">notedleavechinasizesguestrobotheavytrue,sevengrandcrimesignsawaredancephase>
+
+
+name=diegopage swiss-->
+
+#fff;">Log.com"treatsheet) && 14px;sleepntentfiledja:id="cName"worseshots-box-delta
+<bears:48Z spendbakershops= "";php">ction13px;brianhellosize=o=%2F joinmaybe , fjsimg" ")[0]MTopBType"newlyDanskczechtrailknowsfaq">zh-cn10);
+-1");type=bluestrulydavis.js';>
+
+form jesus100% menu.
+
+walesrisksumentddingb-likteachgif" vegasdanskeestishqipsuomisobredesdeentretodospuedeañosestátienehastaotrospartedondenuevohacerformamismomejormundoaquídíassóloayudafechatodastantomenosdatosotrassitiomuchoahoralugarmayorestoshorastenerantesfotosestaspaísnuevasaludforosmedioquienmesespoderchileserávecesdecirjoséestarventagrupohechoellostengoamigocosasnivelgentemismaairesjuliotemashaciafavorjuniolibrepuntobuenoautorabrilbuenatextomarzosaberlistaluegocómoenerojuegoperúhaberestoynuncamujervalorfueralibrogustaigualvotoscasosguíapuedosomosavisousteddebennochebuscafaltaeurosseriedichocursoclavecasasleónplazolargoobrasvistaapoyojuntotratavistocrearcampohemoscincocargopisosordenhacenáreadiscopedrocercapuedapapelmenorútilclarojorgecalleponertardenadiemarcasigueellassiglocochemotosmadreclaserestoniñoquedapasarbancohijosviajepabloéstevienereinodejarfondocanalnorteletracausatomarmanoslunesautosvillavendopesartipostengamarcollevapadreunidovamoszonasambosbandamariaabusomuchasubirriojavivirgradochicaallíjovendichaestantalessalirsuelopesosfinesllamabuscoéstalleganegroplazahumorpagarjuntadobleislasbolsabañohablaluchaÁreadicenjugarnotasvalleallácargadolorabajoestégustomentemariofirmacostofichaplatahogarartesleyesaquelmuseobasespocosmitadcielochicomiedoganarsantoetapadebesplayaredessietecortecoreadudasdeseoviejodeseaaguas"domaincommonstatuseventsmastersystemactionbannerremovescrollupdateglobalmediumfilternumberchangeresultpublicscreenchoosenormaltravelissuessourcetargetspringmodulemobileswitchphotosborderregionitselfsocialactivecolumnrecordfollowtitle>eitherlengthfamilyfriendlayoutauthorcreatereviewsummerserverplayedplayerexpandpolicyformatdoublepointsseriespersonlivingdesignmonthsforcesuniqueweightpeopleenergynaturesearchfigurehavingcustomoffsetletterwindowsubmitrendergroupsuploadhealthmethodvideosschoolfutureshadowdebatevaluesObjectothersrightsleaguechromesimplenoticesharedendingseasonreportonlinesquarebuttonimagesenablemovinglatestwinterFranceperiodstrongrepeatLondondetailformeddemandsecurepassedtoggleplacesdevicestaticcitiesstreamyellowattackstreetflighthiddeninfo">openedusefulvalleycausesleadersecretseconddamagesportsexceptratingsignedthingseffectfieldsstatesofficevisualeditorvolumeReportmuseummoviesparentaccessmostlymother" id="marketgroundchancesurveybeforesymbolmomentspeechmotioninsidematterCenterobjectexistsmiddleEuropegrowthlegacymannerenoughcareeransweroriginportalclientselectrandomclosedtopicscomingfatheroptionsimplyraisedescapechosenchurchdefinereasoncorneroutputmemoryiframepolicemodelsNumberduringoffersstyleskilledlistedcalledsilvermargindeletebetterbrowselimitsGlobalsinglewidgetcenterbudgetnowrapcreditclaimsenginesafetychoicespirit-stylespreadmakingneededrussiapleaseextentScriptbrokenallowschargedividefactormember-basedtheoryconfigaroundworkedhelpedChurchimpactshouldalwayslogo" bottomlist">){var prefixorangeHeader.push(couplegardenbridgelaunchReviewtakingvisionlittledatingButtonbeautythemesforgotSearchanchoralmostloadedChangereturnstringreloadMobileincomesupplySourceordersviewed courseAbout islandPhilipawardshandleimportOfficeregardskillsnationSportsdegreeweekly (e.g.behinddoctorloggedunitedbeyond-scaleacceptservedmarineFootercamera
+_form"leavesstress" />
+.gif" onloadloaderOxfordsistersurvivlistenfemaleDesignsize="appealtext">levelsthankshigherforcedanimalanyoneAfricaagreedrecentPeople wonderpricesturned|| {};main">inlinesundaywrap">failedcensusminutebeaconquotes150px|estateremoteemail"linkedright;signalformal1.htmlsignupprincefloat:.png" forum.AccesspaperssoundsextendHeightsliderUTF-8"& Before. WithstudioownersmanageprofitjQueryannualparamsboughtfamousgooglelongeri++) {israelsayingdecidehome">headerensurebranchpiecesblock;statedtop">boston.test(avatartested_countforumsschemaindex,filledsharesreaderalert(appearSubmitline">body">
+* TheThoughseeingjerseyNews
+System DavidcancertablesprovedApril reallydriveritem">more">boardscolorscampusfirst || [];media.guitarfinishwidth:showedOther .php" assumelayerswilsonstoresreliefswedenCustomeasily your String
+
+Whiltaylorclear:resortfrenchthough") + "buyingbrandsMembername">oppingsector5px;">vspacepostermajor coffeemartinmaturehappenkansaslink">Images=falsewhile hspace0&
+
+In powerPolski-colorjordanBottomStart -count2.htmlnews">01.jpgOnline-rightmillerseniorISBN 00,000 guidesvalue)ectionrepair.xml" rights.html-blockregExp:hoverwithinvirginphones
using
+ var >');
+
+
+bahasabrasilgalegomagyarpolskisrpskiردو中文简体繁體信息中国我们一个公司管理论坛可以服务时间个人产品自己企业查看工作联系没有网站所有评论中心文章用户首页作者技术问题相关下载搜索使用软件在线主题资料视频回复注册网络收藏内容推荐市场消息空间发布什么好友生活图片发展如果手机新闻最新方式北京提供关于更多这个系统知道游戏广告其他发表安全第一会员进行点击版权电子世界设计免费教育加入活动他们商品博客现在上海如何已经留言详细社区登录本站需要价格支持国际链接国家建设朋友阅读法律位置经济选择这样当前分类排行因为交易最后音乐不能通过行业科技可能设备合作大家社会研究专业全部项目这里还是开始情况电脑文件品牌帮助文化资源大学学习地址浏览投资工程要求怎么时候功能主要目前资讯城市方法电影招聘声明任何健康数据美国汽车介绍但是交流生产所以电话显示一些单位人员分析地图旅游工具学生系列网友帖子密码频道控制地区基本全国网上重要第二喜欢进入友情这些考试发现培训以上政府成为环境香港同时娱乐发送一定开发作品标准欢迎解决地方一下以及责任或者客户代表积分女人数码销售出现离线应用列表不同编辑统计查询不要有关机构很多播放组织政策直接能力来源時間看到热门关键专区非常英语百度希望美女比较知识规定建议部门意见精彩日本提高发言方面基金处理权限影片银行还有分享物品经营添加专家这种话题起来业务公告记录简介质量男人影响引用报告部分快速咨询时尚注意申请学校应该历史只是返回购买名称为了成功说明供应孩子专题程序一般會員只有其它保护而且今天窗口动态状态特别认为必须更新小说我們作为媒体包括那么一样国内是否根据电视学院具有过程由于人才出来不过正在明星故事关系标题商务输入一直基础教学了解建筑结果全球通知计划对于艺术相册发生真的建立等级类型经验实现制作来自标签以下原创无法其中個人一切指南关闭集团第三关注因此照片深圳商业广州日期高级最近综合表示专辑行为交通评价觉得精华家庭完成感觉安装得到邮件制度食品虽然转载报价记者方案行政人民用品东西提出酒店然后付款热点以前完全发帖设置领导工业医院看看经典原因平台各种增加材料新增之后职业效果今年论文我国告诉版主修改参与打印快乐机械观点存在精神获得利用继续你们这么模式语言能够雅虎操作风格一起科学体育短信条件治疗运动产业会议导航先生联盟可是問題结构作用调查資料自动负责农业访问实施接受讨论那个反馈加强女性范围服務休闲今日客服觀看参加的话一点保证图书有效测试移动才能决定股票不断需求不得办法之间采用营销投诉目标爱情摄影有些複製文学机会数字装修购物农村全面精品其实事情水平提示上市谢谢普通教师上传类别歌曲拥有创新配件只要时代資訊达到人生订阅老师展示心理贴子網站主題自然级别简单改革那些来说打开代码删除证券节目重点次數多少规划资金找到以后大全主页最佳回答天下保障现代检查投票小时沒有正常甚至代理目录公开复制金融幸福版本形成准备行情回到思想怎样协议认证最好产生按照服装广东动漫采购新手组图面板参考政治容易天地努力人们升级速度人物调整流行造成文字韩国贸易开展相關表现影视如此美容大小报道条款心情许多法规家居书店连接立即举报技巧奥运登入以来理论事件自由中华办公妈妈真正不错全文合同价值别人监督具体世纪团队创业承担增长有人保持商家维修台湾左右股份答案实际电信经理生命宣传任务正式特色下来协会只能当然重新內容指导运行日志賣家超过土地浙江支付推出站长杭州执行制造之一推广现场描述变化传统歌手保险课程医疗经过过去之前收入年度杂志美丽最高登陆未来加工免责教程版块身体重庆出售成本形式土豆出價东方邮箱南京求职取得职位相信页面分钟网页确定图例网址积极错误目的宝贝机关风险授权病毒宠物除了評論疾病及时求购站点儿童每天中央认识每个天津字体台灣维护本页个性官方常见相机战略应当律师方便校园股市房屋栏目员工导致突然道具本网结合档案劳动另外美元引起改变第四会计說明隐私宝宝规范消费共同忘记体系带来名字發表开放加盟受到二手大量成人数量共享区域女孩原则所在结束通信超级配置当时优秀性感房产遊戲出口提交就业保健程度参数事业整个山东情感特殊分類搜尋属于门户财务声音及其财经坚持干部成立利益考虑成都包装用戶比赛文明招商完整真是眼睛伙伴威望领域卫生优惠論壇公共良好充分符合附件特点不可英文资产根本明显密碼公众民族更加享受同学启动适合原来问答本文美食绿色稳定终于生物供求搜狐力量严重永远写真有限竞争对象费用不好绝对十分促进点评影音优势不少欣赏并且有点方向全新信用设施形象资格突破随着重大于是毕业智能化工完美商城统一出版打造產品概况用于保留因素中國存储贴图最愛长期口价理财基地安排武汉里面创建天空首先完善驱动下面不再诚信意义阳光英国漂亮军事玩家群众农民即可名稱家具动画想到注明小学性能考研硬件观看清楚搞笑首頁黄金适用江苏真实主管阶段註冊翻译权利做好似乎通讯施工狀態也许环保培养概念大型机票理解匿名cuandoenviarmadridbuscariniciotiempoporquecuentaestadopuedenjuegoscontraestánnombretienenperfilmaneraamigosciudadcentroaunquepuedesdentroprimerpreciosegúnbuenosvolverpuntossemanahabíaagostonuevosunidoscarlosequiponiñosmuchosalgunacorreoimagenpartirarribamaríahombreempleoverdadcambiomuchasfueronpasadolíneaparecenuevascursosestabaquierolibroscuantoaccesomiguelvarioscuatrotienesgruposseráneuropamediosfrenteacercademásofertacochesmodeloitalialetrasalgúncompracualesexistecuerposiendoprensallegarviajesdineromurciapodrápuestodiariopuebloquieremanuelpropiocrisisciertoseguromuertefuentecerrargrandeefectopartesmedidapropiaofrecetierrae-mailvariasformasfuturoobjetoseguirriesgonormasmismosúnicocaminositiosrazóndebidopruebatoledoteníajesúsesperococinaorigentiendacientocádizhablarseríalatinafuerzaestiloguerraentraréxitolópezagendavídeoevitarpaginametrosjavierpadresfácilcabezaáreassalidaenvíojapónabusosbienestextosllevarpuedanfuertecomúnclaseshumanotenidobilbaounidadestáseditarcreadoдлячтокакилиэтовсеегопритакещеужеКакбезбылониВсеподЭтотомчемнетлетразонагдемнеДляПринаснихтемктогодвоттамСШАмаяЧтовасвамемуТакдванамэтиэтуВамтехпротутнаддняВоттринейВаснимсамтотрубОнимирнееОООлицэтаОнанемдоммойдвеоносудकेहैकीसेकाकोऔरपरनेएककिभीइसकरतोहोआपहीयहयातकथाjagranआजजोअबदोगईजागएहमइनवहयेथेथीघरजबदीकईजीवेनईनएहरउसमेकमवोलेसबमईदेओरआमबसभरबनचलमनआगसीलीعلىإلىهذاآخرعددالىهذهصورغيركانولابينعرضذلكهنايومقالعليانالكنحتىقبلوحةاخرفقطعبدركنإذاكمااحدإلافيهبعضكيفبحثومنوهوأناجدالهاسلمعندليسعبرصلىمنذبهاأنهمثلكنتالاحيثمصرشرححولوفياذالكلمرةانتالفأبوخاصأنتانهاليعضووقدابنخيربنتلكمشاءوهيابوقصصومارقمأحدنحنعدمرأياحةكتبدونيجبمنهتحتجهةسنةيتمكرةغزةنفسبيتللهلناتلكقلبلماعنهأولشيءنورأمافيكبكلذاترتببأنهمسانكبيعفقدحسنلهمشعرأهلشهرقطرطلبprofileservicedefaulthimselfdetailscontentsupportstartedmessagesuccessfashioncountryaccountcreatedstoriesresultsrunningprocesswritingobjectsvisiblewelcomearticleunknownnetworkcompanydynamicbrowserprivacyproblemServicerespectdisplayrequestreservewebsitehistoryfriendsoptionsworkingversionmillionchannelwindow.addressvisitedweathercorrectproductedirectforwardyou canremovedsubjectcontrolarchivecurrentreadinglibrarylimitedmanagerfurthersummarymachineminutesprivatecontextprogramsocietynumberswrittenenabledtriggersourcesloadingelementpartnerfinallyperfectmeaningsystemskeepingculture",journalprojectsurfaces"expiresreviewsbalanceEnglishContentthroughPlease opinioncontactaverageprimaryvillageSpanishgallerydeclinemeetingmissionpopularqualitymeasuregeneralspeciessessionsectionwriterscounterinitialreportsfiguresmembersholdingdisputeearlierexpressdigitalpictureAnothermarriedtrafficleadingchangedcentralvictoryimages/reasonsstudiesfeaturelistingmust beschoolsVersionusuallyepisodeplayinggrowingobviousoverlaypresentactions
+wrapperalreadycertainrealitystorageanotherdesktopofferedpatternunusualDigitalcapitalWebsitefailureconnectreducedAndroiddecadesregular & animalsreleaseAutomatgettingmethodsnothingPopularcaptionletterscapturesciencelicensechangesEngland=1&History = new CentralupdatedSpecialNetworkrequirecommentwarningCollegetoolbarremainsbecauseelectedDeutschfinanceworkersquicklybetweenexactlysettingdiseaseSocietyweaponsexhibit<!--Controlclassescoveredoutlineattacksdevices(windowpurposetitle="Mobile killingshowingItaliandroppedheavilyeffects-1']);
+confirmCurrentadvancesharingopeningdrawingbillionorderedGermanyrelatedincludewhetherdefinedSciencecatalogArticlebuttonslargestuniformjourneysidebarChicagoholidayGeneralpassage,"animatefeelingarrivedpassingnaturalroughly.
+
+The but notdensityBritainChineselack oftributeIreland" data-factorsreceivethat isLibraryhusbandin factaffairsCharlesradicalbroughtfindinglanding:lang="return leadersplannedpremiumpackageAmericaEdition]"Messageneed tovalue="complexlookingstationbelievesmaller-mobilerecordswant tokind ofFirefoxyou aresimilarstudiedmaximumheadingrapidlyclimatekingdomemergedamountsfoundedpioneerformuladynastyhow to SupportrevenueeconomyResultsbrothersoldierlargelycalling."AccountEdward segmentRobert effortsPacificlearnedup withheight:we haveAngelesnations_searchappliedacquiremassivegranted: falsetreatedbiggestbenefitdrivingStudiesminimumperhapsmorningsellingis usedreversevariant role="missingachievepromotestudentsomeoneextremerestorebottom:evolvedall thesitemapenglishway to AugustsymbolsCompanymattersmusicalagainstserving})();
+paymenttroubleconceptcompareparentsplayersregionsmonitor ''The winningexploreadaptedGalleryproduceabilityenhancecareers). The collectSearch ancientexistedfooter handlerprintedconsoleEasternexportswindowsChannelillegalneutralsuggest_headersigning.html">settledwesterncausing-webkitclaimedJusticechaptervictimsThomas mozillapromisepartieseditionoutside:false,hundredOlympic_buttonauthorsreachedchronicdemandssecondsprotectadoptedprepareneithergreatlygreateroverallimprovecommandspecialsearch.worshipfundingthoughthighestinsteadutilityquarterCulturetestingclearlyexposedBrowserliberal} catchProjectexamplehide();FloridaanswersallowedEmperordefenseseriousfreedomSeveral-buttonFurtherout of != nulltrainedDenmarkvoid(0)/all.jspreventRequestStephen
+
+When observe
+Modern provide" alt="borders.
+
+For
+
+Many artistspoweredperformfictiontype ofmedicalticketsopposedCouncilwitnessjusticeGeorge Belgium...twitternotablywaitingwarfare Other rankingphrasesmentionsurvivescholar
+ Countryignoredloss ofjust asGeorgiastrange
+ severalbecomesselect wedding00.htmlmonarchoff theteacherhighly biologylife ofor evenrise of»plusonehunting(thoughDouglasjoiningcirclesFor theAncientVietnamvehiclesuch ascrystalvalue =Windowsenjoyeda smallassumed