Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| e6dea40c8c |
@@ -1,8 +1,10 @@
|
||||
var net = require('net'),
|
||||
websocket = require('../lib/websocket/driver');
|
||||
websocket = require('../lib/websocket/driver'),
|
||||
deflate = require('../lib/websocket/extensions/per_message_deflate');
|
||||
|
||||
var server = net.createServer(function(connection) {
|
||||
var driver = websocket.server();
|
||||
driver.addExtension('permessage-deflate', deflate.create());
|
||||
|
||||
driver.on('connect', function() {
|
||||
if (websocket.isWebSocket(driver)) driver.start();
|
||||
|
||||
@@ -6,13 +6,14 @@ var Emitter = require('events').EventEmitter,
|
||||
var Base = function(request, url, options) {
|
||||
Emitter.call(this);
|
||||
|
||||
this._request = request;
|
||||
this._options = options || {};
|
||||
this._maxLength = this._options.maxLength || this.MAX_LENGTH;
|
||||
this.__headers = new Headers();
|
||||
this.__queue = [];
|
||||
this.readyState = 0;
|
||||
this.url = url;
|
||||
this._request = request;
|
||||
this._options = options || {};
|
||||
this._extensions = {};
|
||||
this._maxLength = this._options.maxLength || this.MAX_LENGTH;
|
||||
this.__headers = new Headers();
|
||||
this.__queue = [];
|
||||
this.readyState = 0;
|
||||
this.url = url;
|
||||
|
||||
this.io = new streams.IO(this);
|
||||
this.messages = new streams.Messages(this);
|
||||
@@ -51,6 +52,10 @@ var instance = {
|
||||
});
|
||||
},
|
||||
|
||||
addExtension: function(name, extension) {
|
||||
this._extensions[name] = extension;
|
||||
},
|
||||
|
||||
getState: function() {
|
||||
return this.STATES[this.readyState] || null;
|
||||
},
|
||||
@@ -108,6 +113,9 @@ var instance = {
|
||||
for (var key in instance)
|
||||
Base.prototype[key] = instance[key];
|
||||
|
||||
Base.parseHeader = function(header) {
|
||||
return Headers.parseHeader(header);
|
||||
};
|
||||
|
||||
Base.ConnectEvent = function() {};
|
||||
|
||||
|
||||
@@ -3,6 +3,22 @@ var Headers = function() {
|
||||
this._lines = [];
|
||||
};
|
||||
|
||||
Headers.parseHeader = function(header) {
|
||||
if (!header) return [];
|
||||
|
||||
return header.split(/\s*,\s*/).map(function(value) {
|
||||
var parts = value.split(/\s*;\s*/),
|
||||
name = parts.shift(),
|
||||
params = {};
|
||||
|
||||
parts.forEach(function(part) {
|
||||
var pair = part.split(/\s*=\s*/);
|
||||
params[pair[0]] = pair[1] || true;
|
||||
});
|
||||
return {name: name, params: params};
|
||||
});
|
||||
};
|
||||
|
||||
Headers.prototype.ALLOWED_DUPLICATES = ['set-cookie', 'set-cookie2', 'warning', 'www-authenticate']
|
||||
|
||||
Headers.prototype.set = function(name, value) {
|
||||
|
||||
@@ -19,7 +19,7 @@ var HttpParser = function(type) {
|
||||
};
|
||||
|
||||
this._parser.onHeaderValue = function(b, start, length) {
|
||||
self.headers[current] = b.toString('utf8', start, start + length);
|
||||
self.set(current, b.toString('utf8', start, start + length));
|
||||
};
|
||||
|
||||
this._parser.onHeadersComplete = this._parser[HTTPParser.kOnHeadersComplete] = function(info) {
|
||||
@@ -27,11 +27,11 @@ var HttpParser = function(type) {
|
||||
self.statusCode = info.statusCode;
|
||||
self.url = info.url;
|
||||
|
||||
var headers = info.headers;
|
||||
var headers = info.headers, name, values;
|
||||
if (!headers) return;
|
||||
|
||||
for (var i = 0, n = headers.length; i < n; i += 2)
|
||||
self.headers[headers[i].toLowerCase()] = headers[i+1];
|
||||
self.set(headers[i].toLowerCase(), headers[i+1]);
|
||||
};
|
||||
|
||||
this._parser.onMessageComplete = this._parser[HTTPParser.kOnMessageComplete] = function() {
|
||||
@@ -63,6 +63,13 @@ HttpParser.METHODS = {
|
||||
24: 'PATCH'
|
||||
};
|
||||
|
||||
HttpParser.prototype.set = function(name, value) {
|
||||
var values = [];
|
||||
if (this.headers.hasOwnProperty(name)) values.push(this.headers[name]);
|
||||
values.push(value);
|
||||
this.headers[name] = values.join(', ');
|
||||
};
|
||||
|
||||
HttpParser.prototype.isComplete = function() {
|
||||
return this._complete;
|
||||
};
|
||||
|
||||
@@ -175,6 +175,7 @@ var instance = {
|
||||
if (!secKey) return '';
|
||||
|
||||
var accept = Hybi.generateAccept(secKey),
|
||||
offers = Base.parseHeader(this._request.headers['sec-websocket-extensions']),
|
||||
protos = this._request.headers['sec-websocket-protocol'],
|
||||
supported = this._protocols,
|
||||
proto,
|
||||
@@ -195,6 +196,20 @@ var instance = {
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: implement a selection procedure for extensions
|
||||
// see http://tools.ietf.org/html/draft-ietf-hybi-permessage-compression-17#section-5
|
||||
var extensions = offers.map(function(offer) {
|
||||
var ext = this._extensions[offer.name];
|
||||
return ext && ext.createSession(offer.params);
|
||||
}, this).filter(function(k) {
|
||||
return k;
|
||||
});
|
||||
|
||||
if (extensions.length > 0) {
|
||||
extensions = extensions.map(function(e) { return e.responseHeader() });
|
||||
headers.push('Sec-WebSocket-Extensions: ' + extensions.join(', '));
|
||||
}
|
||||
|
||||
return new Buffer(headers.concat(this.__headers.toString(), '').join('\r\n'), 'utf8');
|
||||
},
|
||||
|
||||
|
||||
@@ -34,6 +34,7 @@ var instance = {
|
||||
this._delegate = Server.http(this, this._options);
|
||||
this._delegate.messages = this.messages;
|
||||
this._delegate.io = this.io;
|
||||
this._delegate._extensions = this._extensions;
|
||||
|
||||
this._delegate.on('open', function() { self._open() });
|
||||
this.EVENTS.forEach(function(event) {
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
var PerMessageDeflate = function() {
|
||||
this.name = 'permessage-deflate';
|
||||
};
|
||||
|
||||
PerMessageDeflate.create = function() {
|
||||
return new this();
|
||||
};
|
||||
|
||||
PerMessageDeflate.prototype.createSession = function(params) {
|
||||
return new Session(this, params);
|
||||
};
|
||||
|
||||
var Session = function(extension, params) {
|
||||
this._ext = extension;
|
||||
this._params = params;
|
||||
};
|
||||
|
||||
Session.prototype.responseHeader = function() {
|
||||
return this._ext.name;
|
||||
};
|
||||
|
||||
module.exports = PerMessageDeflate;
|
||||
Reference in New Issue
Block a user