Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

http2: Introducing http/2 #14239

Closed
wants to merge 26 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
33ba2d8
http: move utcDate to internal/http.js
jasnell Oct 17, 2016
1cc4d86
tls: add tlsSocket.disableRenegotiation()
jasnell Nov 4, 2016
160197a
deps: add nghttp2 dependency
jasnell Jul 17, 2017
e1989a8
http2: introducing HTTP/2
jasnell Jul 17, 2017
998a4ad
http2: add tests and benchmarks
jasnell Jul 17, 2017
148dedd
http2: remove redundant return in test
jasnell Jul 17, 2017
3223555
http2: fix documentation nits
jasnell Jul 17, 2017
fb3a9c6
doc: include http2.md in all.md
jasnell Jul 17, 2017
e721353
test: fix flakiness in test-http2-client-upload
jasnell Jul 18, 2017
f4f0a28
test: fix flaky test-http2-client-unescaped-path on osx
jasnell Jul 18, 2017
b9848a1
http2: fix abort when client.destroy inside end event
jasnell Jul 19, 2017
8dcad26
http2: refinement and test for socketError
jasnell Jul 19, 2017
754d713
http2: fix socketOnTimeout and a segfault
jasnell Jul 19, 2017
6371510
http2: add range support for respondWith{File|FD}
jasnell Jul 22, 2017
0bdfee6
http2: doc and fixes to the Compatibility API
mcollina Jul 24, 2017
2f51e7d
http2: make writeHead behave like HTTP/1.
mcollina Jul 24, 2017
571deed
http2: address initial pr feedback
jasnell Jul 31, 2017
ec70fc5
http2: refactor trailers API
jasnell Jul 31, 2017
2358b11
http2: get trailers working with the compat api
jasnell Jul 31, 2017
d17aedb
http2: use static allocated arrays
jasnell Aug 1, 2017
40bd27c
http2: minor cleanup
jasnell Aug 1, 2017
5e447fe
http2: fix documentation errors
jasnell Aug 1, 2017
358b3df
http2: add some doc detail for invalid header chars
jasnell Aug 1, 2017
b7539a6
http2: fix compilation error after V8 update
jasnell Aug 3, 2017
886d2c6
http2: fix linting after rebase
jasnell Aug 3, 2017
873c1c5
http2: fix flakiness in timeout
jasnell Aug 3, 2017
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions benchmark/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,12 @@ directory, see [the guide on benchmarks](../doc/guides/writing-and-running-bench
Benchmarks for the <code>http</code> subsystem.
</td>
</tr>
<tr>
<td>http2</td>
<td>
Benchmarks for the <code>http2</code> subsystem.
</td>
</tr>
<tr>
<td>misc</td>
<td>
Expand Down
55 changes: 54 additions & 1 deletion benchmark/_http-benchmarkers.js
Original file line number Diff line number Diff line change
Expand Up @@ -111,10 +111,63 @@ class TestDoubleBenchmarker {
}
}

/**
* HTTP/2 Benchmarker
*/
class H2LoadBenchmarker {
constructor() {
this.name = 'h2load';
this.executable = 'h2load';
const result = child_process.spawnSync(this.executable, ['-h']);
this.present = !(result.error && result.error.code === 'ENOENT');
}

create(options) {
const args = [];
if (typeof options.requests === 'number')
args.push('-n', options.requests);
if (typeof options.clients === 'number')
args.push('-c', options.clients);
if (typeof options.threads === 'number')
args.push('-t', options.threads);
if (typeof options.maxConcurrentStreams === 'number')
args.push('-m', options.maxConcurrentStreams);
if (typeof options.initialWindowSize === 'number')
args.push('-w', options.initialWindowSize);
if (typeof options.sessionInitialWindowSize === 'number')
args.push('-W', options.sessionInitialWindowSize);
if (typeof options.rate === 'number')
args.push('-r', options.rate);
if (typeof options.ratePeriod === 'number')
args.push(`--rate-period=${options.ratePeriod}`);
if (typeof options.duration === 'number')
args.push('-T', options.duration);
if (typeof options.timeout === 'number')
args.push('-N', options.timeout);
if (typeof options.headerTableSize === 'number')
args.push(`--header-table-size=${options.headerTableSize}`);
if (typeof options.encoderHeaderTableSize === 'number') {
args.push(
`--encoder-header-table-size=${options.encoderHeaderTableSize}`);
}
const scheme = options.scheme || 'http';
const host = options.host || '127.0.0.1';
args.push(`${scheme}://${host}:${options.port}${options.path}`);
const child = child_process.spawn(this.executable, args);
return child;
}

processResults(output) {
const rex = /(\d+(?:\.\d+)) req\/s/;
return rex.exec(output)[1];
}
}

