Comparing version 0.7.0 to 0.7.1
{ | ||
"name": "sip.js", | ||
"version": "0.7.0", | ||
"version": "0.7.1", | ||
"authors": [ | ||
@@ -5,0 +5,0 @@ "Will Mitchell <will@onsip.com>", |
@@ -5,3 +5,3 @@ { | ||
"description": "A simple, intuitive, and powerful JavaScript signaling library", | ||
"version": "0.7.0", | ||
"version": "0.7.1", | ||
"main": "src/index.js", | ||
@@ -30,2 +30,3 @@ "browser": { | ||
"devDependencies": { | ||
"beefy": "^2.1.5", | ||
"browserify": "^4.1.8", | ||
@@ -48,2 +49,3 @@ "grunt": "~0.4.0", | ||
"scripts": { | ||
"repl": "beefy test/repl.js --open", | ||
"prepublish": "cd src/Grammar && mkdir -p dist && pegjs --extra-options-file peg.json src/Grammar.pegjs dist/Grammar.js", | ||
@@ -50,0 +52,0 @@ "test": "grunt travis --verbose" |
@@ -54,2 +54,6 @@ "use strict"; | ||
// Save original extraHeaders to be used in .close | ||
this.closeHeaders = this.options.closeWithHeaders ? | ||
(this.options.extraHeaders || []).slice() : []; | ||
this.receiveResponse = function(response) { | ||
@@ -116,3 +120,3 @@ var contact, expires, | ||
self.registrationTimer = null; | ||
self.register(this.options); | ||
self.register(self.options); | ||
}, (expires * 1000) - 3000); | ||
@@ -196,4 +200,9 @@ this.registrationExpiredTimer = SIP.Timers.setTimeout(function () { | ||
close: function() { | ||
var options = { | ||
all: false, | ||
extraHeaders: this.closeHeaders | ||
}; | ||
this.registered_before = this.registered; | ||
this.unregister(); | ||
this.unregister(options); | ||
}, | ||
@@ -200,0 +209,0 @@ |
@@ -29,2 +29,12 @@ "use strict"; | ||
function buildViaHeader (request_sender, transport, id) { | ||
var via; | ||
via = 'SIP/2.0/' + (request_sender.ua.configuration.hackViaTcp ? 'TCP' : transport.server.scheme); | ||
via += ' ' + request_sender.ua.configuration.viaHost + ';branch=' + id; | ||
if (request_sender.ua.configuration.forceRport) { | ||
via += ';rport'; | ||
} | ||
return via; | ||
} | ||
/** | ||
@@ -48,5 +58,3 @@ * @augments SIP.Transactions | ||
via = 'SIP/2.0/' + (request_sender.ua.configuration.hackViaTcp ? 'TCP' : transport.server.scheme); | ||
via += ' ' + request_sender.ua.configuration.viaHost + ';branch=' + this.id; | ||
via = buildViaHeader(request_sender, transport, this.id); | ||
this.request.setHeader('via', via); | ||
@@ -150,5 +158,3 @@ | ||
via = 'SIP/2.0/' + (request_sender.ua.configuration.hackViaTcp ? 'TCP' : transport.server.scheme); | ||
via += ' ' + request_sender.ua.configuration.viaHost + ';branch=' + this.id; | ||
via = buildViaHeader(request_sender, transport, this.id); | ||
this.request.setHeader('via', via); | ||
@@ -334,5 +340,3 @@ | ||
via = 'SIP/2.0/' + (request_sender.ua.configuration.hackViaTcp ? 'TCP' : transport.server.scheme); | ||
via += ' ' + request_sender.ua.configuration.viaHost + ';branch=' + this.id; | ||
via = buildViaHeader(request_sender, transport, this.id); | ||
this.request.setHeader('via', via); | ||
@@ -339,0 +343,0 @@ }; |
@@ -33,2 +33,5 @@ "use strict"; | ||
this.keepAliveInterval = ua.configuration.keepAliveInterval; | ||
this.keepAliveTimer = null; | ||
this.ua.transport = this; | ||
@@ -62,2 +65,34 @@ | ||
/** | ||
* Send a keep-alive (a double-CRLF sequence). | ||
* @private | ||
* @returns {Boolean} | ||
*/ | ||
sendKeepAlive: function() { | ||
return this.send('\r\n\r\n'); | ||
}, | ||
/** | ||
* Start sending keep-alives. | ||
* @private | ||
*/ | ||
startSendingKeepAlives: function() { | ||
if (this.keepAliveInterval && !this.keepAliveTimer) { | ||
this.keepAliveTimer = SIP.Timers.setTimeout(function() { | ||
this.sendKeepAlive(); | ||
this.keepAliveTimer = null; | ||
this.startSendingKeepAlives(); | ||
}.bind(this), computeKeepAliveTimeout(this.keepAliveInterval)); | ||
} | ||
}, | ||
/** | ||
* Stop sending keep-alives. | ||
* @private | ||
*/ | ||
stopSendingKeepAlives: function() { | ||
SIP.Timers.clearTimeout(this.keepAliveTimer); | ||
this.keepAliveTimer = null; | ||
}, | ||
/** | ||
* Disconnect socket. | ||
@@ -70,2 +105,4 @@ */ | ||
this.stopSendingKeepAlives(); | ||
this.closed = true; | ||
@@ -152,2 +189,4 @@ this.logger.log('closing WebSocket ' + this.server.ws_uri); | ||
this.ua.onTransportConnected(this); | ||
// Start sending keep-alives | ||
this.startSendingKeepAlives(); | ||
}, | ||
@@ -165,2 +204,4 @@ | ||
this.stopSendingKeepAlives(); | ||
if (this.reconnection_attempts > 0) { | ||
@@ -310,4 +351,14 @@ this.logger.log('Reconnection attempt ' + this.reconnection_attempts + ' failed (code: ' + e.code + (e.reason? '| reason: ' + e.reason : '') +')'); | ||
/** | ||
* Compute an amount of time in seconds to wait before sending another | ||
* keep-alive. | ||
* @returns {Number} | ||
*/ | ||
function computeKeepAliveTimeout(upperBound) { | ||
var lowerBound = upperBound * 0.8; | ||
return 1000 * (Math.random() * (upperBound - lowerBound) + lowerBound); | ||
} | ||
Transport.C = C; | ||
return Transport; | ||
}; |
@@ -15,6 +15,7 @@ "use strict"; | ||
// UA status codes | ||
STATUS_INIT : 0, | ||
STATUS_READY: 1, | ||
STATUS_USER_CLOSED: 2, | ||
STATUS_NOT_READY: 3, | ||
STATUS_INIT: 0, | ||
STATUS_STARTING: 1, | ||
STATUS_READY: 2, | ||
STATUS_USER_CLOSED: 3, | ||
STATUS_NOT_READY: 4, | ||
@@ -183,3 +184,7 @@ // UA error codes | ||
if (typeof environment.addEventListener === 'function') { | ||
environment.addEventListener('unload', this.stop.bind(this)); | ||
// Google Chrome Packaged Apps don't allow 'unload' listeners: | ||
// unload is not available in packaged apps | ||
if (!(global.chrome && global.chrome.app && global.chrome.app.runtime)) { | ||
environment.addEventListener('unload', this.stop.bind(this)); | ||
} | ||
} | ||
@@ -363,2 +368,3 @@ }; | ||
server = this.getNextWsServer(); | ||
this.status = C.STATUS_STARTING; | ||
new SIP.Transport(this, server); | ||
@@ -369,2 +375,4 @@ } else if(this.status === C.STATUS_USER_CLOSED) { | ||
this.transport.connect(); | ||
} else if (this.status === C.STATUS_STARTING) { | ||
this.logger.log('UA is in STARTING status, not opening new connection'); | ||
} else if (this.status === C.STATUS_READY) { | ||
@@ -883,2 +891,4 @@ this.logger.log('UA is in READY status, not resuming'); | ||
keepAliveInterval: 0, | ||
usePreloadedRoute: false, | ||
@@ -903,2 +913,5 @@ | ||
contactTransport: 'ws', | ||
forceRport: false, | ||
//autostarting | ||
@@ -1032,9 +1045,19 @@ autostart: true, | ||
if (settings.hackIpInContact) { | ||
settings.viaHost = SIP.Utils.getRandomTestNetIP(); | ||
if (typeof settings.hackIpInContact === 'boolean') { | ||
settings.viaHost = SIP.Utils.getRandomTestNetIP(); | ||
} | ||
else if (typeof settings.hackIpInContact === 'string') { | ||
settings.viaHost = settings.hackIpInContact; | ||
} | ||
} | ||
// Contact transport parameter | ||
if (settings.hackWssInTransport) { | ||
settings.contactTransport = 'wss'; | ||
} | ||
this.contact = { | ||
pub_gruu: null, | ||
temp_gruu: null, | ||
uri: new SIP.URI('sip', SIP.Utils.createRandomToken(8), settings.viaHost, null, {transport: ((settings.hackWssInTransport)?'wss':'ws')}), | ||
uri: new SIP.URI('sip', SIP.Utils.createRandomToken(8), settings.viaHost, null, {transport: settings.contactTransport}), | ||
toString: function(options){ | ||
@@ -1049,3 +1072,3 @@ options = options || {}; | ||
if (anonymous) { | ||
contact += (this.temp_gruu || ('sip:anonymous@anonymous.invalid;transport='+(settings.hackWssInTransport)?'wss':'ws')).toString(); | ||
contact += (this.temp_gruu || ('sip:anonymous@anonymous.invalid;transport='+settings.contactTransport)).toString(); | ||
} else { | ||
@@ -1117,2 +1140,3 @@ contact += (this.pub_gruu || this.uri).toString(); | ||
"connectionRecoveryMinInterval", | ||
"keepAliveInterval", | ||
"displayName", | ||
@@ -1122,2 +1146,4 @@ "hackViaTcp", // false. | ||
"hackWssInTransport", //false | ||
"contactTransport", // 'ws' | ||
"forceRport", // false | ||
"iceCheckingTimeout", | ||
@@ -1236,6 +1262,6 @@ "instanceId", | ||
return; | ||
} else if(url.scheme !== 'wss' && url.scheme !== 'ws') { | ||
} else if(['wss', 'ws', 'udp'].indexOf(url.scheme) < 0) { | ||
return; | ||
} else { | ||
wsServers[idx].sip_uri = '<sip:' + url.host + (url.port ? ':' + url.port : '') + ';transport=ws;lr>'; | ||
wsServers[idx].sip_uri = '<sip:' + url.host + (url.port ? ':' + url.port : '') + ';transport=' + url.scheme.replace(/^wss$/i, 'ws') + ';lr>'; | ||
@@ -1299,2 +1325,5 @@ if (!wsServers[idx].weight) { | ||
} | ||
else if (typeof hackIpInContact === 'string' && SIP.Grammar.parse(hackIpInContact, 'host') !== -1) { | ||
return hackIpInContact; | ||
} | ||
}, | ||
@@ -1317,2 +1346,14 @@ | ||
contactTransport: function(contactTransport) { | ||
if (typeof contactTransport === 'string') { | ||
return contactTransport; | ||
} | ||
}, | ||
forceRport: function(forceRport) { | ||
if (typeof forceRport === 'boolean') { | ||
return forceRport; | ||
} | ||
}, | ||
instanceId: function(instanceId) { | ||
@@ -1334,2 +1375,12 @@ if(typeof instanceId !== 'string') { | ||
keepAliveInterval: function(keepAliveInterval) { | ||
var value; | ||
if (SIP.Utils.isDecimal(keepAliveInterval)) { | ||
value = Number(keepAliveInterval); | ||
if (value > 0) { | ||
return value; | ||
} | ||
} | ||
}, | ||
noAnswerTimeout: function(noAnswerTimeout) { | ||
@@ -1336,0 +1387,0 @@ var value; |
@@ -94,2 +94,8 @@ "use strict"; | ||
self.logger.log('ICE candidate received: '+ (e.candidate.candidate === null ? null : e.candidate.candidate.trim())); | ||
if (!self.iceCheckingTimer) { | ||
self.iceCheckingTimer = SIP.Timers.setTimeout(function() { | ||
self.logger.log('RTCIceChecking Timeout Triggered after '+config.iceCheckingTimeout+' milliseconds'); | ||
self.onIceCompleted.resolve(this); | ||
}.bind(this), config.iceCheckingTimeout); | ||
} | ||
} else { | ||
@@ -113,5 +119,5 @@ self.onIceCompleted.resolve(this); | ||
if (this.iceConnectionState === 'checking') { | ||
if (this.iceConnectionState === 'checking' && !self.iceCheckingTimer) { | ||
self.iceCheckingTimer = SIP.Timers.setTimeout(function() { | ||
self.logger.log('RTCIceChecking Timeout Triggered after '+config.iceCheckingTimeout+' micro seconds'); | ||
self.logger.log('RTCIceChecking Timeout Triggered after '+config.iceCheckingTimeout+' milliseconds'); | ||
self.onIceCompleted.resolve(this); | ||
@@ -118,0 +124,0 @@ }.bind(this), config.iceCheckingTimeout); |
@@ -76,2 +76,10 @@ describe('RegisterContext', function() { | ||
}); | ||
it('sets its closeHeaders property if options.closeWithHeaders flag is true', function() { | ||
RegisterContext.register({ | ||
closeWithHeaders: true, | ||
extraHeaders: [ 'X-Foo: foo', 'X-Bar: bar' ] | ||
}); | ||
expect(RegisterContext.closeHeaders.length).toBe(2); | ||
}); | ||
}); | ||
@@ -157,3 +165,4 @@ | ||
}); | ||
it('takes registered and move it to registerd_before', function() { | ||
it('takes registered and move it to registered_before', function() { | ||
expect(RegisterContext.registered).not.toBe(RegisterContext.registered_before); | ||
@@ -164,6 +173,14 @@ RegisterContext.close(); | ||
it('calls unregister', function() { | ||
it('calls unregister with closeHeaders', function() { | ||
jasmine.addCustomEqualityTester(function objectEquality(a, b) { | ||
return a === b || JSON.stringify(a) === JSON.stringify(b); | ||
}); | ||
expect(RegisterContext.unregister).not.toHaveBeenCalled(); | ||
RegisterContext.closeHeaders = [ 'X-Foo: foo' ,'X-Bar: bar' ]; | ||
var mockArgs = { all: false, extraHeaders: RegisterContext.closeHeaders }; | ||
RegisterContext.close(); | ||
expect(RegisterContext.unregister).toHaveBeenCalledWith(); | ||
expect(RegisterContext.unregister).toHaveBeenCalledWith(mockArgs); | ||
}); | ||
@@ -170,0 +187,0 @@ }); |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
779892
18257
12