From 1445a93e7041f11311526a3142e35cd8b800f346 Mon Sep 17 00:00:00 2001
From: Ben Noordhuis <info@bnoordhuis.nl>
Date: Thu, 21 Mar 2019 11:11:21 +0100
Subject: [PATCH] src: micro-optimize ALPN negotiation

99 out of a 100 times (conservative estimate!) the negotiated protocol
will be either "h2" or "http/1.1" so reuse an existing JS string for
those instead of creating a new one every time.
---
 src/env.h          |  2 ++
 src/node_crypto.cc | 18 ++++++++++++++----
 2 files changed, 16 insertions(+), 4 deletions(-)

diff --git a/src/env.h b/src/env.h
index 70c566dce9a08f..edd7ca4d592da9 100644
--- a/src/env.h
+++ b/src/env.h
@@ -190,11 +190,13 @@ constexpr size_t kFsStatsBufferLength = kFsStatsFieldsNumber * 2;
   V(get_data_clone_error_string, "_getDataCloneError")                         \
   V(get_shared_array_buffer_id_string, "_getSharedArrayBufferId")              \
   V(gid_string, "gid")                                                         \
+  V(h2_string, "h2")                                                           \
   V(handle_string, "handle")                                                   \
   V(help_text_string, "helpText")                                              \
   V(homedir_string, "homedir")                                                 \
   V(host_string, "host")                                                       \
   V(hostmaster_string, "hostmaster")                                           \
+  V(http_1_1_string, "http/1.1")                                               \
   V(ignore_string, "ignore")                                                   \
   V(infoaccess_string, "infoAccess")                                           \
   V(inherit_string, "inherit")                                                 \
diff --git a/src/node_crypto.cc b/src/node_crypto.cc
index de94ca9d26a467..4c965f54fd1628 100644
--- a/src/node_crypto.cc
+++ b/src/node_crypto.cc
@@ -65,6 +65,7 @@ using v8::DontDelete;
 using v8::EscapableHandleScope;
 using v8::Exception;
 using v8::External;
+using v8::False;
 using v8::Function;
 using v8::FunctionCallback;
 using v8::FunctionCallbackInfo;
@@ -2503,11 +2504,20 @@ void SSLWrap<Base>::GetALPNNegotiatedProto(
 
   SSL_get0_alpn_selected(w->ssl_.get(), &alpn_proto, &alpn_proto_len);
 
-  if (!alpn_proto)
-    return args.GetReturnValue().Set(false);
+  Local<Value> result;
+  if (alpn_proto_len == 0) {
+    result = False(args.GetIsolate());
+  } else if (alpn_proto_len == sizeof("h2") - 1 &&
+             0 == memcmp(alpn_proto, "h2", sizeof("h2") - 1)) {
+    result = w->env()->h2_string();
+  } else if (alpn_proto_len == sizeof("http/1.1") - 1 &&
+             0 == memcmp(alpn_proto, "http/1.1", sizeof("http/1.1") - 1)) {
+    result = w->env()->http_1_1_string();
+  } else {
+    result = OneByteString(args.GetIsolate(), alpn_proto, alpn_proto_len);
+  }
 
-  args.GetReturnValue().Set(
-      OneByteString(args.GetIsolate(), alpn_proto, alpn_proto_len));
+  args.GetReturnValue().Set(result);
 }