const http_benchmarkers = [
new WrkBenchmarker(),
new AutocannonBenchmarker(),
new TestDoubleBenchmarker()
new TestDoubleBenchmarker(),
new H2LoadBenchmarker()
];

const benchmarkers = {};
Expand Down
43 changes: 43 additions & 0 deletions benchmark/http2/respond-with-fd.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
'use strict';

const common = require('../common.js');
const PORT = common.PORT;
const path = require('path');
const fs = require('fs');

const file = path.join(path.resolve(__dirname, '../fixtures'), 'alice.html');

var bench = common.createBenchmark(main, {
requests: [100, 1000, 10000, 100000, 1000000],
streams: [100, 200, 1000],
clients: [1, 2]
}, { flags: ['--expose-http2', '--no-warnings'] });

function main(conf) {

fs.open(file, 'r', (err, fd) => {
if (err)
throw err;

const n = +conf.requests;
const m = +conf.streams;
const c = +conf.clients;
const http2 = require('http2');
const server = http2.createServer();
server.on('stream', (stream) => {
stream.respondWithFD(fd);
stream.on('error', (err) => {});
});
server.listen(PORT, () => {
bench.http({
path: '/',
requests: n,
maxConcurrentStreams: m,
clients: c,
threads: c
}, () => server.close());
});

});

}
38 changes: 38 additions & 0 deletions benchmark/http2/simple.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
'use strict';

const common = require('../common.js');
const PORT = common.PORT;

const path = require('path');
const fs = require('fs');

const file = path.join(path.resolve(__dirname, '../fixtures'), 'alice.html');

var bench = common.createBenchmark(main, {
requests: [100, 1000, 10000, 100000],
streams: [100, 200, 1000],
clients: [1, 2]
}, { flags: ['--expose-http2', '--no-warnings'] });

