Giter Site home page Giter Site logo

nodejs / http2 Goto Github PK

View Code? Open in Web Editor NEW
520.0 50.0 79.0 197.35 MB

Working on an HTTP/2 implementation for Node.js Core

License: Other

Makefile 0.39% Shell 0.02% R 0.07% JavaScript 65.10% HTML 2.02% C++ 24.19% Python 1.01% POV-Ray SDL 1.09% DTrace 0.46% C 5.18% Batchfile 0.28% Roff 0.19%
nodejs node

http2's Introduction

Node.js

Node.js is a JavaScript runtime built on Chrome's V8 JavaScript engine. Node.js uses an event-driven, non-blocking I/O model that makes it lightweight and efficient. The Node.js package ecosystem, npm, is the largest ecosystem of open source libraries in the world.

The Node.js project is supported by the Node.js Foundation. Contributions, policies, and releases are managed under an open governance model.

This project is bound by a Code of Conduct.

If you need help using or installing Node.js, please use the nodejs/help issue tracker.

Table of Contents

Resources for Newcomers

Official Resources

Unofficial Resources

Please note that unofficial resources are neither managed by (nor necessarily endorsed by) the Node.js TSC/CTC. Specifically, such resources are not currently covered by the Node.js Moderation Policy and the selection and actions of resource operators/moderators are not subject to TSC/CTC oversight.

Release Types

The Node.js project maintains multiple types of releases:

  • Current: Released from active development branches of this repository, versioned by SemVer and signed by a member of the Release Team. Code for Current releases is organized in this repository by major version number. For example: v4.x. The major version number of Current releases will increment every 6 months allowing for breaking changes to be introduced. This happens in April and October every year. Current release lines beginning in October each year have a maximum support life of 8 months. Current release lines beginning in April each year will convert to LTS (see below) after 6 months and receive further support for 30 months.
  • LTS: Releases that receive Long-term Support, with a focus on stability and security. Every second Current release line (major version) will become an LTS line and receive 18 months of Active LTS support and a further 12 months of Maintenance. LTS release lines are given alphabetically ordered codenames, beginning with v4 Argon. LTS releases are less frequent and will attempt to maintain consistent major and minor version numbers, only incrementing patch version numbers. There are no breaking changes or feature additions, except in some special circumstances. More information can be found in the LTS README.
  • Nightly: Versions of code in this repository on the current Current branch, automatically built every 24-hours where changes exist. Use with caution.

Download

Binaries, installers, and source tarballs are available at https://nodejs.org.

Current and LTS Releases

Current and LTS releases are available at https://nodejs.org/download/release/, listed under their version strings. The latest directory is an alias for the latest Current release. The latest LTS release from an LTS line is available in the form: latest-codename. For example: https://nodejs.org/download/release/latest-argon

Nightly Releases

Nightly builds are available at https://nodejs.org/download/nightly/, listed under their version string which includes their date (in UTC time) and the commit SHA at the HEAD of the release.

API Documentation

API documentation is available in each release and nightly directory under docs. https://nodejs.org/api/ points to the API documentation of the latest stable version.

Verifying Binaries

Current, LTS and Nightly download directories all contain a SHASUM256.txt file that lists the SHA checksums for each file available for download.

The SHASUM256.txt can be downloaded using curl.

$ curl -O https://nodejs.org/dist/vx.y.z/SHASUMS256.txt

To check that a downloaded file matches the checksum, run it through sha256sum with a command such as:

$ grep node-vx.y.z.tar.gz SHASUMS256.txt | sha256sum -c -

(Where "node-vx.y.z.tar.gz" is the name of the file you have downloaded)

Additionally, Current and LTS releases (not Nightlies) have GPG signed copies of SHASUM256.txt files available as SHASUM256.txt.asc. You can use gpg to verify that the file has not been tampered with.

To verify a SHASUM256.txt.asc, you will first need to import all of the GPG keys of individuals authorized to create releases. They are listed at the bottom of this README under Release Team. Use a command such as this to import the keys:

$ gpg --keyserver pool.sks-keyservers.net --recv-keys DD8F2338BAE7501E3DD5AC78C273792F7D83545D

(See the bottom of this README for a full script to import active release keys)

You can then use gpg --verify SHASUMS256.txt.asc to verify that the file has been signed by an authorized member of the Node.js team.

Once verified, use the SHASUMS256.txt.asc file to get the checksum for the binary verification command above.

Building Node.js

See BUILDING.md for instructions on how to build Node.js from source. The document also contains a list of officially supported platforms.

Security

All security bugs in Node.js are taken seriously and should be reported by emailing [email protected]. This will be delivered to a subset of the project team who handle security issues. Please don't disclose security bugs publicly until they have been handled by the security team.

Your email will be acknowledged within 24 hours, and you’ll receive a more detailed response to your email within 48 hours indicating the next steps in handling your report.

Current Project Team Members

The Node.js project team comprises a group of core collaborators and a sub-group that forms the Core Technical Committee (CTC) which governs the project. For more information about the governance of the Node.js project, see GOVERNANCE.md.

CTC (Core Technical Committee)

CTC Emeriti

Collaborators

Collaborators follow the COLLABORATOR_GUIDE.md in maintaining the Node.js project.

Release Team

Node.js releases are signed with one of the following GPG keys:

The full set of trusted release keys can be imported by running:

gpg --keyserver pool.sks-keyservers.net --recv-keys 94AE36675C464D64BAFA68DD7434390BDBE9B9C5
gpg --keyserver pool.sks-keyservers.net --recv-keys FD3A5288F042B6850C66B31F09FE44734EB7990E
gpg --keyserver pool.sks-keyservers.net --recv-keys 71DCFD284A79C3B38668286BC97EC7A07EDE3FC1
gpg --keyserver pool.sks-keyservers.net --recv-keys DD8F2338BAE7501E3DD5AC78C273792F7D83545D
gpg --keyserver pool.sks-keyservers.net --recv-keys C4F0DFFF4E8C1A8236409D08E73BC641CC11F4C8
gpg --keyserver pool.sks-keyservers.net --recv-keys B9AE9905FFD7803F25714661B63B535A4C206CA9
gpg --keyserver pool.sks-keyservers.net --recv-keys 56730D5401028683275BD23C23EFEFE93C4CFFFE

See the section above on Verifying Binaries for details on what to do with these keys to verify that a downloaded file is official.

Previous releases may also have been signed with one of the following GPG keys:

Working Groups

Information on the current Node.js Working Groups can be found in the CTC repository.

http2's People

Contributors

addaleax avatar andreasmadsen avatar bnoordhuis avatar cjihrig avatar danbev avatar evanlucas avatar felixge avatar fishrock123 avatar indutny avatar isaacs avatar jasnell avatar koichik avatar mhdawson avatar mscdex avatar mylesborins avatar ofrobots avatar piscisaureus avatar rvagg avatar ry avatar sam-github avatar shigeki avatar silverwind avatar targos avatar thefourtheye avatar timothygu avatar tjfontaine avatar tootallnate avatar trevnorris avatar trott avatar vsemozhetbyt avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

http2's Issues

