mirror of
https://gitlab.torproject.org/tpo/anti-censorship/pluggable-transports/snowflake.git
synced 2025-10-13 20:11:19 -04:00
Lightly massage some of the generated JavaScript
This commit is contained in:
parent
31ad9566e6
commit
1867a3f121
19 changed files with 986 additions and 989 deletions
|
@ -1,26 +1,44 @@
|
||||||
// Generated by CoffeeScript 2.4.1
|
|
||||||
var FILES, FILES_SPEC, INITS, OUTFILE, STATIC, compileCoffee, copyStaticFiles, exec, execSync, fs, spawn;
|
|
||||||
|
|
||||||
fs = require('fs');
|
var fs = require('fs');
|
||||||
|
var { exec, spawn, execSync } = require('child_process');
|
||||||
({exec, spawn, execSync} = require('child_process'));
|
|
||||||
|
|
||||||
// All coffeescript files required.
|
// All coffeescript files required.
|
||||||
FILES = ['broker.coffee', 'config.coffee', 'proxypair.coffee', 'snowflake.coffee', 'ui.coffee', 'util.coffee', 'websocket.coffee', 'shims.coffee'];
|
var FILES = [
|
||||||
|
'broker.coffee',
|
||||||
|
'config.coffee',
|
||||||
|
'proxypair.coffee',
|
||||||
|
'snowflake.coffee',
|
||||||
|
'ui.coffee',
|
||||||
|
'util.coffee',
|
||||||
|
'websocket.coffee',
|
||||||
|
'shims.coffee'
|
||||||
|
];
|
||||||
|
|
||||||
INITS = ['init-badge.coffee', 'init-node.coffee', 'init-webext.coffee'];
|
var INITS = [
|
||||||
|
'init-badge.coffee',
|
||||||
|
'init-node.coffee',
|
||||||
|
'init-webext.coffee'
|
||||||
|
];
|
||||||
|
|
||||||
FILES_SPEC = ['spec/broker.spec.coffee', 'spec/init.spec.coffee', 'spec/proxypair.spec.coffee', 'spec/snowflake.spec.coffee', 'spec/ui.spec.coffee', 'spec/util.spec.coffee', 'spec/websocket.spec.coffee'];
|
var FILES_SPEC = [
|
||||||
|
'spec/broker.spec.coffee',
|
||||||
|
'spec/init.spec.coffee',
|
||||||
|
'spec/proxypair.spec.coffee',
|
||||||
|
'spec/snowflake.spec.coffee',
|
||||||
|
'spec/ui.spec.coffee',
|
||||||
|
'spec/util.spec.coffee',
|
||||||
|
'spec/websocket.spec.coffee'
|
||||||
|
];
|
||||||
|
|
||||||
OUTFILE = 'snowflake.js';
|
var OUTFILE = 'snowflake.js';
|
||||||
|
|
||||||
STATIC = 'static';
|
var STATIC = 'static';
|
||||||
|
|
||||||
copyStaticFiles = function() {
|
var copyStaticFiles = function() {
|
||||||
return exec('cp ' + STATIC + '/* build/');
|
return exec('cp ' + STATIC + '/* build/');
|
||||||
};
|
};
|
||||||
|
|
||||||
compileCoffee = function(outDir, init) {
|
var compileCoffee = function(outDir, init) {
|
||||||
var files;
|
var files;
|
||||||
files = FILES.concat('init-' + init + '.coffee');
|
files = FILES.concat('init-' + init + '.coffee');
|
||||||
return exec('cat ' + files.join(' ') + ' | coffee -cs > ' + outDir + '/' + OUTFILE, function(err, stdout, stderr) {
|
return exec('cat ' + files.join(' ') + ' | coffee -cs > ' + outDir + '/' + OUTFILE, function(err, stdout, stderr) {
|
||||||
|
|
|
@ -1,15 +1,13 @@
|
||||||
// Generated by CoffeeScript 2.4.1
|
|
||||||
/*
|
/*
|
||||||
Communication with the snowflake broker.
|
Communication with the snowflake broker.
|
||||||
|
|
||||||
Browser snowflakes must register with the broker in order
|
Browser snowflakes must register with the broker in order
|
||||||
to get assigned to clients.
|
to get assigned to clients.
|
||||||
*/
|
*/
|
||||||
var Broker;
|
|
||||||
|
|
||||||
Broker = (function() {
|
|
||||||
// Represents a broker running remotely.
|
// Represents a broker running remotely.
|
||||||
class Broker {
|
class Broker {
|
||||||
|
|
||||||
// When interacting with the Broker, snowflake must generate a unique session
|
// When interacting with the Broker, snowflake must generate a unique session
|
||||||
// ID so the Broker can keep track of each proxy's signalling channels.
|
// ID so the Broker can keep track of each proxy's signalling channels.
|
||||||
// On construction, this Broker object does not do anything until
|
// On construction, this Broker object does not do anything until
|
||||||
|
@ -120,7 +118,3 @@ Broker = (function() {
|
||||||
};
|
};
|
||||||
|
|
||||||
Broker.prototype.clients = 0;
|
Broker.prototype.clients = 0;
|
||||||
|
|
||||||
return Broker;
|
|
||||||
|
|
||||||
}).call(this);
|
|
||||||
|
|
|
@ -1,7 +1,4 @@
|
||||||
// Generated by CoffeeScript 2.4.1
|
|
||||||
var Config;
|
|
||||||
|
|
||||||
Config = (function() {
|
|
||||||
class Config {};
|
class Config {};
|
||||||
|
|
||||||
Config.prototype.brokerUrl = 'snowflake-broker.bamsoftware.com';
|
Config.prototype.brokerUrl = 'snowflake-broker.bamsoftware.com';
|
||||||
|
@ -37,7 +34,3 @@ Config = (function() {
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
};
|
};
|
||||||
|
|
||||||
return Config;
|
|
||||||
|
|
||||||
}).call(this);
|
|
||||||
|
|
|
@ -1,37 +1,35 @@
|
||||||
// Generated by CoffeeScript 2.4.1
|
|
||||||
/*
|
/*
|
||||||
Entry point.
|
Entry point.
|
||||||
*/
|
*/
|
||||||
var dbg, debug, init, log, query, silenceNotifications, snowflake;
|
|
||||||
|
|
||||||
if (((typeof TESTING === "undefined" || TESTING === null) || !TESTING) && !Util.featureDetect()) {
|
if (((typeof TESTING === "undefined" || TESTING === null) || !TESTING) && !Util.featureDetect()) {
|
||||||
console.log('webrtc feature not detected. shutting down');
|
console.log('webrtc feature not detected. shutting down');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
snowflake = null;
|
var snowflake = null;
|
||||||
|
|
||||||
query = Query.parse(location);
|
var query = Query.parse(location);
|
||||||
|
|
||||||
debug = Params.getBool(query, 'debug', false);
|
var debug = Params.getBool(query, 'debug', false);
|
||||||
|
|
||||||
silenceNotifications = Params.getBool(query, 'silent', false);
|
var silenceNotifications = Params.getBool(query, 'silent', false);
|
||||||
|
|
||||||
// Log to both console and UI if applicable.
|
// Log to both console and UI if applicable.
|
||||||
// Requires that the snowflake and UI objects are hooked up in order to
|
// Requires that the snowflake and UI objects are hooked up in order to
|
||||||
// log to console.
|
// log to console.
|
||||||
log = function(msg) {
|
var log = function(msg) {
|
||||||
console.log('Snowflake: ' + msg);
|
console.log('Snowflake: ' + msg);
|
||||||
return snowflake != null ? snowflake.ui.log(msg) : void 0;
|
return snowflake != null ? snowflake.ui.log(msg) : void 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
dbg = function(msg) {
|
var dbg = function(msg) {
|
||||||
if (debug || ((snowflake != null ? snowflake.ui : void 0) instanceof DebugUI)) {
|
if (debug || ((snowflake != null ? snowflake.ui : void 0) instanceof DebugUI)) {
|
||||||
return log(msg);
|
return log(msg);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
init = function() {
|
var init = function() {
|
||||||
var broker, config, ui;
|
var broker, config, ui;
|
||||||
config = new Config;
|
config = new Config;
|
||||||
if ('off' !== query['ratelimit']) {
|
if ('off' !== query['ratelimit']) {
|
||||||
|
|
|
@ -1,22 +1,20 @@
|
||||||
// Generated by CoffeeScript 2.4.1
|
|
||||||
/*
|
/*
|
||||||
Entry point.
|
Entry point.
|
||||||
*/
|
*/
|
||||||
var broker, config, dbg, log, snowflake, ui;
|
|
||||||
|
|
||||||
config = new Config;
|
var config = new Config;
|
||||||
|
|
||||||
ui = new UI();
|
var ui = new UI();
|
||||||
|
|
||||||
broker = new Broker(config.brokerUrl);
|
var broker = new Broker(config.brokerUrl);
|
||||||
|
|
||||||
snowflake = new Snowflake(config, ui, broker);
|
var snowflake = new Snowflake(config, ui, broker);
|
||||||
|
|
||||||
log = function(msg) {
|
var log = function(msg) {
|
||||||
return console.log('Snowflake: ' + msg);
|
return console.log('Snowflake: ' + msg);
|
||||||
};
|
};
|
||||||
|
|
||||||
dbg = log;
|
var dbg = log;
|
||||||
|
|
||||||
log('== snowflake proxy ==');
|
log('== snowflake proxy ==');
|
||||||
|
|
||||||
|
|
|
@ -1,28 +1,26 @@
|
||||||
// Generated by CoffeeScript 2.4.1
|
|
||||||
/*
|
/*
|
||||||
Entry point.
|
Entry point.
|
||||||
*/
|
*/
|
||||||
var broker, config, dbg, debug, init, log, snowflake, ui, update;
|
|
||||||
|
|
||||||
debug = false;
|
var debug = false;
|
||||||
|
|
||||||
snowflake = null;
|
var snowflake = null;
|
||||||
|
|
||||||
config = null;
|
var config = null;
|
||||||
|
|
||||||
broker = null;
|
var broker = null;
|
||||||
|
|
||||||
ui = null;
|
var ui = null;
|
||||||
|
|
||||||
// Log to both console and UI if applicable.
|
// Log to both console and UI if applicable.
|
||||||
// Requires that the snowflake and UI objects are hooked up in order to
|
// Requires that the snowflake and UI objects are hooked up in order to
|
||||||
// log to console.
|
// log to console.
|
||||||
log = function(msg) {
|
var log = function(msg) {
|
||||||
console.log('Snowflake: ' + msg);
|
console.log('Snowflake: ' + msg);
|
||||||
return snowflake != null ? snowflake.ui.log(msg) : void 0;
|
return snowflake != null ? snowflake.ui.log(msg) : void 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
dbg = function(msg) {
|
var dbg = function(msg) {
|
||||||
if (debug) {
|
if (debug) {
|
||||||
return log(msg);
|
return log(msg);
|
||||||
}
|
}
|
||||||
|
@ -37,7 +35,7 @@ if (!Util.featureDetect()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
init = function() {
|
var init = function() {
|
||||||
config = new Config;
|
config = new Config;
|
||||||
ui = new WebExtUI();
|
ui = new WebExtUI();
|
||||||
broker = new Broker(config.brokerUrl);
|
broker = new Broker(config.brokerUrl);
|
||||||
|
@ -46,7 +44,7 @@ init = function() {
|
||||||
return ui.initToggle();
|
return ui.initToggle();
|
||||||
};
|
};
|
||||||
|
|
||||||
update = function() {
|
var update = function() {
|
||||||
if (!ui.enabled) {
|
if (!ui.enabled) {
|
||||||
// Do not activate the proxy if any number of conditions are true.
|
// Do not activate the proxy if any number of conditions are true.
|
||||||
snowflake.disable();
|
snowflake.disable();
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
// Generated by CoffeeScript 2.4.1
|
|
||||||
/*
|
/*
|
||||||
Represents a single:
|
Represents a single:
|
||||||
|
|
||||||
|
@ -7,10 +6,9 @@ Represents a single:
|
||||||
Every ProxyPair has a Snowflake ID, which is necessary when responding to the
|
Every ProxyPair has a Snowflake ID, which is necessary when responding to the
|
||||||
Broker with an WebRTC answer.
|
Broker with an WebRTC answer.
|
||||||
*/
|
*/
|
||||||
var ProxyPair;
|
|
||||||
|
|
||||||
ProxyPair = (function() {
|
|
||||||
class ProxyPair {
|
class ProxyPair {
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Constructs a ProxyPair where:
|
Constructs a ProxyPair where:
|
||||||
- @relayAddr is the destination relay
|
- @relayAddr is the destination relay
|
||||||
|
@ -256,7 +254,3 @@ ProxyPair = (function() {
|
||||||
ProxyPair.prototype.onCleanup = null;
|
ProxyPair.prototype.onCleanup = null;
|
||||||
|
|
||||||
ProxyPair.prototype.id = null;
|
ProxyPair.prototype.id = null;
|
||||||
|
|
||||||
return ProxyPair;
|
|
||||||
|
|
||||||
}).call(this);
|
|
||||||
|
|
|
@ -1,8 +1,6 @@
|
||||||
// Generated by CoffeeScript 2.4.1
|
|
||||||
/*
|
/*
|
||||||
WebRTC shims for multiple browsers.
|
WebRTC shims for multiple browsers.
|
||||||
*/
|
*/
|
||||||
var IceCandidate, PeerConnection, SessionDescription, WebSocket, XMLHttpRequest, chrome, document, location, webrtc, window;
|
|
||||||
|
|
||||||
if (typeof module !== "undefined" && module !== null ? module.exports : void 0) {
|
if (typeof module !== "undefined" && module !== null ? module.exports : void 0) {
|
||||||
window = {};
|
window = {};
|
||||||
|
@ -22,7 +20,6 @@ if (typeof module !== "undefined" && module !== null ? module.exports : void 0)
|
||||||
({ XMLHttpRequest } = require('xmlhttprequest'));
|
({ XMLHttpRequest } = require('xmlhttprequest'));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
window = this;
|
|
||||||
document = window.document;
|
document = window.document;
|
||||||
chrome = window.chrome;
|
chrome = window.chrome;
|
||||||
location = window.location.search.substr(1);
|
location = window.location.search.substr(1);
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
// Generated by CoffeeScript 2.4.1
|
|
||||||
/*
|
/*
|
||||||
A Coffeescript WebRTC snowflake proxy
|
A Coffeescript WebRTC snowflake proxy
|
||||||
|
|
||||||
|
@ -9,11 +8,10 @@ this proxy must always act as the answerer.
|
||||||
|
|
||||||
TODO: More documentation
|
TODO: More documentation
|
||||||
*/
|
*/
|
||||||
var Snowflake;
|
|
||||||
|
|
||||||
Snowflake = (function() {
|
|
||||||
// Minimum viable snowflake for now - just 1 client.
|
// Minimum viable snowflake for now - just 1 client.
|
||||||
class Snowflake {
|
class Snowflake {
|
||||||
|
|
||||||
// Prepare the Snowflake with a Broker (to find clients) and optional UI.
|
// Prepare the Snowflake with a Broker (to find clients) and optional UI.
|
||||||
constructor(config, ui, broker) {
|
constructor(config, ui, broker) {
|
||||||
// Receive an SDP offer from some client assigned by the Broker,
|
// Receive an SDP offer from some client assigned by the Broker,
|
||||||
|
@ -176,7 +174,3 @@ Snowflake = (function() {
|
||||||
Snowflake.MESSAGE = {
|
Snowflake.MESSAGE = {
|
||||||
CONFIRMATION: 'You\'re currently serving a Tor user via Snowflake.'
|
CONFIRMATION: 'You\'re currently serving a Tor user via Snowflake.'
|
||||||
};
|
};
|
||||||
|
|
||||||
return Snowflake;
|
|
||||||
|
|
||||||
}).call(this);
|
|
||||||
|
|
|
@ -1,39 +1,32 @@
|
||||||
// Generated by CoffeeScript 2.4.1
|
|
||||||
/*
|
/*
|
||||||
jasmine tests for Snowflake broker
|
jasmine tests for Snowflake broker
|
||||||
*/
|
*/
|
||||||
var XMLHttpRequest;
|
|
||||||
|
|
||||||
XMLHttpRequest = (function() {
|
|
||||||
// fake xhr
|
// fake xhr
|
||||||
// class XMLHttpRequest
|
// class XMLHttpRequest
|
||||||
class XMLHttpRequest {
|
class XMLHttpRequest {
|
||||||
constructor() {
|
constructor() {
|
||||||
this.onreadystatechange = null;
|
this.onreadystatechange = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
open() {}
|
open() {}
|
||||||
|
|
||||||
setRequestHeader() {}
|
setRequestHeader() {}
|
||||||
|
|
||||||
send() {}
|
send() {}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
XMLHttpRequest.prototype.DONE = 1;
|
XMLHttpRequest.prototype.DONE = 1;
|
||||||
|
|
||||||
return XMLHttpRequest;
|
|
||||||
|
|
||||||
}).call(this);
|
|
||||||
|
|
||||||
describe('Broker', function() {
|
describe('Broker', function() {
|
||||||
|
|
||||||
it('can be created', function() {
|
it('can be created', function() {
|
||||||
var b;
|
var b;
|
||||||
b = new Broker('fake');
|
b = new Broker('fake');
|
||||||
expect(b.url).toEqual('https://fake/');
|
expect(b.url).toEqual('https://fake/');
|
||||||
return expect(b.id).not.toBeNull();
|
expect(b.id).not.toBeNull();
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('getClientOffer', function() {
|
describe('getClientOffer', function() {
|
||||||
|
|
||||||
it('polls and promises a client offer', function(done) {
|
it('polls and promises a client offer', function(done) {
|
||||||
var b, poll;
|
var b, poll;
|
||||||
b = new Broker('fake');
|
b = new Broker('fake');
|
||||||
|
@ -55,6 +48,7 @@ describe('Broker', function() {
|
||||||
return done();
|
return done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('rejects if the broker timed-out', function(done) {
|
it('rejects if the broker timed-out', function(done) {
|
||||||
var b, poll;
|
var b, poll;
|
||||||
b = new Broker('fake');
|
b = new Broker('fake');
|
||||||
|
@ -75,7 +69,8 @@ describe('Broker', function() {
|
||||||
return done();
|
return done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
return it('rejects on any other status', function(done) {
|
|
||||||
|
it('rejects on any other status', function(done) {
|
||||||
var b, poll;
|
var b, poll;
|
||||||
b = new Broker('fake');
|
b = new Broker('fake');
|
||||||
// fake timed-out request from broker
|
// fake timed-out request from broker
|
||||||
|
@ -95,18 +90,20 @@ describe('Broker', function() {
|
||||||
expect(b._xhr.status).toBe(1337);
|
expect(b._xhr.status).toBe(1337);
|
||||||
return done();
|
return done();
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('responds to the broker with answer', function() {
|
it('responds to the broker with answer', function() {
|
||||||
var b;
|
var b = new Broker('fake');
|
||||||
b = new Broker('fake');
|
|
||||||
spyOn(b, '_postRequest');
|
spyOn(b, '_postRequest');
|
||||||
b.sendAnswer('fake id', 123);
|
b.sendAnswer('fake id', 123);
|
||||||
return expect(b._postRequest).toHaveBeenCalledWith('fake id', jasmine.any(Object), 'answer', '123');
|
expect(b._postRequest).toHaveBeenCalledWith('fake id', jasmine.any(Object), 'answer', '123');
|
||||||
});
|
});
|
||||||
return it('POST XMLHttpRequests to the broker', function() {
|
|
||||||
var b;
|
it('POST XMLHttpRequests to the broker', function() {
|
||||||
b = new Broker('fake');
|
var b = new Broker('fake');
|
||||||
b._xhr = new XMLHttpRequest();
|
b._xhr = new XMLHttpRequest();
|
||||||
spyOn(b._xhr, 'open');
|
spyOn(b._xhr, 'open');
|
||||||
spyOn(b._xhr, 'setRequestHeader');
|
spyOn(b._xhr, 'setRequestHeader');
|
||||||
|
@ -114,6 +111,7 @@ describe('Broker', function() {
|
||||||
b._postRequest(0, b._xhr, 'test', 'data');
|
b._postRequest(0, b._xhr, 'test', 'data');
|
||||||
expect(b._xhr.open).toHaveBeenCalled();
|
expect(b._xhr.open).toHaveBeenCalled();
|
||||||
expect(b._xhr.setRequestHeader).toHaveBeenCalled();
|
expect(b._xhr.setRequestHeader).toHaveBeenCalled();
|
||||||
return expect(b._xhr.send).toHaveBeenCalled();
|
expect(b._xhr.send).toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,8 +1,6 @@
|
||||||
// Generated by CoffeeScript 2.4.1
|
|
||||||
// Fake snowflake to interact with
|
// Fake snowflake to interact with
|
||||||
var snowflake;
|
|
||||||
|
|
||||||
snowflake = {
|
var snowflake = {
|
||||||
ui: new UI,
|
ui: new UI,
|
||||||
broker: {
|
broker: {
|
||||||
sendAnswer: function() {}
|
sendAnswer: function() {}
|
||||||
|
@ -11,24 +9,25 @@ snowflake = {
|
||||||
};
|
};
|
||||||
|
|
||||||
describe('Init', function() {
|
describe('Init', function() {
|
||||||
|
|
||||||
it('gives a dialog when closing, only while active', function() {
|
it('gives a dialog when closing, only while active', function() {
|
||||||
var msg, silenceNotifications;
|
|
||||||
silenceNotifications = false;
|
silenceNotifications = false;
|
||||||
snowflake.state = Snowflake.MODE.WEBRTC_READY;
|
snowflake.state = Snowflake.MODE.WEBRTC_READY;
|
||||||
msg = window.onbeforeunload();
|
var msg = window.onbeforeunload();
|
||||||
expect(snowflake.state).toBe(Snowflake.MODE.WEBRTC_READY);
|
expect(snowflake.state).toBe(Snowflake.MODE.WEBRTC_READY);
|
||||||
expect(msg).toBe(Snowflake.MESSAGE.CONFIRMATION);
|
expect(msg).toBe(Snowflake.MESSAGE.CONFIRMATION);
|
||||||
snowflake.state = Snowflake.MODE.INIT;
|
snowflake.state = Snowflake.MODE.INIT;
|
||||||
msg = window.onbeforeunload();
|
msg = window.onbeforeunload();
|
||||||
expect(snowflake.state).toBe(Snowflake.MODE.INIT);
|
expect(snowflake.state).toBe(Snowflake.MODE.INIT);
|
||||||
return expect(msg).toBe(null);
|
expect(msg).toBe(null);
|
||||||
});
|
});
|
||||||
return it('does not give a dialog when silent flag is on', function() {
|
|
||||||
var msg, silenceNotifications;
|
it('does not give a dialog when silent flag is on', function() {
|
||||||
silenceNotifications = true;
|
silenceNotifications = true;
|
||||||
snowflake.state = Snowflake.MODE.WEBRTC_READY;
|
snowflake.state = Snowflake.MODE.WEBRTC_READY;
|
||||||
msg = window.onbeforeunload();
|
var msg = window.onbeforeunload();
|
||||||
expect(snowflake.state).toBe(Snowflake.MODE.WEBRTC_READY);
|
expect(snowflake.state).toBe(Snowflake.MODE.WEBRTC_READY);
|
||||||
return expect(msg).toBe(null);
|
expect(msg).toBe(null);
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,17 +1,15 @@
|
||||||
// Generated by CoffeeScript 2.4.1
|
|
||||||
/*
|
/*
|
||||||
jasmine tests for Snowflake proxypair
|
jasmine tests for Snowflake proxypair
|
||||||
*/
|
*/
|
||||||
var MessageEvent, arrayMatching;
|
|
||||||
|
|
||||||
// Replacement for MessageEvent constructor.
|
// Replacement for MessageEvent constructor.
|
||||||
// https://developer.mozilla.org/en-US/docs/Web/API/MessageEvent/MessageEvent
|
// https://developer.mozilla.org/en-US/docs/Web/API/MessageEvent/MessageEvent
|
||||||
MessageEvent = function(type, init) {
|
var MessageEvent = function(type, init) {
|
||||||
return init;
|
return init;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Asymmetic matcher that checks that two arrays have the same contents.
|
// Asymmetic matcher that checks that two arrays have the same contents.
|
||||||
arrayMatching = function(sample) {
|
var arrayMatching = function(sample) {
|
||||||
return {
|
return {
|
||||||
asymmetricMatch: function(other) {
|
asymmetricMatch: function(other) {
|
||||||
var _, a, b, i, j, len;
|
var _, a, b, i, j, len;
|
||||||
|
@ -35,46 +33,57 @@ arrayMatching = function(sample) {
|
||||||
};
|
};
|
||||||
|
|
||||||
describe('ProxyPair', function() {
|
describe('ProxyPair', function() {
|
||||||
|
|
||||||
var config, destination, fakeRelay, pp, rateLimit;
|
var config, destination, fakeRelay, pp, rateLimit;
|
||||||
fakeRelay = Parse.address('0.0.0.0:12345');
|
fakeRelay = Parse.address('0.0.0.0:12345');
|
||||||
rateLimit = new DummyRateLimit;
|
rateLimit = new DummyRateLimit;
|
||||||
config = new Config;
|
config = new Config;
|
||||||
destination = [];
|
destination = [];
|
||||||
|
|
||||||
// Using the mock PeerConnection definition from spec/snowflake.spec.coffee.
|
// Using the mock PeerConnection definition from spec/snowflake.spec.coffee.
|
||||||
pp = new ProxyPair(fakeRelay, rateLimit, config.pcConfig);
|
var pp = new ProxyPair(fakeRelay, rateLimit, config.pcConfig);
|
||||||
|
|
||||||
beforeEach(function() {
|
beforeEach(function() {
|
||||||
return pp.begin();
|
return pp.begin();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('begins webrtc connection', function() {
|
it('begins webrtc connection', function() {
|
||||||
return expect(pp.pc).not.toBeNull();
|
return expect(pp.pc).not.toBeNull();
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('accepts WebRTC offer from some client', function() {
|
describe('accepts WebRTC offer from some client', function() {
|
||||||
|
|
||||||
beforeEach(function() {
|
beforeEach(function() {
|
||||||
return pp.begin();
|
return pp.begin();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('rejects invalid offers', function() {
|
it('rejects invalid offers', function() {
|
||||||
expect(typeof pp.pc.setRemoteDescription).toBe("function");
|
expect(typeof pp.pc.setRemoteDescription).toBe("function");
|
||||||
expect(pp.pc).not.toBeNull();
|
expect(pp.pc).not.toBeNull();
|
||||||
expect(pp.receiveWebRTCOffer({})).toBe(false);
|
expect(pp.receiveWebRTCOffer({})).toBe(false);
|
||||||
return expect(pp.receiveWebRTCOffer({
|
expect(pp.receiveWebRTCOffer({
|
||||||
type: 'answer'
|
type: 'answer'
|
||||||
})).toBe(false);
|
})).toBe(false);
|
||||||
});
|
});
|
||||||
return it('accepts valid offers', function() {
|
|
||||||
|
it('accepts valid offers', function() {
|
||||||
expect(pp.pc).not.toBeNull();
|
expect(pp.pc).not.toBeNull();
|
||||||
return expect(pp.receiveWebRTCOffer({
|
expect(pp.receiveWebRTCOffer({
|
||||||
type: 'offer',
|
type: 'offer',
|
||||||
sdp: 'foo'
|
sdp: 'foo'
|
||||||
})).toBe(true);
|
})).toBe(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('responds with a WebRTC answer correctly', function() {
|
it('responds with a WebRTC answer correctly', function() {
|
||||||
spyOn(snowflake.broker, 'sendAnswer');
|
spyOn(snowflake.broker, 'sendAnswer');
|
||||||
pp.pc.onicecandidate({
|
pp.pc.onicecandidate({
|
||||||
candidate: null
|
candidate: null
|
||||||
});
|
});
|
||||||
return expect(snowflake.broker.sendAnswer).toHaveBeenCalled();
|
expect(snowflake.broker.sendAnswer).toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('handles a new data channel correctly', function() {
|
it('handles a new data channel correctly', function() {
|
||||||
expect(pp.client).toBeNull();
|
expect(pp.client).toBeNull();
|
||||||
pp.pc.ondatachannel({
|
pp.pc.ondatachannel({
|
||||||
|
@ -84,21 +93,25 @@ describe('ProxyPair', function() {
|
||||||
expect(pp.client.onopen).not.toBeNull();
|
expect(pp.client.onopen).not.toBeNull();
|
||||||
expect(pp.client.onclose).not.toBeNull();
|
expect(pp.client.onclose).not.toBeNull();
|
||||||
expect(pp.client.onerror).not.toBeNull();
|
expect(pp.client.onerror).not.toBeNull();
|
||||||
return expect(pp.client.onmessage).not.toBeNull();
|
expect(pp.client.onmessage).not.toBeNull();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('connects to the relay once datachannel opens', function() {
|
it('connects to the relay once datachannel opens', function() {
|
||||||
spyOn(pp, 'connectRelay');
|
spyOn(pp, 'connectRelay');
|
||||||
pp.client.onopen();
|
pp.client.onopen();
|
||||||
return expect(pp.connectRelay).toHaveBeenCalled();
|
expect(pp.connectRelay).toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('connects to a relay', function() {
|
it('connects to a relay', function() {
|
||||||
pp.connectRelay();
|
pp.connectRelay();
|
||||||
expect(pp.relay.onopen).not.toBeNull();
|
expect(pp.relay.onopen).not.toBeNull();
|
||||||
expect(pp.relay.onclose).not.toBeNull();
|
expect(pp.relay.onclose).not.toBeNull();
|
||||||
expect(pp.relay.onerror).not.toBeNull();
|
expect(pp.relay.onerror).not.toBeNull();
|
||||||
return expect(pp.relay.onmessage).not.toBeNull();
|
expect(pp.relay.onmessage).not.toBeNull();
|
||||||
});
|
});
|
||||||
return describe('flushes data between client and relay', function() {
|
|
||||||
|
describe('flushes data between client and relay', function() {
|
||||||
|
|
||||||
it('proxies data from client to relay', function() {
|
it('proxies data from client to relay', function() {
|
||||||
var msg;
|
var msg;
|
||||||
pp.pc.ondatachannel({
|
pp.pc.ondatachannel({
|
||||||
|
@ -116,8 +129,9 @@ describe('ProxyPair', function() {
|
||||||
pp.onClientToRelayMessage(msg);
|
pp.onClientToRelayMessage(msg);
|
||||||
pp.flush();
|
pp.flush();
|
||||||
expect(pp.client.send).not.toHaveBeenCalled();
|
expect(pp.client.send).not.toHaveBeenCalled();
|
||||||
return expect(pp.relay.send).toHaveBeenCalledWith(arrayMatching([1, 2, 3]));
|
expect(pp.relay.send).toHaveBeenCalledWith(arrayMatching([1, 2, 3]));
|
||||||
});
|
});
|
||||||
|
|
||||||
it('proxies data from relay to client', function() {
|
it('proxies data from relay to client', function() {
|
||||||
var msg;
|
var msg;
|
||||||
spyOn(pp.client, 'send');
|
spyOn(pp.client, 'send');
|
||||||
|
@ -128,16 +142,19 @@ describe('ProxyPair', function() {
|
||||||
pp.onRelayToClientMessage(msg);
|
pp.onRelayToClientMessage(msg);
|
||||||
pp.flush();
|
pp.flush();
|
||||||
expect(pp.client.send).toHaveBeenCalledWith(arrayMatching([4, 5, 6]));
|
expect(pp.client.send).toHaveBeenCalledWith(arrayMatching([4, 5, 6]));
|
||||||
return expect(pp.relay.send).not.toHaveBeenCalled();
|
expect(pp.relay.send).not.toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
return it('sends nothing with nothing to flush', function() {
|
|
||||||
|
it('sends nothing with nothing to flush', function() {
|
||||||
spyOn(pp.client, 'send');
|
spyOn(pp.client, 'send');
|
||||||
spyOn(pp.relay, 'send');
|
spyOn(pp.relay, 'send');
|
||||||
pp.flush();
|
pp.flush();
|
||||||
expect(pp.client.send).not.toHaveBeenCalled();
|
expect(pp.client.send).not.toHaveBeenCalled();
|
||||||
return expect(pp.relay.send).not.toHaveBeenCalled();
|
expect(pp.relay.send).not.toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// TODO: rate limit tests
|
// TODO: rate limit tests
|
||||||
|
|
|
@ -1,62 +1,43 @@
|
||||||
// Generated by CoffeeScript 2.4.1
|
|
||||||
/*
|
/*
|
||||||
jasmine tests for Snowflake
|
jasmine tests for Snowflake
|
||||||
*/
|
*/
|
||||||
var FakeBroker, PeerConnection, SessionDescription, WebSocket, config, log, ui;
|
|
||||||
|
|
||||||
// Fake browser functionality:
|
// Fake browser functionality:
|
||||||
PeerConnection = class PeerConnection {
|
class PeerConnection {
|
||||||
setRemoteDescription() {
|
setRemoteDescription() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
send(data) {}
|
send(data) {}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
SessionDescription = (function() {
|
|
||||||
class SessionDescription {};
|
class SessionDescription {};
|
||||||
|
|
||||||
SessionDescription.prototype.type = 'offer';
|
SessionDescription.prototype.type = 'offer';
|
||||||
|
|
||||||
return SessionDescription;
|
|
||||||
|
|
||||||
}).call(this);
|
|
||||||
|
|
||||||
WebSocket = (function() {
|
|
||||||
class WebSocket {
|
class WebSocket {
|
||||||
constructor() {
|
constructor() {
|
||||||
this.bufferedAmount = 0;
|
this.bufferedAmount = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
send(data) {}
|
send(data) {}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
WebSocket.prototype.OPEN = 1;
|
WebSocket.prototype.OPEN = 1;
|
||||||
|
|
||||||
WebSocket.prototype.CLOSED = 0;
|
WebSocket.prototype.CLOSED = 0;
|
||||||
|
|
||||||
return WebSocket;
|
var log = function() {};
|
||||||
|
|
||||||
}).call(this);
|
var config = new Config;
|
||||||
|
|
||||||
log = function() {};
|
var ui = new UI;
|
||||||
|
|
||||||
config = new Config;
|
class FakeBroker {
|
||||||
|
|
||||||
ui = new UI;
|
|
||||||
|
|
||||||
FakeBroker = class FakeBroker {
|
|
||||||
getClientOffer() {
|
getClientOffer() {
|
||||||
return new Promise(function(F, R) {
|
return new Promise(function(F, R) {
|
||||||
return {};
|
return {};
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
describe('Snowflake', function() {
|
describe('Snowflake', function() {
|
||||||
|
|
||||||
it('constructs correctly', function() {
|
it('constructs correctly', function() {
|
||||||
var s;
|
var s;
|
||||||
s = new Snowflake(config, ui, {
|
s = new Snowflake(config, ui, {
|
||||||
|
@ -67,22 +48,25 @@ describe('Snowflake', function() {
|
||||||
fake: 'broker'
|
fake: 'broker'
|
||||||
});
|
});
|
||||||
expect(s.ui).not.toBeNull();
|
expect(s.ui).not.toBeNull();
|
||||||
return expect(s.retries).toBe(0);
|
expect(s.retries).toBe(0);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('sets relay address correctly', function() {
|
it('sets relay address correctly', function() {
|
||||||
var s;
|
var s;
|
||||||
s = new Snowflake(config, ui, null);
|
s = new Snowflake(config, ui, null);
|
||||||
s.setRelayAddr('foo');
|
s.setRelayAddr('foo');
|
||||||
return expect(s.relayAddr).toEqual('foo');
|
expect(s.relayAddr).toEqual('foo');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('initalizes WebRTC connection', function() {
|
it('initalizes WebRTC connection', function() {
|
||||||
var s;
|
var s;
|
||||||
s = new Snowflake(config, ui, new FakeBroker());
|
s = new Snowflake(config, ui, new FakeBroker());
|
||||||
spyOn(s.broker, 'getClientOffer').and.callThrough();
|
spyOn(s.broker, 'getClientOffer').and.callThrough();
|
||||||
s.beginWebRTC();
|
s.beginWebRTC();
|
||||||
expect(s.retries).toBe(1);
|
expect(s.retries).toBe(1);
|
||||||
return expect(s.broker.getClientOffer).toHaveBeenCalled();
|
expect(s.broker.getClientOffer).toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('receives SDP offer and sends answer', function() {
|
it('receives SDP offer and sends answer', function() {
|
||||||
var pair, s;
|
var pair, s;
|
||||||
s = new Snowflake(config, ui, new FakeBroker());
|
s = new Snowflake(config, ui, new FakeBroker());
|
||||||
|
@ -92,8 +76,9 @@ describe('Snowflake', function() {
|
||||||
spyOn(pair, 'receiveWebRTCOffer').and.returnValue(true);
|
spyOn(pair, 'receiveWebRTCOffer').and.returnValue(true);
|
||||||
spyOn(s, 'sendAnswer');
|
spyOn(s, 'sendAnswer');
|
||||||
s.receiveOffer(pair, '{"type":"offer","sdp":"foo"}');
|
s.receiveOffer(pair, '{"type":"offer","sdp":"foo"}');
|
||||||
return expect(s.sendAnswer).toHaveBeenCalled();
|
expect(s.sendAnswer).toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('does not send answer when receiving invalid offer', function() {
|
it('does not send answer when receiving invalid offer', function() {
|
||||||
var pair, s;
|
var pair, s;
|
||||||
s = new Snowflake(config, ui, new FakeBroker());
|
s = new Snowflake(config, ui, new FakeBroker());
|
||||||
|
@ -103,12 +88,14 @@ describe('Snowflake', function() {
|
||||||
spyOn(pair, 'receiveWebRTCOffer').and.returnValue(false);
|
spyOn(pair, 'receiveWebRTCOffer').and.returnValue(false);
|
||||||
spyOn(s, 'sendAnswer');
|
spyOn(s, 'sendAnswer');
|
||||||
s.receiveOffer(pair, '{"type":"not a good offer","sdp":"foo"}');
|
s.receiveOffer(pair, '{"type":"not a good offer","sdp":"foo"}');
|
||||||
return expect(s.sendAnswer).not.toHaveBeenCalled();
|
expect(s.sendAnswer).not.toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
return it('can make a proxypair', function() {
|
|
||||||
|
it('can make a proxypair', function() {
|
||||||
var s;
|
var s;
|
||||||
s = new Snowflake(config, ui, new FakeBroker());
|
s = new Snowflake(config, ui, new FakeBroker());
|
||||||
s.makeProxyPair();
|
s.makeProxyPair();
|
||||||
return expect(s.proxyPairs.length).toBe(1);
|
expect(s.proxyPairs.length).toBe(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,10 +1,7 @@
|
||||||
// Generated by CoffeeScript 2.4.1
|
|
||||||
/*
|
/*
|
||||||
jasmine tests for Snowflake UI
|
jasmine tests for Snowflake UI
|
||||||
*/
|
*/
|
||||||
var document;
|
var document = {
|
||||||
|
|
||||||
document = {
|
|
||||||
getElementById: function(id) {
|
getElementById: function(id) {
|
||||||
return {};
|
return {};
|
||||||
},
|
},
|
||||||
|
@ -14,6 +11,7 @@ document = {
|
||||||
};
|
};
|
||||||
|
|
||||||
describe('UI', function() {
|
describe('UI', function() {
|
||||||
|
|
||||||
it('activates debug mode when badge does not exist', function() {
|
it('activates debug mode when badge does not exist', function() {
|
||||||
var u;
|
var u;
|
||||||
spyOn(document, 'getElementById').and.callFake(function(id) {
|
spyOn(document, 'getElementById').and.callFake(function(id) {
|
||||||
|
@ -25,8 +23,9 @@ describe('UI', function() {
|
||||||
u = new DebugUI();
|
u = new DebugUI();
|
||||||
expect(document.getElementById.calls.count()).toEqual(2);
|
expect(document.getElementById.calls.count()).toEqual(2);
|
||||||
expect(u.$status).not.toBeNull();
|
expect(u.$status).not.toBeNull();
|
||||||
return expect(u.$msglog).not.toBeNull();
|
expect(u.$msglog).not.toBeNull();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('is not debug mode when badge exists', function() {
|
it('is not debug mode when badge exists', function() {
|
||||||
var u;
|
var u;
|
||||||
spyOn(document, 'getElementById').and.callFake(function(id) {
|
spyOn(document, 'getElementById').and.callFake(function(id) {
|
||||||
|
@ -38,8 +37,9 @@ describe('UI', function() {
|
||||||
u = new BadgeUI();
|
u = new BadgeUI();
|
||||||
expect(document.getElementById).toHaveBeenCalled();
|
expect(document.getElementById).toHaveBeenCalled();
|
||||||
expect(document.getElementById.calls.count()).toEqual(1);
|
expect(document.getElementById.calls.count()).toEqual(1);
|
||||||
return expect(u.$badge).not.toBeNull();
|
expect(u.$badge).not.toBeNull();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('sets status message when in debug mode', function() {
|
it('sets status message when in debug mode', function() {
|
||||||
var u;
|
var u;
|
||||||
u = new DebugUI();
|
u = new DebugUI();
|
||||||
|
@ -50,16 +50,18 @@ describe('UI', function() {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
u.setStatus('test');
|
u.setStatus('test');
|
||||||
return expect(u.$status.innerHTML).toEqual('Status: test');
|
expect(u.$status.innerHTML).toEqual('Status: test');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('sets message log css correctly for debug mode', function() {
|
it('sets message log css correctly for debug mode', function() {
|
||||||
var u;
|
var u;
|
||||||
u = new DebugUI();
|
u = new DebugUI();
|
||||||
u.setActive(true);
|
u.setActive(true);
|
||||||
expect(u.$msglog.className).toEqual('active');
|
expect(u.$msglog.className).toEqual('active');
|
||||||
u.setActive(false);
|
u.setActive(false);
|
||||||
return expect(u.$msglog.className).toEqual('');
|
expect(u.$msglog.className).toEqual('');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('sets badge css correctly for non-debug mode', function() {
|
it('sets badge css correctly for non-debug mode', function() {
|
||||||
var u;
|
var u;
|
||||||
u = new BadgeUI();
|
u = new BadgeUI();
|
||||||
|
@ -67,9 +69,10 @@ describe('UI', function() {
|
||||||
u.setActive(true);
|
u.setActive(true);
|
||||||
expect(u.$badge.className).toEqual('active');
|
expect(u.$badge.className).toEqual('active');
|
||||||
u.setActive(false);
|
u.setActive(false);
|
||||||
return expect(u.$badge.className).toEqual('');
|
expect(u.$badge.className).toEqual('');
|
||||||
});
|
});
|
||||||
return it('logs to the textarea correctly when debug mode', function() {
|
|
||||||
|
it('logs to the textarea correctly when debug mode', function() {
|
||||||
var u;
|
var u;
|
||||||
u = new DebugUI();
|
u = new DebugUI();
|
||||||
u.$msglog = {
|
u.$msglog = {
|
||||||
|
@ -79,6 +82,7 @@ describe('UI', function() {
|
||||||
};
|
};
|
||||||
u.log('test');
|
u.log('test');
|
||||||
expect(u.$msglog.value).toEqual('test\n');
|
expect(u.$msglog.value).toEqual('test\n');
|
||||||
return expect(u.$msglog.scrollTop).toEqual(1337);
|
expect(u.$msglog.scrollTop).toEqual(1337);
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,10 +1,12 @@
|
||||||
// Generated by CoffeeScript 2.4.1
|
|
||||||
/*
|
/*
|
||||||
jasmine tests for Snowflake utils
|
jasmine tests for Snowflake utils
|
||||||
*/
|
*/
|
||||||
|
|
||||||
describe('Parse', function() {
|
describe('Parse', function() {
|
||||||
|
|
||||||
describe('cookie', function() {
|
describe('cookie', function() {
|
||||||
return it('parses correctly', function() {
|
|
||||||
|
it('parses correctly', function() {
|
||||||
expect(Parse.cookie('')).toEqual({});
|
expect(Parse.cookie('')).toEqual({});
|
||||||
expect(Parse.cookie('a=b')).toEqual({
|
expect(Parse.cookie('a=b')).toEqual({
|
||||||
a: 'b'
|
a: 'b'
|
||||||
|
@ -30,12 +32,15 @@ describe('Parse', function() {
|
||||||
expect(Parse.cookie('key=%26%20')).toEqual({
|
expect(Parse.cookie('key=%26%20')).toEqual({
|
||||||
key: '& '
|
key: '& '
|
||||||
});
|
});
|
||||||
return expect(Parse.cookie('a=\'\'')).toEqual({
|
expect(Parse.cookie('a=\'\'')).toEqual({
|
||||||
a: '\'\''
|
a: '\'\''
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('address', function() {
|
describe('address', function() {
|
||||||
|
|
||||||
it('parses IPv4', function() {
|
it('parses IPv4', function() {
|
||||||
expect(Parse.address('')).toBeNull();
|
expect(Parse.address('')).toBeNull();
|
||||||
expect(Parse.address('3.3.3.3:4444')).toEqual({
|
expect(Parse.address('3.3.3.3:4444')).toEqual({
|
||||||
|
@ -45,9 +50,10 @@ describe('Parse', function() {
|
||||||
expect(Parse.address('3.3.3.3')).toBeNull();
|
expect(Parse.address('3.3.3.3')).toBeNull();
|
||||||
expect(Parse.address('3.3.3.3:0x1111')).toBeNull();
|
expect(Parse.address('3.3.3.3:0x1111')).toBeNull();
|
||||||
expect(Parse.address('3.3.3.3:-4444')).toBeNull();
|
expect(Parse.address('3.3.3.3:-4444')).toBeNull();
|
||||||
return expect(Parse.address('3.3.3.3:65536')).toBeNull();
|
expect(Parse.address('3.3.3.3:65536')).toBeNull();
|
||||||
});
|
});
|
||||||
return it('parses IPv6', function() {
|
|
||||||
|
it('parses IPv6', function() {
|
||||||
expect(Parse.address('[1:2::a:f]:4444')).toEqual({
|
expect(Parse.address('[1:2::a:f]:4444')).toEqual({
|
||||||
host: '1:2::a:f',
|
host: '1:2::a:f',
|
||||||
port: 4444
|
port: 4444
|
||||||
|
@ -56,15 +62,17 @@ describe('Parse', function() {
|
||||||
expect(Parse.address('[1:2::a:f]:0x1111')).toBeNull();
|
expect(Parse.address('[1:2::a:f]:0x1111')).toBeNull();
|
||||||
expect(Parse.address('[1:2::a:f]:-4444')).toBeNull();
|
expect(Parse.address('[1:2::a:f]:-4444')).toBeNull();
|
||||||
expect(Parse.address('[1:2::a:f]:65536')).toBeNull();
|
expect(Parse.address('[1:2::a:f]:65536')).toBeNull();
|
||||||
return expect(Parse.address('[1:2::ffff:1.2.3.4]:4444')).toEqual({
|
expect(Parse.address('[1:2::ffff:1.2.3.4]:4444')).toEqual({
|
||||||
host: '1:2::ffff:1.2.3.4',
|
host: '1:2::ffff:1.2.3.4',
|
||||||
port: 4444
|
port: 4444
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
return describe('ipFromSDP', function() {
|
|
||||||
var testCases;
|
describe('ipFromSDP', function() {
|
||||||
testCases = [
|
|
||||||
|
var testCases = [
|
||||||
{
|
{
|
||||||
// https://tools.ietf.org/html/rfc4566#section-5
|
// https://tools.ietf.org/html/rfc4566#section-5
|
||||||
sdp: "v=0\no=jdoe 2890844526 2890842807 IN IP4 10.47.16.5\ns=SDP Seminar\ni=A Seminar on the session description protocol\nu=http://www.example.com/seminars/sdp.pdf\ne=j.doe@example.com (Jane Doe)\nc=IN IP4 224.2.17.12/127\nt=2873397496 2873404696\na=recvonly\nm=audio 49170 RTP/AVP 0\nm=video 51372 RTP/AVP 99\na=rtpmap:99 h263-1998/90000",
|
sdp: "v=0\no=jdoe 2890844526 2890842807 IN IP4 10.47.16.5\ns=SDP Seminar\ni=A Seminar on the session description protocol\nu=http://www.example.com/seminars/sdp.pdf\ne=j.doe@example.com (Jane Doe)\nc=IN IP4 224.2.17.12/127\nt=2873397496 2873404696\na=recvonly\nm=audio 49170 RTP/AVP 0\nm=video 51372 RTP/AVP 99\na=rtpmap:99 h263-1998/90000",
|
||||||
|
@ -128,7 +136,8 @@ describe('Parse', function() {
|
||||||
expected: void 0
|
expected: void 0
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
return it('parses SDP', function() {
|
|
||||||
|
it('parses SDP', function() {
|
||||||
var i, len, ref, ref1, results, test;
|
var i, len, ref, ref1, results, test;
|
||||||
results = [];
|
results = [];
|
||||||
for (i = 0, len = testCases.length; i < len; i++) {
|
for (i = 0, len = testCases.length; i < len; i++) {
|
||||||
|
@ -143,10 +152,13 @@ describe('Parse', function() {
|
||||||
}
|
}
|
||||||
return results;
|
return results;
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('query string', function() {
|
describe('query string', function() {
|
||||||
|
|
||||||
it('should parse correctly', function() {
|
it('should parse correctly', function() {
|
||||||
expect(Query.parse('')).toEqual({});
|
expect(Query.parse('')).toEqual({});
|
||||||
expect(Query.parse('a=b')).toEqual({
|
expect(Query.parse('a=b')).toEqual({
|
||||||
|
@ -178,11 +190,12 @@ describe('query string', function() {
|
||||||
expect(Query.parse('a+b=c')).toEqual({
|
expect(Query.parse('a+b=c')).toEqual({
|
||||||
'a b': 'c'
|
'a b': 'c'
|
||||||
});
|
});
|
||||||
return expect(Query.parse('a=b+c+d')).toEqual({
|
expect(Query.parse('a=b+c+d')).toEqual({
|
||||||
a: 'b c d'
|
a: 'b c d'
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
return it('uses the first appearance of duplicate key', function() {
|
|
||||||
|
it('uses the first appearance of duplicate key', function() {
|
||||||
expect(Query.parse('a=b&c=d&a=e')).toEqual({
|
expect(Query.parse('a=b&c=d&a=e')).toEqual({
|
||||||
a: 'b',
|
a: 'b',
|
||||||
c: 'd'
|
c: 'd'
|
||||||
|
@ -201,21 +214,24 @@ describe('query string', function() {
|
||||||
a: 'b',
|
a: 'b',
|
||||||
'': ''
|
'': ''
|
||||||
});
|
});
|
||||||
return expect(Query.parse('a=b&&c=d')).toEqual({
|
expect(Query.parse('a=b&&c=d')).toEqual({
|
||||||
a: 'b',
|
a: 'b',
|
||||||
'': '',
|
'': '',
|
||||||
c: 'd'
|
c: 'd'
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('Params', function() {
|
describe('Params', function() {
|
||||||
|
|
||||||
describe('bool', function() {
|
describe('bool', function() {
|
||||||
var getBool;
|
|
||||||
getBool = function(query) {
|
var getBool = function(query) {
|
||||||
return Params.getBool(Query.parse(query), 'param', false);
|
return Params.getBool(Query.parse(query), 'param', false);
|
||||||
};
|
};
|
||||||
return it('parses correctly', function() {
|
|
||||||
|
it('parses correctly', function() {
|
||||||
expect(getBool('param=true')).toBe(true);
|
expect(getBool('param=true')).toBe(true);
|
||||||
expect(getBool('param')).toBe(true);
|
expect(getBool('param')).toBe(true);
|
||||||
expect(getBool('param=')).toBe(true);
|
expect(getBool('param=')).toBe(true);
|
||||||
|
@ -223,19 +239,23 @@ describe('Params', function() {
|
||||||
expect(getBool('param=0')).toBe(false);
|
expect(getBool('param=0')).toBe(false);
|
||||||
expect(getBool('param=false')).toBe(false);
|
expect(getBool('param=false')).toBe(false);
|
||||||
expect(getBool('param=unexpected')).toBeNull();
|
expect(getBool('param=unexpected')).toBeNull();
|
||||||
return expect(getBool('pram=true')).toBe(false);
|
expect(getBool('pram=true')).toBe(false);
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
return describe('address', function() {
|
|
||||||
var DEFAULT, getAddress;
|
describe('address', function() {
|
||||||
DEFAULT = {
|
|
||||||
|
var DEFAULT = {
|
||||||
host: '1.1.1.1',
|
host: '1.1.1.1',
|
||||||
port: 2222
|
port: 2222
|
||||||
};
|
};
|
||||||
getAddress = function(query) {
|
|
||||||
|
var getAddress = function(query) {
|
||||||
return Params.getAddress(query, 'addr', DEFAULT);
|
return Params.getAddress(query, 'addr', DEFAULT);
|
||||||
};
|
};
|
||||||
return it('parses correctly', function() {
|
|
||||||
|
it('parses correctly', function() {
|
||||||
expect(getAddress({})).toEqual(DEFAULT);
|
expect(getAddress({})).toEqual(DEFAULT);
|
||||||
expect(getAddress({
|
expect(getAddress({
|
||||||
addr: '3.3.3.3:4444'
|
addr: '3.3.3.3:4444'
|
||||||
|
@ -246,9 +266,11 @@ describe('Params', function() {
|
||||||
expect(getAddress({
|
expect(getAddress({
|
||||||
x: '3.3.3.3:4444'
|
x: '3.3.3.3:4444'
|
||||||
})).toEqual(DEFAULT);
|
})).toEqual(DEFAULT);
|
||||||
return expect(getAddress({
|
expect(getAddress({
|
||||||
addr: '---'
|
addr: '---'
|
||||||
})).toBeNull();
|
})).toBeNull();
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,32 +1,39 @@
|
||||||
// Generated by CoffeeScript 2.4.1
|
|
||||||
/*
|
/*
|
||||||
jasmine tests for Snowflake websocket
|
jasmine tests for Snowflake websocket
|
||||||
*/
|
*/
|
||||||
|
|
||||||
describe('BuildUrl', function() {
|
describe('BuildUrl', function() {
|
||||||
|
|
||||||
it('should parse just protocol and host', function() {
|
it('should parse just protocol and host', function() {
|
||||||
return expect(WS.buildUrl('http', 'example.com')).toBe('http://example.com');
|
expect(WS.buildUrl('http', 'example.com')).toBe('http://example.com');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should handle different ports', function() {
|
it('should handle different ports', function() {
|
||||||
expect(WS.buildUrl('http', 'example.com', 80)).toBe('http://example.com');
|
expect(WS.buildUrl('http', 'example.com', 80)).toBe('http://example.com');
|
||||||
expect(WS.buildUrl('http', 'example.com', 81)).toBe('http://example.com:81');
|
expect(WS.buildUrl('http', 'example.com', 81)).toBe('http://example.com:81');
|
||||||
expect(WS.buildUrl('http', 'example.com', 443)).toBe('http://example.com:443');
|
expect(WS.buildUrl('http', 'example.com', 443)).toBe('http://example.com:443');
|
||||||
return expect(WS.buildUrl('http', 'example.com', 444)).toBe('http://example.com:444');
|
expect(WS.buildUrl('http', 'example.com', 444)).toBe('http://example.com:444');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should handle paths', function() {
|
it('should handle paths', function() {
|
||||||
expect(WS.buildUrl('http', 'example.com', 80, '/')).toBe('http://example.com/');
|
expect(WS.buildUrl('http', 'example.com', 80, '/')).toBe('http://example.com/');
|
||||||
expect(WS.buildUrl('http', 'example.com', 80, '/test?k=%#v')).toBe('http://example.com/test%3Fk%3D%25%23v');
|
expect(WS.buildUrl('http', 'example.com', 80, '/test?k=%#v')).toBe('http://example.com/test%3Fk%3D%25%23v');
|
||||||
return expect(WS.buildUrl('http', 'example.com', 80, '/test')).toBe('http://example.com/test');
|
expect(WS.buildUrl('http', 'example.com', 80, '/test')).toBe('http://example.com/test');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should handle params', function() {
|
it('should handle params', function() {
|
||||||
expect(WS.buildUrl('http', 'example.com', 80, '/test', [['k', '%#v']])).toBe('http://example.com/test?k=%25%23v');
|
expect(WS.buildUrl('http', 'example.com', 80, '/test', [['k', '%#v']])).toBe('http://example.com/test?k=%25%23v');
|
||||||
return expect(WS.buildUrl('http', 'example.com', 80, '/test', [['a', 'b'], ['c', 'd']])).toBe('http://example.com/test?a=b&c=d');
|
expect(WS.buildUrl('http', 'example.com', 80, '/test', [['a', 'b'], ['c', 'd']])).toBe('http://example.com/test?a=b&c=d');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should handle ips', function() {
|
it('should handle ips', function() {
|
||||||
expect(WS.buildUrl('http', '1.2.3.4')).toBe('http://1.2.3.4');
|
expect(WS.buildUrl('http', '1.2.3.4')).toBe('http://1.2.3.4');
|
||||||
return expect(WS.buildUrl('http', '1:2::3:4')).toBe('http://[1:2::3:4]');
|
expect(WS.buildUrl('http', '1:2::3:4')).toBe('http://[1:2::3:4]');
|
||||||
});
|
});
|
||||||
return it('should handle bogus', function() {
|
|
||||||
|
it('should handle bogus', function() {
|
||||||
expect(WS.buildUrl('http', 'bog][us')).toBe('http://bog%5D%5Bus');
|
expect(WS.buildUrl('http', 'bog][us')).toBe('http://bog%5D%5Bus');
|
||||||
return expect(WS.buildUrl('http', 'bog:u]s')).toBe('http://bog%3Au%5Ds');
|
expect(WS.buildUrl('http', 'bog:u]s')).toBe('http://bog%3Au%5Ds');
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
27
proxy/ui.js
27
proxy/ui.js
|
@ -1,12 +1,9 @@
|
||||||
// Generated by CoffeeScript 2.4.1
|
|
||||||
/*
|
/*
|
||||||
All of Snowflake's DOM manipulation and inputs.
|
All of Snowflake's DOM manipulation and inputs.
|
||||||
*/
|
*/
|
||||||
var BadgeUI, DebugUI, UI, WebExtUI,
|
|
||||||
boundMethodCheck = function(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new Error('Bound instance method accessed before binding'); } };
|
|
||||||
|
|
||||||
UI = (function() {
|
|
||||||
class UI {
|
class UI {
|
||||||
|
|
||||||
setStatus(msg) {}
|
setStatus(msg) {}
|
||||||
|
|
||||||
setActive(connected) {
|
setActive(connected) {
|
||||||
|
@ -21,12 +18,9 @@ UI = (function() {
|
||||||
|
|
||||||
UI.prototype.enabled = true;
|
UI.prototype.enabled = true;
|
||||||
|
|
||||||
return UI;
|
|
||||||
|
|
||||||
}).call(this);
|
|
||||||
|
|
||||||
BadgeUI = (function() {
|
|
||||||
class BadgeUI extends UI {
|
class BadgeUI extends UI {
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
super();
|
super();
|
||||||
this.$badge = document.getElementById('badge');
|
this.$badge = document.getElementById('badge');
|
||||||
|
@ -41,12 +35,9 @@ BadgeUI = (function() {
|
||||||
|
|
||||||
BadgeUI.prototype.$badge = null;
|
BadgeUI.prototype.$badge = null;
|
||||||
|
|
||||||
return BadgeUI;
|
|
||||||
|
|
||||||
}).call(this);
|
|
||||||
|
|
||||||
DebugUI = (function() {
|
|
||||||
class DebugUI extends UI {
|
class DebugUI extends UI {
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
super();
|
super();
|
||||||
// Setup other DOM handlers if it's debug mode.
|
// Setup other DOM handlers if it's debug mode.
|
||||||
|
@ -83,12 +74,9 @@ DebugUI = (function() {
|
||||||
|
|
||||||
DebugUI.prototype.$status = null;
|
DebugUI.prototype.$status = null;
|
||||||
|
|
||||||
return DebugUI;
|
|
||||||
|
|
||||||
}).call(this);
|
|
||||||
|
|
||||||
WebExtUI = (function() {
|
|
||||||
class WebExtUI extends UI {
|
class WebExtUI extends UI {
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
super();
|
super();
|
||||||
this.onConnect = this.onConnect.bind(this);
|
this.onConnect = this.onConnect.bind(this);
|
||||||
|
@ -131,7 +119,6 @@ WebExtUI = (function() {
|
||||||
}
|
}
|
||||||
|
|
||||||
onConnect(port) {
|
onConnect(port) {
|
||||||
boundMethodCheck(this, WebExtUI);
|
|
||||||
this.port = port;
|
this.port = port;
|
||||||
port.onDisconnect.addListener(this.onDisconnect);
|
port.onDisconnect.addListener(this.onDisconnect);
|
||||||
port.onMessage.addListener(this.onMessage);
|
port.onMessage.addListener(this.onMessage);
|
||||||
|
@ -140,7 +127,6 @@ WebExtUI = (function() {
|
||||||
|
|
||||||
onMessage(m) {
|
onMessage(m) {
|
||||||
var storing;
|
var storing;
|
||||||
boundMethodCheck(this, WebExtUI);
|
|
||||||
this.enabled = m.enabled;
|
this.enabled = m.enabled;
|
||||||
this.setEnabled(this.enabled);
|
this.setEnabled(this.enabled);
|
||||||
this.postActive();
|
this.postActive();
|
||||||
|
@ -152,7 +138,6 @@ WebExtUI = (function() {
|
||||||
}
|
}
|
||||||
|
|
||||||
onDisconnect(port) {
|
onDisconnect(port) {
|
||||||
boundMethodCheck(this, WebExtUI);
|
|
||||||
return this.port = null;
|
return this.port = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -191,7 +176,3 @@ WebExtUI = (function() {
|
||||||
WebExtUI.prototype.port = null;
|
WebExtUI.prototype.port = null;
|
||||||
|
|
||||||
WebExtUI.prototype.stats = null;
|
WebExtUI.prototype.stats = null;
|
||||||
|
|
||||||
return WebExtUI;
|
|
||||||
|
|
||||||
}).call(this);
|
|
||||||
|
|
|
@ -1,13 +1,11 @@
|
||||||
// Generated by CoffeeScript 2.4.1
|
|
||||||
/*
|
/*
|
||||||
A Coffeescript WebRTC snowflake proxy
|
A Coffeescript WebRTC snowflake proxy
|
||||||
|
|
||||||
Contains helpers for parsing query strings and other utilities.
|
Contains helpers for parsing query strings and other utilities.
|
||||||
*/
|
*/
|
||||||
var BucketRateLimit, DummyRateLimit, Params, Parse, Query, Util;
|
|
||||||
|
|
||||||
Util = (function() {
|
|
||||||
class Util {
|
class Util {
|
||||||
|
|
||||||
static mightBeTBB() {
|
static mightBeTBB() {
|
||||||
return Util.TBB_UAS.indexOf(window.navigator.userAgent) > -1 && (window.navigator.mimeTypes && window.navigator.mimeTypes.length === 0);
|
return Util.TBB_UAS.indexOf(window.navigator.userAgent) > -1 && (window.navigator.mimeTypes && window.navigator.mimeTypes.length === 0);
|
||||||
}
|
}
|
||||||
|
@ -41,13 +39,16 @@ Util = (function() {
|
||||||
// It would not be effective for Tor Browser users to run the proxy.
|
// It would not be effective for Tor Browser users to run the proxy.
|
||||||
// Do we seem to be running in Tor Browser? Check the user-agent string and for
|
// Do we seem to be running in Tor Browser? Check the user-agent string and for
|
||||||
// no listing of supported MIME types.
|
// no listing of supported MIME types.
|
||||||
Util.TBB_UAS = ['Mozilla/5.0 (Windows NT 6.1; rv:10.0) Gecko/20100101 Firefox/10.0', 'Mozilla/5.0 (Windows NT 6.1; rv:17.0) Gecko/20100101 Firefox/17.0', 'Mozilla/5.0 (Windows NT 6.1; rv:24.0) Gecko/20100101 Firefox/24.0', 'Mozilla/5.0 (Windows NT 6.1; rv:31.0) Gecko/20100101 Firefox/31.0'];
|
Util.TBB_UAS = [
|
||||||
|
'Mozilla/5.0 (Windows NT 6.1; rv:10.0) Gecko/20100101 Firefox/10.0',
|
||||||
|
'Mozilla/5.0 (Windows NT 6.1; rv:17.0) Gecko/20100101 Firefox/17.0',
|
||||||
|
'Mozilla/5.0 (Windows NT 6.1; rv:24.0) Gecko/20100101 Firefox/24.0',
|
||||||
|
'Mozilla/5.0 (Windows NT 6.1; rv:31.0) Gecko/20100101 Firefox/31.0'
|
||||||
|
];
|
||||||
|
|
||||||
return Util;
|
|
||||||
|
|
||||||
}).call(this);
|
class Query {
|
||||||
|
|
||||||
Query = class Query {
|
|
||||||
/*
|
/*
|
||||||
Parse a URL query string or application/x-www-form-urlencoded body. The
|
Parse a URL query string or application/x-www-form-urlencoded body. The
|
||||||
return type is an object mapping string keys to string values. By design,
|
return type is an object mapping string keys to string values. By design,
|
||||||
|
@ -100,7 +101,9 @@ Query = class Query {
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
Parse = class Parse {
|
|
||||||
|
class Parse {
|
||||||
|
|
||||||
// Parse a cookie data string (usually document.cookie). The return type is an
|
// Parse a cookie data string (usually document.cookie). The return type is an
|
||||||
// object mapping cookies names to values. Returns null on error.
|
// object mapping cookies names to values. Returns null on error.
|
||||||
// http://www.w3.org/TR/DOM-Level-2-HTML/html.html#ID-8747038
|
// http://www.w3.org/TR/DOM-Level-2-HTML/html.html#ID-8747038
|
||||||
|
@ -202,7 +205,9 @@ Parse = class Parse {
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
Params = class Params {
|
|
||||||
|
class Params {
|
||||||
|
|
||||||
static getBool(query, param, defaultValue) {
|
static getBool(query, param, defaultValue) {
|
||||||
var val;
|
var val;
|
||||||
val = query[param];
|
val = query[param];
|
||||||
|
@ -254,8 +259,9 @@ Params = class Params {
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
BucketRateLimit = (function() {
|
|
||||||
class BucketRateLimit {
|
class BucketRateLimit {
|
||||||
|
|
||||||
constructor(capacity, time) {
|
constructor(capacity, time) {
|
||||||
this.capacity = capacity;
|
this.capacity = capacity;
|
||||||
this.time = time;
|
this.time = time;
|
||||||
|
@ -295,12 +301,10 @@ BucketRateLimit = (function() {
|
||||||
|
|
||||||
BucketRateLimit.prototype.lastUpdate = new Date();
|
BucketRateLimit.prototype.lastUpdate = new Date();
|
||||||
|
|
||||||
return BucketRateLimit;
|
|
||||||
|
|
||||||
}).call(this);
|
|
||||||
|
|
||||||
// A rate limiter that never limits.
|
// A rate limiter that never limits.
|
||||||
DummyRateLimit = class DummyRateLimit {
|
class DummyRateLimit {
|
||||||
|
|
||||||
constructor(capacity, time) {
|
constructor(capacity, time) {
|
||||||
this.capacity = capacity;
|
this.capacity = capacity;
|
||||||
this.time = time;
|
this.time = time;
|
||||||
|
|
|
@ -1,11 +1,9 @@
|
||||||
// Generated by CoffeeScript 2.4.1
|
|
||||||
/*
|
/*
|
||||||
Only websocket-specific stuff.
|
Only websocket-specific stuff.
|
||||||
*/
|
*/
|
||||||
var WS;
|
|
||||||
|
|
||||||
WS = (function() {
|
|
||||||
class WS {
|
class WS {
|
||||||
|
|
||||||
// Build an escaped URL string from unescaped components. Only scheme and host
|
// Build an escaped URL string from unescaped components. Only scheme and host
|
||||||
// are required. See RFC 3986, section 3.
|
// are required. See RFC 3986, section 3.
|
||||||
static buildUrl(scheme, host, port, path, params) {
|
static buildUrl(scheme, host, port, path, params) {
|
||||||
|
@ -64,7 +62,3 @@ WS = (function() {
|
||||||
http: 80,
|
http: 80,
|
||||||
https: 443
|
https: 443
|
||||||
};
|
};
|
||||||
|
|
||||||
return WS;
|
|
||||||
|
|
||||||
}).call(this);
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue