Comparing version 0.1.4 to 1.0.0
@@ -1,55 +0,15 @@ | ||
/** | ||
* SPDY server implementation | ||
*/ | ||
var spdy = exports; | ||
/** | ||
* zlib wrapper | ||
*/ | ||
spdy.ZLib = require('./spdy/zlib').ZLib; | ||
spdy.createZLib = require('./spdy/zlib').createZLib; | ||
// Exports utils | ||
spdy.utils = require('./spdy/utils'); | ||
/** | ||
* enums | ||
*/ | ||
spdy.enums = require('./spdy/enums').enums; | ||
// Export parser&framer | ||
spdy.parser = require('./spdy/parser'); | ||
spdy.framer = require('./spdy/framer'); | ||
/** | ||
* protocol | ||
*/ | ||
spdy.createControlFrame = require('./spdy/protocol').createControlFrame; | ||
spdy.createRstFrame = require('./spdy/protocol').createRstFrame; | ||
spdy.createSettingsFrame = require('./spdy/protocol').createSettingsFrame; | ||
spdy.createDataFrame = require('./spdy/protocol').createDataFrame; | ||
// Export ServerResponse | ||
spdy.response = require('./spdy/response'); | ||
/** | ||
* parser | ||
*/ | ||
spdy.createParser = require('./spdy/parser').createParser; | ||
spdy.Parser = require('./spdy/parser').Parser; | ||
/** | ||
* request | ||
*/ | ||
spdy.Request = require('./spdy/request').Request; | ||
spdy.createRequest = require('./spdy/request').createRequest; | ||
/** | ||
* push stream | ||
*/ | ||
spdy.PushStream = require('./spdy/push_stream').PushStream; | ||
spdy.createPushStream = require('./spdy/push_stream').createPushStream; | ||
/** | ||
* response | ||
*/ | ||
spdy.Response = require('./spdy/response').Response; | ||
spdy.createResponse = require('./spdy/response').createResponse; | ||
/** | ||
* core | ||
*/ | ||
spdy.createServer = require('./spdy/core').createServer; | ||
spdy.Server = require('./spdy/core').Server; | ||
// Export server | ||
spdy.server = require('./spdy/server'); | ||
spdy.createServer = spdy.server.create; |
@@ -1,185 +0,152 @@ | ||
/** | ||
* Protocol Parser | ||
*/ | ||
var parser = exports; | ||
var Buffer = require('buffer').Buffer, | ||
Stream = require('stream').Stream, | ||
util = require('util'); | ||
var spdy = require('../spdy'), | ||
util = require('util'), | ||
stream = require('stream'), | ||
Buffer = require('buffer').Buffer; | ||
var enums = require('../spdy').enums; | ||
// | ||
// ### function Parser (connection) | ||
// #### @connection {Connection} SPDY connection | ||
// SPDY protocol frames parser's @constructor | ||
// | ||
function Parser(connection) { | ||
stream.Stream.call(this); | ||
/** | ||
* Compatibility with older versions of node | ||
*/ | ||
if (!Buffer.prototype.readUInt32BE) { | ||
Buffer.prototype.readUInt32BE = function(offset, noAssert) { | ||
return this.readUInt32(offset, 'big'); | ||
}; | ||
Buffer.prototype.readUInt16BE = function(offset, noAssert) { | ||
return this.readUInt16(offset, 'big'); | ||
}; | ||
} | ||
this.paused = false; | ||
this.buffer = []; | ||
this.buffered = 0; | ||
this.waiting = 8; | ||
/** | ||
* Class @constructor | ||
*/ | ||
var Parser = exports.Parser = function(zlib) { | ||
Stream.call(this); | ||
this.state = { type: 'frame-head' }; | ||
this.connection = connection; | ||
this.writable = this.readable = true; | ||
this.readable = this.writable = true; | ||
} | ||
util.inherits(Parser, stream.Stream); | ||
this.zlib = zlib; | ||
this.buffers = []; | ||
// | ||
// ### function create (connection) | ||
// #### @connection {Connection} SPDY connection | ||
// @constructor wrapper | ||
// | ||
parser.create = function create(connection) { | ||
return new Parser(connection); | ||
}; | ||
util.inherits(Parser, Stream); | ||
exports.createParser = function(zlib) { | ||
return new Parser(zlib); | ||
}; | ||
/** | ||
* Bufferize written data | ||
*/ | ||
Parser.prototype.write = function(chunk) { | ||
this.buffers.push(chunk); | ||
this.parse(); | ||
}; | ||
/** | ||
* Concatenates first N buffers to get chunk of `len` size | ||
*/ | ||
Parser.prototype.concat = function(len) { | ||
var buffers = this.buffers, | ||
total = buffers.length, | ||
newSize = 0; | ||
for (var i = 0; i < total && newSize < len; i++) { | ||
newSize += buffers[i].length; | ||
// | ||
// ### function write (data) | ||
// #### @data {Buffer} chunk of data | ||
// Writes or buffers data to parser | ||
// | ||
Parser.prototype.write = function write(data) { | ||
if (data !== undefined) { | ||
// Buffer data | ||
this.buffer.push(data); | ||
this.buffered += data.length; | ||
} | ||
if (newSize < len) return new Buffer(0); | ||
// Notify caller about state (for piping) | ||
if (this.paused) return false; | ||
if (i < total) i++; | ||
// We shall not do anything until we get all expected data | ||
if (this.buffered < this.waiting) return; | ||
// In case that we already have a chunk of needed size | ||
// Just return it | ||
if (i == 1) return buffers[0]; | ||
var self = this, | ||
buffer = new Buffer(this.waiting), | ||
sliced = 0, | ||
offset = 0; | ||
var result = new Buffer(newSize); | ||
for (var j = 0, offset = 0; offset < newSize && j < i; j++) { | ||
buffers[j].copy(result, offset); | ||
offset += buffers[j].length; | ||
} | ||
while (this.waiting > offset && this.buffered >= this.waiting && | ||
sliced < this.buffer.length) { | ||
var chunk = this.buffer[sliced++], | ||
overmatched = false; | ||
buffers = this.buffers = buffers.slice(i - 1); | ||
buffers[0] = result; | ||
// Copy chunk into `buffer` | ||
if (chunk.length > this.waiting - offset) { | ||
chunk.copy(buffer, offset, 0, this.waiting - offset); | ||
return result; | ||
}; | ||
this.buffer[--sliced] = chunk.slice(this.waiting - offset); | ||
this.buffered += this.buffer[sliced].length; | ||
overmatched = true; | ||
} else { | ||
chunk.copy(buffer, offset); | ||
} | ||
/** | ||
* Parse buffered data | ||
*/ | ||
Parser.prototype.parse = function() { | ||
var buffer = this.concat(8); | ||
// Move offset and decrease amount of buffered data | ||
offset += chunk.length; | ||
this.buffered -= chunk.length; | ||
// Headers are at least 8 bytes | ||
if (buffer.length < 8) return; | ||
if (overmatched) break; | ||
} | ||
var len = buffer.readUInt32BE(4) & 0xffffff; | ||
// Remove used buffers | ||
this.buffer = this.buffer.slice(sliced); | ||
buffer = this.concat(8 + len); | ||
// Executed parser for buffered data | ||
this.paused = true; | ||
this.execute(this.connection, this.state, buffer, function (err, waiting) { | ||
// And unpause once execution finished | ||
self.paused = false; | ||
self.emit('drain'); | ||
// Buffered data less than packet | ||
if (buffer.length < (8 + len)) return; | ||
// Propagate errors | ||
if (err) return self.emit('error', err); | ||
var headers = { | ||
c: ((buffer[0] & 128) >> 7) === 1, | ||
length: len | ||
}; | ||
// Set new `waiting` | ||
self.waiting = waiting; | ||
if (headers.c) { | ||
headers.version = buffer.readUInt16BE(0) & 0x7fff; | ||
headers.type = buffer.readUInt16BE(2); | ||
} else { | ||
headers.streamID = buffer.readUInt32BE(0); | ||
} | ||
if (self.waiting <= self.buffered) self.write(); | ||
}); | ||
}; | ||
headers.flags = buffer[4]; | ||
// | ||
// ### function end () | ||
// Stream's end() implementation | ||
// | ||
Parser.prototype.end = function end() { | ||
this.emit('end'); | ||
}; | ||
var data = buffer.slice(8, 8 + headers.length); | ||
// | ||
// ### function execute (connection, state, data, callback) | ||
// #### @connection {Connection} SPDY connection | ||
// #### @state {Object} Parser's state | ||
// #### @data {Buffer} Incoming data | ||
// #### @callback {Function} continuation callback | ||
// Parse buffered data | ||
// | ||
Parser.prototype.execute = function execute(connection, state, data, callback) { | ||
if (state.type === 'frame-head') { | ||
var header = state.header = { | ||
control: (data.readUInt8(0) & 0x80) === 0x80 ? true : false, | ||
version: null, | ||
type: null, | ||
id: null, | ||
flags: data.readUInt8(4), | ||
length: data.readUInt32BE(4) & 0x00ffffff | ||
}; | ||
this.buffers[0] = buffer.slice(8 + headers.length); | ||
if (!this.buffers[0].length) { | ||
this.buffers.shift(); | ||
} | ||
if (headers.c) { | ||
if (headers.type === enums.SYN_STREAM) { | ||
var parsed = { | ||
streamID: data.readUInt32BE(0) & 0x7fffffff, | ||
assocStreamID: data.readUInt32BE(4) & 0x7fffffff, | ||
priority: (data[8] && 192) >> 6, | ||
nameValues: {} | ||
}; | ||
if (header.control) { | ||
header.version = data.readUInt16BE(0) & 0x7fff; | ||
header.type = data.readUInt16BE(2); | ||
} else { | ||
header.id = data.readUInt32BE(0) & 0x7fffffff; | ||
} | ||
if (headers.type === enums.SYN_REPLY) { | ||
var parsed = { | ||
streamID: data.readUInt32BE(0) & 0x7fffffff, | ||
nameValues: {} | ||
}; | ||
} | ||
if (headers.type === enums.RST_STREAM) { | ||
var parsed = { | ||
streamID: data.readUInt32BE(0) & 0x7fffffff, | ||
statusCode: data.readUInt32BE(4) | ||
}; | ||
data = parsed; | ||
} | ||
if (headers.type === enums.SYN_STREAM || | ||
headers.type === enums.SYN_REPLY) { | ||
try { | ||
var offset = headers.type === enums.SYN_STREAM ? 10 : 6, | ||
nvs = this.zlib.inflate(data.slice(offset)), | ||
nvsCount = (nvs[0] << 8) + nvs[1]; | ||
state.type = 'frame-body'; | ||
callback(null, header.length); | ||
} else if (state.type === 'frame-body') { | ||
var self = this; | ||
nvs = nvs.slice(2); | ||
while (nvsCount > 0) { | ||
var nameLen = (nvs[0] << 8) + nvs[1], | ||
name = nvs.slice(2, 2 + nameLen); | ||
nvs = nvs.slice(2 + nameLen); | ||
spdy.framer.execute(connection, state.header, data, function(err, frame) { | ||
if (err) return callback(err); | ||
var valueLen = nvs.readUInt16BE(0), | ||
value = nvs.slice(2, 2 + valueLen); | ||
nvs = nvs.slice(2 + valueLen); | ||
self.emit('frame', frame); | ||
parsed.nameValues[name.toString()] = value.toString(); | ||
nvsCount --; | ||
} | ||
data = parsed; | ||
} catch(e) { | ||
this.emit('error', parsed.streamID); | ||
return; | ||
} | ||
} | ||
state.type = 'frame-head'; | ||
callback(null, 8); | ||
}); | ||
} | ||
this.emit(headers.c ? 'cframe' : 'dframe', { | ||
headers: headers, | ||
data: data | ||
}); | ||
// Probably we have more data buffered - so continue | ||
process.nextTick(this.parse.bind(this)); | ||
}; | ||
/** | ||
* End of stream | ||
*/ | ||
Parser.prototype.end = function() {}; | ||
Parser.prototype.destroy = function() {}; |
@@ -1,245 +0,49 @@ | ||
/** | ||
* Response class | ||
*/ | ||
var spdy = require('../spdy'), | ||
http = require('http'); | ||
var Buffer = require('buffer').Buffer, | ||
util = require('util'), | ||
stream = require('stream'), | ||
fs = require('fs'), | ||
enums = require('../spdy').enums, | ||
createControlFrame = require('../spdy').createControlFrame, | ||
createDataFrame = require('../spdy').createDataFrame, | ||
createPushStream = require('../spdy').createPushStream, | ||
createParser = require('../spdy').createParser, | ||
createZLib = require('../spdy').createZLib; | ||
// | ||
// ### function writeHead (statusCode) | ||
// #### @statusCode {Number} HTTP Status code | ||
// .writeHead() wrapper | ||
// (Sorry, copy pasted from lib/http.js) | ||
// | ||
exports.writeHead = function(statusCode) { | ||
if (this._headerSent) return; | ||
this._headerSent = true; | ||
/** | ||
* Class constructor | ||
*/ | ||
var Response = exports.Response = function(cframe, c) { | ||
stream.Stream.call(this); | ||
this.cframe = cframe; | ||
this.streamID = cframe.data.streamID; | ||
this.c = c; | ||
var reasonPhrase, headers, headerIndex; | ||
this.statusCode = 200; | ||
this._headers = { | ||
'Connection': 'keep-alive' | ||
}; | ||
this._written = false; | ||
this._reasonPhrase = 'OK'; | ||
this._push = function() {}; | ||
// For stream.pipe and others | ||
this.writable = true; | ||
}; | ||
util.inherits(Response, stream.Stream); | ||
exports.createResponse = function(cframe, c) { | ||
return new Response(cframe, c); | ||
}; | ||
/** | ||
* Respond w/ SYN_REPLY | ||
*/ | ||
Response.prototype.writeHead = function(code, reasonPhrase, headers) { | ||
if (headers === undefined) { | ||
headers = reasonPhrase; | ||
reasonPhrase = ''; | ||
if (typeof arguments[1] == 'string') { | ||
reasonPhrase = arguments[1]; | ||
headerIndex = 2; | ||
} else { | ||
reasonPhrase = http.STATUS_CODES[statusCode] || 'unknown'; | ||
headerIndex = 1; | ||
} | ||
this.statusCode = statusCode; | ||
headers = headers || {}; | ||
for (var i in headers) { | ||
this._headers[i] = headers[i]; | ||
} | ||
this._reasonPhrase || (this.reasonPhrase = reasonPhrase); | ||
this.statusCode = code; | ||
}; | ||
var obj = arguments[headerIndex]; | ||
/** | ||
* Flush buffered head | ||
*/ | ||
Response.prototype._flushHead = function() { | ||
if (this._written) { | ||
throw Error('Headers was already written'); | ||
} | ||
this._written = true; | ||
if (obj && this._headers) { | ||
// Slow-case: when progressive API and header fields are passed. | ||
headers = this._renderHeaders(); | ||
var headers = this._headers; | ||
headers.status = this.statusCode + ' ' + this._reasonPhrase; | ||
headers.version = 'HTTP/1.1'; | ||
var cframe = createControlFrame(this.c.zlib, { | ||
type: enums.SYN_REPLY, | ||
streamID: this.streamID | ||
}, headers); | ||
return this.c.write(cframe); | ||
}; | ||
Response.prototype.pushLater = function(resources) { | ||
var that = this; | ||
this.deferred_streams = []; | ||
// Send headers for each post-response server push stream, but DO | ||
// NOT sent data yet | ||
resources.forEach(function(push_contents) { | ||
var filename = push_contents[0] | ||
, url = push_contents[1] | ||
, data = fs.readFileSync(filename) | ||
, push_stream = createPushStream(that.cframe, that.c, url); | ||
push_stream._flushHead(); | ||
push_stream._written = true; | ||
that.deferred_streams.push([push_stream, data]); | ||
}); | ||
}; | ||
Response.prototype._pushLaterData = function(resources) { | ||
if (typeof(this.deferred_streams) == 'undefined') return; | ||
this.deferred_streams.forEach(function(stream_and_data) { | ||
var stream = stream_and_data[0] | ||
, data = stream_and_data[1]; | ||
stream.write(data); | ||
stream.end(); | ||
}); | ||
}; | ||
/** | ||
* Write any data (Internal) | ||
*/ | ||
Response.prototype._write = function(data, encoding, fin) { | ||
if (!this._written) { | ||
this._flushHead(); | ||
this._push_stream(); | ||
// handle object case | ||
var keys = Object.keys(obj); | ||
for (var i = 0; i < keys.length; i++) { | ||
var k = keys[i]; | ||
if (k) headers[k] = obj[k]; | ||
} | ||
} else if (this._headers) { | ||
// only progressive api is used | ||
headers = this._renderHeaders(); | ||
} else { | ||
// only writeHead() called | ||
headers = obj; | ||
} | ||
encoding = encoding || 'utf8'; | ||
if (data === undefined) { | ||
data = new Buffer(0); | ||
} | ||
// cleanup | ||
this._header = ''; | ||
// Write the data frame | ||
var dframe = createDataFrame(this.getStreamCompressor(), { | ||
streamID: this.streamID, | ||
flags: 0 | ||
}, Buffer.isBuffer(data) ? data : new Buffer(data, encoding)); | ||
this.c.write(dframe); | ||
// Write the data FIN if this if fin | ||
if (fin) { | ||
var dfin = createDataFrame(this.getStreamCompressor(), { | ||
streamID: this.streamID, | ||
flags: enums.DATA_FLAG_FIN | ||
}, new Buffer(0)); | ||
this.c.write(dfin); | ||
} | ||
// Push any deferred data streams | ||
this._pushLaterData(); | ||
spdy.framer.sendSynReply(this.socket, statusCode, reasonPhrase, headers); | ||
}; | ||
Response.prototype.getStreamCompressor = function(streamID) { | ||
if (this.stream_compressor) | ||
return this.stream_compressor; | ||
this.stream_compressor = createZLib({use_dictionary: false}); | ||
return this.stream_compressor; | ||
}; | ||
/** | ||
* Write data | ||
*/ | ||
Response.prototype.write = function(data, encoding) { | ||
return this._write(data, encoding, false); | ||
}; | ||
/** | ||
* End stream | ||
*/ | ||
Response.prototype.end = function(data, encoding) { | ||
this.writable = false; | ||
return this._write(data, encoding, true); | ||
}; | ||
/** | ||
* Cloning node.js default API | ||
*/ | ||
Response.prototype.setHeader = function(name, value) { | ||
if (arguments.length < 2) { | ||
throw new Error('`name` and `value` are required for setHeader().'); | ||
} | ||
if (this._written) { | ||
throw new Error('Can\'t set headers after they are sent.'); | ||
} | ||
this._headers[name] = Array.isArray(value) ? value.join(';') : value; | ||
}; | ||
/** | ||
* Cloning node.js default API | ||
*/ | ||
Response.prototype.getHeader = function(name) { | ||
if (arguments.length < 1) { | ||
throw new Error('`name` is required for getHeader().'); | ||
} | ||
if (this._written) { | ||
throw new Error('Can\'t use mutable header APIs after sent.'); | ||
} | ||
return this._headers[name]; | ||
}; | ||
/** | ||
* Cloning node.js default API | ||
*/ | ||
Response.prototype.removeHeader = function(name) { | ||
if (arguments.length < 1) { | ||
throw new Error('`name` is required for getHeader().'); | ||
} | ||
if (this._written) { | ||
throw new Error('Can\'t remove headers after they are sent.'); | ||
} | ||
delete this._headers[name]; | ||
}; | ||
/** | ||
* Server push | ||
*/ | ||
Response.prototype.setPush = function(fn) { | ||
if (typeof(fn) === 'function') | ||
this._push = fn; | ||
}; | ||
Response.prototype._push_stream = function() { | ||
return this._push(this); | ||
}; | ||
Response.prototype.push_file = function(filename, url) { | ||
console.log('[warn] Response#push_file has been deprecate. Please switch to pushFile instead.'); | ||
return this.pushFile(filename, url); | ||
}; | ||
Response.prototype.pushFile = function(filename, url) { | ||
this.push(fs.readFileSync(filename), url); | ||
}; | ||
Response.prototype.push = function(data, url) { | ||
var push_stream = createPushStream(this.cframe, this.c, url); | ||
push_stream.write(data); | ||
push_stream.end(); | ||
}; |
{ | ||
"name": "spdy", | ||
"description": "Implementation of the SPDY protocol on node.js.", | ||
"version": "0.1.4", | ||
"version": "1.0.0", | ||
"author": "Fedor Indutny <fedor.indutny@gmail.com>", | ||
"dependencies": { | ||
"zlibcontext": "~ 1.0.9" | ||
}, | ||
"contributors": [ | ||
"Chris Storm <github@eeecooks.com>", | ||
"François de Metz <francois@2metz.fr>" | ||
], | ||
"dependencies": {}, | ||
"engines": [ | ||
"node >= 0.6.0" | ||
"node ~ 0.7.0" | ||
], | ||
@@ -12,0 +14,0 @@ "main": "./lib/spdy", |
@@ -1,42 +0,49 @@ | ||
# SPDY Server on node.js (BETA) | ||
# SPDY Server for node.js | ||
Required node.js version - at least 0.5.0-pre. | ||
With this module you can create [SPDY](http://www.chromium.org/spdy) servers | ||
in node.js with natural http module interface and fallback to regular https | ||
(for browsers that doesn't support SPDY yet). | ||
Because of libuv integration in node.js core latest version of one is not usable, try this checking out at this commit instead: https://github.com/joyent/node/commit/9812e31 | ||
It's using SSL's NPN feature that is available in node from 0.6.0 version, but | ||
requires you to build node with latest openssl. | ||
With that module you can create true [SPDY](http://www.chromium.org/spdy) servers with natural http module interface and fallback to HTTPS (for browsers that doesn't support SPDY). | ||
## Node+OpenSSL building | ||
It's using SSL's NPN feature that will be available in node.js from 0.5.0-pre version, but you'll need to compile it with latest available version of OpenSSL. | ||
At the moment node-spdy requires zlib dictionary support, which will come to | ||
node.js only in 0.7.x version. To build 0.7.x version follow instructions below: | ||
Instruction for setting up development environment can be found in @eee-c article here: http://japhr.blogspot.com/2011/06/setting-up-node-spdy.html | ||
```bash | ||
git clone git://github.com/joyent/node.git | ||
cd node | ||
./configure --prefix=$HOME/.node/dev # <- or any other dir | ||
## Alternative instructions | ||
make install -j4 # in -jN, N is number of CPU cores on your machine | ||
1. grab http://cvs.openssl.org | ||
2. build it | ||
3. build node.js with that version of openssl | ||
# Add node's bin to PATH env variable | ||
echo 'export PATH=$HOME/.node/dev/bin:$PATH' >> ~/.bashrc | ||
./configure --openssl-includes=/path/to/openssl/include \ | ||
--openssl-libpath=/path/to/openssl | ||
make install | ||
# | ||
# You have working node 0.7.x + NPN now !!! | ||
# | ||
``` | ||
4. have fun with SPDY and node.js! | ||
## Usage | ||
var options = { | ||
key: fs.readFileSync(__dirname + '/../keys/spdy-key.pem'), | ||
cert: fs.readFileSync(__dirname + '/../keys/spdy-cert.pem'), | ||
ca: fs.readFileSync(__dirname + '/../keys/spdy-csr.pem'), | ||
NPNProtocols: ['spdy/2'] | ||
}; | ||
```javascript | ||
var spdy = require('spdy'); | ||
spdy.createServer(options, function(req, res) { | ||
res.writeHead(200); | ||
res.end('hello world!'); | ||
}); | ||
var options = { | ||
key: fs.readFileSync(__dirname + '/../keys/spdy-key.pem'), | ||
cert: fs.readFileSync(__dirname + '/../keys/spdy-cert.pem'), | ||
ca: fs.readFileSync(__dirname + '/../keys/spdy-csr.pem') | ||
}; | ||
As you can see it provides well known req/res interface for handling requests | ||
and responding to them. | ||
spdy.createServer(options, function(req, res) { | ||
res.writeHead(200); | ||
res.end('hello world!'); | ||
}); | ||
spdy.listen(443); | ||
``` | ||
## Helping project | ||
@@ -46,4 +53,10 @@ | ||
## LICENSE | ||
#### Contributors | ||
* [Fedor Indutny](https://github.com/indutny) | ||
* [Chris Storm](https://github.com/eee-c) | ||
* [François de Metz](https://github.com/francois2metz) | ||
#### LICENSE | ||
This software is licensed under the MIT License. | ||
@@ -50,0 +63,0 @@ |
var fs = require('fs'), | ||
http = require('http'), | ||
spdy = require('../lib/spdy'), | ||
tls = require('tls'), | ||
buffer = require('buffer').Buffer, | ||
NPNProtocols = new Buffer(7); | ||
spdy = require('../lib/spdy'); | ||
if (!tls.NPN_ENABLED) throw 'You\'re using not NPN-enabled version of node.js'; | ||
// Don't crash on errors | ||
@@ -20,3 +14,2 @@ process.on('uncaughtException', function (err) { | ||
ca: fs.readFileSync(__dirname + '/../keys/spdy-csr.pem'), | ||
NPNProtocols: ['spdy/2'] | ||
}; | ||
@@ -26,4 +19,2 @@ | ||
var bigBuffer = new Buffer(JSON.stringify({ok: true})); | ||
var server = spdy.createServer(options, function(req, res) { | ||
@@ -38,2 +29,3 @@ if (req.method == 'POST') { | ||
} | ||
static(req, res, function() { | ||
@@ -40,0 +32,0 @@ res.writeHead(404); |
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
Network access
Supply chain riskThis module accesses the network.
Found 1 instance in 1 package
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
Found 1 instance in 1 package
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
204774
0
28
1
84
7
1226
- Removedzlibcontext@~ 1.0.9
- Removedzlibcontext@1.0.9(transitive)