MaxListenersExceededWarning: Possible EventEmitter memory leak detected.

  • Version: http2 v. 3.3.6
  • Platform: NodeJS 7.7.1
  • Subsystem: KoaJS (v. 1.2.4), Koa-send, koa-router, koa-passport

I am using http2 in a project that is using SSL from Let's encrypt.
If i use http2 i get this error, instead if i switch over https module all work good.
(node:60502) MaxListenersExceededWarning: Possible EventEmitter memory leak detected. 11 close listeners added. Use emitter.setMaxListeners() to increase limit

http2 client: end event not emitted if no data listener registered

The http2 client will not emit end, given no data listener is registered, even if the server ends the response.

The following code calls req.on('end') just in the case req.on('data') is registered.

'use strict';
require('../common');
const assert = require('assert');
const http2 = require('http2');

const testResBody = 'other stuff!\n';

const server = http2.createServer((req, res) => {
  res.writeHead(200, {
    'Content-Type': 'text/plain'
  });
  res.end(testResBody);
});

server.listen(0, function() {
  const client = http2.connect(`http://localhost:${this.address().port}`);

  const headers = { ':path': '/' };
  const req = client.request(headers)
  req.setEncoding('utf8');

  // XXX: remove this and ` req.on('end')` is never called 
  let data = '';
  req.on('data', (d) => data += d);

  req.on('response', (headers) => {
    assert.ok('date' in headers,
              'Response headers contain a date.');
  });

  req.on('end', () => {
    server.close();
    process.exit();
  });
  req.end();
});

http2: client.socket.destroy() throws AssertionError: Internal HTTP/2 Failure. Stream does not exist.

I just tried to write some tests like this.

'use strict';

const common = require('../common');
const assert = require('assert');
const http2 = require('http2');
const path = require('path');
const tls = require('tls');
const net = require('net');
const fs = require('fs');
const body =
  '<html><head></head><body><h1>this is some data</h2></body></html>';

const server = http2.createServer((req, res) => {
  res.setHeader('foobar', 'baz');
  res.setHeader('X-POWERED-BY', 'node-test');
  res.end(body);
});

server.listen(0, common.mustCall(() => {
  const client = http2.connect(`http://localhost:${server.address().port}`);
  const headers = { ':path': '/' };
  const req = client.request(headers);
  req.setEncoding('utf8');
  req.on('response', common.mustCall(function(headers) {
    client.socket.destroy();
    server.close();
    assert.strictEqual(headers['foobar'], 'baz');
    assert.strictEqual(headers['x-powered-by'], 'node-test');
  }));
  req.end();
}));

server.on('error', common.mustNotCall());

but I have got the following errors

