|
|
- 'use strict';
-
- var util = require('util'),
- HttpParser = require('../http_parser'),
- Base = require('./base'),
- Draft75 = require('./draft75'),
- Draft76 = require('./draft76'),
- Hybi = require('./hybi');
-
- var Server = function(options) {
- Base.call(this, null, null, options);
- this._http = new HttpParser('request');
- };
- util.inherits(Server, Base);
-
- var instance = {
- EVENTS: ['open', 'message', 'error', 'close'],
-
- _bindEventListeners: function() {
- this.messages.on('error', function() {});
- this.on('error', function() {});
- },
-
- parse: function(chunk) {
- if (this._delegate) return this._delegate.parse(chunk);
-
- this._http.parse(chunk);
- if (!this._http.isComplete()) return;
-
- this.method = this._http.method;
- this.url = this._http.url;
- this.headers = this._http.headers;
- this.body = this._http.body;
-
- var self = this;
- this._delegate = Server.http(this, this._options);
- this._delegate.messages = this.messages;
- this._delegate.io = this.io;
- this._open();
-
- this.EVENTS.forEach(function(event) {
- this._delegate.on(event, function(e) { self.emit(event, e) });
- }, this);
-
- this.protocol = this._delegate.protocol;
- this.version = this._delegate.version;
-
- this.parse(this._http.body);
- this.emit('connect', new Base.ConnectEvent());
- },
-
- _open: function() {
- this.__queue.forEach(function(msg) {
- this._delegate[msg[0]].apply(this._delegate, msg[1]);
- }, this);
- this.__queue = [];
- }
- };
-
- ['addExtension', 'setHeader', 'start', 'frame', 'text', 'binary', 'ping', 'close'].forEach(function(method) {
- instance[method] = function() {
- if (this._delegate) {
- return this._delegate[method].apply(this._delegate, arguments);
- } else {
- this.__queue.push([method, arguments]);
- return true;
- }
- };
- });
-
- for (var key in instance)
- Server.prototype[key] = instance[key];
-
- Server.isSecureRequest = function(request) {
- if (request.connection && request.connection.authorized !== undefined) return true;
- if (request.socket && request.socket.secure) return true;
-
- var headers = request.headers;
- if (!headers) return false;
- if (headers['https'] === 'on') return true;
- if (headers['x-forwarded-ssl'] === 'on') return true;
- if (headers['x-forwarded-scheme'] === 'https') return true;
- if (headers['x-forwarded-proto'] === 'https') return true;
-
- return false;
- };
-
- Server.determineUrl = function(request) {
- var scheme = this.isSecureRequest(request) ? 'wss:' : 'ws:';
- return scheme + '//' + request.headers.host + request.url;
- };
-
- Server.http = function(request, options) {
- options = options || {};
- if (options.requireMasking === undefined) options.requireMasking = true;
-
- var headers = request.headers,
- version = headers['sec-websocket-version'],
- key = headers['sec-websocket-key'],
- key1 = headers['sec-websocket-key1'],
- key2 = headers['sec-websocket-key2'],
- url = this.determineUrl(request);
-
- if (version || key)
- return new Hybi(request, url, options);
- else if (key1 || key2)
- return new Draft76(request, url, options);
- else
- return new Draft75(request, url, options);
- };
-
- module.exports = Server;
|