http2: introducing HTTP/2
At long last: The initial *experimental* implementation of HTTP/2.
This is an accumulation of the work that has been done in the nodejs/http2
repository, squashed down to a couple of commits. The original commit
history has been preserved in the nodejs/http2 repository.
This PR introduces the nghttp2 C library as a new dependency. This library
provides the majority of the HTTP/2 protocol implementation, with the rest
of the code here providing the mapping of the library into a usable JS API.
Within src, a handful of new node_http2_*.c and node_http2_*.h files are
introduced. These provide the internal mechanisms that interface with nghttp
and define the `process.binding('http2')` interface.
The JS API is defined within `internal/http2/*.js`.
There are two APIs provided: Core and Compat.
The Core API is HTTP/2 specific and is designed to be as minimal and as
efficient as possible.
The Compat API is intended to be as close to the existing HTTP/1 API as
possible, with some exceptions.
Tests, documentation and initial benchmarks are included.
The `http2` module is gated by a new `--expose-http2` command line flag.
When used, `require('http2')` will be exposed to users. Note that there
is an existing `http2` module on npm that would be impacted by the introduction
of this module, which is the main reason for gating this behind a flag.
When using `require('http2')` the first time, a process warning will be
emitted indicating that an experimental feature is being used.
To run the benchmarks, the `h2load` tool (part of the nghttp project) is
required: `./node benchmarks/http2/simple.js benchmarker=h2load`. Only
two benchmarks are currently available.
Additional configuration options to enable verbose debugging are provided:
```
$ ./configure --debug-http2 --debug-nghttp2
$ NODE_DEBUG=http2 ./node
```
The `--debug-http2` configuration option enables verbose debug statements
from the `src/node_http2_*` files. The `--debug-nghttp2` enables the nghttp
library's own verbose debug output. The `NODE_DEBUG=http2` enables JS-level
debug output.
The following illustrates as simple HTTP/2 server and client interaction:
(The HTTP/2 client and server support both plain text and TLS connections)
```jt client = http2.connect('http://localhost:80');
const req = client.request({ ':path': '/some/path' });
req.on('data', (chunk) => { /* do something with the data */ });
req.on('end', () => {
client.destroy();
});
// Plain text (non-TLS server)
const server = http2.createServer();
server.on('stream', (stream, requestHeaders) => {
stream.respond({ ':status': 200 });
stream.write('hello ');
stream.end('world');
});
server.listen(80);
```
```js
const http2 = require('http2');
const client = http2.connect('http://localhost');
```
Author: Anna Henningsen <anna@addaleax.net>
Author: Colin Ihrig <cjihrig@gmail.com>
Author: Daniel Bevenius <daniel.bevenius@gmail.com>
Author: James M Snell <jasnell@gmail.com>
Author: Jun Mukai
Author: Kelvin Jin
Author: Matteo Collina <matteo.collina@gmail.com>
Author: Robert Kowalski <rok@kowalski.gd>
Author: Santiago Gimeno <santiago.gimeno@gmail.com>
Author: Sebastiaan Deckers <sebdeckers83@gmail.com>
Author: Yosuke Furukawa <yosuke.furukawa@gmail.com>
PR-URL: https://github.com/nodejs/node/pull/14239
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
8 years ago
|
|
|
'use strict';
|
|
|
|
|
|
|
|
const binding = process.binding('http2');
|
|
|
|
const errors = require('internal/errors');
|
|
|
|
|
|
|
|
const {
|
|
|
|
NGHTTP2_SESSION_CLIENT,
|
|
|
|
NGHTTP2_SESSION_SERVER,
|
|
|
|
|
http2: introducing HTTP/2
At long last: The initial *experimental* implementation of HTTP/2.
This is an accumulation of the work that has been done in the nodejs/http2
repository, squashed down to a couple of commits. The original commit
history has been preserved in the nodejs/http2 repository.
This PR introduces the nghttp2 C library as a new dependency. This library
provides the majority of the HTTP/2 protocol implementation, with the rest
of the code here providing the mapping of the library into a usable JS API.
Within src, a handful of new node_http2_*.c and node_http2_*.h files are
introduced. These provide the internal mechanisms that interface with nghttp
and define the `process.binding('http2')` interface.
The JS API is defined within `internal/http2/*.js`.
There are two APIs provided: Core and Compat.
The Core API is HTTP/2 specific and is designed to be as minimal and as
efficient as possible.
The Compat API is intended to be as close to the existing HTTP/1 API as
possible, with some exceptions.
Tests, documentation and initial benchmarks are included.
The `http2` module is gated by a new `--expose-http2` command line flag.
When used, `require('http2')` will be exposed to users. Note that there
is an existing `http2` module on npm that would be impacted by the introduction
of this module, which is the main reason for gating this behind a flag.
When using `require('http2')` the first time, a process warning will be
emitted indicating that an experimental feature is being used.
To run the benchmarks, the `h2load` tool (part of the nghttp project) is
required: `./node benchmarks/http2/simple.js benchmarker=h2load`. Only
two benchmarks are currently available.
Additional configuration options to enable verbose debugging are provided:
```
$ ./configure --debug-http2 --debug-nghttp2
$ NODE_DEBUG=http2 ./node
```
The `--debug-http2` configuration option enables verbose debug statements
from the `src/node_http2_*` files. The `--debug-nghttp2` enables the nghttp
library's own verbose debug output. The `NODE_DEBUG=http2` enables JS-level
debug output.
The following illustrates as simple HTTP/2 server and client interaction:
(The HTTP/2 client and server support both plain text and TLS connections)
```jt client = http2.connect('http://localhost:80');
const req = client.request({ ':path': '/some/path' });
req.on('data', (chunk) => { /* do something with the data */ });
req.on('end', () => {
client.destroy();
});
// Plain text (non-TLS server)
const server = http2.createServer();
server.on('stream', (stream, requestHeaders) => {
stream.respond({ ':status': 200 });
stream.write('hello ');
stream.end('world');
});
server.listen(80);
```
```js
const http2 = require('http2');
const client = http2.connect('http://localhost');
```
Author: Anna Henningsen <anna@addaleax.net>
Author: Colin Ihrig <cjihrig@gmail.com>
Author: Daniel Bevenius <daniel.bevenius@gmail.com>
Author: James M Snell <jasnell@gmail.com>
Author: Jun Mukai
Author: Kelvin Jin
Author: Matteo Collina <matteo.collina@gmail.com>
Author: Robert Kowalski <rok@kowalski.gd>
Author: Santiago Gimeno <santiago.gimeno@gmail.com>
Author: Sebastiaan Deckers <sebdeckers83@gmail.com>
Author: Yosuke Furukawa <yosuke.furukawa@gmail.com>
PR-URL: https://github.com/nodejs/node/pull/14239
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
8 years ago
|
|
|
HTTP2_HEADER_STATUS,
|
|
|
|
HTTP2_HEADER_METHOD,
|
|
|
|
HTTP2_HEADER_AUTHORITY,
|
|
|
|
HTTP2_HEADER_SCHEME,
|
|
|
|
HTTP2_HEADER_PATH,
|
|
|
|
HTTP2_HEADER_ACCESS_CONTROL_ALLOW_CREDENTIALS,
|
|
|
|
HTTP2_HEADER_ACCESS_CONTROL_MAX_AGE,
|
|
|
|
HTTP2_HEADER_ACCESS_CONTROL_REQUEST_METHOD,
|
http2: introducing HTTP/2
At long last: The initial *experimental* implementation of HTTP/2.
This is an accumulation of the work that has been done in the nodejs/http2
repository, squashed down to a couple of commits. The original commit
history has been preserved in the nodejs/http2 repository.
This PR introduces the nghttp2 C library as a new dependency. This library
provides the majority of the HTTP/2 protocol implementation, with the rest
of the code here providing the mapping of the library into a usable JS API.
Within src, a handful of new node_http2_*.c and node_http2_*.h files are
introduced. These provide the internal mechanisms that interface with nghttp
and define the `process.binding('http2')` interface.
The JS API is defined within `internal/http2/*.js`.
There are two APIs provided: Core and Compat.
The Core API is HTTP/2 specific and is designed to be as minimal and as
efficient as possible.
The Compat API is intended to be as close to the existing HTTP/1 API as
possible, with some exceptions.
Tests, documentation and initial benchmarks are included.
The `http2` module is gated by a new `--expose-http2` command line flag.
When used, `require('http2')` will be exposed to users. Note that there
is an existing `http2` module on npm that would be impacted by the introduction
of this module, which is the main reason for gating this behind a flag.
When using `require('http2')` the first time, a process warning will be
emitted indicating that an experimental feature is being used.
To run the benchmarks, the `h2load` tool (part of the nghttp project) is
required: `./node benchmarks/http2/simple.js benchmarker=h2load`. Only
two benchmarks are currently available.
Additional configuration options to enable verbose debugging are provided:
```
$ ./configure --debug-http2 --debug-nghttp2
$ NODE_DEBUG=http2 ./node
```
The `--debug-http2` configuration option enables verbose debug statements
from the `src/node_http2_*` files. The `--debug-nghttp2` enables the nghttp
library's own verbose debug output. The `NODE_DEBUG=http2` enables JS-level
debug output.
The following illustrates as simple HTTP/2 server and client interaction:
(The HTTP/2 client and server support both plain text and TLS connections)
```jt client = http2.connect('http://localhost:80');
const req = client.request({ ':path': '/some/path' });
req.on('data', (chunk) => { /* do something with the data */ });
req.on('end', () => {
client.destroy();
});
// Plain text (non-TLS server)
const server = http2.createServer();
server.on('stream', (stream, requestHeaders) => {
stream.respond({ ':status': 200 });
stream.write('hello ');
stream.end('world');
});
server.listen(80);
```
```js
const http2 = require('http2');
const client = http2.connect('http://localhost');
```
Author: Anna Henningsen <anna@addaleax.net>
Author: Colin Ihrig <cjihrig@gmail.com>
Author: Daniel Bevenius <daniel.bevenius@gmail.com>
Author: James M Snell <jasnell@gmail.com>
Author: Jun Mukai
Author: Kelvin Jin
Author: Matteo Collina <matteo.collina@gmail.com>
Author: Robert Kowalski <rok@kowalski.gd>
Author: Santiago Gimeno <santiago.gimeno@gmail.com>
Author: Sebastiaan Deckers <sebdeckers83@gmail.com>
Author: Yosuke Furukawa <yosuke.furukawa@gmail.com>
PR-URL: https://github.com/nodejs/node/pull/14239
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
8 years ago
|
|
|
HTTP2_HEADER_AGE,
|
|
|
|
HTTP2_HEADER_AUTHORIZATION,
|
|
|
|
HTTP2_HEADER_CONTENT_ENCODING,
|
|
|
|
HTTP2_HEADER_CONTENT_LANGUAGE,
|
|
|
|
HTTP2_HEADER_CONTENT_LENGTH,
|
|
|
|
HTTP2_HEADER_CONTENT_LOCATION,
|
|
|
|
HTTP2_HEADER_CONTENT_MD5,
|
|
|
|
HTTP2_HEADER_CONTENT_RANGE,
|
|
|
|
HTTP2_HEADER_CONTENT_TYPE,
|
|
|
|
HTTP2_HEADER_COOKIE,
|
|
|
|
HTTP2_HEADER_DATE,
|
|
|
|
HTTP2_HEADER_DNT,
|
http2: introducing HTTP/2
At long last: The initial *experimental* implementation of HTTP/2.
This is an accumulation of the work that has been done in the nodejs/http2
repository, squashed down to a couple of commits. The original commit
history has been preserved in the nodejs/http2 repository.
This PR introduces the nghttp2 C library as a new dependency. This library
provides the majority of the HTTP/2 protocol implementation, with the rest
of the code here providing the mapping of the library into a usable JS API.
Within src, a handful of new node_http2_*.c and node_http2_*.h files are
introduced. These provide the internal mechanisms that interface with nghttp
and define the `process.binding('http2')` interface.
The JS API is defined within `internal/http2/*.js`.
There are two APIs provided: Core and Compat.
The Core API is HTTP/2 specific and is designed to be as minimal and as
efficient as possible.
The Compat API is intended to be as close to the existing HTTP/1 API as
possible, with some exceptions.
Tests, documentation and initial benchmarks are included.
The `http2` module is gated by a new `--expose-http2` command line flag.
When used, `require('http2')` will be exposed to users. Note that there
is an existing `http2` module on npm that would be impacted by the introduction
of this module, which is the main reason for gating this behind a flag.
When using `require('http2')` the first time, a process warning will be
emitted indicating that an experimental feature is being used.
To run the benchmarks, the `h2load` tool (part of the nghttp project) is
required: `./node benchmarks/http2/simple.js benchmarker=h2load`. Only
two benchmarks are currently available.
Additional configuration options to enable verbose debugging are provided:
```
$ ./configure --debug-http2 --debug-nghttp2
$ NODE_DEBUG=http2 ./node
```
The `--debug-http2` configuration option enables verbose debug statements
from the `src/node_http2_*` files. The `--debug-nghttp2` enables the nghttp
library's own verbose debug output. The `NODE_DEBUG=http2` enables JS-level
debug output.
The following illustrates as simple HTTP/2 server and client interaction:
(The HTTP/2 client and server support both plain text and TLS connections)
```jt client = http2.connect('http://localhost:80');
const req = client.request({ ':path': '/some/path' });
req.on('data', (chunk) => { /* do something with the data */ });
req.on('end', () => {
client.destroy();
});
// Plain text (non-TLS server)
const server = http2.createServer();
server.on('stream', (stream, requestHeaders) => {
stream.respond({ ':status': 200 });
stream.write('hello ');
stream.end('world');
});
server.listen(80);
```
```js
const http2 = require('http2');
const client = http2.connect('http://localhost');
```
Author: Anna Henningsen <anna@addaleax.net>
Author: Colin Ihrig <cjihrig@gmail.com>
Author: Daniel Bevenius <daniel.bevenius@gmail.com>
Author: James M Snell <jasnell@gmail.com>
Author: Jun Mukai
Author: Kelvin Jin
Author: Matteo Collina <matteo.collina@gmail.com>
Author: Robert Kowalski <rok@kowalski.gd>
Author: Santiago Gimeno <santiago.gimeno@gmail.com>
Author: Sebastiaan Deckers <sebdeckers83@gmail.com>
Author: Yosuke Furukawa <yosuke.furukawa@gmail.com>
PR-URL: https://github.com/nodejs/node/pull/14239
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
8 years ago
|
|
|
HTTP2_HEADER_ETAG,
|
|
|
|
HTTP2_HEADER_EXPIRES,
|
|
|
|
HTTP2_HEADER_FROM,
|
|
|
|
HTTP2_HEADER_IF_MATCH,
|
|
|
|
HTTP2_HEADER_IF_NONE_MATCH,
|
|
|
|
HTTP2_HEADER_IF_MODIFIED_SINCE,
|
|
|
|
HTTP2_HEADER_IF_RANGE,
|
|
|
|
HTTP2_HEADER_IF_UNMODIFIED_SINCE,
|
|
|
|
HTTP2_HEADER_LAST_MODIFIED,
|
|
|
|
HTTP2_HEADER_LOCATION,
|
|
|
|
HTTP2_HEADER_MAX_FORWARDS,
|
|
|
|
HTTP2_HEADER_PROXY_AUTHORIZATION,
|
|
|
|
HTTP2_HEADER_RANGE,
|
|
|
|
HTTP2_HEADER_REFERER,
|
|
|
|
HTTP2_HEADER_RETRY_AFTER,
|
|
|
|
HTTP2_HEADER_SET_COOKIE,
|
|
|
|
HTTP2_HEADER_TK,
|
|
|
|
HTTP2_HEADER_UPGRADE_INSECURE_REQUESTS,
|
http2: introducing HTTP/2
At long last: The initial *experimental* implementation of HTTP/2.
This is an accumulation of the work that has been done in the nodejs/http2
repository, squashed down to a couple of commits. The original commit
history has been preserved in the nodejs/http2 repository.
This PR introduces the nghttp2 C library as a new dependency. This library
provides the majority of the HTTP/2 protocol implementation, with the rest
of the code here providing the mapping of the library into a usable JS API.
Within src, a handful of new node_http2_*.c and node_http2_*.h files are
introduced. These provide the internal mechanisms that interface with nghttp
and define the `process.binding('http2')` interface.
The JS API is defined within `internal/http2/*.js`.
There are two APIs provided: Core and Compat.
The Core API is HTTP/2 specific and is designed to be as minimal and as
efficient as possible.
The Compat API is intended to be as close to the existing HTTP/1 API as
possible, with some exceptions.
Tests, documentation and initial benchmarks are included.
The `http2` module is gated by a new `--expose-http2` command line flag.
When used, `require('http2')` will be exposed to users. Note that there
is an existing `http2` module on npm that would be impacted by the introduction
of this module, which is the main reason for gating this behind a flag.
When using `require('http2')` the first time, a process warning will be
emitted indicating that an experimental feature is being used.
To run the benchmarks, the `h2load` tool (part of the nghttp project) is
required: `./node benchmarks/http2/simple.js benchmarker=h2load`. Only
two benchmarks are currently available.
Additional configuration options to enable verbose debugging are provided:
```
$ ./configure --debug-http2 --debug-nghttp2
$ NODE_DEBUG=http2 ./node
```
The `--debug-http2` configuration option enables verbose debug statements
from the `src/node_http2_*` files. The `--debug-nghttp2` enables the nghttp
library's own verbose debug output. The `NODE_DEBUG=http2` enables JS-level
debug output.
The following illustrates as simple HTTP/2 server and client interaction:
(The HTTP/2 client and server support both plain text and TLS connections)
```jt client = http2.connect('http://localhost:80');
const req = client.request({ ':path': '/some/path' });
req.on('data', (chunk) => { /* do something with the data */ });
req.on('end', () => {
client.destroy();
});
// Plain text (non-TLS server)
const server = http2.createServer();
server.on('stream', (stream, requestHeaders) => {
stream.respond({ ':status': 200 });
stream.write('hello ');
stream.end('world');
});
server.listen(80);
```
```js
const http2 = require('http2');
const client = http2.connect('http://localhost');
```
Author: Anna Henningsen <anna@addaleax.net>
Author: Colin Ihrig <cjihrig@gmail.com>
Author: Daniel Bevenius <daniel.bevenius@gmail.com>
Author: James M Snell <jasnell@gmail.com>
Author: Jun Mukai
Author: Kelvin Jin
Author: Matteo Collina <matteo.collina@gmail.com>
Author: Robert Kowalski <rok@kowalski.gd>
Author: Santiago Gimeno <santiago.gimeno@gmail.com>
Author: Sebastiaan Deckers <sebdeckers83@gmail.com>
Author: Yosuke Furukawa <yosuke.furukawa@gmail.com>
PR-URL: https://github.com/nodejs/node/pull/14239
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
8 years ago
|
|
|
HTTP2_HEADER_USER_AGENT,
|
|
|
|
HTTP2_HEADER_X_CONTENT_TYPE_OPTIONS,
|
http2: introducing HTTP/2
At long last: The initial *experimental* implementation of HTTP/2.
This is an accumulation of the work that has been done in the nodejs/http2
repository, squashed down to a couple of commits. The original commit
history has been preserved in the nodejs/http2 repository.
This PR introduces the nghttp2 C library as a new dependency. This library
provides the majority of the HTTP/2 protocol implementation, with the rest
of the code here providing the mapping of the library into a usable JS API.
Within src, a handful of new node_http2_*.c and node_http2_*.h files are
introduced. These provide the internal mechanisms that interface with nghttp
and define the `process.binding('http2')` interface.
The JS API is defined within `internal/http2/*.js`.
There are two APIs provided: Core and Compat.
The Core API is HTTP/2 specific and is designed to be as minimal and as
efficient as possible.
The Compat API is intended to be as close to the existing HTTP/1 API as
possible, with some exceptions.
Tests, documentation and initial benchmarks are included.
The `http2` module is gated by a new `--expose-http2` command line flag.
When used, `require('http2')` will be exposed to users. Note that there
is an existing `http2` module on npm that would be impacted by the introduction
of this module, which is the main reason for gating this behind a flag.
When using `require('http2')` the first time, a process warning will be
emitted indicating that an experimental feature is being used.
To run the benchmarks, the `h2load` tool (part of the nghttp project) is
required: `./node benchmarks/http2/simple.js benchmarker=h2load`. Only
two benchmarks are currently available.
Additional configuration options to enable verbose debugging are provided:
```
$ ./configure --debug-http2 --debug-nghttp2
$ NODE_DEBUG=http2 ./node
```
The `--debug-http2` configuration option enables verbose debug statements
from the `src/node_http2_*` files. The `--debug-nghttp2` enables the nghttp
library's own verbose debug output. The `NODE_DEBUG=http2` enables JS-level
debug output.
The following illustrates as simple HTTP/2 server and client interaction:
(The HTTP/2 client and server support both plain text and TLS connections)
```jt client = http2.connect('http://localhost:80');
const req = client.request({ ':path': '/some/path' });
req.on('data', (chunk) => { /* do something with the data */ });
req.on('end', () => {
client.destroy();
});
// Plain text (non-TLS server)
const server = http2.createServer();
server.on('stream', (stream, requestHeaders) => {
stream.respond({ ':status': 200 });
stream.write('hello ');
stream.end('world');
});
server.listen(80);
```
```js
const http2 = require('http2');
const client = http2.connect('http://localhost');
```
Author: Anna Henningsen <anna@addaleax.net>
Author: Colin Ihrig <cjihrig@gmail.com>
Author: Daniel Bevenius <daniel.bevenius@gmail.com>
Author: James M Snell <jasnell@gmail.com>
Author: Jun Mukai
Author: Kelvin Jin
Author: Matteo Collina <matteo.collina@gmail.com>
Author: Robert Kowalski <rok@kowalski.gd>
Author: Santiago Gimeno <santiago.gimeno@gmail.com>
Author: Sebastiaan Deckers <sebdeckers83@gmail.com>
Author: Yosuke Furukawa <yosuke.furukawa@gmail.com>
PR-URL: https://github.com/nodejs/node/pull/14239
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
8 years ago
|
|
|
|
|
|
|
HTTP2_HEADER_CONNECTION,
|
|
|
|
HTTP2_HEADER_UPGRADE,
|
|
|
|
HTTP2_HEADER_HTTP2_SETTINGS,
|
|
|
|
HTTP2_HEADER_TE,
|
|
|
|
HTTP2_HEADER_TRANSFER_ENCODING,
|
|
|
|
HTTP2_HEADER_HOST,
|
|
|
|
HTTP2_HEADER_KEEP_ALIVE,
|
|
|
|
HTTP2_HEADER_PROXY_CONNECTION,
|
|
|
|
|
|
|
|
HTTP2_METHOD_DELETE,
|
|
|
|
HTTP2_METHOD_GET,
|
|
|
|
HTTP2_METHOD_HEAD
|
|
|
|
} = binding.constants;
|
|
|
|
|
|
|
|
// This set is defined strictly by the HTTP/2 specification. Only
|
|
|
|
// :-prefixed headers defined by that specification may be added to
|
|
|
|
// this set.
|
|
|
|
const kValidPseudoHeaders = new Set([
|
|
|
|
HTTP2_HEADER_STATUS,
|
|
|
|
HTTP2_HEADER_METHOD,
|
|
|
|
HTTP2_HEADER_AUTHORITY,
|
|
|
|
HTTP2_HEADER_SCHEME,
|
|
|
|
HTTP2_HEADER_PATH
|
|
|
|
]);
|
|
|
|
|
|
|
|
// This set contains headers that are permitted to have only a single
|
|
|
|
// value. Multiple instances must not be specified.
|
|
|
|
const kSingleValueHeaders = new Set([
|
|
|
|
HTTP2_HEADER_STATUS,
|
|
|
|
HTTP2_HEADER_METHOD,
|
|
|
|
HTTP2_HEADER_AUTHORITY,
|
|
|
|
HTTP2_HEADER_SCHEME,
|
|
|
|
HTTP2_HEADER_PATH,
|
|
|
|
HTTP2_HEADER_ACCESS_CONTROL_ALLOW_CREDENTIALS,
|
|
|
|
HTTP2_HEADER_ACCESS_CONTROL_MAX_AGE,
|
|
|
|
HTTP2_HEADER_ACCESS_CONTROL_REQUEST_METHOD,
|
http2: introducing HTTP/2
At long last: The initial *experimental* implementation of HTTP/2.
This is an accumulation of the work that has been done in the nodejs/http2
repository, squashed down to a couple of commits. The original commit
history has been preserved in the nodejs/http2 repository.
This PR introduces the nghttp2 C library as a new dependency. This library
provides the majority of the HTTP/2 protocol implementation, with the rest
of the code here providing the mapping of the library into a usable JS API.
Within src, a handful of new node_http2_*.c and node_http2_*.h files are
introduced. These provide the internal mechanisms that interface with nghttp
and define the `process.binding('http2')` interface.
The JS API is defined within `internal/http2/*.js`.
There are two APIs provided: Core and Compat.
The Core API is HTTP/2 specific and is designed to be as minimal and as
efficient as possible.
The Compat API is intended to be as close to the existing HTTP/1 API as
possible, with some exceptions.
Tests, documentation and initial benchmarks are included.
The `http2` module is gated by a new `--expose-http2` command line flag.
When used, `require('http2')` will be exposed to users. Note that there
is an existing `http2` module on npm that would be impacted by the introduction
of this module, which is the main reason for gating this behind a flag.
When using `require('http2')` the first time, a process warning will be
emitted indicating that an experimental feature is being used.
To run the benchmarks, the `h2load` tool (part of the nghttp project) is
required: `./node benchmarks/http2/simple.js benchmarker=h2load`. Only
two benchmarks are currently available.
Additional configuration options to enable verbose debugging are provided:
```
$ ./configure --debug-http2 --debug-nghttp2
$ NODE_DEBUG=http2 ./node
```
The `--debug-http2` configuration option enables verbose debug statements
from the `src/node_http2_*` files. The `--debug-nghttp2` enables the nghttp
library's own verbose debug output. The `NODE_DEBUG=http2` enables JS-level
debug output.
The following illustrates as simple HTTP/2 server and client interaction:
(The HTTP/2 client and server support both plain text and TLS connections)
```jt client = http2.connect('http://localhost:80');
const req = client.request({ ':path': '/some/path' });
req.on('data', (chunk) => { /* do something with the data */ });
req.on('end', () => {
client.destroy();
});
// Plain text (non-TLS server)
const server = http2.createServer();
server.on('stream', (stream, requestHeaders) => {
stream.respond({ ':status': 200 });
stream.write('hello ');
stream.end('world');
});
server.listen(80);
```
```js
const http2 = require('http2');
const client = http2.connect('http://localhost');
```
Author: Anna Henningsen <anna@addaleax.net>
Author: Colin Ihrig <cjihrig@gmail.com>
Author: Daniel Bevenius <daniel.bevenius@gmail.com>
Author: James M Snell <jasnell@gmail.com>
Author: Jun Mukai
Author: Kelvin Jin
Author: Matteo Collina <matteo.collina@gmail.com>
Author: Robert Kowalski <rok@kowalski.gd>
Author: Santiago Gimeno <santiago.gimeno@gmail.com>
Author: Sebastiaan Deckers <sebdeckers83@gmail.com>
Author: Yosuke Furukawa <yosuke.furukawa@gmail.com>
PR-URL: https://github.com/nodejs/node/pull/14239
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
8 years ago
|
|
|
HTTP2_HEADER_AGE,
|
|
|
|
HTTP2_HEADER_AUTHORIZATION,
|
|
|
|
HTTP2_HEADER_CONTENT_ENCODING,
|
|
|
|
HTTP2_HEADER_CONTENT_LANGUAGE,
|
|
|
|
HTTP2_HEADER_CONTENT_LENGTH,
|
|
|
|
HTTP2_HEADER_CONTENT_LOCATION,
|
|
|
|
HTTP2_HEADER_CONTENT_MD5,
|
|
|
|
HTTP2_HEADER_CONTENT_RANGE,
|
|
|
|
HTTP2_HEADER_CONTENT_TYPE,
|
|
|
|
HTTP2_HEADER_DATE,
|
|
|
|
HTTP2_HEADER_DNT,
|
http2: introducing HTTP/2
At long last: The initial *experimental* implementation of HTTP/2.
This is an accumulation of the work that has been done in the nodejs/http2
repository, squashed down to a couple of commits. The original commit
history has been preserved in the nodejs/http2 repository.
This PR introduces the nghttp2 C library as a new dependency. This library
provides the majority of the HTTP/2 protocol implementation, with the rest
of the code here providing the mapping of the library into a usable JS API.
Within src, a handful of new node_http2_*.c and node_http2_*.h files are
introduced. These provide the internal mechanisms that interface with nghttp
and define the `process.binding('http2')` interface.
The JS API is defined within `internal/http2/*.js`.
There are two APIs provided: Core and Compat.
The Core API is HTTP/2 specific and is designed to be as minimal and as
efficient as possible.
The Compat API is intended to be as close to the existing HTTP/1 API as
possible, with some exceptions.
Tests, documentation and initial benchmarks are included.
The `http2` module is gated by a new `--expose-http2` command line flag.
When used, `require('http2')` will be exposed to users. Note that there
is an existing `http2` module on npm that would be impacted by the introduction
of this module, which is the main reason for gating this behind a flag.
When using `require('http2')` the first time, a process warning will be
emitted indicating that an experimental feature is being used.
To run the benchmarks, the `h2load` tool (part of the nghttp project) is
required: `./node benchmarks/http2/simple.js benchmarker=h2load`. Only
two benchmarks are currently available.
Additional configuration options to enable verbose debugging are provided:
```
$ ./configure --debug-http2 --debug-nghttp2
$ NODE_DEBUG=http2 ./node
```
The `--debug-http2` configuration option enables verbose debug statements
from the `src/node_http2_*` files. The `--debug-nghttp2` enables the nghttp
library's own verbose debug output. The `NODE_DEBUG=http2` enables JS-level
debug output.
The following illustrates as simple HTTP/2 server and client interaction:
(The HTTP/2 client and server support both plain text and TLS connections)
```jt client = http2.connect('http://localhost:80');
const req = client.request({ ':path': '/some/path' });
req.on('data', (chunk) => { /* do something with the data */ });
req.on('end', () => {
client.destroy();
});
// Plain text (non-TLS server)
const server = http2.createServer();
server.on('stream', (stream, requestHeaders) => {
stream.respond({ ':status': 200 });
stream.write('hello ');
stream.end('world');
});
server.listen(80);
```
```js
const http2 = require('http2');
const client = http2.connect('http://localhost');
```
Author: Anna Henningsen <anna@addaleax.net>
Author: Colin Ihrig <cjihrig@gmail.com>
Author: Daniel Bevenius <daniel.bevenius@gmail.com>
Author: James M Snell <jasnell@gmail.com>
Author: Jun Mukai
Author: Kelvin Jin
Author: Matteo Collina <matteo.collina@gmail.com>
Author: Robert Kowalski <rok@kowalski.gd>
Author: Santiago Gimeno <santiago.gimeno@gmail.com>
Author: Sebastiaan Deckers <sebdeckers83@gmail.com>
Author: Yosuke Furukawa <yosuke.furukawa@gmail.com>
PR-URL: https://github.com/nodejs/node/pull/14239
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
8 years ago
|
|
|
HTTP2_HEADER_ETAG,
|
|
|
|
HTTP2_HEADER_EXPIRES,
|
|
|
|
HTTP2_HEADER_FROM,
|
|
|
|
HTTP2_HEADER_IF_MATCH,
|
|
|
|
HTTP2_HEADER_IF_MODIFIED_SINCE,
|
|
|
|
HTTP2_HEADER_IF_NONE_MATCH,
|
|
|
|
HTTP2_HEADER_IF_RANGE,
|
|
|
|
HTTP2_HEADER_IF_UNMODIFIED_SINCE,
|
|
|
|
HTTP2_HEADER_LAST_MODIFIED,
|
|
|
|
HTTP2_HEADER_LOCATION,
|
|
|
|
HTTP2_HEADER_MAX_FORWARDS,
|
|
|
|
HTTP2_HEADER_PROXY_AUTHORIZATION,
|
|
|
|
HTTP2_HEADER_RANGE,
|
|
|
|
HTTP2_HEADER_REFERER,
|
|
|
|
HTTP2_HEADER_RETRY_AFTER,
|
|
|
|
HTTP2_HEADER_TK,
|
|
|
|
HTTP2_HEADER_UPGRADE_INSECURE_REQUESTS,
|
|
|
|
HTTP2_HEADER_USER_AGENT,
|
|
|
|
HTTP2_HEADER_X_CONTENT_TYPE_OPTIONS
|
http2: introducing HTTP/2
At long last: The initial *experimental* implementation of HTTP/2.
This is an accumulation of the work that has been done in the nodejs/http2
repository, squashed down to a couple of commits. The original commit
history has been preserved in the nodejs/http2 repository.
This PR introduces the nghttp2 C library as a new dependency. This library
provides the majority of the HTTP/2 protocol implementation, with the rest
of the code here providing the mapping of the library into a usable JS API.
Within src, a handful of new node_http2_*.c and node_http2_*.h files are
introduced. These provide the internal mechanisms that interface with nghttp
and define the `process.binding('http2')` interface.
The JS API is defined within `internal/http2/*.js`.
There are two APIs provided: Core and Compat.
The Core API is HTTP/2 specific and is designed to be as minimal and as
efficient as possible.
The Compat API is intended to be as close to the existing HTTP/1 API as
possible, with some exceptions.
Tests, documentation and initial benchmarks are included.
The `http2` module is gated by a new `--expose-http2` command line flag.
When used, `require('http2')` will be exposed to users. Note that there
is an existing `http2` module on npm that would be impacted by the introduction
of this module, which is the main reason for gating this behind a flag.
When using `require('http2')` the first time, a process warning will be
emitted indicating that an experimental feature is being used.
To run the benchmarks, the `h2load` tool (part of the nghttp project) is
required: `./node benchmarks/http2/simple.js benchmarker=h2load`. Only
two benchmarks are currently available.
Additional configuration options to enable verbose debugging are provided:
```
$ ./configure --debug-http2 --debug-nghttp2
$ NODE_DEBUG=http2 ./node
```
The `--debug-http2` configuration option enables verbose debug statements
from the `src/node_http2_*` files. The `--debug-nghttp2` enables the nghttp
library's own verbose debug output. The `NODE_DEBUG=http2` enables JS-level
debug output.
The following illustrates as simple HTTP/2 server and client interaction:
(The HTTP/2 client and server support both plain text and TLS connections)
```jt client = http2.connect('http://localhost:80');
const req = client.request({ ':path': '/some/path' });
req.on('data', (chunk) => { /* do something with the data */ });
req.on('end', () => {
client.destroy();
});
// Plain text (non-TLS server)
const server = http2.createServer();
server.on('stream', (stream, requestHeaders) => {
stream.respond({ ':status': 200 });
stream.write('hello ');
stream.end('world');
});
server.listen(80);
```
```js
const http2 = require('http2');
const client = http2.connect('http://localhost');
```
Author: Anna Henningsen <anna@addaleax.net>
Author: Colin Ihrig <cjihrig@gmail.com>
Author: Daniel Bevenius <daniel.bevenius@gmail.com>
Author: James M Snell <jasnell@gmail.com>
Author: Jun Mukai
Author: Kelvin Jin
Author: Matteo Collina <matteo.collina@gmail.com>
Author: Robert Kowalski <rok@kowalski.gd>
Author: Santiago Gimeno <santiago.gimeno@gmail.com>
Author: Sebastiaan Deckers <sebdeckers83@gmail.com>
Author: Yosuke Furukawa <yosuke.furukawa@gmail.com>
PR-URL: https://github.com/nodejs/node/pull/14239
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
8 years ago
|
|
|
]);
|
|
|
|
|
|
|
|
// The HTTP methods in this set are specifically defined as assigning no
|
|
|
|
// meaning to the request payload. By default, unless the user explicitly
|
|
|
|
// overrides the endStream option on the request method, the endStream
|
|
|
|
// option will be defaulted to true when these methods are used.
|
|
|
|
const kNoPayloadMethods = new Set([
|
|
|
|
HTTP2_METHOD_DELETE,
|
|
|
|
HTTP2_METHOD_GET,
|
|
|
|
HTTP2_METHOD_HEAD
|
|
|
|
]);
|
|
|
|
|
|
|
|
// The following ArrayBuffer instances are used to share memory more efficiently
|
|
|
|
// with the native binding side for a number of methods. These are not intended
|
|
|
|
// to be used directly by users in any way. The ArrayBuffers are created on
|
|
|
|
// the native side with values that are filled in on demand, the js code then
|
|
|
|
// reads those values out. The set of IDX constants that follow identify the
|
|
|
|
// relevant data positions within these buffers.
|
|
|
|
const { settingsBuffer, optionsBuffer } = binding;
|
http2: introducing HTTP/2
At long last: The initial *experimental* implementation of HTTP/2.
This is an accumulation of the work that has been done in the nodejs/http2
repository, squashed down to a couple of commits. The original commit
history has been preserved in the nodejs/http2 repository.
This PR introduces the nghttp2 C library as a new dependency. This library
provides the majority of the HTTP/2 protocol implementation, with the rest
of the code here providing the mapping of the library into a usable JS API.
Within src, a handful of new node_http2_*.c and node_http2_*.h files are
introduced. These provide the internal mechanisms that interface with nghttp
and define the `process.binding('http2')` interface.
The JS API is defined within `internal/http2/*.js`.
There are two APIs provided: Core and Compat.
The Core API is HTTP/2 specific and is designed to be as minimal and as
efficient as possible.
The Compat API is intended to be as close to the existing HTTP/1 API as
possible, with some exceptions.
Tests, documentation and initial benchmarks are included.
The `http2` module is gated by a new `--expose-http2` command line flag.
When used, `require('http2')` will be exposed to users. Note that there
is an existing `http2` module on npm that would be impacted by the introduction
of this module, which is the main reason for gating this behind a flag.
When using `require('http2')` the first time, a process warning will be
emitted indicating that an experimental feature is being used.
To run the benchmarks, the `h2load` tool (part of the nghttp project) is
required: `./node benchmarks/http2/simple.js benchmarker=h2load`. Only
two benchmarks are currently available.
Additional configuration options to enable verbose debugging are provided:
```
$ ./configure --debug-http2 --debug-nghttp2
$ NODE_DEBUG=http2 ./node
```
The `--debug-http2` configuration option enables verbose debug statements
from the `src/node_http2_*` files. The `--debug-nghttp2` enables the nghttp
library's own verbose debug output. The `NODE_DEBUG=http2` enables JS-level
debug output.
The following illustrates as simple HTTP/2 server and client interaction:
(The HTTP/2 client and server support both plain text and TLS connections)
```jt client = http2.connect('http://localhost:80');
const req = client.request({ ':path': '/some/path' });
req.on('data', (chunk) => { /* do something with the data */ });
req.on('end', () => {
client.destroy();
});
// Plain text (non-TLS server)
const server = http2.createServer();
server.on('stream', (stream, requestHeaders) => {
stream.respond({ ':status': 200 });
stream.write('hello ');
stream.end('world');
});
server.listen(80);
```
```js
const http2 = require('http2');
const client = http2.connect('http://localhost');
```
Author: Anna Henningsen <anna@addaleax.net>
Author: Colin Ihrig <cjihrig@gmail.com>
Author: Daniel Bevenius <daniel.bevenius@gmail.com>
Author: James M Snell <jasnell@gmail.com>
Author: Jun Mukai
Author: Kelvin Jin
Author: Matteo Collina <matteo.collina@gmail.com>
Author: Robert Kowalski <rok@kowalski.gd>
Author: Santiago Gimeno <santiago.gimeno@gmail.com>
Author: Sebastiaan Deckers <sebdeckers83@gmail.com>
Author: Yosuke Furukawa <yosuke.furukawa@gmail.com>
PR-URL: https://github.com/nodejs/node/pull/14239
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
8 years ago
|
|
|
|
|
|
|
// Note that Float64Array is used here because there is no Int64Array available
|
|
|
|
// and these deal with numbers that can be beyond the range of Uint32 and Int32.
|
|
|
|
// The values set on the native side will always be integers. This is not a
|
|
|
|
// unique example of this, this pattern can be found in use in other parts of
|
|
|
|
// Node.js core as a performance optimization.
|
|
|
|
const { sessionState, streamState } = binding;
|
http2: introducing HTTP/2
At long last: The initial *experimental* implementation of HTTP/2.
This is an accumulation of the work that has been done in the nodejs/http2
repository, squashed down to a couple of commits. The original commit
history has been preserved in the nodejs/http2 repository.
This PR introduces the nghttp2 C library as a new dependency. This library
provides the majority of the HTTP/2 protocol implementation, with the rest
of the code here providing the mapping of the library into a usable JS API.
Within src, a handful of new node_http2_*.c and node_http2_*.h files are
introduced. These provide the internal mechanisms that interface with nghttp
and define the `process.binding('http2')` interface.
The JS API is defined within `internal/http2/*.js`.
There are two APIs provided: Core and Compat.
The Core API is HTTP/2 specific and is designed to be as minimal and as
efficient as possible.
The Compat API is intended to be as close to the existing HTTP/1 API as
possible, with some exceptions.
Tests, documentation and initial benchmarks are included.
The `http2` module is gated by a new `--expose-http2` command line flag.
When used, `require('http2')` will be exposed to users. Note that there
is an existing `http2` module on npm that would be impacted by the introduction
of this module, which is the main reason for gating this behind a flag.
When using `require('http2')` the first time, a process warning will be
emitted indicating that an experimental feature is being used.
To run the benchmarks, the `h2load` tool (part of the nghttp project) is
required: `./node benchmarks/http2/simple.js benchmarker=h2load`. Only
two benchmarks are currently available.
Additional configuration options to enable verbose debugging are provided:
```
$ ./configure --debug-http2 --debug-nghttp2
$ NODE_DEBUG=http2 ./node
```
The `--debug-http2` configuration option enables verbose debug statements
from the `src/node_http2_*` files. The `--debug-nghttp2` enables the nghttp
library's own verbose debug output. The `NODE_DEBUG=http2` enables JS-level
debug output.
The following illustrates as simple HTTP/2 server and client interaction:
(The HTTP/2 client and server support both plain text and TLS connections)
```jt client = http2.connect('http://localhost:80');
const req = client.request({ ':path': '/some/path' });
req.on('data', (chunk) => { /* do something with the data */ });
req.on('end', () => {
client.destroy();
});
// Plain text (non-TLS server)
const server = http2.createServer();
server.on('stream', (stream, requestHeaders) => {
stream.respond({ ':status': 200 });
stream.write('hello ');
stream.end('world');
});
server.listen(80);
```
```js
const http2 = require('http2');
const client = http2.connect('http://localhost');
```
Author: Anna Henningsen <anna@addaleax.net>
Author: Colin Ihrig <cjihrig@gmail.com>
Author: Daniel Bevenius <daniel.bevenius@gmail.com>
Author: James M Snell <jasnell@gmail.com>
Author: Jun Mukai
Author: Kelvin Jin
Author: Matteo Collina <matteo.collina@gmail.com>
Author: Robert Kowalski <rok@kowalski.gd>
Author: Santiago Gimeno <santiago.gimeno@gmail.com>
Author: Sebastiaan Deckers <sebdeckers83@gmail.com>
Author: Yosuke Furukawa <yosuke.furukawa@gmail.com>
PR-URL: https://github.com/nodejs/node/pull/14239
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
8 years ago
|
|
|
|
|
|
|
const IDX_SETTINGS_HEADER_TABLE_SIZE = 0;
|
|
|
|
const IDX_SETTINGS_ENABLE_PUSH = 1;
|
|
|
|
const IDX_SETTINGS_INITIAL_WINDOW_SIZE = 2;
|
|
|
|
const IDX_SETTINGS_MAX_FRAME_SIZE = 3;
|
|
|
|
const IDX_SETTINGS_MAX_CONCURRENT_STREAMS = 4;
|
|
|
|
const IDX_SETTINGS_MAX_HEADER_LIST_SIZE = 5;
|
|
|
|
const IDX_SETTINGS_FLAGS = 6;
|
|
|
|
|
|
|
|
const IDX_SESSION_STATE_EFFECTIVE_LOCAL_WINDOW_SIZE = 0;
|
|
|
|
const IDX_SESSION_STATE_EFFECTIVE_RECV_DATA_LENGTH = 1;
|
|
|
|
const IDX_SESSION_STATE_NEXT_STREAM_ID = 2;
|
|
|
|
const IDX_SESSION_STATE_LOCAL_WINDOW_SIZE = 3;
|
|
|
|
const IDX_SESSION_STATE_LAST_PROC_STREAM_ID = 4;
|
|
|
|
const IDX_SESSION_STATE_REMOTE_WINDOW_SIZE = 5;
|
|
|
|
const IDX_SESSION_STATE_OUTBOUND_QUEUE_SIZE = 6;
|
|
|
|
const IDX_SESSION_STATE_HD_DEFLATE_DYNAMIC_TABLE_SIZE = 7;
|
|
|
|
const IDX_SESSION_STATE_HD_INFLATE_DYNAMIC_TABLE_SIZE = 8;
|
|
|
|
const IDX_STREAM_STATE = 0;
|
|
|
|
const IDX_STREAM_STATE_WEIGHT = 1;
|
|
|
|
const IDX_STREAM_STATE_SUM_DEPENDENCY_WEIGHT = 2;
|
|
|
|
const IDX_STREAM_STATE_LOCAL_CLOSE = 3;
|
|
|
|
const IDX_STREAM_STATE_REMOTE_CLOSE = 4;
|
|
|
|
const IDX_STREAM_STATE_LOCAL_WINDOW_SIZE = 5;
|
|
|
|
|
|
|
|
const IDX_OPTIONS_MAX_DEFLATE_DYNAMIC_TABLE_SIZE = 0;
|
|
|
|
const IDX_OPTIONS_MAX_RESERVED_REMOTE_STREAMS = 1;
|
|
|
|
const IDX_OPTIONS_MAX_SEND_HEADER_BLOCK_LENGTH = 2;
|
|
|
|
const IDX_OPTIONS_PEER_MAX_CONCURRENT_STREAMS = 3;
|
|
|
|
const IDX_OPTIONS_PADDING_STRATEGY = 4;
|
|
|
|
const IDX_OPTIONS_FLAGS = 5;
|
|
|
|
|
|
|
|
function updateOptionsBuffer(options) {
|
|
|
|
var flags = 0;
|
|
|
|
if (typeof options.maxDeflateDynamicTableSize === 'number') {
|
|
|
|
flags |= (1 << IDX_OPTIONS_MAX_DEFLATE_DYNAMIC_TABLE_SIZE);
|
|
|
|
optionsBuffer[IDX_OPTIONS_MAX_DEFLATE_DYNAMIC_TABLE_SIZE] =
|
|
|
|
options.maxDeflateDynamicTableSize;
|
|
|
|
}
|
|
|
|
if (typeof options.maxReservedRemoteStreams === 'number') {
|
|
|
|
flags |= (1 << IDX_OPTIONS_MAX_RESERVED_REMOTE_STREAMS);
|
|
|
|
optionsBuffer[IDX_OPTIONS_MAX_RESERVED_REMOTE_STREAMS] =
|
|
|
|
options.maxReservedRemoteStreams;
|
|
|
|
}
|
|
|
|
if (typeof options.maxSendHeaderBlockLength === 'number') {
|
|
|
|
flags |= (1 << IDX_OPTIONS_MAX_SEND_HEADER_BLOCK_LENGTH);
|
|
|
|
optionsBuffer[IDX_OPTIONS_MAX_SEND_HEADER_BLOCK_LENGTH] =
|
|
|
|
options.maxSendHeaderBlockLength;
|
|
|
|
}
|
|
|
|
if (typeof options.peerMaxConcurrentStreams === 'number') {
|
|
|
|
flags |= (1 << IDX_OPTIONS_PEER_MAX_CONCURRENT_STREAMS);
|
|
|
|
optionsBuffer[IDX_OPTIONS_PEER_MAX_CONCURRENT_STREAMS] =
|
|
|
|
options.peerMaxConcurrentStreams;
|
|
|
|
}
|
|
|
|
if (typeof options.paddingStrategy === 'number') {
|
|
|
|
flags |= (1 << IDX_OPTIONS_PADDING_STRATEGY);
|
|
|
|
optionsBuffer[IDX_OPTIONS_PADDING_STRATEGY] =
|
|
|
|
options.paddingStrategy;
|
|
|
|
}
|
|
|
|
optionsBuffer[IDX_OPTIONS_FLAGS] = flags;
|
|
|
|
}
|
|
|
|
|
|
|
|
function getDefaultSettings() {
|
|
|
|
settingsBuffer[IDX_SETTINGS_FLAGS] = 0;
|
|
|
|
binding.refreshDefaultSettings();
|
|
|
|
const holder = Object.create(null);
|
|
|
|
|
|
|
|
const flags = settingsBuffer[IDX_SETTINGS_FLAGS];
|
|
|
|
|
|
|
|
if ((flags & (1 << IDX_SETTINGS_HEADER_TABLE_SIZE)) ===
|
|
|
|
(1 << IDX_SETTINGS_HEADER_TABLE_SIZE)) {
|
|
|
|
holder.headerTableSize =
|
|
|
|
settingsBuffer[IDX_SETTINGS_HEADER_TABLE_SIZE];
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((flags & (1 << IDX_SETTINGS_ENABLE_PUSH)) ===
|
|
|
|
(1 << IDX_SETTINGS_ENABLE_PUSH)) {
|
|
|
|
holder.enablePush =
|
|
|
|
settingsBuffer[IDX_SETTINGS_ENABLE_PUSH] === 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((flags & (1 << IDX_SETTINGS_INITIAL_WINDOW_SIZE)) ===
|
|
|
|
(1 << IDX_SETTINGS_INITIAL_WINDOW_SIZE)) {
|
|
|
|
holder.initialWindowSize =
|
|
|
|
settingsBuffer[IDX_SETTINGS_INITIAL_WINDOW_SIZE];
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((flags & (1 << IDX_SETTINGS_MAX_FRAME_SIZE)) ===
|
|
|
|
(1 << IDX_SETTINGS_MAX_FRAME_SIZE)) {
|
|
|
|
holder.maxFrameSize =
|
|
|
|
settingsBuffer[IDX_SETTINGS_MAX_FRAME_SIZE];
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((flags & (1 << IDX_SETTINGS_MAX_CONCURRENT_STREAMS)) ===
|
|
|
|
(1 << IDX_SETTINGS_MAX_CONCURRENT_STREAMS)) {
|
|
|
|
holder.maxConcurrentStreams =
|
|
|
|
settingsBuffer[IDX_SETTINGS_MAX_CONCURRENT_STREAMS];
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((flags & (1 << IDX_SETTINGS_MAX_HEADER_LIST_SIZE)) ===
|
|
|
|
(1 << IDX_SETTINGS_MAX_HEADER_LIST_SIZE)) {
|
|
|
|
holder.maxHeaderListSize =
|
|
|
|
settingsBuffer[IDX_SETTINGS_MAX_HEADER_LIST_SIZE];
|
|
|
|
}
|
|
|
|
|
|
|
|
return holder;
|
|
|
|
}
|
|
|
|
|
|
|
|
// remote is a boolean. true to fetch remote settings, false to fetch local.
|
|
|
|
// this is only called internally
|
|
|
|
function getSettings(session, remote) {
|
|
|
|
const holder = Object.create(null);
|
|
|
|
if (remote)
|
|
|
|
binding.refreshRemoteSettings(session);
|
|
|
|
else
|
|
|
|
binding.refreshLocalSettings(session);
|
|
|
|
|
|
|
|
holder.headerTableSize =
|
|
|
|
settingsBuffer[IDX_SETTINGS_HEADER_TABLE_SIZE];
|
|
|
|
holder.enablePush =
|
|
|
|
!!settingsBuffer[IDX_SETTINGS_ENABLE_PUSH];
|
|
|
|
holder.initialWindowSize =
|
|
|
|
settingsBuffer[IDX_SETTINGS_INITIAL_WINDOW_SIZE];
|
|
|
|
holder.maxFrameSize =
|
|
|
|
settingsBuffer[IDX_SETTINGS_MAX_FRAME_SIZE];
|
|
|
|
holder.maxConcurrentStreams =
|
|
|
|
settingsBuffer[IDX_SETTINGS_MAX_CONCURRENT_STREAMS];
|
|
|
|
holder.maxHeaderListSize =
|
|
|
|
settingsBuffer[IDX_SETTINGS_MAX_HEADER_LIST_SIZE];
|
|
|
|
return holder;
|
|
|
|
}
|
|
|
|
|
|
|
|
function updateSettingsBuffer(settings) {
|
|
|
|
var flags = 0;
|
|
|
|
if (typeof settings.headerTableSize === 'number') {
|
|
|
|
flags |= (1 << IDX_SETTINGS_HEADER_TABLE_SIZE);
|
|
|
|
settingsBuffer[IDX_SETTINGS_HEADER_TABLE_SIZE] =
|
|
|
|
settings.headerTableSize;
|
|
|
|
}
|
|
|
|
if (typeof settings.maxConcurrentStreams === 'number') {
|
|
|
|
flags |= (1 << IDX_SETTINGS_MAX_CONCURRENT_STREAMS);
|
|
|
|
settingsBuffer[IDX_SETTINGS_MAX_CONCURRENT_STREAMS] =
|
|
|
|
settings.maxConcurrentStreams;
|
|
|
|
}
|
|
|
|
if (typeof settings.initialWindowSize === 'number') {
|
|
|
|
flags |= (1 << IDX_SETTINGS_INITIAL_WINDOW_SIZE);
|
|
|
|
settingsBuffer[IDX_SETTINGS_INITIAL_WINDOW_SIZE] =
|
|
|
|
settings.initialWindowSize;
|
|
|
|
}
|
|
|
|
if (typeof settings.maxFrameSize === 'number') {
|
|
|
|
flags |= (1 << IDX_SETTINGS_MAX_FRAME_SIZE);
|
|
|
|
settingsBuffer[IDX_SETTINGS_MAX_FRAME_SIZE] =
|
|
|
|
settings.maxFrameSize;
|
|
|
|
}
|
|
|
|
if (typeof settings.maxHeaderListSize === 'number') {
|
|
|
|
flags |= (1 << IDX_SETTINGS_MAX_HEADER_LIST_SIZE);
|
|
|
|
settingsBuffer[IDX_SETTINGS_MAX_HEADER_LIST_SIZE] =
|
|
|
|
settings.maxHeaderListSize;
|
|
|
|
}
|
|
|
|
if (typeof settings.enablePush === 'boolean') {
|
|
|
|
flags |= (1 << IDX_SETTINGS_ENABLE_PUSH);
|
|
|
|
settingsBuffer[IDX_SETTINGS_ENABLE_PUSH] = Number(settings.enablePush);
|
|
|
|
}
|
|
|
|
|
|
|
|
settingsBuffer[IDX_SETTINGS_FLAGS] = flags;
|
|
|
|
}
|
|
|
|
|
|
|
|
function getSessionState(session) {
|
|
|
|
const holder = Object.create(null);
|
|
|
|
binding.refreshSessionState(session);
|
|
|
|
holder.effectiveLocalWindowSize =
|
|
|
|
sessionState[IDX_SESSION_STATE_EFFECTIVE_LOCAL_WINDOW_SIZE];
|
|
|
|
holder.effectiveRecvDataLength =
|
|
|
|
sessionState[IDX_SESSION_STATE_EFFECTIVE_RECV_DATA_LENGTH];
|
|
|
|
holder.nextStreamID =
|
|
|
|
sessionState[IDX_SESSION_STATE_NEXT_STREAM_ID];
|
|
|
|
holder.localWindowSize =
|
|
|
|
sessionState[IDX_SESSION_STATE_LOCAL_WINDOW_SIZE];
|
|
|
|
holder.lastProcStreamID =
|
|
|
|
sessionState[IDX_SESSION_STATE_LAST_PROC_STREAM_ID];
|
|
|
|
holder.remoteWindowSize =
|
|
|
|
sessionState[IDX_SESSION_STATE_REMOTE_WINDOW_SIZE];
|
|
|
|
holder.outboundQueueSize =
|
|
|
|
sessionState[IDX_SESSION_STATE_OUTBOUND_QUEUE_SIZE];
|
|
|
|
holder.deflateDynamicTableSize =
|
|
|
|
sessionState[IDX_SESSION_STATE_HD_DEFLATE_DYNAMIC_TABLE_SIZE];
|
|
|
|
holder.inflateDynamicTableSize =
|
|
|
|
sessionState[IDX_SESSION_STATE_HD_INFLATE_DYNAMIC_TABLE_SIZE];
|
|
|
|
return holder;
|
|
|
|
}
|
|
|
|
|
|
|
|
function getStreamState(session, stream) {
|
|
|
|
const holder = Object.create(null);
|
|
|
|
binding.refreshStreamState(session, stream);
|
|
|
|
holder.state =
|
|
|
|
streamState[IDX_STREAM_STATE];
|
|
|
|
holder.weight =
|
|
|
|
streamState[IDX_STREAM_STATE_WEIGHT];
|
|
|
|
holder.sumDependencyWeight =
|
|
|
|
streamState[IDX_STREAM_STATE_SUM_DEPENDENCY_WEIGHT];
|
|
|
|
holder.localClose =
|
|
|
|
streamState[IDX_STREAM_STATE_LOCAL_CLOSE];
|
|
|
|
holder.remoteClose =
|
|
|
|
streamState[IDX_STREAM_STATE_REMOTE_CLOSE];
|
|
|
|
holder.localWindowSize =
|
|
|
|
streamState[IDX_STREAM_STATE_LOCAL_WINDOW_SIZE];
|
|
|
|
return holder;
|
|
|
|
}
|
|
|
|
|
|
|
|
function isIllegalConnectionSpecificHeader(name, value) {
|
|
|
|
switch (name) {
|
|
|
|
case HTTP2_HEADER_CONNECTION:
|
|
|
|
case HTTP2_HEADER_UPGRADE:
|
|
|
|
case HTTP2_HEADER_HOST:
|
|
|
|
case HTTP2_HEADER_HTTP2_SETTINGS:
|
|
|
|
case HTTP2_HEADER_KEEP_ALIVE:
|
|
|
|
case HTTP2_HEADER_PROXY_CONNECTION:
|
|
|
|
case HTTP2_HEADER_TRANSFER_ENCODING:
|
|
|
|
return true;
|
|
|
|
case HTTP2_HEADER_TE:
|
|
|
|
const val = Array.isArray(value) ? value.join(', ') : value;
|
|
|
|
return val !== 'trailers';
|
|
|
|
default:
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function assertValidPseudoHeader(key) {
|
|
|
|
if (!kValidPseudoHeaders.has(key)) {
|
|
|
|
const err = new errors.Error('ERR_HTTP2_INVALID_PSEUDOHEADER', key);
|
|
|
|
Error.captureStackTrace(err, assertValidPseudoHeader);
|
|
|
|
return err;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function assertValidPseudoHeaderResponse(key) {
|
|
|
|
if (key !== ':status') {
|
|
|
|
const err = new errors.Error('ERR_HTTP2_INVALID_PSEUDOHEADER', key);
|
|
|
|
Error.captureStackTrace(err, assertValidPseudoHeaderResponse);
|
|
|
|
return err;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function assertValidPseudoHeaderTrailer(key) {
|
|
|
|
const err = new errors.Error('ERR_HTTP2_INVALID_PSEUDOHEADER', key);
|
|
|
|
Error.captureStackTrace(err, assertValidPseudoHeaderTrailer);
|
|
|
|
return err;
|
|
|
|
}
|
|
|
|
|
|
|
|
function mapToHeaders(map,
|
|
|
|
assertValuePseudoHeader = assertValidPseudoHeader) {
|
|
|
|
let ret = '';
|
|
|
|
let count = 0;
|
http2: introducing HTTP/2
At long last: The initial *experimental* implementation of HTTP/2.
This is an accumulation of the work that has been done in the nodejs/http2
repository, squashed down to a couple of commits. The original commit
history has been preserved in the nodejs/http2 repository.
This PR introduces the nghttp2 C library as a new dependency. This library
provides the majority of the HTTP/2 protocol implementation, with the rest
of the code here providing the mapping of the library into a usable JS API.
Within src, a handful of new node_http2_*.c and node_http2_*.h files are
introduced. These provide the internal mechanisms that interface with nghttp
and define the `process.binding('http2')` interface.
The JS API is defined within `internal/http2/*.js`.
There are two APIs provided: Core and Compat.
The Core API is HTTP/2 specific and is designed to be as minimal and as
efficient as possible.
The Compat API is intended to be as close to the existing HTTP/1 API as
possible, with some exceptions.
Tests, documentation and initial benchmarks are included.
The `http2` module is gated by a new `--expose-http2` command line flag.
When used, `require('http2')` will be exposed to users. Note that there
is an existing `http2` module on npm that would be impacted by the introduction
of this module, which is the main reason for gating this behind a flag.
When using `require('http2')` the first time, a process warning will be
emitted indicating that an experimental feature is being used.
To run the benchmarks, the `h2load` tool (part of the nghttp project) is
required: `./node benchmarks/http2/simple.js benchmarker=h2load`. Only
two benchmarks are currently available.
Additional configuration options to enable verbose debugging are provided:
```
$ ./configure --debug-http2 --debug-nghttp2
$ NODE_DEBUG=http2 ./node
```
The `--debug-http2` configuration option enables verbose debug statements
from the `src/node_http2_*` files. The `--debug-nghttp2` enables the nghttp
library's own verbose debug output. The `NODE_DEBUG=http2` enables JS-level
debug output.
The following illustrates as simple HTTP/2 server and client interaction:
(The HTTP/2 client and server support both plain text and TLS connections)
```jt client = http2.connect('http://localhost:80');
const req = client.request({ ':path': '/some/path' });
req.on('data', (chunk) => { /* do something with the data */ });
req.on('end', () => {
client.destroy();
});
// Plain text (non-TLS server)
const server = http2.createServer();
server.on('stream', (stream, requestHeaders) => {
stream.respond({ ':status': 200 });
stream.write('hello ');
stream.end('world');
});
server.listen(80);
```
```js
const http2 = require('http2');
const client = http2.connect('http://localhost');
```
Author: Anna Henningsen <anna@addaleax.net>
Author: Colin Ihrig <cjihrig@gmail.com>
Author: Daniel Bevenius <daniel.bevenius@gmail.com>
Author: James M Snell <jasnell@gmail.com>
Author: Jun Mukai
Author: Kelvin Jin
Author: Matteo Collina <matteo.collina@gmail.com>
Author: Robert Kowalski <rok@kowalski.gd>
Author: Santiago Gimeno <santiago.gimeno@gmail.com>
Author: Sebastiaan Deckers <sebdeckers83@gmail.com>
Author: Yosuke Furukawa <yosuke.furukawa@gmail.com>
PR-URL: https://github.com/nodejs/node/pull/14239
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
8 years ago
|
|
|
const keys = Object.keys(map);
|
|
|
|
const singles = new Set();
|
|
|
|
for (var i = 0; i < keys.length; i++) {
|
|
|
|
let key = keys[i];
|
|
|
|
let value = map[key];
|
|
|
|
let val;
|
|
|
|
if (typeof key === 'symbol' || value === undefined || !key)
|
|
|
|
continue;
|
|
|
|
key = String(key).toLowerCase();
|
|
|
|
const isArray = Array.isArray(value);
|
|
|
|
if (isArray) {
|
|
|
|
switch (value.length) {
|
|
|
|
case 0:
|
|
|
|
continue;
|
|
|
|
case 1:
|
|
|
|
value = String(value[0]);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
if (kSingleValueHeaders.has(key))
|
|
|
|
return new errors.Error('ERR_HTTP2_HEADER_SINGLE_VALUE', key);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (key[0] === ':') {
|
|
|
|
const err = assertValuePseudoHeader(key);
|
|
|
|
if (err !== undefined)
|
|
|
|
return err;
|
|
|
|
ret = `${key}\0${String(value)}\0${ret}`;
|
|
|
|
count++;
|
http2: introducing HTTP/2
At long last: The initial *experimental* implementation of HTTP/2.
This is an accumulation of the work that has been done in the nodejs/http2
repository, squashed down to a couple of commits. The original commit
history has been preserved in the nodejs/http2 repository.
This PR introduces the nghttp2 C library as a new dependency. This library
provides the majority of the HTTP/2 protocol implementation, with the rest
of the code here providing the mapping of the library into a usable JS API.
Within src, a handful of new node_http2_*.c and node_http2_*.h files are
introduced. These provide the internal mechanisms that interface with nghttp
and define the `process.binding('http2')` interface.
The JS API is defined within `internal/http2/*.js`.
There are two APIs provided: Core and Compat.
The Core API is HTTP/2 specific and is designed to be as minimal and as
efficient as possible.
The Compat API is intended to be as close to the existing HTTP/1 API as
possible, with some exceptions.
Tests, documentation and initial benchmarks are included.
The `http2` module is gated by a new `--expose-http2` command line flag.
When used, `require('http2')` will be exposed to users. Note that there
is an existing `http2` module on npm that would be impacted by the introduction
of this module, which is the main reason for gating this behind a flag.
When using `require('http2')` the first time, a process warning will be
emitted indicating that an experimental feature is being used.
To run the benchmarks, the `h2load` tool (part of the nghttp project) is
required: `./node benchmarks/http2/simple.js benchmarker=h2load`. Only
two benchmarks are currently available.
Additional configuration options to enable verbose debugging are provided:
```
$ ./configure --debug-http2 --debug-nghttp2
$ NODE_DEBUG=http2 ./node
```
The `--debug-http2` configuration option enables verbose debug statements
from the `src/node_http2_*` files. The `--debug-nghttp2` enables the nghttp
library's own verbose debug output. The `NODE_DEBUG=http2` enables JS-level
debug output.
The following illustrates as simple HTTP/2 server and client interaction:
(The HTTP/2 client and server support both plain text and TLS connections)
```jt client = http2.connect('http://localhost:80');
const req = client.request({ ':path': '/some/path' });
req.on('data', (chunk) => { /* do something with the data */ });
req.on('end', () => {
client.destroy();
});
// Plain text (non-TLS server)
const server = http2.createServer();
server.on('stream', (stream, requestHeaders) => {
stream.respond({ ':status': 200 });
stream.write('hello ');
stream.end('world');
});
server.listen(80);
```
```js
const http2 = require('http2');
const client = http2.connect('http://localhost');
```
Author: Anna Henningsen <anna@addaleax.net>
Author: Colin Ihrig <cjihrig@gmail.com>
Author: Daniel Bevenius <daniel.bevenius@gmail.com>
Author: James M Snell <jasnell@gmail.com>
Author: Jun Mukai
Author: Kelvin Jin
Author: Matteo Collina <matteo.collina@gmail.com>
Author: Robert Kowalski <rok@kowalski.gd>
Author: Santiago Gimeno <santiago.gimeno@gmail.com>
Author: Sebastiaan Deckers <sebdeckers83@gmail.com>
Author: Yosuke Furukawa <yosuke.furukawa@gmail.com>
PR-URL: https://github.com/nodejs/node/pull/14239
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
8 years ago
|
|
|
} else {
|
|
|
|
if (kSingleValueHeaders.has(key)) {
|
|
|
|
if (singles.has(key))
|
|
|
|
return new errors.Error('ERR_HTTP2_HEADER_SINGLE_VALUE', key);
|
|
|
|
singles.add(key);
|
|
|
|
}
|
|
|
|
if (isIllegalConnectionSpecificHeader(key, value)) {
|
|
|
|
return new errors.Error('ERR_HTTP2_INVALID_CONNECTION_HEADERS');
|
|
|
|
}
|
|
|
|
if (isArray) {
|
|
|
|
for (var k = 0; k < value.length; k++) {
|
|
|
|
val = String(value[k]);
|
|
|
|
ret += `${key}\0${val}\0`;
|
http2: introducing HTTP/2
At long last: The initial *experimental* implementation of HTTP/2.
This is an accumulation of the work that has been done in the nodejs/http2
repository, squashed down to a couple of commits. The original commit
history has been preserved in the nodejs/http2 repository.
This PR introduces the nghttp2 C library as a new dependency. This library
provides the majority of the HTTP/2 protocol implementation, with the rest
of the code here providing the mapping of the library into a usable JS API.
Within src, a handful of new node_http2_*.c and node_http2_*.h files are
introduced. These provide the internal mechanisms that interface with nghttp
and define the `process.binding('http2')` interface.
The JS API is defined within `internal/http2/*.js`.
There are two APIs provided: Core and Compat.
The Core API is HTTP/2 specific and is designed to be as minimal and as
efficient as possible.
The Compat API is intended to be as close to the existing HTTP/1 API as
possible, with some exceptions.
Tests, documentation and initial benchmarks are included.
The `http2` module is gated by a new `--expose-http2` command line flag.
When used, `require('http2')` will be exposed to users. Note that there
is an existing `http2` module on npm that would be impacted by the introduction
of this module, which is the main reason for gating this behind a flag.
When using `require('http2')` the first time, a process warning will be
emitted indicating that an experimental feature is being used.
To run the benchmarks, the `h2load` tool (part of the nghttp project) is
required: `./node benchmarks/http2/simple.js benchmarker=h2load`. Only
two benchmarks are currently available.
Additional configuration options to enable verbose debugging are provided:
```
$ ./configure --debug-http2 --debug-nghttp2
$ NODE_DEBUG=http2 ./node
```
The `--debug-http2` configuration option enables verbose debug statements
from the `src/node_http2_*` files. The `--debug-nghttp2` enables the nghttp
library's own verbose debug output. The `NODE_DEBUG=http2` enables JS-level
debug output.
The following illustrates as simple HTTP/2 server and client interaction:
(The HTTP/2 client and server support both plain text and TLS connections)
```jt client = http2.connect('http://localhost:80');
const req = client.request({ ':path': '/some/path' });
req.on('data', (chunk) => { /* do something with the data */ });
req.on('end', () => {
client.destroy();
});
// Plain text (non-TLS server)
const server = http2.createServer();
server.on('stream', (stream, requestHeaders) => {
stream.respond({ ':status': 200 });
stream.write('hello ');
stream.end('world');
});
server.listen(80);
```
```js
const http2 = require('http2');
const client = http2.connect('http://localhost');
```
Author: Anna Henningsen <anna@addaleax.net>
Author: Colin Ihrig <cjihrig@gmail.com>
Author: Daniel Bevenius <daniel.bevenius@gmail.com>
Author: James M Snell <jasnell@gmail.com>
Author: Jun Mukai
Author: Kelvin Jin
Author: Matteo Collina <matteo.collina@gmail.com>
Author: Robert Kowalski <rok@kowalski.gd>
Author: Santiago Gimeno <santiago.gimeno@gmail.com>
Author: Sebastiaan Deckers <sebdeckers83@gmail.com>
Author: Yosuke Furukawa <yosuke.furukawa@gmail.com>
PR-URL: https://github.com/nodejs/node/pull/14239
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
8 years ago
|
|
|
}
|
|
|
|
count += value.length;
|
http2: introducing HTTP/2
At long last: The initial *experimental* implementation of HTTP/2.
This is an accumulation of the work that has been done in the nodejs/http2
repository, squashed down to a couple of commits. The original commit
history has been preserved in the nodejs/http2 repository.
This PR introduces the nghttp2 C library as a new dependency. This library
provides the majority of the HTTP/2 protocol implementation, with the rest
of the code here providing the mapping of the library into a usable JS API.
Within src, a handful of new node_http2_*.c and node_http2_*.h files are
introduced. These provide the internal mechanisms that interface with nghttp
and define the `process.binding('http2')` interface.
The JS API is defined within `internal/http2/*.js`.
There are two APIs provided: Core and Compat.
The Core API is HTTP/2 specific and is designed to be as minimal and as
efficient as possible.
The Compat API is intended to be as close to the existing HTTP/1 API as
possible, with some exceptions.
Tests, documentation and initial benchmarks are included.
The `http2` module is gated by a new `--expose-http2` command line flag.
When used, `require('http2')` will be exposed to users. Note that there
is an existing `http2` module on npm that would be impacted by the introduction
of this module, which is the main reason for gating this behind a flag.
When using `require('http2')` the first time, a process warning will be
emitted indicating that an experimental feature is being used.
To run the benchmarks, the `h2load` tool (part of the nghttp project) is
required: `./node benchmarks/http2/simple.js benchmarker=h2load`. Only
two benchmarks are currently available.
Additional configuration options to enable verbose debugging are provided:
```
$ ./configure --debug-http2 --debug-nghttp2
$ NODE_DEBUG=http2 ./node
```
The `--debug-http2` configuration option enables verbose debug statements
from the `src/node_http2_*` files. The `--debug-nghttp2` enables the nghttp
library's own verbose debug output. The `NODE_DEBUG=http2` enables JS-level
debug output.
The following illustrates as simple HTTP/2 server and client interaction:
(The HTTP/2 client and server support both plain text and TLS connections)
```jt client = http2.connect('http://localhost:80');
const req = client.request({ ':path': '/some/path' });
req.on('data', (chunk) => { /* do something with the data */ });
req.on('end', () => {
client.destroy();
});
// Plain text (non-TLS server)
const server = http2.createServer();
server.on('stream', (stream, requestHeaders) => {
stream.respond({ ':status': 200 });
stream.write('hello ');
stream.end('world');
});
server.listen(80);
```
```js
const http2 = require('http2');
const client = http2.connect('http://localhost');
```
Author: Anna Henningsen <anna@addaleax.net>
Author: Colin Ihrig <cjihrig@gmail.com>
Author: Daniel Bevenius <daniel.bevenius@gmail.com>
Author: James M Snell <jasnell@gmail.com>
Author: Jun Mukai
Author: Kelvin Jin
Author: Matteo Collina <matteo.collina@gmail.com>
Author: Robert Kowalski <rok@kowalski.gd>
Author: Santiago Gimeno <santiago.gimeno@gmail.com>
Author: Sebastiaan Deckers <sebdeckers83@gmail.com>
Author: Yosuke Furukawa <yosuke.furukawa@gmail.com>
PR-URL: https://github.com/nodejs/node/pull/14239
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
8 years ago
|
|
|
} else {
|
|
|
|
val = String(value);
|
|
|
|
ret += `${key}\0${val}\0`;
|
|
|
|
count++;
|
http2: introducing HTTP/2
At long last: The initial *experimental* implementation of HTTP/2.
This is an accumulation of the work that has been done in the nodejs/http2
repository, squashed down to a couple of commits. The original commit
history has been preserved in the nodejs/http2 repository.
This PR introduces the nghttp2 C library as a new dependency. This library
provides the majority of the HTTP/2 protocol implementation, with the rest
of the code here providing the mapping of the library into a usable JS API.
Within src, a handful of new node_http2_*.c and node_http2_*.h files are
introduced. These provide the internal mechanisms that interface with nghttp
and define the `process.binding('http2')` interface.
The JS API is defined within `internal/http2/*.js`.
There are two APIs provided: Core and Compat.
The Core API is HTTP/2 specific and is designed to be as minimal and as
efficient as possible.
The Compat API is intended to be as close to the existing HTTP/1 API as
possible, with some exceptions.
Tests, documentation and initial benchmarks are included.
The `http2` module is gated by a new `--expose-http2` command line flag.
When used, `require('http2')` will be exposed to users. Note that there
is an existing `http2` module on npm that would be impacted by the introduction
of this module, which is the main reason for gating this behind a flag.
When using `require('http2')` the first time, a process warning will be
emitted indicating that an experimental feature is being used.
To run the benchmarks, the `h2load` tool (part of the nghttp project) is
required: `./node benchmarks/http2/simple.js benchmarker=h2load`. Only
two benchmarks are currently available.
Additional configuration options to enable verbose debugging are provided:
```
$ ./configure --debug-http2 --debug-nghttp2
$ NODE_DEBUG=http2 ./node
```
The `--debug-http2` configuration option enables verbose debug statements
from the `src/node_http2_*` files. The `--debug-nghttp2` enables the nghttp
library's own verbose debug output. The `NODE_DEBUG=http2` enables JS-level
debug output.
The following illustrates as simple HTTP/2 server and client interaction:
(The HTTP/2 client and server support both plain text and TLS connections)
```jt client = http2.connect('http://localhost:80');
const req = client.request({ ':path': '/some/path' });
req.on('data', (chunk) => { /* do something with the data */ });
req.on('end', () => {
client.destroy();
});
// Plain text (non-TLS server)
const server = http2.createServer();
server.on('stream', (stream, requestHeaders) => {
stream.respond({ ':status': 200 });
stream.write('hello ');
stream.end('world');
});
server.listen(80);
```
```js
const http2 = require('http2');
const client = http2.connect('http://localhost');
```
Author: Anna Henningsen <anna@addaleax.net>
Author: Colin Ihrig <cjihrig@gmail.com>
Author: Daniel Bevenius <daniel.bevenius@gmail.com>
Author: James M Snell <jasnell@gmail.com>
Author: Jun Mukai
Author: Kelvin Jin
Author: Matteo Collina <matteo.collina@gmail.com>
Author: Robert Kowalski <rok@kowalski.gd>
Author: Santiago Gimeno <santiago.gimeno@gmail.com>
Author: Sebastiaan Deckers <sebdeckers83@gmail.com>
Author: Yosuke Furukawa <yosuke.furukawa@gmail.com>
PR-URL: https://github.com/nodejs/node/pull/14239
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
8 years ago
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return [ret, count];
|
http2: introducing HTTP/2
At long last: The initial *experimental* implementation of HTTP/2.
This is an accumulation of the work that has been done in the nodejs/http2
repository, squashed down to a couple of commits. The original commit
history has been preserved in the nodejs/http2 repository.
This PR introduces the nghttp2 C library as a new dependency. This library
provides the majority of the HTTP/2 protocol implementation, with the rest
of the code here providing the mapping of the library into a usable JS API.
Within src, a handful of new node_http2_*.c and node_http2_*.h files are
introduced. These provide the internal mechanisms that interface with nghttp
and define the `process.binding('http2')` interface.
The JS API is defined within `internal/http2/*.js`.
There are two APIs provided: Core and Compat.
The Core API is HTTP/2 specific and is designed to be as minimal and as
efficient as possible.
The Compat API is intended to be as close to the existing HTTP/1 API as
possible, with some exceptions.
Tests, documentation and initial benchmarks are included.
The `http2` module is gated by a new `--expose-http2` command line flag.
When used, `require('http2')` will be exposed to users. Note that there
is an existing `http2` module on npm that would be impacted by the introduction
of this module, which is the main reason for gating this behind a flag.
When using `require('http2')` the first time, a process warning will be
emitted indicating that an experimental feature is being used.
To run the benchmarks, the `h2load` tool (part of the nghttp project) is
required: `./node benchmarks/http2/simple.js benchmarker=h2load`. Only
two benchmarks are currently available.
Additional configuration options to enable verbose debugging are provided:
```
$ ./configure --debug-http2 --debug-nghttp2
$ NODE_DEBUG=http2 ./node
```
The `--debug-http2` configuration option enables verbose debug statements
from the `src/node_http2_*` files. The `--debug-nghttp2` enables the nghttp
library's own verbose debug output. The `NODE_DEBUG=http2` enables JS-level
debug output.
The following illustrates as simple HTTP/2 server and client interaction:
(The HTTP/2 client and server support both plain text and TLS connections)
```jt client = http2.connect('http://localhost:80');
const req = client.request({ ':path': '/some/path' });
req.on('data', (chunk) => { /* do something with the data */ });
req.on('end', () => {
client.destroy();
});
// Plain text (non-TLS server)
const server = http2.createServer();
server.on('stream', (stream, requestHeaders) => {
stream.respond({ ':status': 200 });
stream.write('hello ');
stream.end('world');
});
server.listen(80);
```
```js
const http2 = require('http2');
const client = http2.connect('http://localhost');
```
Author: Anna Henningsen <anna@addaleax.net>
Author: Colin Ihrig <cjihrig@gmail.com>
Author: Daniel Bevenius <daniel.bevenius@gmail.com>
Author: James M Snell <jasnell@gmail.com>
Author: Jun Mukai
Author: Kelvin Jin
Author: Matteo Collina <matteo.collina@gmail.com>
Author: Robert Kowalski <rok@kowalski.gd>
Author: Santiago Gimeno <santiago.gimeno@gmail.com>
Author: Sebastiaan Deckers <sebdeckers83@gmail.com>
Author: Yosuke Furukawa <yosuke.furukawa@gmail.com>
PR-URL: https://github.com/nodejs/node/pull/14239
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
8 years ago
|
|
|
}
|
|
|
|
|
|
|
|
class NghttpError extends Error {
|
|
|
|
constructor(ret) {
|
|
|
|
super(binding.nghttp2ErrorString(ret));
|
|
|
|
this.code = 'ERR_HTTP2_ERROR';
|
|
|
|
this.name = 'Error [ERR_HTTP2_ERROR]';
|
|
|
|
this.errno = ret;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function assertIsObject(value, name, types = 'object') {
|
http2: introducing HTTP/2
At long last: The initial *experimental* implementation of HTTP/2.
This is an accumulation of the work that has been done in the nodejs/http2
repository, squashed down to a couple of commits. The original commit
history has been preserved in the nodejs/http2 repository.
This PR introduces the nghttp2 C library as a new dependency. This library
provides the majority of the HTTP/2 protocol implementation, with the rest
of the code here providing the mapping of the library into a usable JS API.
Within src, a handful of new node_http2_*.c and node_http2_*.h files are
introduced. These provide the internal mechanisms that interface with nghttp
and define the `process.binding('http2')` interface.
The JS API is defined within `internal/http2/*.js`.
There are two APIs provided: Core and Compat.
The Core API is HTTP/2 specific and is designed to be as minimal and as
efficient as possible.
The Compat API is intended to be as close to the existing HTTP/1 API as
possible, with some exceptions.
Tests, documentation and initial benchmarks are included.
The `http2` module is gated by a new `--expose-http2` command line flag.
When used, `require('http2')` will be exposed to users. Note that there
is an existing `http2` module on npm that would be impacted by the introduction
of this module, which is the main reason for gating this behind a flag.
When using `require('http2')` the first time, a process warning will be
emitted indicating that an experimental feature is being used.
To run the benchmarks, the `h2load` tool (part of the nghttp project) is
required: `./node benchmarks/http2/simple.js benchmarker=h2load`. Only
two benchmarks are currently available.
Additional configuration options to enable verbose debugging are provided:
```
$ ./configure --debug-http2 --debug-nghttp2
$ NODE_DEBUG=http2 ./node
```
The `--debug-http2` configuration option enables verbose debug statements
from the `src/node_http2_*` files. The `--debug-nghttp2` enables the nghttp
library's own verbose debug output. The `NODE_DEBUG=http2` enables JS-level
debug output.
The following illustrates as simple HTTP/2 server and client interaction:
(The HTTP/2 client and server support both plain text and TLS connections)
```jt client = http2.connect('http://localhost:80');
const req = client.request({ ':path': '/some/path' });
req.on('data', (chunk) => { /* do something with the data */ });
req.on('end', () => {
client.destroy();
});
// Plain text (non-TLS server)
const server = http2.createServer();
server.on('stream', (stream, requestHeaders) => {
stream.respond({ ':status': 200 });
stream.write('hello ');
stream.end('world');
});
server.listen(80);
```
```js
const http2 = require('http2');
const client = http2.connect('http://localhost');
```
Author: Anna Henningsen <anna@addaleax.net>
Author: Colin Ihrig <cjihrig@gmail.com>
Author: Daniel Bevenius <daniel.bevenius@gmail.com>
Author: James M Snell <jasnell@gmail.com>
Author: Jun Mukai
Author: Kelvin Jin
Author: Matteo Collina <matteo.collina@gmail.com>
Author: Robert Kowalski <rok@kowalski.gd>
Author: Santiago Gimeno <santiago.gimeno@gmail.com>
Author: Sebastiaan Deckers <sebdeckers83@gmail.com>
Author: Yosuke Furukawa <yosuke.furukawa@gmail.com>
PR-URL: https://github.com/nodejs/node/pull/14239
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
8 years ago
|
|
|
if (value !== undefined &&
|
|
|
|
(value === null ||
|
|
|
|
typeof value !== 'object' ||
|
|
|
|
Array.isArray(value))) {
|
|
|
|
const err = new errors.TypeError('ERR_INVALID_ARG_TYPE', name, types);
|
http2: introducing HTTP/2
At long last: The initial *experimental* implementation of HTTP/2.
This is an accumulation of the work that has been done in the nodejs/http2
repository, squashed down to a couple of commits. The original commit
history has been preserved in the nodejs/http2 repository.
This PR introduces the nghttp2 C library as a new dependency. This library
provides the majority of the HTTP/2 protocol implementation, with the rest
of the code here providing the mapping of the library into a usable JS API.
Within src, a handful of new node_http2_*.c and node_http2_*.h files are
introduced. These provide the internal mechanisms that interface with nghttp
and define the `process.binding('http2')` interface.
The JS API is defined within `internal/http2/*.js`.
There are two APIs provided: Core and Compat.
The Core API is HTTP/2 specific and is designed to be as minimal and as
efficient as possible.
The Compat API is intended to be as close to the existing HTTP/1 API as
possible, with some exceptions.
Tests, documentation and initial benchmarks are included.
The `http2` module is gated by a new `--expose-http2` command line flag.
When used, `require('http2')` will be exposed to users. Note that there
is an existing `http2` module on npm that would be impacted by the introduction
of this module, which is the main reason for gating this behind a flag.
When using `require('http2')` the first time, a process warning will be
emitted indicating that an experimental feature is being used.
To run the benchmarks, the `h2load` tool (part of the nghttp project) is
required: `./node benchmarks/http2/simple.js benchmarker=h2load`. Only
two benchmarks are currently available.
Additional configuration options to enable verbose debugging are provided:
```
$ ./configure --debug-http2 --debug-nghttp2
$ NODE_DEBUG=http2 ./node
```
The `--debug-http2` configuration option enables verbose debug statements
from the `src/node_http2_*` files. The `--debug-nghttp2` enables the nghttp
library's own verbose debug output. The `NODE_DEBUG=http2` enables JS-level
debug output.
The following illustrates as simple HTTP/2 server and client interaction:
(The HTTP/2 client and server support both plain text and TLS connections)
```jt client = http2.connect('http://localhost:80');
const req = client.request({ ':path': '/some/path' });
req.on('data', (chunk) => { /* do something with the data */ });
req.on('end', () => {
client.destroy();
});
// Plain text (non-TLS server)
const server = http2.createServer();
server.on('stream', (stream, requestHeaders) => {
stream.respond({ ':status': 200 });
stream.write('hello ');
stream.end('world');
});
server.listen(80);
```
```js
const http2 = require('http2');
const client = http2.connect('http://localhost');
```
Author: Anna Henningsen <anna@addaleax.net>
Author: Colin Ihrig <cjihrig@gmail.com>
Author: Daniel Bevenius <daniel.bevenius@gmail.com>
Author: James M Snell <jasnell@gmail.com>
Author: Jun Mukai
Author: Kelvin Jin
Author: Matteo Collina <matteo.collina@gmail.com>
Author: Robert Kowalski <rok@kowalski.gd>
Author: Santiago Gimeno <santiago.gimeno@gmail.com>
Author: Sebastiaan Deckers <sebdeckers83@gmail.com>
Author: Yosuke Furukawa <yosuke.furukawa@gmail.com>
PR-URL: https://github.com/nodejs/node/pull/14239
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
8 years ago
|
|
|
Error.captureStackTrace(err, assertIsObject);
|
|
|
|
throw err;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function assertWithinRange(name, value, min = 0, max = Infinity) {
|
|
|
|
if (value !== undefined &&
|
|
|
|
(typeof value !== 'number' || value < min || value > max)) {
|
|
|
|
const err = new errors.RangeError('ERR_HTTP2_INVALID_SETTING_VALUE',
|
|
|
|
name, value);
|
|
|
|
err.min = min;
|
|
|
|
err.max = max;
|
|
|
|
err.actual = value;
|
|
|
|
Error.captureStackTrace(err, assertWithinRange);
|
|
|
|
throw err;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function toHeaderObject(headers) {
|
|
|
|
const obj = Object.create(null);
|
|
|
|
for (var n = 0; n < headers.length; n = n + 2) {
|
|
|
|
var name = headers[n];
|
|
|
|
var value = headers[n + 1];
|
|
|
|
if (name === HTTP2_HEADER_STATUS)
|
|
|
|
value |= 0;
|
|
|
|
var existing = obj[name];
|
|
|
|
if (existing === undefined) {
|
|
|
|
obj[name] = value;
|
|
|
|
} else if (!kSingleValueHeaders.has(name)) {
|
|
|
|
switch (name) {
|
|
|
|
case HTTP2_HEADER_COOKIE:
|
|
|
|
// https://tools.ietf.org/html/rfc7540#section-8.1.2.5
|
|
|
|
// "...If there are multiple Cookie header fields after decompression,
|
|
|
|
// these MUST be concatenated into a single octet string using the
|
|
|
|
// two-octet delimiter of 0x3B, 0x20 (the ASCII string "; ") before
|
|
|
|
// being passed into a non-HTTP/2 context."
|
|
|
|
obj[name] = `${existing}; ${value}`;
|
|
|
|
break;
|
|
|
|
case HTTP2_HEADER_SET_COOKIE:
|
|
|
|
// https://tools.ietf.org/html/rfc7230#section-3.2.2
|
|
|
|
// "Note: In practice, the "Set-Cookie" header field ([RFC6265]) often
|
|
|
|
// appears multiple times in a response message and does not use the
|
|
|
|
// list syntax, violating the above requirements on multiple header
|
|
|
|
// fields with the same name. Since it cannot be combined into a
|
|
|
|
// single field-value, recipients ought to handle "Set-Cookie" as a
|
|
|
|
// special case while processing header fields."
|
|
|
|
if (Array.isArray(existing))
|
|
|
|
existing.push(value);
|
|
|
|
else
|
|
|
|
obj[name] = [existing, value];
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
// https://tools.ietf.org/html/rfc7230#section-3.2.2
|
|
|
|
// "A recipient MAY combine multiple header fields with the same field
|
|
|
|
// name into one "field-name: field-value" pair, without changing the
|
|
|
|
// semantics of the message, by appending each subsequent field value
|
|
|
|
// to the combined field value in order, separated by a comma."
|
|
|
|
obj[name] = `${existing}, ${value}`;
|
|
|
|
break;
|
http2: introducing HTTP/2
At long last: The initial *experimental* implementation of HTTP/2.
This is an accumulation of the work that has been done in the nodejs/http2
repository, squashed down to a couple of commits. The original commit
history has been preserved in the nodejs/http2 repository.
This PR introduces the nghttp2 C library as a new dependency. This library
provides the majority of the HTTP/2 protocol implementation, with the rest
of the code here providing the mapping of the library into a usable JS API.
Within src, a handful of new node_http2_*.c and node_http2_*.h files are
introduced. These provide the internal mechanisms that interface with nghttp
and define the `process.binding('http2')` interface.
The JS API is defined within `internal/http2/*.js`.
There are two APIs provided: Core and Compat.
The Core API is HTTP/2 specific and is designed to be as minimal and as
efficient as possible.
The Compat API is intended to be as close to the existing HTTP/1 API as
possible, with some exceptions.
Tests, documentation and initial benchmarks are included.
The `http2` module is gated by a new `--expose-http2` command line flag.
When used, `require('http2')` will be exposed to users. Note that there
is an existing `http2` module on npm that would be impacted by the introduction
of this module, which is the main reason for gating this behind a flag.
When using `require('http2')` the first time, a process warning will be
emitted indicating that an experimental feature is being used.
To run the benchmarks, the `h2load` tool (part of the nghttp project) is
required: `./node benchmarks/http2/simple.js benchmarker=h2load`. Only
two benchmarks are currently available.
Additional configuration options to enable verbose debugging are provided:
```
$ ./configure --debug-http2 --debug-nghttp2
$ NODE_DEBUG=http2 ./node
```
The `--debug-http2` configuration option enables verbose debug statements
from the `src/node_http2_*` files. The `--debug-nghttp2` enables the nghttp
library's own verbose debug output. The `NODE_DEBUG=http2` enables JS-level
debug output.
The following illustrates as simple HTTP/2 server and client interaction:
(The HTTP/2 client and server support both plain text and TLS connections)
```jt client = http2.connect('http://localhost:80');
const req = client.request({ ':path': '/some/path' });
req.on('data', (chunk) => { /* do something with the data */ });
req.on('end', () => {
client.destroy();
});
// Plain text (non-TLS server)
const server = http2.createServer();
server.on('stream', (stream, requestHeaders) => {
stream.respond({ ':status': 200 });
stream.write('hello ');
stream.end('world');
});
server.listen(80);
```
```js
const http2 = require('http2');
const client = http2.connect('http://localhost');
```
Author: Anna Henningsen <anna@addaleax.net>
Author: Colin Ihrig <cjihrig@gmail.com>
Author: Daniel Bevenius <daniel.bevenius@gmail.com>
Author: James M Snell <jasnell@gmail.com>
Author: Jun Mukai
Author: Kelvin Jin
Author: Matteo Collina <matteo.collina@gmail.com>
Author: Robert Kowalski <rok@kowalski.gd>
Author: Santiago Gimeno <santiago.gimeno@gmail.com>
Author: Sebastiaan Deckers <sebdeckers83@gmail.com>
Author: Yosuke Furukawa <yosuke.furukawa@gmail.com>
PR-URL: https://github.com/nodejs/node/pull/14239
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
8 years ago
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return obj;
|
|
|
|
}
|
|
|
|
|
|
|
|
function isPayloadMeaningless(method) {
|
|
|
|
return kNoPayloadMethods.has(method);
|
|
|
|
}
|
|
|
|
|
|
|
|
function sessionName(type) {
|
|
|
|
switch (type) {
|
|
|
|
case NGHTTP2_SESSION_CLIENT:
|
|
|
|
return 'client';
|
|
|
|
case NGHTTP2_SESSION_SERVER:
|
|
|
|
return 'server';
|
|
|
|
default:
|
|
|
|
return '<invalid>';
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
http2: introducing HTTP/2
At long last: The initial *experimental* implementation of HTTP/2.
This is an accumulation of the work that has been done in the nodejs/http2
repository, squashed down to a couple of commits. The original commit
history has been preserved in the nodejs/http2 repository.
This PR introduces the nghttp2 C library as a new dependency. This library
provides the majority of the HTTP/2 protocol implementation, with the rest
of the code here providing the mapping of the library into a usable JS API.
Within src, a handful of new node_http2_*.c and node_http2_*.h files are
introduced. These provide the internal mechanisms that interface with nghttp
and define the `process.binding('http2')` interface.
The JS API is defined within `internal/http2/*.js`.
There are two APIs provided: Core and Compat.
The Core API is HTTP/2 specific and is designed to be as minimal and as
efficient as possible.
The Compat API is intended to be as close to the existing HTTP/1 API as
possible, with some exceptions.
Tests, documentation and initial benchmarks are included.
The `http2` module is gated by a new `--expose-http2` command line flag.
When used, `require('http2')` will be exposed to users. Note that there
is an existing `http2` module on npm that would be impacted by the introduction
of this module, which is the main reason for gating this behind a flag.
When using `require('http2')` the first time, a process warning will be
emitted indicating that an experimental feature is being used.
To run the benchmarks, the `h2load` tool (part of the nghttp project) is
required: `./node benchmarks/http2/simple.js benchmarker=h2load`. Only
two benchmarks are currently available.
Additional configuration options to enable verbose debugging are provided:
```
$ ./configure --debug-http2 --debug-nghttp2
$ NODE_DEBUG=http2 ./node
```
The `--debug-http2` configuration option enables verbose debug statements
from the `src/node_http2_*` files. The `--debug-nghttp2` enables the nghttp
library's own verbose debug output. The `NODE_DEBUG=http2` enables JS-level
debug output.
The following illustrates as simple HTTP/2 server and client interaction:
(The HTTP/2 client and server support both plain text and TLS connections)
```jt client = http2.connect('http://localhost:80');
const req = client.request({ ':path': '/some/path' });
req.on('data', (chunk) => { /* do something with the data */ });
req.on('end', () => {
client.destroy();
});
// Plain text (non-TLS server)
const server = http2.createServer();
server.on('stream', (stream, requestHeaders) => {
stream.respond({ ':status': 200 });
stream.write('hello ');
stream.end('world');
});
server.listen(80);
```
```js
const http2 = require('http2');
const client = http2.connect('http://localhost');
```
Author: Anna Henningsen <anna@addaleax.net>
Author: Colin Ihrig <cjihrig@gmail.com>
Author: Daniel Bevenius <daniel.bevenius@gmail.com>
Author: James M Snell <jasnell@gmail.com>
Author: Jun Mukai
Author: Kelvin Jin
Author: Matteo Collina <matteo.collina@gmail.com>
Author: Robert Kowalski <rok@kowalski.gd>
Author: Santiago Gimeno <santiago.gimeno@gmail.com>
Author: Sebastiaan Deckers <sebdeckers83@gmail.com>
Author: Yosuke Furukawa <yosuke.furukawa@gmail.com>
PR-URL: https://github.com/nodejs/node/pull/14239
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
8 years ago
|
|
|
module.exports = {
|
|
|
|
assertIsObject,
|
|
|
|
assertValidPseudoHeaderResponse,
|
|
|
|
assertValidPseudoHeaderTrailer,
|
|
|
|
assertWithinRange,
|
|
|
|
getDefaultSettings,
|
|
|
|
getSessionState,
|
|
|
|
getSettings,
|
|
|
|
getStreamState,
|
|
|
|
isPayloadMeaningless,
|
|
|
|
mapToHeaders,
|
|
|
|
NghttpError,
|
|
|
|
sessionName,
|
http2: introducing HTTP/2
At long last: The initial *experimental* implementation of HTTP/2.
This is an accumulation of the work that has been done in the nodejs/http2
repository, squashed down to a couple of commits. The original commit
history has been preserved in the nodejs/http2 repository.
This PR introduces the nghttp2 C library as a new dependency. This library
provides the majority of the HTTP/2 protocol implementation, with the rest
of the code here providing the mapping of the library into a usable JS API.
Within src, a handful of new node_http2_*.c and node_http2_*.h files are
introduced. These provide the internal mechanisms that interface with nghttp
and define the `process.binding('http2')` interface.
The JS API is defined within `internal/http2/*.js`.
There are two APIs provided: Core and Compat.
The Core API is HTTP/2 specific and is designed to be as minimal and as
efficient as possible.
The Compat API is intended to be as close to the existing HTTP/1 API as
possible, with some exceptions.
Tests, documentation and initial benchmarks are included.
The `http2` module is gated by a new `--expose-http2` command line flag.
When used, `require('http2')` will be exposed to users. Note that there
is an existing `http2` module on npm that would be impacted by the introduction
of this module, which is the main reason for gating this behind a flag.
When using `require('http2')` the first time, a process warning will be
emitted indicating that an experimental feature is being used.
To run the benchmarks, the `h2load` tool (part of the nghttp project) is
required: `./node benchmarks/http2/simple.js benchmarker=h2load`. Only
two benchmarks are currently available.
Additional configuration options to enable verbose debugging are provided:
```
$ ./configure --debug-http2 --debug-nghttp2
$ NODE_DEBUG=http2 ./node
```
The `--debug-http2` configuration option enables verbose debug statements
from the `src/node_http2_*` files. The `--debug-nghttp2` enables the nghttp
library's own verbose debug output. The `NODE_DEBUG=http2` enables JS-level
debug output.
The following illustrates as simple HTTP/2 server and client interaction:
(The HTTP/2 client and server support both plain text and TLS connections)
```jt client = http2.connect('http://localhost:80');
const req = client.request({ ':path': '/some/path' });
req.on('data', (chunk) => { /* do something with the data */ });
req.on('end', () => {
client.destroy();
});
// Plain text (non-TLS server)
const server = http2.createServer();
server.on('stream', (stream, requestHeaders) => {
stream.respond({ ':status': 200 });
stream.write('hello ');
stream.end('world');
});
server.listen(80);
```
```js
const http2 = require('http2');
const client = http2.connect('http://localhost');
```
Author: Anna Henningsen <anna@addaleax.net>
Author: Colin Ihrig <cjihrig@gmail.com>
Author: Daniel Bevenius <daniel.bevenius@gmail.com>
Author: James M Snell <jasnell@gmail.com>
Author: Jun Mukai
Author: Kelvin Jin
Author: Matteo Collina <matteo.collina@gmail.com>
Author: Robert Kowalski <rok@kowalski.gd>
Author: Santiago Gimeno <santiago.gimeno@gmail.com>
Author: Sebastiaan Deckers <sebdeckers83@gmail.com>
Author: Yosuke Furukawa <yosuke.furukawa@gmail.com>
PR-URL: https://github.com/nodejs/node/pull/14239
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
8 years ago
|
|
|
toHeaderObject,
|
|
|
|
updateOptionsBuffer,
|
|
|
|
updateSettingsBuffer
|
|
|
|
};
|