assert.js:86
  throw new assert.AssertionError({
  ^
AssertionError: Internal HTTP/2 Failure. Stream does not exist.
    at Http2Session.onSessionStreamClose [as onstreamclose] (internal/http2/core.js:152:3)

But following code is passed

'use strict';

const common = require('../common');
const assert = require('assert');
const http2 = require('http2');
const path = require('path');
const tls = require('tls');
const net = require('net');
const fs = require('fs');
const body =
  '<html><head></head><body><h1>this is some data</h2></body></html>';

const server = http2.createServer((req, res) => {
  res.setHeader('foobar', 'baz');
  res.setHeader('X-POWERED-BY', 'node-test');
  res.end(body);
});

server.listen(0, common.mustCall(() => {
  const client = http2.connect(`http://localhost:${server.address().port}`);
  const headers = { ':path': '/' };
  const req = client.request(headers);
  req.setEncoding('utf8');
  req.on('response', common.mustCall(function(headers) {
    assert.strictEqual(headers['foobar'], 'baz');
    assert.strictEqual(headers['x-powered-by'], 'node-test');
  }));

  let data = '';
  req.on('data', (d) => data += d);
  req.on('end', () => {
    assert.strictEqual(body, data);
    // close in here
    client.socket.destroy();
    server.close();
  });
  req.end();
}));

server.on('error', common.mustNotCall());
  • Subsystem:
    http2

I tried to debug this, but I cannot find some hints.

 // here is the assertion code, but my code run this method twice, same id.
function onSessionStreamClose(id, code) {
  const owner = this[kOwner];
  const state = owner[kState];
  const streams = state.streams;
  const stream = streams.get(id);
  assert(stream, 'Internal HTTP/2 Failure. Stream does not exist.');
  timers._unrefActive(this); // Unref the session timer
  timers._unrefActive(stream); // Unref the stream timer
  // Notify the stream that it has been closed.
  stream.emit('streamClosed', code);
  timers.unenroll(stream);
  stream[kSession] = undefined;
  streams.delete(id);
}

http/2: starting HTTP/2 for "http" URIs (http/1 upgrade to http/2)

For anyone who wants to take on the challenge of implementing support for automatic upgrades from HTTP/1 to HTTP/2, here are the basic requirements from the spec:


Starting HTTP/2 for "http" URIs

A client that makes a request for an "http" URI without prior knowledge about support for HTTP/2 on the next hop uses the HTTP Upgrade mechanism (Section 6.7 of [RFC7230]). The client does so by making an HTTP/1.1 request that includes an Upgrade header field with the "h2c" token. Such an HTTP/1.1 request MUST include exactly one HTTP2-Settings (Section 3.2.1) header field.

For example:

GET / HTTP/1.1
Host: server.example.com
Connection: Upgrade, HTTP2-Settings
Upgrade: h2c
HTTP2-Settings: <base64url encoding of HTTP/2 SETTINGS payload>

Requests that contain a payload body MUST be sent in their entirety before the client can send HTTP/2 frames. This means that a large request can block the use of the connection until it is completely sent.

If concurrency of an initial request with subsequent requests is important, an OPTIONS request can be used to perform the upgrade to HTTP/2, at the cost of an additional round trip.

A server that does not support HTTP/2 can respond to the request as though the Upgrade header field were absent:

HTTP/1.1 200 OK
Content-Length: 243
Content-Type: text/html
...

A server MUST ignore an "h2" token in an Upgrade header field. Presence of a token with "h2" implies HTTP/2 over TLS, which is instead negotiated as described in Section 3.3.

A server that supports HTTP/2 accepts the upgrade with a 101 (Switching Protocols) response. After the empty line that terminates the 101 response, the server can begin sending HTTP/2 frames. These frames MUST include a response to the request that initiated the upgrade.

For example:

HTTP/1.1 101 Switching Protocols
Connection: Upgrade
Upgrade: h2c

[ HTTP/2 connection ...

The first HTTP/2 frame sent by the server MUST be a server connection preface (Section 3.5) consisting of a SETTINGS frame (Section 6.5). Upon receiving the 101 response, the client MUST send a connection preface (Section 3.5), which includes a SETTINGS frame.

The HTTP/1.1 request that is sent prior to upgrade is assigned a stream identifier of 1 (see Section 5.1.1) with default priority values (Section 5.3.5). Stream 1 is implicitly "half-closed" from the client toward the server (see Section 5.1), since the request is completed as an HTTP/1.1 request. After commencing the HTTP/2 connection, stream 1 is used for the response.


As far as implementation is concerned, the upgrade path can essentially be handled either as a special handler for the 'upgrade' event or as a special case inside the existing HTTP implementation.

http2: Build failure on Windows

CI is showing nghttp2 library failing to build on windows: https://ci.nodejs.org/job/node-compile-windows/8991/label=win-vcbt2015/console

Partial list of failures
formal parameter list illegal (compiling source file lib\nghttp2_session.c) [c:\workspace\node-compile-windows\label\win-vcbt2015\deps\nghttp2\nghttp2.vcxproj]
c:\workspace\node-compile-windows\label\win-vcbt2015\deps\nghttp2\lib\includes\nghttp2/nghttp2.h(2188): error C2081: 'nghttp2_select_padding_callback': name in formal parameter list illegal (compiling source file lib\nghttp2_stream.c) [c:\workspace\node-compile-windows\label\win-vcbt2015\deps\nghttp2\nghttp2.vcxproj]
c:\workspace\node-compile-windows\label\win-vcbt2015\deps\nghttp2\lib\includes\nghttp2/nghttp2.h(2041): error C2059: syntax error: ';' (compiling source file lib\nghttp2_submit.c) [c:\workspace\node-compile-windows\label\win-vcbt2015\deps\nghttp2\nghttp2.vcxproj]
c:\workspace\node-compile-windows\label\win-vcbt2015\deps\nghttp2\lib\nghttp2_hd.h(426): error C2059: syntax error: ';' (compiling source file lib\nghttp2_outbound_item.c) [c:\workspace\node-compile-windows\label\win-vcbt2015\deps\nghttp2\nghttp2.vcxproj]
c:\workspace\node-compile-windows\label\win-vcbt2015\deps\nghttp2\lib\includes\nghttp2/nghttp2.h(2820): error C2059: syntax error: '<parameter-list>' (compiling source file lib\nghttp2_rcbuf.c) [c:\workspace\node-compile-windows\label\win-vcbt2015\deps\nghttp2\nghttp2.vcxproj]
c:\workspace\node-compile-windows\label\win-vcbt2015\deps\nghttp2\lib\includes\nghttp2/nghttp2.h(3728): error C2059: syntax error: 'type' (compiling source file lib\nghttp2_priority_spec.c) [c:\workspace\node-compile-windows\label\win-vcbt2015\deps\nghttp2\nghttp2.vcxproj]
c:\workspace\node-compile-windows\label\win-vcbt2015\deps\nghttp2\lib\includes\nghttp2/nghttp2.h(3797): error C2143: syntax error: missing '{' before '*' (compiling source file lib\nghttp2_queue.c) [c:\workspace\node-compile-windows\label\win-vcbt2015\deps\nghttp2\nghttp2.vcxproj]
c:\workspace\node-compile-windows\label\win-vcbt2015\deps\nghttp2\lib\includes\nghttp2/nghttp2.h(2199): error C2061: syntax error: identifier 'data_source_read_length_callback' (compiling source file lib\nghttp2_session.c) [c:\workspace\node-compile-windows\label\win-vcbt2015\deps\nghttp2\nghttp2.vcxproj]
c:\workspace\node-compile-windows\label\win-vcbt2015\deps\nghttp2\lib\includes\nghttp2/nghttp2.h(2188): error C2061: syntax error: identifier 'select_padding_callback' (compiling source file lib\nghttp2_stream.c) [c:\workspace\node-compile-windows\label\win-vcbt2015\deps\nghttp2\nghttp2.vcxproj]
c:\workspace\node-compile-windows\label\win-vcbt2015\deps\nghttp2\lib\includes\nghttp2/nghttp2.h(2041): error C2059: syntax error: ')' (compiling source file lib\nghttp2_submit.c) [c:\workspace\node-compile-windows\label\win-vcbt2015\deps\nghttp2\nghttp2.vcxproj]
c:\workspace\node-compile-windows\label\win-vcbt2015\deps\nghttp2\lib\nghttp2_hd.h(426): error C2059: syntax error: '<parameter-list>' (compiling source file lib\nghttp2_outbound_item.c) [c:\workspace\node-compile-windows\label\win-vcbt2015\deps\nghttp2\nghttp2.vcxproj]
c:\workspace\node-compile-windows\label\win-vcbt2015\deps\nghttp2\lib\includes\nghttp2/nghttp2.h(2930): error C2061: syntax error: identifier 'nghttp2_session_mem_recv' (compiling source file lib\nghttp2_rcbuf.c) [c:\workspace\node-compile-windows\label\win-vcbt2015\deps\nghttp2\nghttp2.vcxproj]
c:\workspace\node-compile-windows\label\win-vcbt2015\deps\nghttp2\lib\includes\nghttp2/nghttp2.h(3728): error C2059: syntax error: ')' (compiling source file lib\nghttp2_priority_spec.c) [c:\workspace\node-compile-windows\label\win-vcbt2015\deps\nghttp2\nghttp2.vcxproj]
c:\workspace\node-compile-windows\label\win-vcbt2015\deps\nghttp2\lib\includes\nghttp2/nghttp2.h(3797): error C2059: syntax error: ')' (compiling source file lib\nghttp2_queue.c) [c:\workspace\node-compile-windows\label\win-vcbt2015\deps\nghttp2\nghttp2.vcxproj]
c:\workspace\node-compile-windows\label\win-vcbt2015\deps\nghttp2\lib\includes\nghttp2/nghttp2.h(2199): error C2059: syntax error: ';' (compiling source file lib\nghttp2_session.c) [c:\workspace\node-compile-windows\label\win-vcbt2015\deps\nghttp2\nghttp2.vcxproj]
c:\workspace\node-compile-windows\label\win-vcbt2015\deps\nghttp2\lib\includes\nghttp2/nghttp2.h(2188): error C2059: syntax error: ';' (compiling source file lib\nghttp2_stream.c) [c:\workspace\node-compile-windows\label\win-vcbt2015\deps\nghttp2\nghttp2.vcxproj]

Sending illegal frame (DATA) in CLOSED state. and AssertionError: false == true

node -v 6.9.2
One error

Debug: internal, implementation, error
	Error: Sending illegal frame (DATA) in CLOSED state.
	at Stream.transition [as _transition] (/var/www/revizor-game.ru/node_modules/http2/lib/protocol/stream.js:628:33)
	at Stream._finishing (/var/www/revizor-game.ru/node_modules/http2/lib/protocol/stream.js:349:10)
	at emitNone (events.js:67:13)
	at Stream.emit (events.js:166:7)
	at finishMaybe (_stream_writable.js:468:14)
	at endWritable (_stream_writable.js:478:3)
	at Stream.Writable.end (_stream_writable.js:443:5)
	at OutgoingResponse._finish (/var/www/revizor-game.ru/node_modules/http2/lib/http.js:352:17)
	at emitNone (events.js:72:20)
	at OutgoingResponse.emit (events.js:166:7)
	at finishMaybe (_stream_writable.js:468:14)
	at endWritable (_stream_writable.js:478:3)
	at OutgoingResponse.Writable.end (_stream_writable.js:443:5)
	at OutgoingResponse.end (/var/www/revizor-game.ru/node_modules/http2/lib/http.js:753:40)
	at ReadStream.onend (_stream_readable.js:490:10)
	at ReadStream.g (events.js:260:16)

second

Debug: internal, implementation, error
    AssertionError: false == true
    at Connection._send (/var/www/revizor-game.ru/node_modules/http2/lib/protocol/connection.js:326:9)
    at runCallback (timers.js:637:20)
    at tryOnImmediate (timers.js:610:5)
    at processImmediate [as _immediateCallback] (timers.js:582:5)

My server.js

$lib.s = new Hapi.Server();
var listener = http2.createServer({
    key: fs.readFileSync('/var/www/revizor-game.ru.key', 'utf8'),
    cert: fs.readFileSync('/var/www/ca.crt', 'utf8'),
    pfx: fs.readFileSync('/var/www/pfx.pfx')
});

$lib.s.connection({
    listener: listener,
    host: 'revizor-game.ru',
    port: 443,
    tls: true
    // tls: {
    //     key: fs.readFileSync('/var/www/revizor-game.ru.key', 'utf8'),
    //     cert: fs.readFileSync('/var/www/ca.crt', 'utf8')
    // }
});

and boot.js (clustering) - http://pastebin.com/YzGsJVUk

Why is http2 exposed as a property of the http module?

Hi everyone. I'm just curious why http2 is exposed via require('http').HTTP2? Is this temporary, or the final API? It seems a bit clunky. I was hoping we'd see require('http2').

As an aside, this is really cool stuff. Really exciting to see this under development. Thanks for your efforts here. 🍻

setHeader is an hot function

Currently we cross the JS/C++ boundary quite a lot in setHeader, and we cause some mallocs. Can we avoid that, or make it less of an issue? Maybe we can batch the headers, and pass them down all together before starting the reply.
schermata 2016-12-09 alle 11 54 46

http2: async_hooks support

We need to make sure there is proper async hooks support here. Specifically, we need appropriate hooks for the creation / destruction of an Http2Session, hooks for the creation / destruction of a Stream, each of the write operations, and the session shutdown operation.

a better default configuration for TLS connection of http2

It seems the TLS socket is initialized as tls.connect(port, host, options) in http2.connect. Some existing HTTP2 servers require some TLS options to set up the connection properly. More specifically:

  • servername (for Server Name Indication)
  • ALPN / NPN, specifying 'h2'

I believe those should be set by defaults, then passing a URL string will just work.

Also, maybe it's better to use secureConnect event instead of connect event for the TLS sockets for setting up a session -- so that it won't go into the session if some TLS setup failure happens.

HTTP/2 requests

Hey guys, i see this is a WIP repo - way to go for that important feature!

My question:
Is it part of the plan to add support for HTTP/2 for requests going out of a node app (client mode)
e.g. something like

http.request(options[, callback])

Will use HTTP/2.

(asking since all the discussions that i've seen here are referring to adding HTTP/2 server capabilities)

Many thanks.

http2: prioritization api / support

There are several things needed here:

  1. Method for setting the priority (this is already available)
  2. Event when a priority change request has been received.
  3. Event when the priority of a stream has actually changed.

Feb 2017 meeting

How about we set up a call in the next couple of weeks to discuss how this is moving forward? There have been a lot of progress.

http2: streams does not exist in onSessionStreamClose

Command: h2load -n 1000 http://localhost:8000/.

Error:

assert.js:86
  throw new assert.AssertionError({
  ^
AssertionError: Internal HTTP/2 Failure. Stream does not exist.
    at Http2Session.onSessionStreamClose [as onstreamclose] (internal/http2/core.js:152:3)

The reason this happens is because onSessionStreamClose is called after onSessionClose.
server:

const fs = require('fs');
const http2 = require('http2');
const options = {
  key: fs.readFileSync('./key.pem'),
  cert: fs.readFileSync('./cert.pem')
};

function handler(req, res) {
  res.writeHead(200, {'content-type': 'text/html'});
  res.end('<html><head></head><body><h1>this is some data</h2></body></html>');
}

function onStream (stream) {
  stream.respond({
    'content-type': 'text/html',
    ':status': 200
  })
  stream.end('<html><head></head><body><h1>this is some data</h2></body></html>');
}

const server = http2.createServer(options);
// server.on('request', handler)
server.on('stream', onStream)
server.setTimeout(10 * 1000);
server.listen(8000);

process.on('SIGINT', quit)
process.on('SIGHUP', quit)
process.on('SIGTERM', quit)

function quit () {
  server.close()
  console.log('closing server')
  process.exit(0)
}

http2: failures on raspbian

https://ci.nodejs.org/job/node-test-binary-arm/7999/RUN_SUBSET=4,label=pi2-raspbian-wheezy/console

not ok 93 parallel/test-http2-create-client-connect
  ---
  duration_ms: 1.537
  severity: fail
  stack: |-
    (node:11017) ExperimentalWarning: The http2 module is an experimental API.
    internal/http2/core.js:375
        handle.consume(socket._handle._externalStream);
                                     ^
    
    TypeError: Cannot read property '_externalStream' of null
        at internal/http2/core.js:375:34
        at new Http2Session (internal/http2/core.js:435:7)
        at createClientSession (internal/http2/core.js:1340:19)
        at connect (internal/http2/core.js:1402:19)
        at items.forEach (/home/iojs/build/workspace/node-test-binary-arm/test/parallel/test-http2-create-client-connect.js:39:20)
        at Array.forEach (native)
        at Http2Server.<anonymous> (/home/iojs/build/workspace/node-test-binary-arm/test/parallel/test-http2-create-client-connect.js:37:11)
        at Http2Server.<anonymous> (/home/iojs/build/workspace/node-test-binary-arm/test/common.js:462:15)
        at emitNone (events.js:105:13)
        at Http2Server.emit (events.js:207:7)
  ...
not ok 94 parallel/test-http2-server-startup
  ---
  duration_ms: 3.639
  severity: fail
  stack: |-
    (node:11033) ExperimentalWarning: The http2 module is an experimental API.
    
    assert.js:86
      throw new assert.AssertionError({
      ^
    AssertionError: server timeout failed
        at Timeout.setTimeout [as _onTimeout] (/home/iojs/build/workspace/node-test-binary-arm/test/parallel/test-http2-server-startup.js:80:35)
        at ontimeout (timers.js:407:14)
        at tryOnTimeout (timers.js:271:5)
        at Timer.listOnTimeout (timers.js:235:5)
  ...

http2: status code is string instead of number

The status code is a string now, not of type number any more.

Apart from the compat change, from a user perspective its a bit unhandy to get back the statuscode as a string, as you have to cast it before you make something like:

if (statusCode >= 200) { // todo ... }

Example for failing, ported http1 test:

'use strict';

const common = require('../common');
const assert = require('assert');

const http2 = require('http2');

const server = http2.createServer(function(request, response) {
  console.log('responding to ' + request.url);

  response.writeHead(200, {'Content-Type': 'text/plain'});
  response.write('1\n');
  response.write('');
  response.write('2\n');
  response.write('');
  response.end('3\n');

  this.close();
});

server.listen(0, common.mustCall(function() {
  const client = http2.connect(`http://localhost:${this.address().port}`);

  const headers = { ':path': '/' };
  const req = client.request(headers).setEncoding('ascii');

  let response = '';

  req.on('response', (headers) => {
    assert.strictEqual(200, headers[':status']);
  });

  req.on('data', function(chunk) {
    response += chunk;
  });

  req.on('end', common.mustCall(function(a,b,c) {
    assert.strictEqual('1\n2\n3\n', response);
  }));

  req.end();
}));

fails with:

assert.js:86
  throw new assert.AssertionError({
  ^
AssertionError: 200 === '200'
    at ClientHttp2Stream.req.on (/Users/robert/projects/http2/test/parallel/test-http2-write-empty-string.js:30:12)
    at emitTwo (events.js:125:13)
    at ClientHttp2Stream.emit (events.js:213:7)
    at Http2Session.onSessionHeaders [as onheaders] (internal/http2/core.js:194:12)

Http2Session::destroy doesn't destroy associated socket

Http2Session::destroy doesn't call destroy on its socket, so in order to close a connection completely on the client side, socket.destroy() must be called on the socket exposed by the Http2Session object.

I noticed that socket.destroy calls destroy on its parent session (I would've expected the other way around). Is there a reason for doing this?

Cannot find res.createPushResponse() in Http2Response.

  • v8.0.0-pre:
  • Darwin:

Thanks for your nice work.

Seems that the doc for the http2 is not updated, I know that the http2 module itself implemented as a separate module named http2 but cannot find the res.createPushResponse method. Can you please help me?

Thanks again.

TODOs

  • Check in nghttp2 deps, initial build support
  • Begin src/node_http2.cc and src/node_http2.h glue code
  • Begin lib/internal/http2.js implementation
  • Basic server
  • Graceful server side connection shutdown
  • Server server timeout handling / or, how to know when the server can shut down the socket
  • Are we leaking any memory?
  • Tests tests test tests
  • Benchmarks
  • Documentation

Test List

cc: @jasnell, @mcollina, @addaleax

I start working on the test list today, I will be updating the list while gathering more information. I'm open the issue that way everyone can give feedback about what should be in/out/priority, etc...

Test List

  • Errors conditions (James list)
  • Server with connections that prematurely exists (James list)
  • Basic server with configuration options set (James list)
  • Server that responds with a file (pipe test) (James list)
  • Basic server with simple async response (James list)
  • Basic server with and without TLS. Create server instance, start listening, accept request with simple sync response (James list)
  • Server client error
  • Response Status code
  • HTTP Methods
  • Invalid (URLs and headers fields)
  • uncaughtException
  • Default values (port, encoding, method, headers)
  • Connect (request, response, length)
  • DNS error

Client

  • abort event
  • abort
  • aborted event
  • agent
  • check HTTP token
  • default headers exist
  • default
  • encoding
  • get URL
  • keep alive release before the finish
  • parse error
  • pipe end
  • read in error
  • readable
  • reject chunked with content length
  • response domain

tests not passing

=== release test-async-wrap-check-providers ===
Path: parallel/test-async-wrap-check-providers
Not all keys have been used:
[ 'HTTP2SESSION', 'HTTP2STREAM' ]

assert.js:85
  throw new assert.AssertionError({
  ^
AssertionError: 2 === 0
    at process.<anonymous> (/Users/matteo/Repositories/http2/test/parallel/test-async-wrap-check-providers.js:122:12)
    at emitOne (events.js:101:20)
    at process.emit (events.js:188:7)
Command: out/Release/node /Users/matteo/Repositories/http2/test/parallel/test-async-wrap-check-providers.js
=== release test-process-versions ===
Path: parallel/test-process-versions
assert.js:85
  throw new assert.AssertionError({
  ^
AssertionError: [ 'ares',
  'cldr',
  'http_parser',
  'icu',
  'modules',
  'nghttp2',
  'node',
  'openssl',
  'tz',
  'unicode',
  'uv',
  'v deepStrictEqual [ 'ares',
  'cldr',
  'http_parser',
  'icu',
  'modules',
  'node',
  'openssl',
  'tz',
  'unicode',
  'uv',
  'v8',
  'zlib'
    at Object.<anonymous> (/Users/matteo/Repositories/http2/test/parallel/test-process-versions.js:22:8)
    at Module._compile (module.js:573:32)
    at Object.Module._extensions..js (module.js:582:10)
    at Module.load (module.js:490:32)
    at tryModuleLoad (module.js:449:12)
    at Function.Module._load (module.js:441:3)
    at Module.runMain (module.js:607:10)
    at run (bootstrap_node.js:420:7)
    at startup (bootstrap_node.js:139:9)
    at bootstrap_node.js:535:3
Command: out/Release/node /Users/matteo/Repositories/http2/test/parallel/test-process-versions.js
[02:00|% 100|+ 1276|-   2]: Done
make: *** [test] Error 1

Requesting write access

Would it be possible for me to get write access to this repo so that I can merge approved PRs?

http2: HTTP 1 connection upgrade path

In the current http/1 implementation, support for detecting an HTTP/2 upgrade request can be added. This would take two forms: 1. when setting up an HTTPS server, detect the ALPN h2 option, and 2. when setting up an HTTP (plaintext) server, detecting the upgrade request. If either of these are detected, then either the existing upgrade event, or a new upgrade-http2 event on the server can be triggered, allowing handing off of the socket to the http2 implementation. It ought to be possible to simply attach the socket to a new Http2Session object then go from there.

(description above added by @jasnell)

cc @jasnell @mikeal

Process notes

Now that we have quite a few more people looking at this and looking to contribute, we should start formalizing the process. I talked about some of this at the collaborator summit meeting yesterday, so I apologize if it's a repeat for some of you.

  1. Up to this point, it's largely been @mcollina and I working on this so we hadn't been following a more formal review and sign off process. Now that there are more of us, we'll do the sign off on PRs like we do in core. We may not need to wait the full 48 hours to land stuff, but we still will need sign off before landing things.

  2. Force pushes to master will happen. I will only do these when either (a) rebasing nodejs/http2 master with nodejs/node master to keep things up to date or (b) squashing commits to clean up the history (see item 3 below).

  3. For the most part, we're going to start maintaining separate commits rather than squashing those down like we have been. This will ensure a proper history to be maintained, which will be important once we get around to opening the PR to nodejs/master. That said, there are no doubt going to be smaller commits that can be squashed (usually small trivial type fixes). If you're ok with your commits being squashed into the history. Put (Squash) in some way in the commit message and I'll use that as a guide.

  4. We have the nodejs/http2 team that will have commit rights to this repo. If you'd like to join that team, let either myself or @mcollina know and we'll get you added.

  5. A number of tracking issues with the outstanding todos have been opened following the discussion at collab summit yesterday. These do not yet have a lot of detail in them and I will be working to fill out that detail. These will be he ideal areas of jumping in to help. If you'd like to work on a particular area, please drop a comment into the thread so that others know what you're working on in order to avoid accidentally duplicating work.

  6. I will be scheduling a weekly status hangout to discuss ongoing progress. I have no idea what times will work yet. Expect a doodle poll to be posted.

How do I get http2 session ?

I would like to write some tests about http2 session, but I don't understand how to get the session from http2 server.

according to implementation guide, we have the following example codes.

const session = getSessionSomehow();
const socket = getSocketSomehow();
session.on('send', (buffer) => socket.write(buffer));

if the API does not exist yet, I will send other PR.

  • Version:
  • Platform:
  • Subsystem:
    http2

missing unit tests

I think we should track down all the part of the APIs and tests that needs to be added.
Having a list of unit tests that we want to cover makes easier for others to contribute.

stream.respond() not ordering :status header correctly

This works:

 function onStream (stream) {
  stream.respond({
    ':status': 200,
    'content-type': 'text/html'
  })
  stream.end('<html><head></head><body><h1>this is some data</h2></body></html>');
}

This doesn't:

function onStream (stream) {
  stream.respond({
    'content-type': 'text/html',
    ':status': 200
  })
  stream.end('<html><head></head><body><h1>this is some data</h2></body></html>');
}

This is the output

$ nghttp -v http://localhost:8000/hello
[  0.003] Connected
[  0.003] send SETTINGS frame <length=12, flags=0x00, stream_id=0>
          (niv=2)
          [SETTINGS_MAX_CONCURRENT_STREAMS(0x03):100]
          [SETTINGS_INITIAL_WINDOW_SIZE(0x04):65535]
[  0.003] send PRIORITY frame <length=5, flags=0x00, stream_id=3>
          (dep_stream_id=0, weight=201, exclusive=0)
[  0.003] send PRIORITY frame <length=5, flags=0x00, stream_id=5>
          (dep_stream_id=0, weight=101, exclusive=0)
[  0.003] send PRIORITY frame <length=5, flags=0x00, stream_id=7>
          (dep_stream_id=0, weight=1, exclusive=0)
[  0.003] send PRIORITY frame <length=5, flags=0x00, stream_id=9>
          (dep_stream_id=7, weight=1, exclusive=0)
[  0.003] send PRIORITY frame <length=5, flags=0x00, stream_id=11>
          (dep_stream_id=3, weight=1, exclusive=0)
[  0.003] send HEADERS frame <length=44, flags=0x25, stream_id=13>
          ; END_STREAM | END_HEADERS | PRIORITY
          (padlen=0, dep_stream_id=11, weight=16, exclusive=0)
          ; Open new stream
          :method: GET
          :path: /hello
          :scheme: http
          :authority: localhost:8000
          accept: */*
          accept-encoding: gzip, deflate
          user-agent: nghttp2/1.17.0
[  0.007] recv SETTINGS frame <length=0, flags=0x00, stream_id=0>
          (niv=0)
[  0.007] recv SETTINGS frame <length=0, flags=0x01, stream_id=0>
          ; ACK
          (niv=0)
[  0.007] send SETTINGS frame <length=0, flags=0x01, stream_id=0>
          ; ACK
          (niv=0)
[  0.016] recv (stream_id=13) content-type: text/html
[  0.016] [ERROR] Invalid HTTP header field was received: frame type: 1, stream: 13, name: [:status], value: [200]
[  0.016] [INVALID; error=Invalid HTTP header field was received] recv HEADERS frame <length=34, flags=0x04, stream_id=13>
          ; END_HEADERS
          (padlen=0)
          ; First response header
[  0.016] send RST_STREAM frame <length=4, flags=0x00, stream_id=13>
          (error_code=PROTOCOL_ERROR(0x01))
[  0.016] send GOAWAY frame <length=8, flags=0x00, stream_id=0>
          (last_stream_id=0, error_code=NO_ERROR(0x00), opaque_data(0)=[])
Some requests were not processed. total=1, processed=0

cc @jasnell I think we should send :status before everything

http2: cookies

The set-cookie header may appear multiple times. Its values should be handled as an Array in all response header methods.

HTTP2 docs

We should start working on docs, as it would be easier to onboard new collabs.
Also, docs would show inconsistencies in the API, so it's a good idea overall.

delayed open scenario

I'm trying to add "delayed open" scenario, and I am trying to create an Http2Stream before we have a connected socket.

I have a prototype that defers handle.consume(socket._handle._externalStream);, but then I get into:

    frame #0: 0x00000001009ab8b0 node`node::http2::Http2Session::Send(this=0x0000000103803400, buf=0x00000001023292d0, length=58) + 38 at node_http2.cc:697 [opt]
   694  void Http2Session::Send(uv_buf_t* buf,
   695                          size_t length) {
   696    // Do not attempt to write data if the stream is not alive or is closing
-> 697    if (stream_ == nullptr || !stream_->IsAlive() || stream_->IsClosing()) {
   698      return;
   699    }
   700

@jasnell do you think what I am trying to achieve is feasible?

Client hangs after first WINDOW_UPDATE

The client seems to hang sometimes after sending its first WINDOW_UPDATE frame, and this is most readily seen when it opens a single stream with a small initialWindowSize. In C++, DrainCallbacks isn't being called after the first window update frame is sent.

I think there is a race condition involved, given that opening multiple streams increases the likelihood that all streams will receive all of their data without hanging, probably because the interleaving gives each stream enough time to reset state or something.

Maybe this is related to #19?

http2: segfault in test-async-wrap-check-providers

On several of the linux images in CI, we're getting segfaults in test/parallel/test-async-wrap-check-providers: https://ci.nodejs.org/job/node-test-commit-linux/9842/nodes=ubuntu1610-x64/console

Partial test results
not ok 6 parallel/test-async-wrap-check-providers
  ---
  duration_ms: 0.711
  severity: fail
  stack: |-
    *** Error in `out/Release/node': free(): invalid pointer: 0x000055abb0dd4218 ***
    ======= Backtrace: =========
    /lib/x86_64-linux-gnu/libc.so.6(+0x790cb)[0x7f007c9970cb]
    /lib/x86_64-linux-gnu/libc.so.6(+0x8275a)[0x7f007c9a075a]
    /lib/x86_64-linux-gnu/libc.so.6(cfree+0x4c)[0x7f007c9a418c]
    out/Release/node(_ZN2v88internal11MemoryChunk20ReleaseOldToNewSlotsEv+0x16d)[0x55abae787d0d]
    out/Release/node(_ZN2v88internal11MemoryChunk22ReleaseAllocatedMemoryEv+0x52)[0x55abae787fa2]
    out/Release/node(_ZN2v88internal15MemoryAllocator17PerformFreeMemoryEPNS0_11MemoryChunkE+0x1b)[0x55abae78804b]
    out/Release/node(_ZN2v88internal10PagedSpace8TearDownEv+0x45)[0x55abae788825]
    out/Release/node(_ZN2v88internal8OldSpaceD0Ev+0x19)[0x55abae7229c9]
    out/Release/node(_ZN2v88internal4Heap8TearDownEv+0x2d7)[0x55abae737177]
    out/Release/node(_ZN2v88internal7Isolate6DeinitEv+0x1d9)[0x55abae8150a9]
    out/Release/node(_ZN2v88internal7Isolate8TearDownEv+0x53)[0x55abae8152f3]
    out/Release/node(_ZN4node5StartEP9uv_loop_siPKPKciS5_+0xdc7)[0x55abaed05a97]
    out/Release/node(_ZN4node5StartEiPPc+0x11c)[0x55abaed0034c]
    /lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xf1)[0x7f007c93e3f1]
    out/Release/node(_start+0x2a)[0x55abae09fa1a]
    ======= Memory map: ========
    acbb9880000-acbb9900000 ---p 00000000 00:00 0 
    c2e1ba00000-c2e1ba80000 ---p 00000000 00:00 0 
    100d88880000-100d88885000 rw-p 00000000 00:00 0 
    100d88885000-100d88900000 ---p 00000000 00:00 0 
    105e49387000-105e49580000 ---p 00000000 00:00 0 
    105e49580000-105e49583000 rw-p 00000000 00:00 0 
    105e49583000-105e49584000 ---p 00000000 00:00 0 
    105e49584000-105e495fe000 rwxp 00000000 00:00 0 
    105e495fe000-105e49600000 ---p 00000000 00:00 0 
    105e49600000-105e49603000 rw-p 00000000 00:00 0 
    105e49603000-105e49604000 ---p 00000000 00:00 0 
    105e49604000-105e49674000 rwxp 00000000 00:00 0 
    105e49674000-105e49680000 ---p 00000000 00:00 0 
    105e49680000-105e49683000 rw-p 00000000 00:00 0 
    105e49683000-105e49684000 ---p 00000000 00:00 0 
    105e49684000-105e496ff000 rwxp 00000000 00:00 0 
    105e496ff000-105e49700000 ---p 00000000 00:00 0 
    105e49700000-105e49703000 rw-p 00000000 00:00 0 
    105e49703000-105e49704000 ---p 00000000 00:00 0 
    105e49704000-105e4977f000 rwxp 00000000 00:00 0 
    105e4977f000-105e69387000 ---p 00000000 00:00 0 
    15d002e00000-15d002e80000 ---p 00000000 00:00 0 
    1a7f63400000-1a7f63480000 ---p 00000000 00:00 0 
    1e9256500000-1e9256580000 ---p 00000000 00:00 0 
    230d93f80000-230d94000000 ---p 00000000 00:00 0 
    24363b500000-24363b580000 rw-p 00000000 00:00 0 
    305658b00000-305658b80000 ---p 00000000 00:00 0 
    34938d480000-34938d500000 rw-p 00000000 00:00 0 
    370310c53000-370310c54000 ---p 00000000 00:00 0 
    370310c54000-370310c5c000 rw-p 00000000 00:00 0 
    370310c5c000-370310c5f000 ---p 00000000 00:00 0 
    3de472d80000-3de472e00000 ---p 00000000 00:00 0 
    55abadafd000-55abaf993000 r-xp 00000000 fd:01 1074288                    /home/iojs/build/workspace/node-test-commit-linux/nodes/ubuntu1610-x64/out/Release/node
    55abafb93000-55abafc1d000 r--p 01e96000 fd:01 1074288                    /home/iojs/build/workspace/node-test-commit-linux/nodes/ubuntu1610-x64/out/Release/node
    55abafc1d000-55abafc37000 rw-p 01f20000 fd:01 1074288                    /home/iojs/build/workspace/node-test-commit-linux/nodes/ubuntu1610-x64/out/Release/node
    55abafc37000-55abafc50000 rw-p 00000000 00:00 0 
    55abb0bb5000-55abb0e19000 rw-p 00000000 00:00 0                          [heap]
    7f005c000000-7f005c021000 rw-p 00000000 00:00 0 
    7f005c021000-7f0060000000 ---p 00000000 00:00 0 
    7f0060000000-7f0060021000 rw-p 00000000 00:00 0 
    7f0060021000-7f0064000000 ---p 00000000 00:00 0 
    7f0064000000-7f0064021000 rw-p 00000000 00:00 0 
    7f0064021000-7f0068000000 ---p 00000000 00:00 0 
    7f0068000000-7f0068021000 rw-p 00000000 00:00 0 
    7f0068021000-7f006c000000 ---p 00000000 00:00 0 
    7f006c000000-7f006c021000 rw-p 00000000 00:00 0 
    7f006c021000-7f0070000000 ---p 00000000 00:00 0 
    7f0070000000-7f0070021000 rw-p 00000000 00:00 0 
    7f0070021000-7f0074000000 ---p 00000000 00:00 0 
    7f0074000000-7f0074021000 rw-p 00000000 00:00 0 
    7f0074021000-7f0078000000 ---p 00000000 00:00 0 
    7f0078704000-7f007870f000 r-xp 00000000 fd:01 24067                      /lib/x86_64-linux-gnu/libnss_files-2.24.so
    7f007870f000-7f007890e000 ---p 0000b000 fd:01 24067                      /lib/x86_64-linux-gnu/libnss_files-2.24.so
    7f007890e000-7f007890f000 r--p 0000a000 fd:01 24067                      /lib/x86_64-linux-gnu/libnss_files-2.24.so
    7f007890f000-7f0078910000 rw-p 0000b000 fd:01 24067                      /lib/x86_64-linux-gnu/libnss_files-2.24.so
    7f0078910000-7f0078916000 rw-p 00000000 00:00 0 
    7f0078916000-7f0078917000 ---p 00000000 00:00 0 
    7f0078917000-7f0079117000 rw-p 00000000 00:00 0 
    7f0079117000-7f0079118000 ---p 00000000 00:00 0 
    7f0079118000-7f0079918000 rw-p 00000000 00:00 0 
    7f0079918000-7f0079919000 ---p 00000000 00:00 0 
    7f0079919000-7f007a119000 rw-p 00000000 00:00 0 
    7f007a119000-7f007a11a000 ---p 00000000 00:00 0 
    7f007a11a000-7f007a91a000 rw-p 00000000 00:00 0 
    7f007a91a000-7f007a91b000 ---p 00000000 00:00 0 
    7f007a91b000-7f007b11b000 rw-p 00000000 00:00 0 
    7f007b11b000-7f007b11c000 ---p 00000000 00:00 0 
    7f007b11c000-7f007b91c000 rw-p 00000000 00:00 0 
    7f007b91c000-7f007b91d000 ---p 00000000 00:00 0 
    7f007b91d000-7f007c11d000 rw-p 00000000 00:00 0 
    7f007c11d000-7f007c11e000 ---p 00000000 00:00 0 
    7f007c11e000-7f007c91e000 rw-p 00000000 00:00 0 
    7f007c91e000-7f007cadb000 r-xp 00000000 fd:01 24057                      /lib/x86_64-linux-gnu/libc-2.24.so
    7f007cadb000-7f007ccdb000 ---p 001bd000 fd:01 24057                      /lib/x86_64-linux-gnu/libc-2.24.so
    7f007ccdb000-7f007ccdf000 r--p 001bd000 fd:01 24057                      /lib/x86_64-linux-gnu/libc-2.24.so
    7f007ccdf000-7f007cce1000 rw-p 001c1000 fd:01 24057                      /lib/x86_64-linux-gnu/libc-2.24.so
    7f007cce1000-7f007cce5000 rw-p 00000000 00:00 0 
    7f007cce5000-7f007ccfd000 r-xp 00000000 fd:01 24072                      /lib/x86_64-linux-gnu/libpthread-2.24.so
    7f007ccfd000-7f007cefd000 ---p 00018000 fd:01 24072                      /lib/x86_64-linux-gnu/libpthread-2.24.so
    7f007cefd000-7f007cefe000 r--p 00018000 fd:01 24072                      /lib/x86_64-linux-gnu/libpthread-2.24.so
    7f007cefe000-7f007ceff000 rw-p 00019000 fd:01 24072                      /lib/x86_64-linux-gnu/libpthread-2.24.so
    7f007ceff000-7f007cf03000 rw-p 00000000 00:00 0 
    7f007cf03000-7f007cf19000 r-xp 00000000 fd:01 1908                       /lib/x86_64-linux-gnu/libgcc_s.so.1
    7f007cf19000-7f007d118000 ---p 00016000 fd:01 1908                       /lib/x86_64-linux-gnu/libgcc_s.so.1
    7f007d118000-7f007d119000 r--p 00015000 fd:01 1908                       /lib/x86_64-linux-gnu/libgcc_s.so.1
    7f007d119000-7f007d11a000 rw-p 00016000 fd:01 1908                       /lib/x86_64-linux-gnu/libgcc_s.so.1
    7f007d11a000-7f007d222000 r-xp 00000000 fd:01 24061                      /lib/x86_64-linux-gnu/libm-2.24.so
    7f007d222000-7f007d421000 ---p 00108000 fd:01 24061                      /lib/x86_64-linux-gnu/libm-2.24.so
    7f007d421000-7f007d422000 r--p 00107000 fd:01 24061                      /lib/x86_64-linux-gnu/libm-2.24.so
    7f007d422000-7f007d423000 rw-p 00108000 fd:01 24061                      /lib/x86_64-linux-gnu/libm-2.24.so
    7f007d423000-7f007d59b000 r-xp 00000000 fd:01 6389                       /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.22
    7f007d59b000-7f007d79b000 ---p 00178000 fd:01 6389                       /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.22
    7f007d79b000-7f007d7a5000 r--p 00178000 fd:01 6389                       /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.22
    7f007d7a5000-7f007d7a7000 rw-p 00182000 fd:01 6389                       /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.22
    7f007d7a7000-7f007d7ab000 rw-p 00000000 00:00 0 
    7f007d7ab000-7f007d7b2000 r-xp 00000000 fd:01 24074                      /lib/x86_64-linux-gnu/librt-2.24.so
    7f007d7b2000-7f007d9b1000 ---p 00007000 fd:01 24074                      /lib/x86_64-linux-gnu/librt-2.24.so
    7f007d9b1000-7f007d9b2000 r--p 00006000 fd:01 24074                      /lib/x86_64-linux-gnu/librt-2.24.so
    7f007d9b2000-7f007d9b3000 rw-p 00007000 fd:01 24074                      /lib/x86_64-linux-gnu/librt-2.24.so
    7f007d9b3000-7f007d9b6000 r-xp 00000000 fd:01 24060                      /lib/x86_64-linux-gnu/libdl-2.24.so
    7f007d9b6000-7f007dbb5000 ---p 00003000 fd:01 24060                      /lib/x86_64-linux-gnu/libdl-2.24.so
    7f007dbb5000-7f007dbb6000 r--p 00002000 fd:01 24060                      /lib/x86_64-linux-gnu/libdl-2.24.so
    7f007dbb6000-7f007dbb7000 rw-p 00003000 fd:01 24060                      /lib/x86_64-linux-gnu/libdl-2.24.so
    7f007dbb7000-7f007dbdc000 r-xp 00000000 fd:01 24053                      /lib/x86_64-linux-gnu/ld-2.24.so
    7f007ddca000-7f007ddd0000 rw-p 00000000 00:00 0 
    7f007ddd3000-7f007ddd4000 rw-p 00000000 00:00 0 
    7f007ddd4000-7f007ddd5000 ---p 00000000 00:00 0 
    7f007ddd5000-7f007dddb000 rw-p 00000000 00:00 0 
    7f007dddb000-7f007dddc000 r--p 00024000 fd:01 24053                      /lib/x86_64-linux-gnu/ld-2.24.so
    7f007dddc000-7f007dddd000 rw-p 00025000 fd:01 24053                      /lib/x86_64-linux-gnu/ld-2.24.so
    7f007dddd000-7f007ddde000 rw-p 00000000 00:00 0 
    7ffcb3126000-7ffcb3147000 rw-p 00000000 00:00 0                          [stack]
    7ffcb3164000-7ffcb3166000 r--p 00000000 00:00 0                          [vvar]
    7ffcb3166000-7ffcb3168000 r-xp 00000000 00:00 0                          [vdso]
    ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0                  [vsyscall]
  ...

http2: get path throws

To me it looks getting the path and/or headers is broken:

internal/http2/compat.js:253
    return headers.get(constants.HTTP2_HEADER_PATH);
                  ^

TypeError: Cannot read property 'get' of undefined
    at Http2ServerRequest.get path [as path] (internal/http2/compat.js:253:19)
    at Http2Server.http2.createServer (/Users/robert/projects/http2/test/parallel/test-http2-set-cookies.js:31:18)
    at emitTwo (events.js:125:13)
    at Http2Server.emit (events.js:213:7)
    at Http2Server.onServerStream (internal/http2/compat.js:501:10)
    at emitThree (events.js:135:13)
    at Http2Server.emit (events.js:216:7)
    at Http2Session.sessionOnStream (internal/http2/core.js:1035:10)
    at emitThree (events.js:135:13)
    at Http2Session.emit (events.js:216:7)

still haven't found out if the client doesn't send a path in general or if the issue is on the server side

'use strict';
require('../common');
const assert = require('assert');
const http2 = require('http2');

const server = http2.createServer((req, res) => {
  console.log(req.path)
});
server.listen(0);

server.on('listening', function() {
  const client = http2.connect(`http://localhost:${this.address().port}`);

  const headers = { ':path': '/' };
  const req = client.request(headers).setEncoding('utf8');
});

process.on('exit', function() {
  assert.strictEqual(2, nresponses);
});

depends on #75 -- without #75 a request crashes with:

internal/http2/compat.js:282
    this[kHeaders] = linkedList.create();
                                ^

TypeError: linkedList.create is not a function
    at new Http2ServerResponse (internal/http2/compat.js:282:33)
    at Http2Server.onServerStream (internal/http2/compat.js:456:5)
    at emitThree (events.js:135:13)
    at Http2Server.emit (events.js:216:7)
    at Http2Session.sessionOnStream (internal/http2/core.js:1035:10)
    at emitThree (events.js:135:13)
    at Http2Session.emit (events.js:216:7)
    at Http2Session.onSessionHeaders [as onheaders] (internal/http2/core.js:104:11)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.