Comparing version 1.0.0 to 1.0.1
@@ -12,3 +12,7 @@ var fs = require('fs'); | ||
// Sending the request | ||
var request = http2.get(process.argv.pop()); | ||
// It would be `var request = http2.get(process.argv.pop());` if we wouldn't care about plain mode | ||
var options = require('url').parse(process.argv.pop()); | ||
options.plain = Boolean(process.env.HTTP2_PLAIN); | ||
var request = http2.request(options); | ||
request.end(); | ||
@@ -15,0 +19,0 @@ // Receiving the response |
@@ -5,10 +5,17 @@ var fs = require('fs'); | ||
var serverjs = fs.readFileSync(path.join(__dirname, './server.js')); | ||
var options = { | ||
var options = process.env.HTTP2_PLAIN ? { | ||
plain: true | ||
} : { | ||
key: fs.readFileSync(path.join(__dirname, '/localhost.key')), | ||
cert: fs.readFileSync(path.join(__dirname, '/localhost.crt')), | ||
log: require('../test/util').createLogger('server') | ||
cert: fs.readFileSync(path.join(__dirname, '/localhost.crt')) | ||
}; | ||
// Passing bunyan logger (optional) | ||
options.log = require('../test/util').createLogger('server'); | ||
// We cache one file to be able to do simple performance tests without waiting for the disk | ||
var cachedFile = fs.readFileSync(path.join(__dirname, './server.js')); | ||
var cachedUrl = '/server.js'; | ||
// Creating the server | ||
var server = http2.createServer(options, function(request, response) { | ||
@@ -18,4 +25,4 @@ var filename = path.join(__dirname, request.url); | ||
// Serving server.js from cache. Useful for microbenchmarks. | ||
if (request.url === '/server.js') { | ||
response.end(serverjs); | ||
if (request.url === cachedUrl) { | ||
response.end(cachedFile); | ||
} | ||
@@ -22,0 +29,0 @@ |
Version history | ||
=============== | ||
### 1.0.1 (2013-10-14) ### | ||
* Support for ALPN if node supports it (currently needs a custom build) | ||
* Fix for a few small issues | ||
* [Tarball](https://github.com/molnarg/node-http2/archive/node-http2-1.0.1.tar.gz) | ||
### 1.0.0 (2013-09-23) ### | ||
@@ -5,0 +11,0 @@ |
@@ -13,2 +13,5 @@ // Public API | ||
// | ||
// - **Class: http2.Endpoint**: an API for using the raw HTTP/2 framing layer. For documentation | ||
// see the [lib/endpoint.js](endpoint.html) file. | ||
// | ||
// - **Class: http2.Server** | ||
@@ -159,2 +162,10 @@ // - **Event: 'connection' (socket, [endpoint])**: there's a second argument if the negotiation of | ||
// When doing NPN/ALPN negotiation, HTTP/1.1 is used as fallback | ||
var supportedProtocols = [implementedVersion, 'http/1.1', 'http/1.0']; | ||
// Using ALPN or NPN depending on node.js support (preferring ALPN) | ||
var negotiationMethod = process.features.tls_alpn ? 'ALPN' : 'NPN'; | ||
var protocolList = process.features.tls_alpn ? 'ALPNProtocols' : 'NPNProtocols'; | ||
var negotiatedProtocol = process.features.tls_alpn ? 'alpnProtocol' : 'npnProtocol'; | ||
// Logging | ||
@@ -203,5 +214,7 @@ // ------- | ||
this.trailers = undefined; | ||
this._lastHeadersSeen = undefined; | ||
// * Other metadata is filled in when the headers arrive. | ||
stream.once('headers', this._onHeaders.bind(this)); | ||
stream.once('end', this._onEnd.bind(this)); | ||
} | ||
@@ -235,8 +248,11 @@ IncomingMessage.prototype = Object.create(PassThrough.prototype, { constructor: { value: IncomingMessage } }); | ||
// * The next header block, if any, will represent the trailers | ||
this.stream.once('headers', this._onTrailers.bind(this)); | ||
// * The last header block, if it's not the first, will represent the trailers | ||
var self = this; | ||
this.stream.on('headers', function(headers) { | ||
self._lastHeadersSeen = headers; | ||
}); | ||
}; | ||
IncomingMessage.prototype._onTrailers = function _onTrailers(trailers) { | ||
this.trailers = trailers; | ||
IncomingMessage.prototype._onEnd = function _onEnd() { | ||
this.trailers = this._lastHeadersSeen; | ||
}; | ||
@@ -347,7 +363,7 @@ | ||
// HTTP2 over TLS (using NPN instean of ALPN) | ||
// HTTP2 over TLS (using NPN or ALPN) | ||
if ((options.key && options.cert) || options.pfx) { | ||
this._log.info('Creating HTTP/2 server over TLS/NPN'); | ||
this._log.info('Creating HTTP/2 server over TLS/' + negotiationMethod); | ||
this._mode = 'tls'; | ||
options.NPNProtocols = [implementedVersion, 'http/1.1', 'http/1.0']; | ||
options[protocolList] = supportedProtocols; | ||
this._server = https.createServer(options); | ||
@@ -357,3 +373,3 @@ this._originalSocketListeners = this._server.listeners('secureConnection'); | ||
this._server.on('secureConnection', function(socket) { | ||
if (socket.npnProtocol === implementedVersion && socket.servername) { | ||
if (socket[negotiatedProtocol] === implementedVersion && socket.servername) { | ||
start(socket); | ||
@@ -410,3 +426,3 @@ } else { | ||
this._log.info({ client: socket.remoteAddress + ':' + socket.remotePort, | ||
protocol: socket.npnProtocol, | ||
protocol: socket[negotiatedProtocol], | ||
SNI: socket.servername | ||
@@ -652,9 +668,9 @@ }, 'Falling back to simple HTTPS'); | ||
// * Using an own HTTPS agent, because the global agent does not look at `NPNProtocols` when | ||
// * Using an own HTTPS agent, because the global agent does not look at `NPN/ALPNProtocols` when | ||
// generating the key identifying the connection, so we may get useless non-negotiated TLS | ||
// channels even if we ask for a negotiated one. This agent will contain only negotiated | ||
// channels. | ||
this._httpsAgent = new https.Agent({ | ||
NPNProtocols: [implementedVersion, 'http/1.1', 'http/1.0'] | ||
}); | ||
var agentOptions = {}; | ||
agentOptions[protocolList] = supportedProtocols; | ||
this._httpsAgent = new https.Agent(agentOptions); | ||
@@ -677,3 +693,3 @@ this.sockets = this._httpsAgent.sockets; | ||
if (options.protocol === 'http:') { | ||
if (!options.plain && options.protocol === 'http:') { | ||
this._log.error('Trying to negotiate client request with Upgrade from HTTP/1.1'); | ||
@@ -713,6 +729,6 @@ throw new Error('HTTP1.1 -> HTTP2 upgrade is not yet supported.'); | ||
// * HTTP/2 over TLS negotiated using NPN (or later ALPN) | ||
// * HTTP/2 over TLS negotiated using NPN or ALPN | ||
else { | ||
var started = false; | ||
options.NPNProtocols = [implementedVersion, 'http/1.1', 'http/1.0']; | ||
options[protocolList] = supportedProtocols; | ||
options.servername = options.host; // Server Name Indication | ||
@@ -723,3 +739,3 @@ options.agent = this._httpsAgent; | ||
httpsRequest.on('socket', function(socket) { | ||
if (socket.npnProtocol !== undefined) { | ||
if (socket[negotiatedProtocol] !== undefined) { | ||
negotiated(); | ||
@@ -734,3 +750,3 @@ } else { | ||
var endpoint; | ||
if (httpsRequest.socket.npnProtocol === implementedVersion) { | ||
if (httpsRequest.socket[negotiatedProtocol] === implementedVersion) { | ||
httpsRequest.socket.emit('agentRemove'); | ||
@@ -936,5 +952,6 @@ unbundleSocket(httpsRequest.socket); | ||
// values, or an invalid value as a stream error of type PROTOCOL_ERROR. | ||
// Note: currently, we do not enforce it strictly: we accept any format, and parse it as int | ||
// * HTTP/2.0 does not define a way to carry the reason phrase that is included in an HTTP/1.1 | ||
// status line. | ||
this.statusCode = this._checkSpecialHeader(':status', headers[':status']); | ||
this.statusCode = parseInt(this._checkSpecialHeader(':status', headers[':status'])); | ||
@@ -941,0 +958,0 @@ // * Handling regular headers. |
{ | ||
"name": "http2", | ||
"version": "1.0.0", | ||
"version": "1.0.1", | ||
"description": "An HTTP/2 client and server implementation", | ||
@@ -35,4 +35,8 @@ "main": "lib/index.js", | ||
"author": "Gábor Molnár <gabor@molnar.es> (http://gabor.molnar.es)", | ||
"contributors": [ | ||
"Nick Hurley", | ||
"Mike Belshe" | ||
], | ||
"license": "MIT", | ||
"readmeFilename": "README.md" | ||
} |
@@ -5,4 +5,3 @@ node-http2 | ||
An HTTP/2 ([draft-ietf-httpbis-http2-06](http://tools.ietf.org/html/draft-ietf-httpbis-http2-06)) | ||
client and server implementation for node.js, developed as a [Google Summer of Code | ||
project](https://google-melange.appspot.com/gsoc/project/google/gsoc2013/molnarg/5001). | ||
client and server implementation for node.js. | ||
@@ -77,11 +76,10 @@ Installation | ||
I post weekly status updates [on my blog](http://gabor.molnar.es/blog/categories/google-summer-of-code/). | ||
Short version: main missing items are: | ||
* ALPN support for negotiating HTTP/2 over TLS (it's done with NPN for now) | ||
(issue [#5](https://github.com/molnarg/node-http2/issues/5)) | ||
* Upgrade mechanism to start HTTP/2 over unencrypted channel | ||
* ALPN is not yet supported in node.js (see | ||
[this issue](https://github.com/joyent/node/issues/5945)). For ALPN support, you will have to use | ||
[Shigeki Ohtsu's node.js fork](https://github.com/shigeki/node/tree/alpn_support) until this code | ||
gets merged upstream. | ||
* Upgrade mechanism to start HTTP/2 over unencrypted channel is not implemented yet | ||
(issue [#4](https://github.com/molnarg/node-http2/issues/4)) | ||
* Other minor features found in | ||
[this list](https://github.com/molnarg/node-http2/issues?labels=feature) | ||
[this list](https://github.com/molnarg/node-http2/issues?labels=feature) are not implemented yet | ||
@@ -121,8 +119,8 @@ Development | ||
To generate a code coverage report, run `npm test --coverage` (which runs very slowly, be patient). | ||
Code coverage summary as of version 0.4.1: | ||
Code coverage summary as of version 1.0.1: | ||
``` | ||
Statements : 93.33% ( 1538/1648 ) | ||
Branches : 84.91% ( 585/689 ) | ||
Functions : 95.65% ( 198/207 ) | ||
Lines : 93.3% ( 1532/1642 ) | ||
Statements : 93.26% ( 1563/1676 ) | ||
Branches : 84.85% ( 605/713 ) | ||
Functions : 94.81% ( 201/212 ) | ||
Lines : 93.23% ( 1557/1670 ) | ||
``` | ||
@@ -163,4 +161,5 @@ | ||
Special thanks to Google for financing the development of this module as part of their [Summer of | ||
Code program](https://developers.google.com/open-source/soc/), and Nick Hurley of Mozilla, my GSoC | ||
mentor, who helps with regular code review and technical advices. | ||
Code program](https://developers.google.com/open-source/soc/) (project: [HTTP/2 prototype server | ||
implementation](https://google-melange.appspot.com/gsoc/project/google/gsoc2013/molnarg/5001)), and | ||
Nick Hurley of Mozilla, my GSoC mentor, who helped with regular code review and technical advices. | ||
@@ -167,0 +166,0 @@ License |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
1042289
6494
168
13