function main(conf) {
const n = +conf.requests;
const m = +conf.streams;
const c = +conf.clients;
const http2 = require('http2');
const server = http2.createServer();
server.on('stream', (stream) => {
const out = fs.createReadStream(file);
stream.respond();
out.pipe(stream);
stream.on('error', (err) => {});
});
server.listen(PORT, () => {
bench.http({
path: '/',
requests: n,
maxConcurrentStreams: m,
clients: c,
threads: c
}, () => { server.close(); });
});
}
22 changes: 22 additions & 0 deletions configure
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,8 @@ shared_optgroup = optparse.OptionGroup(parser, "Shared libraries",
intl_optgroup = optparse.OptionGroup(parser, "Internationalization",
"Flags that lets you enable i18n features in Node.js as well as which "
"library you want to build against.")
http2_optgroup = optparse.OptionGroup(parser, "HTTP2",
"Flags that allows you to control HTTP2 features in Node.js")

# Options should be in alphabetical order but keep --prefix at the top,
# that's arguably the one people will be looking for most.
Expand Down Expand Up @@ -397,6 +399,16 @@ intl_optgroup.add_option('--download-path',

parser.add_option_group(intl_optgroup)

http2_optgroup.add_option('--debug-http2',
action='store_true',
dest='debug_http2',
help='build with http2 debug statements on (default is false)')

http2_optgroup.add_option('--debug-nghttp2',
action='store_true',
dest='debug_nghttp2',
help='build nghttp2 with DEBUGBUILD (default is false)')

parser.add_option('--with-perfctr',
action='store_true',
dest='with_perfctr',
Expand Down Expand Up @@ -898,6 +910,16 @@ def configure_node(o):
if options.enable_static:
o['variables']['node_target_type'] = 'static_library'

if options.debug_http2:
o['variables']['debug_http2'] = 1
else:
o['variables']['debug_http2'] = 'false'

if options.debug_nghttp2:
o['variables']['debug_nghttp2'] = 1
else:
o['variables']['debug_nghttp2'] = 'false'

o['variables']['node_no_browser_globals'] = b(options.no_browser_globals)
o['variables']['node_shared'] = b(options.shared)
node_module_version = getmoduleversion.get_version()
Expand Down
63 changes: 63 additions & 0 deletions deps/nghttp2/lib/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
add_subdirectory(includes)

include_directories(
"${CMAKE_CURRENT_SOURCE_DIR}/includes"
"${CMAKE_CURRENT_BINARY_DIR}/includes"
)

add_definitions(-DBUILDING_NGHTTP2)

set(NGHTTP2_SOURCES
nghttp2_pq.c nghttp2_map.c nghttp2_queue.c
nghttp2_frame.c
nghttp2_buf.c
nghttp2_stream.c nghttp2_outbound_item.c
nghttp2_session.c nghttp2_submit.c
nghttp2_helper.c
nghttp2_npn.c
nghttp2_hd.c nghttp2_hd_huffman.c nghttp2_hd_huffman_data.c
nghttp2_version.c
nghttp2_priority_spec.c
nghttp2_option.c
nghttp2_callbacks.c
nghttp2_mem.c
nghttp2_http.c
nghttp2_rcbuf.c
nghttp2_debug.c
)

set(NGHTTP2_RES "")

if(WIN32)
configure_file(
version.rc.in
${CMAKE_CURRENT_BINARY_DIR}/version.rc
@ONLY)

set(NGHTTP2_RES ${CMAKE_CURRENT_BINARY_DIR}/version.rc)
endif()

# Public shared library
add_library(nghttp2 SHARED ${NGHTTP2_SOURCES} ${NGHTTP2_RES})
set_target_properties(nghttp2 PROPERTIES
COMPILE_FLAGS "${WARNCFLAGS}"
VERSION ${LT_VERSION} SOVERSION ${LT_SOVERSION}
C_VISIBILITY_PRESET hidden
)

if(HAVE_CUNIT)
# Static library (for unittests because of symbol visibility)
add_library(nghttp2_static STATIC ${NGHTTP2_SOURCES})
set_target_properties(nghttp2_static PROPERTIES
COMPILE_FLAGS "${WARNCFLAGS}"
VERSION ${LT_VERSION} SOVERSION ${LT_SOVERSION}
ARCHIVE_OUTPUT_NAME nghttp2
)
target_compile_definitions(nghttp2_static PUBLIC "-DNGHTTP2_STATICLIB")
endif()

install(TARGETS nghttp2
DESTINATION "${CMAKE_INSTALL_LIBDIR}")

install(FILES "${CMAKE_CURRENT_BINARY_DIR}/libnghttp2.pc"
DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig")
72 changes: 72 additions & 0 deletions deps/nghttp2/lib/Makefile.am
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
# nghttp2 - HTTP/2 C Library

# Copyright (c) 2012, 2013 Tatsuhiro Tsujikawa

# Permission is hereby granted, free of charge, to any person obtaining
# a copy of this software and associated documentation files (the
# "Software"), to deal in the Software without restriction, including
# without limitation the rights to use, copy, modify, merge, publish,
# distribute, sublicense, and/or sell copies of the Software, and to
# permit persons to whom the Software is furnished to do so, subject to
# the following conditions:

# The above copyright notice and this permission notice shall be
# included in all copies or substantial portions of the Software.

# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
SUBDIRS = includes

EXTRA_DIST = Makefile.msvc CMakeLists.txt version.rc.in

AM_CFLAGS = $(WARNCFLAGS) $(EXTRACFLAG)
AM_CPPFLAGS = -I$(srcdir)/includes -I$(builddir)/includes -DBUILDING_NGHTTP2 \
@DEFS@

pkgconfigdir = $(libdir)/pkgconfig
pkgconfig_DATA = libnghttp2.pc
DISTCLEANFILES = $(pkgconfig_DATA)

lib_LTLIBRARIES = libnghttp2.la

OBJECTS = nghttp2_pq.c nghttp2_map.c nghttp2_queue.c \
nghttp2_frame.c \
nghttp2_buf.c \
nghttp2_stream.c nghttp2_outbound_item.c \
nghttp2_session.c nghttp2_submit.c \
nghttp2_helper.c \
nghttp2_npn.c \
nghttp2_hd.c nghttp2_hd_huffman.c nghttp2_hd_huffman_data.c \
nghttp2_version.c \
nghttp2_priority_spec.c \
nghttp2_option.c \
nghttp2_callbacks.c \
nghttp2_mem.c \
nghttp2_http.c \
nghttp2_rcbuf.c \
nghttp2_debug.c

HFILES = nghttp2_pq.h nghttp2_int.h nghttp2_map.h nghttp2_queue.h \
nghttp2_frame.h \
nghttp2_buf.h \
nghttp2_session.h nghttp2_helper.h nghttp2_stream.h nghttp2_int.h \
nghttp2_npn.h \
nghttp2_submit.h nghttp2_outbound_item.h \
nghttp2_net.h \
nghttp2_hd.h nghttp2_hd_huffman.h \
nghttp2_priority_spec.h \
nghttp2_option.h \
nghttp2_callbacks.h \
nghttp2_mem.h \
nghttp2_http.h \
nghttp2_rcbuf.h \
nghttp2_debug.h

libnghttp2_la_SOURCES = $(HFILES) $(OBJECTS)
libnghttp2_la_LDFLAGS = -no-undefined \
-version-info $(LT_CURRENT):$(LT_REVISION):$(LT_AGE)
Loading