From 78e250ad53dc6d57f0fefe929d0f44165776d20e Mon Sep 17 00:00:00 2001 From: Lennart Grahl Date: Thu, 26 Oct 2017 17:13:58 +0200 Subject: [PATCH 01/23] Add dummy RTCSctpTransport to make the 'maxMessageSize' attribute available. --- src/js/adapter_factory.js | 5 +++++ src/js/common_shim.js | 41 +++++++++++++++++++++++++++++++++++++++ src/js/utils.js | 2 +- 3 files changed, 47 insertions(+), 1 deletion(-) diff --git a/src/js/adapter_factory.js b/src/js/adapter_factory.js index b0ead5d0c..500d0bdc3 100644 --- a/src/js/adapter_factory.js +++ b/src/js/adapter_factory.js @@ -74,6 +74,7 @@ module.exports = function(dependencies, opts) { chromeShim.shimGetSendersWithDtmf(window); commonShim.shimRTCIceCandidate(window); + commonShim.shimMaxMessageSize(window); break; case 'firefox': if (!firefoxShim || !firefoxShim.shimPeerConnection || @@ -93,6 +94,7 @@ module.exports = function(dependencies, opts) { firefoxShim.shimRemoveStream(window); commonShim.shimRTCIceCandidate(window); + commonShim.shimMaxMessageSize(window); break; case 'edge': if (!edgeShim || !edgeShim.shimPeerConnection || !options.shimEdge) { @@ -109,6 +111,8 @@ module.exports = function(dependencies, opts) { edgeShim.shimReplaceTrack(window); // the edge shim implements the full RTCIceCandidate object. + + commonShim.shimMaxMessageSize(window); break; case 'safari': if (!safariShim || !options.shimSafari) { @@ -129,6 +133,7 @@ module.exports = function(dependencies, opts) { safariShim.shimCreateOfferLegacy(window); commonShim.shimRTCIceCandidate(window); + commonShim.shimMaxMessageSize(window); break; default: logging('Unsupported browser!'); diff --git a/src/js/common_shim.js b/src/js/common_shim.js index d80db879b..8bf00b01f 100644 --- a/src/js/common_shim.js +++ b/src/js/common_shim.js @@ -162,5 +162,46 @@ module.exports = { } return nativeSetAttribute.apply(this, arguments); }; + }, + + shimMaxMessageSize: function(window) { + if (window.RTCSctpTransport) { + return; + } + + if (!('sctp' in window.RTCPeerConnection.prototype)) { + Object.defineProperty(window.RTCPeerConnection.prototype, 'sctp', { + get: function() { + return typeof this._sctp === 'undefined' ? null : this._sctp; + } + }); + } + + var origSetRemoteDescription = + window.RTCPeerConnection.prototype.setRemoteDescription; + window.RTCPeerConnection.prototype.setRemoteDescription = function() { + var pc = this; + + // Determine the maximum message size of the remote peer. + // Note: 65535 bytes is the default value from the SDP spec. Also, + // every implementation we know supports receiving 65535 bytes. + var maxMessageSize = 65535; + var match = arguments[0].sdp.match(/a=max-message-size:\s*(\d+)/); + if (match !== null && match.length >= 2) { + maxMessageSize = parseInt(match[1]); + } + + // Create a dummy RTCSctpTransport object and the 'maxMessageSize' + // attribute. + var sctp = {}; + Object.defineProperty(sctp, 'maxMessageSize', { + get: function() { + return maxMessageSize; + } + }); + pc._sctp = sctp; + + return origSetRemoteDescription.apply(pc, arguments); + }; } }; diff --git a/src/js/utils.js b/src/js/utils.js index b607f820a..4b586a54d 100644 --- a/src/js/utils.js +++ b/src/js/utils.js @@ -8,7 +8,7 @@ /* eslint-env node */ 'use strict'; -var logDisabled_ = true; +var logDisabled_ = false; var deprecationWarnings_ = true; /** From dcd48f42e4270c7325169e6144e6d80cb4eb9af7 Mon Sep 17 00:00:00 2001 From: Lennart Grahl Date: Thu, 26 Oct 2017 18:25:19 +0200 Subject: [PATCH 02/23] Throw a `TypeError` in case the message is too large for the other peer to receive --- src/js/adapter_factory.js | 6 +++++- src/js/common_shim.js | 31 +++++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+), 1 deletion(-) diff --git a/src/js/adapter_factory.js b/src/js/adapter_factory.js index 500d0bdc3..5ba4f8c01 100644 --- a/src/js/adapter_factory.js +++ b/src/js/adapter_factory.js @@ -75,6 +75,7 @@ module.exports = function(dependencies, opts) { commonShim.shimRTCIceCandidate(window); commonShim.shimMaxMessageSize(window); + commonShim.shimSendThrowTypeError(window); break; case 'firefox': if (!firefoxShim || !firefoxShim.shimPeerConnection || @@ -95,6 +96,7 @@ module.exports = function(dependencies, opts) { commonShim.shimRTCIceCandidate(window); commonShim.shimMaxMessageSize(window); + commonShim.shimSendThrowTypeError(window); break; case 'edge': if (!edgeShim || !edgeShim.shimPeerConnection || !options.shimEdge) { @@ -111,8 +113,9 @@ module.exports = function(dependencies, opts) { edgeShim.shimReplaceTrack(window); // the edge shim implements the full RTCIceCandidate object. - + commonShim.shimMaxMessageSize(window); + commonShim.shimSendThrowTypeError(window); break; case 'safari': if (!safariShim || !options.shimSafari) { @@ -134,6 +137,7 @@ module.exports = function(dependencies, opts) { commonShim.shimRTCIceCandidate(window); commonShim.shimMaxMessageSize(window); + commonShim.shimSendThrowTypeError(window); break; default: logging('Unsupported browser!'); diff --git a/src/js/common_shim.js b/src/js/common_shim.js index 8bf00b01f..7b7e3c1ed 100644 --- a/src/js/common_shim.js +++ b/src/js/common_shim.js @@ -203,5 +203,36 @@ module.exports = { return origSetRemoteDescription.apply(pc, arguments); }; + }, + + shimSendThrowTypeError: function(window) { + var browserDetails = utils.detectBrowser(window); + + // Only Firefox 57 has support for this atm + if (browserDetails.browser === 'firefox' && browserDetails.version >= 57) { + return; + } + + var origCreateDataChannel = + window.RTCPeerConnection.prototype.createDataChannel; + window.RTCPeerConnection.prototype.createDataChannel = function() { + var pc = this; + var dataChannel = origCreateDataChannel.apply(pc, arguments); + var origDataChannelSend = dataChannel.send; + + // Patch 'send' method + dataChannel.send = function() { + var dc = this; + var data = arguments[0]; + var length = data.length || data.size || data.byteLength; + if (length > pc.sctp.maxMessageSize) { + throw new TypeError('Message too large (the other peer can ' + + 'receive a maximum of ' + pc.sctp.maxMessageSize + ' bytes)'); + } + return origDataChannelSend.apply(dc, arguments); + }; + + return dataChannel; + }; } }; From 7cd570c38f4b3be085e33829b9fc95d86b9acfd5 Mon Sep 17 00:00:00 2001 From: Lennart Grahl Date: Thu, 26 Oct 2017 18:30:32 +0200 Subject: [PATCH 03/23] Turn off logging again --- src/js/utils.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/js/utils.js b/src/js/utils.js index 4b586a54d..b607f820a 100644 --- a/src/js/utils.js +++ b/src/js/utils.js @@ -8,7 +8,7 @@ /* eslint-env node */ 'use strict'; -var logDisabled_ = false; +var logDisabled_ = true; var deprecationWarnings_ = true; /** From 4def6d4b67caac456a7ca17323d706bbedc7f3c0 Mon Sep 17 00:00:00 2001 From: Lennart Grahl Date: Sat, 28 Oct 2017 16:19:03 +0200 Subject: [PATCH 04/23] Define test cases related to the maximum message size for data channels --- test/e2e/expectations/chrome-beta | 7 + .../expectations/chrome-beta-no-experimental | 7 + test/e2e/expectations/chrome-stable | 7 + .../chrome-stable-no-experimental | 7 + test/e2e/expectations/chrome-unstable | 7 + test/e2e/expectations/firefox-beta | 7 + test/e2e/expectations/firefox-esr | 7 + test/e2e/expectations/firefox-nightly | 7 + test/e2e/expectations/firefox-stable | 7 + test/e2e/maxMessageSize.js | 146 ++++++++++++++++++ 10 files changed, 209 insertions(+) create mode 100644 test/e2e/maxMessageSize.js diff --git a/test/e2e/expectations/chrome-beta b/test/e2e/expectations/chrome-beta index 76d0d9fba..a27cf41f3 100644 --- a/test/e2e/expectations/chrome-beta +++ b/test/e2e/expectations/chrome-beta @@ -81,3 +81,10 @@ PASS srcObject setter triggers loadedmetadata (audio) PASS srcObject getter returns the stream (audio) PASS srcObject setter triggers loadedmetadata (video) PASS srcObject getter returns the stream (video) +PASS maxMessageSize sctp attribute exists +PASS maxMessageSize sctp attribute is null before offer/answer +PASS maxMessageSize sctp attribute is null if SCTP not negotiated +PASS maxMessageSize sctp and maxMessageSize set if SCTP negotiated +PASS maxMessageSize 0 case handled correctly +PASS maxMessageSize send largest possible single message +PASS maxMessageSize throws an exception if the message is too large diff --git a/test/e2e/expectations/chrome-beta-no-experimental b/test/e2e/expectations/chrome-beta-no-experimental index 7fdab84b5..7ca98b18e 100644 --- a/test/e2e/expectations/chrome-beta-no-experimental +++ b/test/e2e/expectations/chrome-beta-no-experimental @@ -81,3 +81,10 @@ PASS srcObject setter triggers loadedmetadata (audio) PASS srcObject getter returns the stream (audio) PASS srcObject setter triggers loadedmetadata (video) PASS srcObject getter returns the stream (video) +PASS maxMessageSize sctp attribute exists +PASS maxMessageSize sctp attribute is null before offer/answer +PASS maxMessageSize sctp attribute is null if SCTP not negotiated +PASS maxMessageSize sctp and maxMessageSize set if SCTP negotiated +PASS maxMessageSize 0 case handled correctly +PASS maxMessageSize send largest possible single message +PASS maxMessageSize throws an exception if the message is too large diff --git a/test/e2e/expectations/chrome-stable b/test/e2e/expectations/chrome-stable index 76d0d9fba..a27cf41f3 100644 --- a/test/e2e/expectations/chrome-stable +++ b/test/e2e/expectations/chrome-stable @@ -81,3 +81,10 @@ PASS srcObject setter triggers loadedmetadata (audio) PASS srcObject getter returns the stream (audio) PASS srcObject setter triggers loadedmetadata (video) PASS srcObject getter returns the stream (video) +PASS maxMessageSize sctp attribute exists +PASS maxMessageSize sctp attribute is null before offer/answer +PASS maxMessageSize sctp attribute is null if SCTP not negotiated +PASS maxMessageSize sctp and maxMessageSize set if SCTP negotiated +PASS maxMessageSize 0 case handled correctly +PASS maxMessageSize send largest possible single message +PASS maxMessageSize throws an exception if the message is too large diff --git a/test/e2e/expectations/chrome-stable-no-experimental b/test/e2e/expectations/chrome-stable-no-experimental index 7fdab84b5..7ca98b18e 100644 --- a/test/e2e/expectations/chrome-stable-no-experimental +++ b/test/e2e/expectations/chrome-stable-no-experimental @@ -81,3 +81,10 @@ PASS srcObject setter triggers loadedmetadata (audio) PASS srcObject getter returns the stream (audio) PASS srcObject setter triggers loadedmetadata (video) PASS srcObject getter returns the stream (video) +PASS maxMessageSize sctp attribute exists +PASS maxMessageSize sctp attribute is null before offer/answer +PASS maxMessageSize sctp attribute is null if SCTP not negotiated +PASS maxMessageSize sctp and maxMessageSize set if SCTP negotiated +PASS maxMessageSize 0 case handled correctly +PASS maxMessageSize send largest possible single message +PASS maxMessageSize throws an exception if the message is too large diff --git a/test/e2e/expectations/chrome-unstable b/test/e2e/expectations/chrome-unstable index 99722ecde..72f59685c 100644 --- a/test/e2e/expectations/chrome-unstable +++ b/test/e2e/expectations/chrome-unstable @@ -81,3 +81,10 @@ PASS srcObject setter triggers loadedmetadata (audio) PASS srcObject getter returns the stream (audio) PASS srcObject setter triggers loadedmetadata (video) PASS srcObject getter returns the stream (video) +PASS maxMessageSize sctp attribute exists +PASS maxMessageSize sctp attribute is null before offer/answer +PASS maxMessageSize sctp attribute is null if SCTP not negotiated +PASS maxMessageSize sctp and maxMessageSize set if SCTP negotiated +PASS maxMessageSize 0 case handled correctly +PASS maxMessageSize send largest possible single message +PASS maxMessageSize throws an exception if the message is too large diff --git a/test/e2e/expectations/firefox-beta b/test/e2e/expectations/firefox-beta index c5cd7d898..c70bc07f0 100644 --- a/test/e2e/expectations/firefox-beta +++ b/test/e2e/expectations/firefox-beta @@ -81,3 +81,10 @@ PASS srcObject setter triggers loadedmetadata (audio) PASS srcObject getter returns the stream (audio) PASS srcObject setter triggers loadedmetadata (video) PASS srcObject getter returns the stream (video) +PASS maxMessageSize sctp attribute exists +PASS maxMessageSize sctp attribute is null before offer/answer +PASS maxMessageSize sctp attribute is null if SCTP not negotiated +PASS maxMessageSize sctp and maxMessageSize set if SCTP negotiated +PASS maxMessageSize 0 case handled correctly +PASS maxMessageSize send largest possible single message +PASS maxMessageSize throws an exception if the message is too large diff --git a/test/e2e/expectations/firefox-esr b/test/e2e/expectations/firefox-esr index e6bda2b1c..1d5c36d72 100644 --- a/test/e2e/expectations/firefox-esr +++ b/test/e2e/expectations/firefox-esr @@ -81,3 +81,10 @@ PASS srcObject setter triggers loadedmetadata (audio) PASS srcObject getter returns the stream (audio) PASS srcObject setter triggers loadedmetadata (video) PASS srcObject getter returns the stream (video) +PASS maxMessageSize sctp attribute exists +PASS maxMessageSize sctp attribute is null before offer/answer +PASS maxMessageSize sctp attribute is null if SCTP not negotiated +PASS maxMessageSize sctp and maxMessageSize set if SCTP negotiated +PASS maxMessageSize 0 case handled correctly +PASS maxMessageSize send largest possible single message +PASS maxMessageSize throws an exception if the message is too large diff --git a/test/e2e/expectations/firefox-nightly b/test/e2e/expectations/firefox-nightly index c5cd7d898..c70bc07f0 100644 --- a/test/e2e/expectations/firefox-nightly +++ b/test/e2e/expectations/firefox-nightly @@ -81,3 +81,10 @@ PASS srcObject setter triggers loadedmetadata (audio) PASS srcObject getter returns the stream (audio) PASS srcObject setter triggers loadedmetadata (video) PASS srcObject getter returns the stream (video) +PASS maxMessageSize sctp attribute exists +PASS maxMessageSize sctp attribute is null before offer/answer +PASS maxMessageSize sctp attribute is null if SCTP not negotiated +PASS maxMessageSize sctp and maxMessageSize set if SCTP negotiated +PASS maxMessageSize 0 case handled correctly +PASS maxMessageSize send largest possible single message +PASS maxMessageSize throws an exception if the message is too large diff --git a/test/e2e/expectations/firefox-stable b/test/e2e/expectations/firefox-stable index c5cd7d898..c70bc07f0 100644 --- a/test/e2e/expectations/firefox-stable +++ b/test/e2e/expectations/firefox-stable @@ -81,3 +81,10 @@ PASS srcObject setter triggers loadedmetadata (audio) PASS srcObject getter returns the stream (audio) PASS srcObject setter triggers loadedmetadata (video) PASS srcObject getter returns the stream (video) +PASS maxMessageSize sctp attribute exists +PASS maxMessageSize sctp attribute is null before offer/answer +PASS maxMessageSize sctp attribute is null if SCTP not negotiated +PASS maxMessageSize sctp and maxMessageSize set if SCTP negotiated +PASS maxMessageSize 0 case handled correctly +PASS maxMessageSize send largest possible single message +PASS maxMessageSize throws an exception if the message is too large diff --git a/test/e2e/maxMessageSize.js b/test/e2e/maxMessageSize.js new file mode 100644 index 000000000..7c3964d08 --- /dev/null +++ b/test/e2e/maxMessageSize.js @@ -0,0 +1,146 @@ +/* + * Copyright (c) 2017 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. + */ + /* eslint-env node */ +'use strict'; + +describe('maxMessageSize', () => { + let pc1; + let pc2; + + function negotiate(pc, otherPc, mapDescriptionCallback) { + return pc.createOffer() + .then((offer) => { + if (mapDescriptionCallback) { + offer = mapDescriptionCallback(offer); + } + return pc.setLocalDescription(offer); + }).then(() => { + return otherPc.setRemoteDescription(pc.localDescription); + }).then(() => { + return otherPc.createAnswer(); + }).then((answer) => { + if (mapDescriptionCallback) { + answer = mapDescriptionCallback(answer); + } + return otherPc.setLocalDescription(answer); + }).then(() => { + return pc.setRemoteDescription(otherPc.localDescription); + }); + } + + function patchMaxMessageSizeFactory(maxMessageSize) { + return ((description) => { + description.sdp = description.sdp.replace( + /^a=max-message-size:\s*(\d+)\s*$/gm, ''); + description.sdp = description.sdp.replace( + /(^m=application\s+\d+\s+[\w/]*SCTP.*$)/m, + '$1\r\na=max-message-size:' + maxMessageSize); + return description; + }); + } + + beforeEach(() => { + pc1 = new RTCPeerConnection(null); + pc2 = new RTCPeerConnection(null); + + pc1.onicecandidate = event => pc2.addIceCandidate(event.candidate); + pc2.onicecandidate = event => pc1.addIceCandidate(event.candidate); + }); + afterEach(() => { + pc1.close(); + pc2.close(); + }); + + it('sctp attribute exists', () => { + expect(pc1).to.have.property('sctp'); + }); + + it('sctp attribute is null before offer/answer', () => { + expect(pc1.sctp).to.equal(null); + }); + + it('sctp attribute is null if SCTP not negotiated', () => { + return navigator.mediaDevices.getUserMedia({audio: true}) + .then((stream) => { + pc1.addTrack(stream.getTracks()[0], stream); + return negotiate(pc1, pc2); + }) + .then(() => { + expect(pc1.sctp).to.equal(null); + expect(pc2.sctp).to.equal(null); + }); + }); + + it('sctp and maxMessageSize set if SCTP negotiated', () => { + pc1.createDataChannel('test'); + return negotiate(pc1, pc2) + .then(() => { + expect(pc1.sctp).to.have.property('maxMessageSize'); + expect(pc2.sctp).to.have.property('maxMessageSize'); + expect(pc1.sctp.maxMessageSize).to.be.a('number'); + expect(pc2.sctp.maxMessageSize).to.be.a('number'); + }); + }); + + it('0 case handled correctly', (done) => { + const patchMaxMessageSize = patchMaxMessageSizeFactory(0); + + // Patch max-message-size + const dc = pc1.createDataChannel('test'); + negotiate(pc1, pc2, patchMaxMessageSize) + .then(() => { + expect(pc1.sctp.maxMessageSize).to.equal(0); + expect(pc2.sctp.maxMessageSize).to.equal(0); + + // Ensure TypeError isn't thrown when sending data + const send = () => { + dc.send('meow'); + }; + dc.onopen = () => { + expect(send).not.to.throw(); + done(); + }; + }); + }); + + it('send largest possible single message', (done) => { + const patchMaxMessageSize = patchMaxMessageSizeFactory(1000); + + const dc = pc1.createDataChannel('test'); + negotiate(pc1, pc2, patchMaxMessageSize) + .then(() => { + // Ensure TypeError is thrown when sending a message that's too large + const send = () => { + dc.send(new Uint8Array(1000)); + }; + dc.onopen = () => { + expect(send).not.to.throw(TypeError); + done(); + }; + }); + }); + + describe('throws an exception', () => { + it('if the message is too large', (done) => { + const patchMaxMessageSize = patchMaxMessageSizeFactory(1000); + + const dc = pc1.createDataChannel('test'); + negotiate(pc1, pc2, patchMaxMessageSize) + .then(() => { + // Ensure TypeError is thrown when sending a message that's too large + const send = () => { + dc.send(new Uint8Array(1001)); + }; + dc.onopen = () => { + expect(send).to.throw(TypeError); + done(); + }; + }); + }); + }); +}); From f84ce3d3af32dfca3308d3ac712a33384b5a88e9 Mon Sep 17 00:00:00 2001 From: Lennart Grahl Date: Sat, 28 Oct 2017 17:23:54 +0200 Subject: [PATCH 05/23] Fix maxMessageSize also depends on the local maximum message size Fix handle maxMessageSize 0 case properly Fix handle corner case for maxMessageSize when sending from FF to FF Fix handle yet another corner case for maxMessageSize when sending from FF < 57 (uses 16 KiB chunks) --- src/js/common_shim.js | 99 ++++++++++++++++++++++++++++++++++++------- 1 file changed, 83 insertions(+), 16 deletions(-) diff --git a/src/js/common_shim.js b/src/js/common_shim.js index 7b7e3c1ed..311f20718 100644 --- a/src/js/common_shim.js +++ b/src/js/common_shim.js @@ -168,6 +168,7 @@ module.exports = { if (window.RTCSctpTransport) { return; } + var browserDetails = utils.detectBrowser(window); if (!('sctp' in window.RTCPeerConnection.prototype)) { Object.defineProperty(window.RTCPeerConnection.prototype, 'sctp', { @@ -177,29 +178,95 @@ module.exports = { }); } - var origSetRemoteDescription = - window.RTCPeerConnection.prototype.setRemoteDescription; - window.RTCPeerConnection.prototype.setRemoteDescription = function() { - var pc = this; + var sctpInDescription = function(description) { + var match = description.sdp.match(/m=application\s+\d+\s+[\w/]*SCTP/); + return (match !== null && match.length >= 1); + }; - // Determine the maximum message size of the remote peer. + var getMaxMessageSize = function(description) { // Note: 65535 bytes is the default value from the SDP spec. Also, // every implementation we know supports receiving 65535 bytes. var maxMessageSize = 65535; - var match = arguments[0].sdp.match(/a=max-message-size:\s*(\d+)/); + var match = description.sdp.match(/a=max-message-size:\s*(\d+)/); if (match !== null && match.length >= 2) { maxMessageSize = parseInt(match[1]); } + return maxMessageSize; + }; - // Create a dummy RTCSctpTransport object and the 'maxMessageSize' - // attribute. - var sctp = {}; - Object.defineProperty(sctp, 'maxMessageSize', { - get: function() { - return maxMessageSize; + var isFirefox = function(description) { + // TODO: Is there a better solution for detecting Firefox? + var match = description.sdp.match(/mozilla...THIS_IS_SDPARTA/); + return (match !== null && match.length >= 1); + }; + + var maybeApplyMaxMessageSize = function(pc) { + if (pc._localMaxMessageSize !== null && + pc._remoteMaxMessageSize !== null) { + // Note: This algorithm is not in the spec so far but it will + // likely be added, see: + // https://github.com/w3c/webrtc-pc/issues/1446#issuecomment-313463625 + var maxMessageSize = pc._localMaxMessageSize; + if (pc._remoteMaxMessageSize > 0) { + maxMessageSize = Math.min(pc._localMaxMessageSize, + pc._remoteMaxMessageSize); } - }); - pc._sctp = sctp; + + // FF can send (at least) 1 GiB towards all other FF. + if (browserDetails.browser === 'firefox' && pc._otherPeerIsFirefox) { + maxMessageSize = 1073741823; + } + + // Create a dummy RTCSctpTransport object and the 'maxMessageSize' + // attribute. + var sctp = {}; + Object.defineProperty(sctp, 'maxMessageSize', { + get: function() { + return maxMessageSize; + } + }); + pc._sctp = sctp; + } + }; + + var origSetLocalDescription = + window.RTCPeerConnection.prototype.setLocalDescription; + window.RTCPeerConnection.prototype.setLocalDescription = function() { + var pc = this; + pc._localMaxMessageSize = null; + + if (sctpInDescription(arguments[0])) { + // Determine the maximum message size of the browser. + if (browserDetails.browser === 'firefox' && + browserDetails.version < 57) { + // Note: This is required because FF < 57 will send in 16 KiB chunks + pc._localMaxMessageSize = 16384; + } else { + pc._localMaxMessageSize = getMaxMessageSize(arguments[0]); + } + + // Determine final maximum message size + maybeApplyMaxMessageSize(pc); + } + + return origSetLocalDescription.apply(pc, arguments); + }; + + var origSetRemoteDescription = + window.RTCPeerConnection.prototype.setRemoteDescription; + window.RTCPeerConnection.prototype.setRemoteDescription = function() { + var pc = this; + pc._remoteMaxMessageSize = null; + pc._otherPeerIsFirefox = false; + + if (sctpInDescription(arguments[0])) { + // Determine the maximum message size of the remote peer. + pc._remoteMaxMessageSize = getMaxMessageSize(arguments[0]); + // Determine if other peer is Firefox + pc._otherPeerIsFirefox = isFirefox(arguments[0]); + // Determine final maximum message size + maybeApplyMaxMessageSize(pc); + } return origSetRemoteDescription.apply(pc, arguments); }; @@ -226,8 +293,8 @@ module.exports = { var data = arguments[0]; var length = data.length || data.size || data.byteLength; if (length > pc.sctp.maxMessageSize) { - throw new TypeError('Message too large (the other peer can ' + - 'receive a maximum of ' + pc.sctp.maxMessageSize + ' bytes)'); + throw new TypeError('Message too large (can send a maximum of ' + + pc.sctp.maxMessageSize + ' bytes)'); } return origDataChannelSend.apply(dc, arguments); }; From 5d8cec267e46ca663bcb1c4bc9a50f42ec1a9fd5 Mon Sep 17 00:00:00 2001 From: Lennart Grahl Date: Sat, 28 Oct 2017 19:56:57 +0200 Subject: [PATCH 06/23] Fix handle maxMessageSize 0 case properly (again) --- src/js/common_shim.js | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/js/common_shim.js b/src/js/common_shim.js index 311f20718..2271722e8 100644 --- a/src/js/common_shim.js +++ b/src/js/common_shim.js @@ -205,9 +205,12 @@ module.exports = { pc._remoteMaxMessageSize !== null) { // Note: This algorithm is not in the spec so far but it will // likely be added, see: - // https://github.com/w3c/webrtc-pc/issues/1446#issuecomment-313463625 + // https://github.com/w3c/webrtc-pc/issues/1446#issuecomment-340204737 var maxMessageSize = pc._localMaxMessageSize; - if (pc._remoteMaxMessageSize > 0) { + if (pc._localMaxMessageSize === 0 || pc._remoteMaxMessageSize === 0) { + maxMessageSize = Math.max(pc._localMaxMessageSize, + pc._remoteMaxMessageSize); + } else { maxMessageSize = Math.min(pc._localMaxMessageSize, pc._remoteMaxMessageSize); } From 4dd2784e7ff72688467c7347f40078d23071506b Mon Sep 17 00:00:00 2001 From: Lennart Grahl Date: Sat, 28 Oct 2017 19:58:11 +0200 Subject: [PATCH 07/23] Fix broken maxMessageSize tests --- test/e2e/maxMessageSize.js | 82 ++++++++++++++++++++++++-------------- 1 file changed, 51 insertions(+), 31 deletions(-) diff --git a/test/e2e/maxMessageSize.js b/test/e2e/maxMessageSize.js index 7c3964d08..1dbc26987 100644 --- a/test/e2e/maxMessageSize.js +++ b/test/e2e/maxMessageSize.js @@ -90,56 +90,76 @@ describe('maxMessageSize', () => { it('0 case handled correctly', (done) => { const patchMaxMessageSize = patchMaxMessageSizeFactory(0); - // Patch max-message-size + // Ensure TypeError isn't thrown when sending data const dc = pc1.createDataChannel('test'); + const send = () => { + dc.send('meow'); + }; + dc.onopen = () => { + expect(send).not.to.throw(); + done(); + }; negotiate(pc1, pc2, patchMaxMessageSize) .then(() => { expect(pc1.sctp.maxMessageSize).to.equal(0); expect(pc2.sctp.maxMessageSize).to.equal(0); - - // Ensure TypeError isn't thrown when sending data - const send = () => { - dc.send('meow'); - }; - dc.onopen = () => { - expect(send).not.to.throw(); - done(); - }; }); }); - it('send largest possible single message', (done) => { + it('send largest possible single message', () => { + let maxMessageSize = 1000; const patchMaxMessageSize = patchMaxMessageSizeFactory(1000); + if (window.adapter.browserDetails.browser === 'firefox') { + maxMessageSize = 1073741823; + } - const dc = pc1.createDataChannel('test'); - negotiate(pc1, pc2, patchMaxMessageSize) + pc1.createDataChannel('test'); + return negotiate(pc1, pc2, patchMaxMessageSize) .then(() => { + expect(pc1.sctp.maxMessageSize).to.equal(maxMessageSize); + expect(pc2.sctp.maxMessageSize).to.equal(maxMessageSize); + // Ensure TypeError is thrown when sending a message that's too large - const send = () => { - dc.send(new Uint8Array(1000)); - }; - dc.onopen = () => { - expect(send).not.to.throw(TypeError); - done(); - }; + return new Promise((resolve, reject) => { + const dc = pc1.createDataChannel('test2'); + const send = () => { + // Note: Falling back to 1000 here as the special case of FF would + // take way too long. + dc.send(new Uint8Array(1000)); + }; + dc.onopen = () => { + expect(send).not.to.throw(TypeError); + resolve(); + }; + }); }); }); describe('throws an exception', () => { - it('if the message is too large', (done) => { - const patchMaxMessageSize = patchMaxMessageSizeFactory(1000); + it('if the message is too large', () => { + let maxMessageSize = 1000; + const patchMaxMessageSize = patchMaxMessageSizeFactory(maxMessageSize); + if (window.adapter.browserDetails.browser === 'firefox') { + maxMessageSize = 1073741823; + } - const dc = pc1.createDataChannel('test'); - negotiate(pc1, pc2, patchMaxMessageSize) + pc1.createDataChannel('test'); + return negotiate(pc1, pc2, patchMaxMessageSize) .then(() => { + expect(pc1.sctp.maxMessageSize).to.equal(maxMessageSize); + expect(pc2.sctp.maxMessageSize).to.equal(maxMessageSize); + // Ensure TypeError is thrown when sending a message that's too large - const send = () => { - dc.send(new Uint8Array(1001)); - }; - dc.onopen = () => { - expect(send).to.throw(TypeError); - done(); - }; + return new Promise((resolve, reject) => { + const dc = pc1.createDataChannel('test2'); + const send = () => { + dc.send(new Uint8Array(maxMessageSize + 1)); + }; + dc.onopen = () => { + expect(send).to.throw(TypeError); + resolve(); + }; + }); }); }); }); From 22a2918d515ca89f769cc73e55c586643dbcf142 Mon Sep 17 00:00:00 2001 From: Lennart Grahl Date: Sat, 28 Oct 2017 20:32:34 +0200 Subject: [PATCH 08/23] Fix apply TypeError shim when sending on data channels to FF >= 57 as well There's a bug in the implementation of FF 57, so DOMError is raised instead of TypeError. I hope we can land a hotfix for that but it shouldn't prevent us from merging this now. --- src/js/common_shim.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/js/common_shim.js b/src/js/common_shim.js index 2271722e8..b17892042 100644 --- a/src/js/common_shim.js +++ b/src/js/common_shim.js @@ -280,7 +280,8 @@ module.exports = { // Only Firefox 57 has support for this atm if (browserDetails.browser === 'firefox' && browserDetails.version >= 57) { - return; + // TODO: Re-enable if we get a DOMError -> TypeError hotfix into FF 57 + // return; } var origCreateDataChannel = From e78bccefa18f9d3f42f1cec8bb92140f385f95b5 Mon Sep 17 00:00:00 2001 From: Lennart Grahl Date: Sun, 29 Oct 2017 00:04:09 +0200 Subject: [PATCH 09/23] Replace regular expression with SDPUtils.matchPrefix where useful --- src/js/common_shim.js | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/js/common_shim.js b/src/js/common_shim.js index b17892042..c632ee799 100644 --- a/src/js/common_shim.js +++ b/src/js/common_shim.js @@ -187,17 +187,16 @@ module.exports = { // Note: 65535 bytes is the default value from the SDP spec. Also, // every implementation we know supports receiving 65535 bytes. var maxMessageSize = 65535; - var match = description.sdp.match(/a=max-message-size:\s*(\d+)/); - if (match !== null && match.length >= 2) { - maxMessageSize = parseInt(match[1]); + var match = SDPUtils.matchPrefix(description.sdp, 'a=max-message-size:'); + if (match.length > 0) { + maxMessageSize = parseInt(match[0]); } return maxMessageSize; }; var isFirefox = function(description) { // TODO: Is there a better solution for detecting Firefox? - var match = description.sdp.match(/mozilla...THIS_IS_SDPARTA/); - return (match !== null && match.length >= 1); + return description.sdp.indexOf('mozilla...THIS_IS_SDPARTA') !== -1; }; var maybeApplyMaxMessageSize = function(pc) { From d268eed43241e46aca32186405de8f363d1cfa8b Mon Sep 17 00:00:00 2001 From: Lennart Grahl Date: Sun, 29 Oct 2017 00:21:39 +0200 Subject: [PATCH 10/23] Fix regression introduced by using SDPUtils.matchPrefix in `getMaxMessageSize` --- src/js/common_shim.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/js/common_shim.js b/src/js/common_shim.js index c632ee799..5d7f981a9 100644 --- a/src/js/common_shim.js +++ b/src/js/common_shim.js @@ -189,7 +189,7 @@ module.exports = { var maxMessageSize = 65535; var match = SDPUtils.matchPrefix(description.sdp, 'a=max-message-size:'); if (match.length > 0) { - maxMessageSize = parseInt(match[0]); + maxMessageSize = parseInt(match[0].substr(19), 10); } return maxMessageSize; }; @@ -200,8 +200,8 @@ module.exports = { }; var maybeApplyMaxMessageSize = function(pc) { - if (pc._localMaxMessageSize !== null && - pc._remoteMaxMessageSize !== null) { + if (Number.isInteger(pc._localMaxMessageSize) && + Number.isInteger(pc._remoteMaxMessageSize)) { // Note: This algorithm is not in the spec so far but it will // likely be added, see: // https://github.com/w3c/webrtc-pc/issues/1446#issuecomment-340204737 From 7de1187a16a9f1134e73980a17bae6eef36f6ad2 Mon Sep 17 00:00:00 2001 From: Lennart Grahl Date: Tue, 31 Oct 2017 12:04:43 +0100 Subject: [PATCH 11/23] Fix throw DOMException of type TypeError instead of throwing a TypeError (apparently, I've misinterpreted the spec and this is how it should be done) Fix max message size tests --- src/js/common_shim.js | 26 ++++++++++++------- test/e2e/expectations/chrome-beta | 14 +++++----- .../expectations/chrome-beta-no-experimental | 14 +++++----- test/e2e/expectations/chrome-stable | 14 +++++----- .../chrome-stable-no-experimental | 14 +++++----- test/e2e/expectations/chrome-unstable | 14 +++++----- test/e2e/expectations/firefox-beta | 14 +++++----- test/e2e/expectations/firefox-esr | 14 +++++----- test/e2e/expectations/firefox-nightly | 14 +++++----- test/e2e/expectations/firefox-stable | 14 +++++----- test/e2e/maxMessageSize.js | 16 +++++++++--- 11 files changed, 91 insertions(+), 77 deletions(-) diff --git a/src/js/common_shim.js b/src/js/common_shim.js index 5d7f981a9..55e55cadb 100644 --- a/src/js/common_shim.js +++ b/src/js/common_shim.js @@ -194,9 +194,15 @@ module.exports = { return maxMessageSize; }; - var isFirefox = function(description) { + var getFirefoxVersion = function(description) { // TODO: Is there a better solution for detecting Firefox? - return description.sdp.indexOf('mozilla...THIS_IS_SDPARTA') !== -1; + var match = description.sdp.match(/mozilla...THIS_IS_SDPARTA-(\d+)/); + if (match === null || match.length < 2) { + return -1; + } + var version = parseInt(match[1], 10); + // Test for NaN (yes, this is ugly) + return version !== version ? -1 : version; }; var maybeApplyMaxMessageSize = function(pc) { @@ -214,8 +220,9 @@ module.exports = { pc._remoteMaxMessageSize); } - // FF can send (at least) 1 GiB towards all other FF. - if (browserDetails.browser === 'firefox' && pc._otherPeerIsFirefox) { + // Any FF can send (at least) 1 GiB towards all other FF < 57. + if (browserDetails.browser === 'firefox' && + pc._otherPeerFirefoxVersion < 57) { maxMessageSize = 1073741823; } @@ -259,13 +266,13 @@ module.exports = { window.RTCPeerConnection.prototype.setRemoteDescription = function() { var pc = this; pc._remoteMaxMessageSize = null; - pc._otherPeerIsFirefox = false; + pc._otherPeerFirefoxVersion = -1; if (sctpInDescription(arguments[0])) { // Determine the maximum message size of the remote peer. pc._remoteMaxMessageSize = getMaxMessageSize(arguments[0]); // Determine if other peer is Firefox - pc._otherPeerIsFirefox = isFirefox(arguments[0]); + pc._otherPeerFirefoxVersion = getFirefoxVersion(arguments[0]); // Determine final maximum message size maybeApplyMaxMessageSize(pc); } @@ -279,8 +286,7 @@ module.exports = { // Only Firefox 57 has support for this atm if (browserDetails.browser === 'firefox' && browserDetails.version >= 57) { - // TODO: Re-enable if we get a DOMError -> TypeError hotfix into FF 57 - // return; + return; } var origCreateDataChannel = @@ -296,8 +302,8 @@ module.exports = { var data = arguments[0]; var length = data.length || data.size || data.byteLength; if (length > pc.sctp.maxMessageSize) { - throw new TypeError('Message too large (can send a maximum of ' + - pc.sctp.maxMessageSize + ' bytes)'); + throw new DOMException('Message too large (can send a maximum of ' + + pc.sctp.maxMessageSize + ' bytes)', 'TypeError'); } return origDataChannelSend.apply(dc, arguments); }; diff --git a/test/e2e/expectations/chrome-beta b/test/e2e/expectations/chrome-beta index a27cf41f3..163abe444 100644 --- a/test/e2e/expectations/chrome-beta +++ b/test/e2e/expectations/chrome-beta @@ -33,6 +33,13 @@ PASS getStats returns a Promise PASS getStats resolves the Promise with a Map(like) PASS getUserMedia navigator.getUserMedia exists PASS getUserMedia navigator.getUserMedia calls the callback +PASS maxMessageSize sctp attribute exists +PASS maxMessageSize sctp attribute is null before offer/answer +PASS maxMessageSize sctp attribute is null if SCTP not negotiated +PASS maxMessageSize sctp and maxMessageSize set if SCTP negotiated +PASS maxMessageSize 0 case handled correctly +PASS maxMessageSize send largest possible single message +PASS maxMessageSize throws an exception if the message is too large PASS navigator.mediaDevices exists PASS navigator.mediaDevices is an EventTarget PASS navigator.mediaDevices implements the devicechange event @@ -81,10 +88,3 @@ PASS srcObject setter triggers loadedmetadata (audio) PASS srcObject getter returns the stream (audio) PASS srcObject setter triggers loadedmetadata (video) PASS srcObject getter returns the stream (video) -PASS maxMessageSize sctp attribute exists -PASS maxMessageSize sctp attribute is null before offer/answer -PASS maxMessageSize sctp attribute is null if SCTP not negotiated -PASS maxMessageSize sctp and maxMessageSize set if SCTP negotiated -PASS maxMessageSize 0 case handled correctly -PASS maxMessageSize send largest possible single message -PASS maxMessageSize throws an exception if the message is too large diff --git a/test/e2e/expectations/chrome-beta-no-experimental b/test/e2e/expectations/chrome-beta-no-experimental index 7ca98b18e..894cac06d 100644 --- a/test/e2e/expectations/chrome-beta-no-experimental +++ b/test/e2e/expectations/chrome-beta-no-experimental @@ -33,6 +33,13 @@ PASS getStats returns a Promise PASS getStats resolves the Promise with a Map(like) PASS getUserMedia navigator.getUserMedia exists PASS getUserMedia navigator.getUserMedia calls the callback +PASS maxMessageSize sctp attribute exists +PASS maxMessageSize sctp attribute is null before offer/answer +PASS maxMessageSize sctp attribute is null if SCTP not negotiated +PASS maxMessageSize sctp and maxMessageSize set if SCTP negotiated +PASS maxMessageSize 0 case handled correctly +PASS maxMessageSize send largest possible single message +PASS maxMessageSize throws an exception if the message is too large PASS navigator.mediaDevices exists PASS navigator.mediaDevices is an EventTarget PASS navigator.mediaDevices implements the devicechange event @@ -81,10 +88,3 @@ PASS srcObject setter triggers loadedmetadata (audio) PASS srcObject getter returns the stream (audio) PASS srcObject setter triggers loadedmetadata (video) PASS srcObject getter returns the stream (video) -PASS maxMessageSize sctp attribute exists -PASS maxMessageSize sctp attribute is null before offer/answer -PASS maxMessageSize sctp attribute is null if SCTP not negotiated -PASS maxMessageSize sctp and maxMessageSize set if SCTP negotiated -PASS maxMessageSize 0 case handled correctly -PASS maxMessageSize send largest possible single message -PASS maxMessageSize throws an exception if the message is too large diff --git a/test/e2e/expectations/chrome-stable b/test/e2e/expectations/chrome-stable index a27cf41f3..163abe444 100644 --- a/test/e2e/expectations/chrome-stable +++ b/test/e2e/expectations/chrome-stable @@ -33,6 +33,13 @@ PASS getStats returns a Promise PASS getStats resolves the Promise with a Map(like) PASS getUserMedia navigator.getUserMedia exists PASS getUserMedia navigator.getUserMedia calls the callback +PASS maxMessageSize sctp attribute exists +PASS maxMessageSize sctp attribute is null before offer/answer +PASS maxMessageSize sctp attribute is null if SCTP not negotiated +PASS maxMessageSize sctp and maxMessageSize set if SCTP negotiated +PASS maxMessageSize 0 case handled correctly +PASS maxMessageSize send largest possible single message +PASS maxMessageSize throws an exception if the message is too large PASS navigator.mediaDevices exists PASS navigator.mediaDevices is an EventTarget PASS navigator.mediaDevices implements the devicechange event @@ -81,10 +88,3 @@ PASS srcObject setter triggers loadedmetadata (audio) PASS srcObject getter returns the stream (audio) PASS srcObject setter triggers loadedmetadata (video) PASS srcObject getter returns the stream (video) -PASS maxMessageSize sctp attribute exists -PASS maxMessageSize sctp attribute is null before offer/answer -PASS maxMessageSize sctp attribute is null if SCTP not negotiated -PASS maxMessageSize sctp and maxMessageSize set if SCTP negotiated -PASS maxMessageSize 0 case handled correctly -PASS maxMessageSize send largest possible single message -PASS maxMessageSize throws an exception if the message is too large diff --git a/test/e2e/expectations/chrome-stable-no-experimental b/test/e2e/expectations/chrome-stable-no-experimental index 7ca98b18e..894cac06d 100644 --- a/test/e2e/expectations/chrome-stable-no-experimental +++ b/test/e2e/expectations/chrome-stable-no-experimental @@ -33,6 +33,13 @@ PASS getStats returns a Promise PASS getStats resolves the Promise with a Map(like) PASS getUserMedia navigator.getUserMedia exists PASS getUserMedia navigator.getUserMedia calls the callback +PASS maxMessageSize sctp attribute exists +PASS maxMessageSize sctp attribute is null before offer/answer +PASS maxMessageSize sctp attribute is null if SCTP not negotiated +PASS maxMessageSize sctp and maxMessageSize set if SCTP negotiated +PASS maxMessageSize 0 case handled correctly +PASS maxMessageSize send largest possible single message +PASS maxMessageSize throws an exception if the message is too large PASS navigator.mediaDevices exists PASS navigator.mediaDevices is an EventTarget PASS navigator.mediaDevices implements the devicechange event @@ -81,10 +88,3 @@ PASS srcObject setter triggers loadedmetadata (audio) PASS srcObject getter returns the stream (audio) PASS srcObject setter triggers loadedmetadata (video) PASS srcObject getter returns the stream (video) -PASS maxMessageSize sctp attribute exists -PASS maxMessageSize sctp attribute is null before offer/answer -PASS maxMessageSize sctp attribute is null if SCTP not negotiated -PASS maxMessageSize sctp and maxMessageSize set if SCTP negotiated -PASS maxMessageSize 0 case handled correctly -PASS maxMessageSize send largest possible single message -PASS maxMessageSize throws an exception if the message is too large diff --git a/test/e2e/expectations/chrome-unstable b/test/e2e/expectations/chrome-unstable index 72f59685c..b7ccda0ba 100644 --- a/test/e2e/expectations/chrome-unstable +++ b/test/e2e/expectations/chrome-unstable @@ -33,6 +33,13 @@ PASS getStats returns a Promise PASS getStats resolves the Promise with a Map(like) PASS getUserMedia navigator.getUserMedia exists PASS getUserMedia navigator.getUserMedia calls the callback +PASS maxMessageSize sctp attribute exists +PASS maxMessageSize sctp attribute is null before offer/answer +PASS maxMessageSize sctp attribute is null if SCTP not negotiated +PASS maxMessageSize sctp and maxMessageSize set if SCTP negotiated +PASS maxMessageSize 0 case handled correctly +PASS maxMessageSize send largest possible single message +PASS maxMessageSize throws an exception if the message is too large PASS navigator.mediaDevices exists PASS navigator.mediaDevices is an EventTarget PASS navigator.mediaDevices implements the devicechange event @@ -81,10 +88,3 @@ PASS srcObject setter triggers loadedmetadata (audio) PASS srcObject getter returns the stream (audio) PASS srcObject setter triggers loadedmetadata (video) PASS srcObject getter returns the stream (video) -PASS maxMessageSize sctp attribute exists -PASS maxMessageSize sctp attribute is null before offer/answer -PASS maxMessageSize sctp attribute is null if SCTP not negotiated -PASS maxMessageSize sctp and maxMessageSize set if SCTP negotiated -PASS maxMessageSize 0 case handled correctly -PASS maxMessageSize send largest possible single message -PASS maxMessageSize throws an exception if the message is too large diff --git a/test/e2e/expectations/firefox-beta b/test/e2e/expectations/firefox-beta index c70bc07f0..605091b31 100644 --- a/test/e2e/expectations/firefox-beta +++ b/test/e2e/expectations/firefox-beta @@ -33,6 +33,13 @@ PASS getStats returns a Promise PASS getStats resolves the Promise with a Map(like) PASS getUserMedia navigator.getUserMedia exists PASS getUserMedia navigator.getUserMedia calls the callback +PASS maxMessageSize sctp attribute exists +PASS maxMessageSize sctp attribute is null before offer/answer +PASS maxMessageSize sctp attribute is null if SCTP not negotiated +PASS maxMessageSize sctp and maxMessageSize set if SCTP negotiated +PASS maxMessageSize 0 case handled correctly +PASS maxMessageSize send largest possible single message +PASS maxMessageSize throws an exception if the message is too large PASS navigator.mediaDevices exists PASS navigator.mediaDevices is an EventTarget PASS navigator.mediaDevices implements the devicechange event @@ -81,10 +88,3 @@ PASS srcObject setter triggers loadedmetadata (audio) PASS srcObject getter returns the stream (audio) PASS srcObject setter triggers loadedmetadata (video) PASS srcObject getter returns the stream (video) -PASS maxMessageSize sctp attribute exists -PASS maxMessageSize sctp attribute is null before offer/answer -PASS maxMessageSize sctp attribute is null if SCTP not negotiated -PASS maxMessageSize sctp and maxMessageSize set if SCTP negotiated -PASS maxMessageSize 0 case handled correctly -PASS maxMessageSize send largest possible single message -PASS maxMessageSize throws an exception if the message is too large diff --git a/test/e2e/expectations/firefox-esr b/test/e2e/expectations/firefox-esr index 1d5c36d72..974a045cb 100644 --- a/test/e2e/expectations/firefox-esr +++ b/test/e2e/expectations/firefox-esr @@ -33,6 +33,13 @@ PASS getStats returns a Promise PASS getStats resolves the Promise with a Map(like) PASS getUserMedia navigator.getUserMedia exists PASS getUserMedia navigator.getUserMedia calls the callback +PASS maxMessageSize sctp attribute exists +PASS maxMessageSize sctp attribute is null before offer/answer +PASS maxMessageSize sctp attribute is null if SCTP not negotiated +PASS maxMessageSize sctp and maxMessageSize set if SCTP negotiated +PASS maxMessageSize 0 case handled correctly +PASS maxMessageSize send largest possible single message +PASS maxMessageSize throws an exception if the message is too large PASS navigator.mediaDevices exists PASS navigator.mediaDevices is an EventTarget PASS navigator.mediaDevices implements the devicechange event @@ -81,10 +88,3 @@ PASS srcObject setter triggers loadedmetadata (audio) PASS srcObject getter returns the stream (audio) PASS srcObject setter triggers loadedmetadata (video) PASS srcObject getter returns the stream (video) -PASS maxMessageSize sctp attribute exists -PASS maxMessageSize sctp attribute is null before offer/answer -PASS maxMessageSize sctp attribute is null if SCTP not negotiated -PASS maxMessageSize sctp and maxMessageSize set if SCTP negotiated -PASS maxMessageSize 0 case handled correctly -PASS maxMessageSize send largest possible single message -PASS maxMessageSize throws an exception if the message is too large diff --git a/test/e2e/expectations/firefox-nightly b/test/e2e/expectations/firefox-nightly index c70bc07f0..605091b31 100644 --- a/test/e2e/expectations/firefox-nightly +++ b/test/e2e/expectations/firefox-nightly @@ -33,6 +33,13 @@ PASS getStats returns a Promise PASS getStats resolves the Promise with a Map(like) PASS getUserMedia navigator.getUserMedia exists PASS getUserMedia navigator.getUserMedia calls the callback +PASS maxMessageSize sctp attribute exists +PASS maxMessageSize sctp attribute is null before offer/answer +PASS maxMessageSize sctp attribute is null if SCTP not negotiated +PASS maxMessageSize sctp and maxMessageSize set if SCTP negotiated +PASS maxMessageSize 0 case handled correctly +PASS maxMessageSize send largest possible single message +PASS maxMessageSize throws an exception if the message is too large PASS navigator.mediaDevices exists PASS navigator.mediaDevices is an EventTarget PASS navigator.mediaDevices implements the devicechange event @@ -81,10 +88,3 @@ PASS srcObject setter triggers loadedmetadata (audio) PASS srcObject getter returns the stream (audio) PASS srcObject setter triggers loadedmetadata (video) PASS srcObject getter returns the stream (video) -PASS maxMessageSize sctp attribute exists -PASS maxMessageSize sctp attribute is null before offer/answer -PASS maxMessageSize sctp attribute is null if SCTP not negotiated -PASS maxMessageSize sctp and maxMessageSize set if SCTP negotiated -PASS maxMessageSize 0 case handled correctly -PASS maxMessageSize send largest possible single message -PASS maxMessageSize throws an exception if the message is too large diff --git a/test/e2e/expectations/firefox-stable b/test/e2e/expectations/firefox-stable index c70bc07f0..605091b31 100644 --- a/test/e2e/expectations/firefox-stable +++ b/test/e2e/expectations/firefox-stable @@ -33,6 +33,13 @@ PASS getStats returns a Promise PASS getStats resolves the Promise with a Map(like) PASS getUserMedia navigator.getUserMedia exists PASS getUserMedia navigator.getUserMedia calls the callback +PASS maxMessageSize sctp attribute exists +PASS maxMessageSize sctp attribute is null before offer/answer +PASS maxMessageSize sctp attribute is null if SCTP not negotiated +PASS maxMessageSize sctp and maxMessageSize set if SCTP negotiated +PASS maxMessageSize 0 case handled correctly +PASS maxMessageSize send largest possible single message +PASS maxMessageSize throws an exception if the message is too large PASS navigator.mediaDevices exists PASS navigator.mediaDevices is an EventTarget PASS navigator.mediaDevices implements the devicechange event @@ -81,10 +88,3 @@ PASS srcObject setter triggers loadedmetadata (audio) PASS srcObject getter returns the stream (audio) PASS srcObject setter triggers loadedmetadata (video) PASS srcObject getter returns the stream (video) -PASS maxMessageSize sctp attribute exists -PASS maxMessageSize sctp attribute is null before offer/answer -PASS maxMessageSize sctp attribute is null if SCTP not negotiated -PASS maxMessageSize sctp and maxMessageSize set if SCTP negotiated -PASS maxMessageSize 0 case handled correctly -PASS maxMessageSize send largest possible single message -PASS maxMessageSize throws an exception if the message is too large diff --git a/test/e2e/maxMessageSize.js b/test/e2e/maxMessageSize.js index 1dbc26987..eb36f30fd 100644 --- a/test/e2e/maxMessageSize.js +++ b/test/e2e/maxMessageSize.js @@ -109,7 +109,8 @@ describe('maxMessageSize', () => { it('send largest possible single message', () => { let maxMessageSize = 1000; const patchMaxMessageSize = patchMaxMessageSizeFactory(1000); - if (window.adapter.browserDetails.browser === 'firefox') { + if (window.adapter.browserDetails.browser === 'firefox' && + window.adapter.browserDetails.version < 57) { maxMessageSize = 1073741823; } @@ -128,7 +129,7 @@ describe('maxMessageSize', () => { dc.send(new Uint8Array(1000)); }; dc.onopen = () => { - expect(send).not.to.throw(TypeError); + expect(send).not.to.throw(); resolve(); }; }); @@ -139,7 +140,8 @@ describe('maxMessageSize', () => { it('if the message is too large', () => { let maxMessageSize = 1000; const patchMaxMessageSize = patchMaxMessageSizeFactory(maxMessageSize); - if (window.adapter.browserDetails.browser === 'firefox') { + if (window.adapter.browserDetails.browser === 'firefox' && + window.adapter.browserDetails.version < 57) { maxMessageSize = 1073741823; } @@ -153,10 +155,16 @@ describe('maxMessageSize', () => { return new Promise((resolve, reject) => { const dc = pc1.createDataChannel('test2'); const send = () => { + // Note: The local MMS is determined incorrectly by FF >= 57 + // See: https://bugzilla.mozilla.org/show_bug.cgi?id=1413140 + if (window.adapter.browserDetails.browser === 'firefox' && + window.adapter.browserDetails.version >= 57) { + maxMessageSize = 1073741823; + } dc.send(new Uint8Array(maxMessageSize + 1)); }; dc.onopen = () => { - expect(send).to.throw(TypeError); + expect(send).to.throw().with.property('name', 'TypeError'); resolve(); }; }); From 9c29712b1ff8a58fc549829e8a7334c52ccdb014 Mon Sep 17 00:00:00 2001 From: Lennart Grahl Date: Fri, 3 Nov 2017 20:44:58 +0100 Subject: [PATCH 12/23] Fix determine maximum message size correctly (do not rely on the local maximum message size at all) Remove MMS 0 case test (not really applicable to an e2e test) --- src/js/common_shim.js | 124 ++++++++---------- test/e2e/expectations/chrome-beta | 17 ++- .../expectations/chrome-beta-no-experimental | 1 - test/e2e/expectations/chrome-stable | 1 - .../chrome-stable-no-experimental | 1 - test/e2e/expectations/chrome-unstable | 1 - test/e2e/expectations/firefox-beta | 1 - test/e2e/expectations/firefox-esr | 1 - test/e2e/expectations/firefox-nightly | 1 - test/e2e/expectations/firefox-stable | 1 - test/e2e/maxMessageSize.js | 77 ++++------- 11 files changed, 92 insertions(+), 134 deletions(-) diff --git a/src/js/common_shim.js b/src/js/common_shim.js index 55e55cadb..24f644935 100644 --- a/src/js/common_shim.js +++ b/src/js/common_shim.js @@ -183,17 +183,6 @@ module.exports = { return (match !== null && match.length >= 1); }; - var getMaxMessageSize = function(description) { - // Note: 65535 bytes is the default value from the SDP spec. Also, - // every implementation we know supports receiving 65535 bytes. - var maxMessageSize = 65535; - var match = SDPUtils.matchPrefix(description.sdp, 'a=max-message-size:'); - if (match.length > 0) { - maxMessageSize = parseInt(match[0].substr(19), 10); - } - return maxMessageSize; - }; - var getFirefoxVersion = function(description) { // TODO: Is there a better solution for detecting Firefox? var match = description.sdp.match(/mozilla...THIS_IS_SDPARTA-(\d+)/); @@ -205,76 +194,79 @@ module.exports = { return version !== version ? -1 : version; }; - var maybeApplyMaxMessageSize = function(pc) { - if (Number.isInteger(pc._localMaxMessageSize) && - Number.isInteger(pc._remoteMaxMessageSize)) { - // Note: This algorithm is not in the spec so far but it will - // likely be added, see: - // https://github.com/w3c/webrtc-pc/issues/1446#issuecomment-340204737 - var maxMessageSize = pc._localMaxMessageSize; - if (pc._localMaxMessageSize === 0 || pc._remoteMaxMessageSize === 0) { - maxMessageSize = Math.max(pc._localMaxMessageSize, - pc._remoteMaxMessageSize); + var getCanSendMaxMessageSize = function(description, remoteIsFirefox) { + // Every implementation we know can send at least 64 KiB. + // Note: Although Chrome is technically able to send up to 256 KiB, the + // data does not reach the other peer reliably. + var canSendMaxMessageSize = 65535; + if (browserDetails.browser === 'firefox') { + if (browserDetails.version < 57) { + if (remoteIsFirefox === -1) { + // FF < 57 will send in 16 KiB chunks using the deprecated PPID + // fragmentation. + canSendMaxMessageSize = 16384; + } else { + // However, other FF (and RAWRTC) can reassemble PPID-fragmented + // messages. Thus, supporting at least 1 GiB when sending. + canSendMaxMessageSize = 1073741823; + } } else { - maxMessageSize = Math.min(pc._localMaxMessageSize, - pc._remoteMaxMessageSize); + // FF >= 57 supports up to 1 GiB. + canSendMaxMessageSize = 1073741823; } - - // Any FF can send (at least) 1 GiB towards all other FF < 57. - if (browserDetails.browser === 'firefox' && - pc._otherPeerFirefoxVersion < 57) { - maxMessageSize = 1073741823; - } - - // Create a dummy RTCSctpTransport object and the 'maxMessageSize' - // attribute. - var sctp = {}; - Object.defineProperty(sctp, 'maxMessageSize', { - get: function() { - return maxMessageSize; - } - }); - pc._sctp = sctp; } + return canSendMaxMessageSize; }; - var origSetLocalDescription = - window.RTCPeerConnection.prototype.setLocalDescription; - window.RTCPeerConnection.prototype.setLocalDescription = function() { - var pc = this; - pc._localMaxMessageSize = null; - - if (sctpInDescription(arguments[0])) { - // Determine the maximum message size of the browser. - if (browserDetails.browser === 'firefox' && - browserDetails.version < 57) { - // Note: This is required because FF < 57 will send in 16 KiB chunks - pc._localMaxMessageSize = 16384; - } else { - pc._localMaxMessageSize = getMaxMessageSize(arguments[0]); - } - - // Determine final maximum message size - maybeApplyMaxMessageSize(pc); + var getMaxMessageSize = function(description, remoteIsFirefox) { + // Note: 65535 bytes is the default value from the SDP spec. Also, + // every implementation we know supports receiving 65535 bytes. + var maxMessageSize = 65535; + var match = SDPUtils.matchPrefix(description.sdp, 'a=max-message-size:'); + if (match.length > 0) { + maxMessageSize = parseInt(match[0].substr(19), 10); + } else if (browserDetails.browser === 'firefox' && + remoteIsFirefox !== -1) { + // If the maximum message size is not present in the remote SDP and + // both local and remote are Firefox, we can receive up to 1 GiB. + maxMessageSize = 1073741823; } - - return origSetLocalDescription.apply(pc, arguments); + return maxMessageSize; }; var origSetRemoteDescription = window.RTCPeerConnection.prototype.setRemoteDescription; window.RTCPeerConnection.prototype.setRemoteDescription = function() { var pc = this; - pc._remoteMaxMessageSize = null; - pc._otherPeerFirefoxVersion = -1; + pc._sctp = null; if (sctpInDescription(arguments[0])) { - // Determine the maximum message size of the remote peer. - pc._remoteMaxMessageSize = getMaxMessageSize(arguments[0]); - // Determine if other peer is Firefox - pc._otherPeerFirefoxVersion = getFirefoxVersion(arguments[0]); + // Check if the remote is FF. + var isFirefox = getFirefoxVersion(arguments[0]); + + // Get the maximum message size the local peer is capable of sending + var canSendMMS = getCanSendMaxMessageSize(arguments[0], isFirefox); + + // Get the maximum message size of the remote peer. + var remoteMMS = getMaxMessageSize(arguments[0], isFirefox); + // Determine final maximum message size - maybeApplyMaxMessageSize(pc); + var maxMessageSize; + if (canSendMMS === 0 || remoteMMS === 0) { + maxMessageSize = Math.max(canSendMMS, remoteMMS); + } else { + maxMessageSize = Math.min(canSendMMS, remoteMMS); + } + + // Create a dummy RTCSctpTransport object and the 'maxMessageSize' + // attribute. + var sctp = {}; + Object.defineProperty(sctp, 'maxMessageSize', { + get: function() { + return maxMessageSize; + } + }); + pc._sctp = sctp; } return origSetRemoteDescription.apply(pc, arguments); diff --git a/test/e2e/expectations/chrome-beta b/test/e2e/expectations/chrome-beta index 163abe444..f5ee90180 100644 --- a/test/e2e/expectations/chrome-beta +++ b/test/e2e/expectations/chrome-beta @@ -2,12 +2,12 @@ PASS addIceCandidate after setRemoteDescription resolves when called with null PASS addIceCandidate after setRemoteDescription resolves when called with undefined PASS addTrack throws an exception if the track has already been added PASS addTrack throws an exception if the track has already been added via addStream -PASS addTrack throws an exception if addStream is called with a stream containing a track already added +ERR addTrack throws an exception if addStream is called with a stream containing a track already added AssertionError PASS addTrack throws an exception if the peerconnection has been closed already PASS addTrack and getSenders creates a sender -PASS addTrack and getLocalStreams returns a stream with audio and video even if just an audio track was added -PASS addTrack and getLocalStreams adds another track to the same stream -PASS addTrack and getLocalStreams plays together nicely +ERR addTrack and getLocalStreams returns a stream with audio and video even if just an audio track was added AssertionError +ERR addTrack and getLocalStreams adds another track to the same stream AssertionError +ERR addTrack and getLocalStreams plays together nicely AssertionError PASS window.adapter exists PASS window.adapter browserDetails exists PASS window.adapter browserDetails detects a browser type @@ -28,7 +28,7 @@ PASS URL.createObjectURL shim works for video using setAttribute PASS dtmf RTCRtpSender.dtmf exists on audio senders PASS dtmf RTCRtpSender.dtmf does not exist on video senders PASS dtmf inserts DTMF when using addStream -PASS dtmf inserts DTMF when using addTrack +ERR dtmf inserts DTMF when using addTrack timeout PASS getStats returns a Promise PASS getStats resolves the Promise with a Map(like) PASS getUserMedia navigator.getUserMedia exists @@ -37,7 +37,6 @@ PASS maxMessageSize sctp attribute exists PASS maxMessageSize sctp attribute is null before offer/answer PASS maxMessageSize sctp attribute is null if SCTP not negotiated PASS maxMessageSize sctp and maxMessageSize set if SCTP negotiated -PASS maxMessageSize 0 case handled correctly PASS maxMessageSize send largest possible single message PASS maxMessageSize throws an exception if the message is too large PASS navigator.mediaDevices exists @@ -61,15 +60,15 @@ PASS track event the event has a set of streams PASS track event the event has a receiver that is contained in the set of receivers ERR track event the event has a transceiver that has a receiver timeout PASS removeTrack allows removeTrack twice -PASS removeTrack throws an exception if the argument is a track, not a sender +ERR removeTrack throws an exception if the argument is a track, not a sender AssertionError PASS removeTrack throws an exception if the sender does not belong to the peerconnection PASS removeTrack throws an exception if the peerconnection has been closed already PASS removeTrack after addStream for an audio/video track after removing a single track only a single sender remains PASS removeTrack after addStream for an audio/video track after removing a single track the local stream remains untouched PASS removeTrack after addStream for an audio/video track after removing all tracks no senders remain -PASS removeTrack after addStream for an audio/video track after removing all tracks no local streams remain +ERR removeTrack after addStream for an audio/video track after removing all tracks no local streams remain AssertionError PASS removeTrack after addTrack for an audio/video track after removing a single track only a single sender remains -PASS removeTrack after addTrack for an audio/video track after removing a single track the local stream remains untouched +ERR removeTrack after addTrack for an audio/video track after removing a single track the local stream remains untouched AssertionError PASS removeTrack after addTrack for an audio/video track after removing all tracks no senders remain PASS removeTrack after addTrack for an audio/video track after removing all tracks no local streams remain PASS RTCIceCandidate window.RTCIceCandidate exists diff --git a/test/e2e/expectations/chrome-beta-no-experimental b/test/e2e/expectations/chrome-beta-no-experimental index 894cac06d..7dfe6cd4c 100644 --- a/test/e2e/expectations/chrome-beta-no-experimental +++ b/test/e2e/expectations/chrome-beta-no-experimental @@ -37,7 +37,6 @@ PASS maxMessageSize sctp attribute exists PASS maxMessageSize sctp attribute is null before offer/answer PASS maxMessageSize sctp attribute is null if SCTP not negotiated PASS maxMessageSize sctp and maxMessageSize set if SCTP negotiated -PASS maxMessageSize 0 case handled correctly PASS maxMessageSize send largest possible single message PASS maxMessageSize throws an exception if the message is too large PASS navigator.mediaDevices exists diff --git a/test/e2e/expectations/chrome-stable b/test/e2e/expectations/chrome-stable index 163abe444..afca9866a 100644 --- a/test/e2e/expectations/chrome-stable +++ b/test/e2e/expectations/chrome-stable @@ -37,7 +37,6 @@ PASS maxMessageSize sctp attribute exists PASS maxMessageSize sctp attribute is null before offer/answer PASS maxMessageSize sctp attribute is null if SCTP not negotiated PASS maxMessageSize sctp and maxMessageSize set if SCTP negotiated -PASS maxMessageSize 0 case handled correctly PASS maxMessageSize send largest possible single message PASS maxMessageSize throws an exception if the message is too large PASS navigator.mediaDevices exists diff --git a/test/e2e/expectations/chrome-stable-no-experimental b/test/e2e/expectations/chrome-stable-no-experimental index 894cac06d..7dfe6cd4c 100644 --- a/test/e2e/expectations/chrome-stable-no-experimental +++ b/test/e2e/expectations/chrome-stable-no-experimental @@ -37,7 +37,6 @@ PASS maxMessageSize sctp attribute exists PASS maxMessageSize sctp attribute is null before offer/answer PASS maxMessageSize sctp attribute is null if SCTP not negotiated PASS maxMessageSize sctp and maxMessageSize set if SCTP negotiated -PASS maxMessageSize 0 case handled correctly PASS maxMessageSize send largest possible single message PASS maxMessageSize throws an exception if the message is too large PASS navigator.mediaDevices exists diff --git a/test/e2e/expectations/chrome-unstable b/test/e2e/expectations/chrome-unstable index b7ccda0ba..778fdfdc1 100644 --- a/test/e2e/expectations/chrome-unstable +++ b/test/e2e/expectations/chrome-unstable @@ -37,7 +37,6 @@ PASS maxMessageSize sctp attribute exists PASS maxMessageSize sctp attribute is null before offer/answer PASS maxMessageSize sctp attribute is null if SCTP not negotiated PASS maxMessageSize sctp and maxMessageSize set if SCTP negotiated -PASS maxMessageSize 0 case handled correctly PASS maxMessageSize send largest possible single message PASS maxMessageSize throws an exception if the message is too large PASS navigator.mediaDevices exists diff --git a/test/e2e/expectations/firefox-beta b/test/e2e/expectations/firefox-beta index 605091b31..0e41794c8 100644 --- a/test/e2e/expectations/firefox-beta +++ b/test/e2e/expectations/firefox-beta @@ -37,7 +37,6 @@ PASS maxMessageSize sctp attribute exists PASS maxMessageSize sctp attribute is null before offer/answer PASS maxMessageSize sctp attribute is null if SCTP not negotiated PASS maxMessageSize sctp and maxMessageSize set if SCTP negotiated -PASS maxMessageSize 0 case handled correctly PASS maxMessageSize send largest possible single message PASS maxMessageSize throws an exception if the message is too large PASS navigator.mediaDevices exists diff --git a/test/e2e/expectations/firefox-esr b/test/e2e/expectations/firefox-esr index 974a045cb..207d79baf 100644 --- a/test/e2e/expectations/firefox-esr +++ b/test/e2e/expectations/firefox-esr @@ -37,7 +37,6 @@ PASS maxMessageSize sctp attribute exists PASS maxMessageSize sctp attribute is null before offer/answer PASS maxMessageSize sctp attribute is null if SCTP not negotiated PASS maxMessageSize sctp and maxMessageSize set if SCTP negotiated -PASS maxMessageSize 0 case handled correctly PASS maxMessageSize send largest possible single message PASS maxMessageSize throws an exception if the message is too large PASS navigator.mediaDevices exists diff --git a/test/e2e/expectations/firefox-nightly b/test/e2e/expectations/firefox-nightly index 605091b31..0e41794c8 100644 --- a/test/e2e/expectations/firefox-nightly +++ b/test/e2e/expectations/firefox-nightly @@ -37,7 +37,6 @@ PASS maxMessageSize sctp attribute exists PASS maxMessageSize sctp attribute is null before offer/answer PASS maxMessageSize sctp attribute is null if SCTP not negotiated PASS maxMessageSize sctp and maxMessageSize set if SCTP negotiated -PASS maxMessageSize 0 case handled correctly PASS maxMessageSize send largest possible single message PASS maxMessageSize throws an exception if the message is too large PASS navigator.mediaDevices exists diff --git a/test/e2e/expectations/firefox-stable b/test/e2e/expectations/firefox-stable index 605091b31..0e41794c8 100644 --- a/test/e2e/expectations/firefox-stable +++ b/test/e2e/expectations/firefox-stable @@ -37,7 +37,6 @@ PASS maxMessageSize sctp attribute exists PASS maxMessageSize sctp attribute is null before offer/answer PASS maxMessageSize sctp attribute is null if SCTP not negotiated PASS maxMessageSize sctp and maxMessageSize set if SCTP negotiated -PASS maxMessageSize 0 case handled correctly PASS maxMessageSize send largest possible single message PASS maxMessageSize throws an exception if the message is too large PASS navigator.mediaDevices exists diff --git a/test/e2e/maxMessageSize.js b/test/e2e/maxMessageSize.js index eb36f30fd..141198a9f 100644 --- a/test/e2e/maxMessageSize.js +++ b/test/e2e/maxMessageSize.js @@ -12,24 +12,26 @@ describe('maxMessageSize', () => { let pc1; let pc2; - function negotiate(pc, otherPc, mapDescriptionCallback) { + function negotiate(pc, otherPc, mapRemoteDescriptionCallback) { return pc.createOffer() .then((offer) => { - if (mapDescriptionCallback) { - offer = mapDescriptionCallback(offer); - } return pc.setLocalDescription(offer); }).then(() => { - return otherPc.setRemoteDescription(pc.localDescription); + let description = pc.localDescription; + if (mapRemoteDescriptionCallback) { + description = mapRemoteDescriptionCallback(description); + } + return otherPc.setRemoteDescription(description); }).then(() => { return otherPc.createAnswer(); }).then((answer) => { - if (mapDescriptionCallback) { - answer = mapDescriptionCallback(answer); - } return otherPc.setLocalDescription(answer); }).then(() => { - return pc.setRemoteDescription(otherPc.localDescription); + let description = otherPc.localDescription; + if (mapRemoteDescriptionCallback) { + description = mapRemoteDescriptionCallback(description); + } + return pc.setRemoteDescription(description); }); } @@ -38,7 +40,7 @@ describe('maxMessageSize', () => { description.sdp = description.sdp.replace( /^a=max-message-size:\s*(\d+)\s*$/gm, ''); description.sdp = description.sdp.replace( - /(^m=application\s+\d+\s+[\w/]*SCTP.*$)/m, + /(^m=application\s+\d+\s+[\w\/]*SCTP.*$)/m, '$1\r\na=max-message-size:' + maxMessageSize); return description; }); @@ -77,42 +79,25 @@ describe('maxMessageSize', () => { }); it('sctp and maxMessageSize set if SCTP negotiated', () => { + const browserDetails = window.adapter.browserDetails; pc1.createDataChannel('test'); return negotiate(pc1, pc2) .then(() => { expect(pc1.sctp).to.have.property('maxMessageSize'); expect(pc2.sctp).to.have.property('maxMessageSize'); - expect(pc1.sctp.maxMessageSize).to.be.a('number'); - expect(pc2.sctp.maxMessageSize).to.be.a('number'); - }); - }); - - it('0 case handled correctly', (done) => { - const patchMaxMessageSize = patchMaxMessageSizeFactory(0); - - // Ensure TypeError isn't thrown when sending data - const dc = pc1.createDataChannel('test'); - const send = () => { - dc.send('meow'); - }; - dc.onopen = () => { - expect(send).not.to.throw(); - done(); - }; - negotiate(pc1, pc2, patchMaxMessageSize) - .then(() => { - expect(pc1.sctp.maxMessageSize).to.equal(0); - expect(pc2.sctp.maxMessageSize).to.equal(0); + expect(pc1.sctp.maxMessageSize).to.be.at.least(65535); + expect(pc2.sctp.maxMessageSize).to.be.at.least(65535); + if (browserDetails.browser === 'firefox') { + expect(pc1.sctp.maxMessageSize).to.equal(1073741823); + expect(pc2.sctp.maxMessageSize).to.equal(1073741823); + } }); }); it('send largest possible single message', () => { - let maxMessageSize = 1000; - const patchMaxMessageSize = patchMaxMessageSizeFactory(1000); - if (window.adapter.browserDetails.browser === 'firefox' && - window.adapter.browserDetails.version < 57) { - maxMessageSize = 1073741823; - } + // Note: Patching to 65535 here as anything beyond that will take too long. + const maxMessageSize = 65535; + const patchMaxMessageSize = patchMaxMessageSizeFactory(maxMessageSize); pc1.createDataChannel('test'); return negotiate(pc1, pc2, patchMaxMessageSize) @@ -124,9 +109,7 @@ describe('maxMessageSize', () => { return new Promise((resolve, reject) => { const dc = pc1.createDataChannel('test2'); const send = () => { - // Note: Falling back to 1000 here as the special case of FF would - // take way too long. - dc.send(new Uint8Array(1000)); + dc.send(new Uint8Array(maxMessageSize)); }; dc.onopen = () => { expect(send).not.to.throw(); @@ -138,12 +121,10 @@ describe('maxMessageSize', () => { describe('throws an exception', () => { it('if the message is too large', () => { - let maxMessageSize = 1000; + // Note: Patching to 65535 here as anything beyond that will take too + // long (including creation of a large array). + const maxMessageSize = 65535; const patchMaxMessageSize = patchMaxMessageSizeFactory(maxMessageSize); - if (window.adapter.browserDetails.browser === 'firefox' && - window.adapter.browserDetails.version < 57) { - maxMessageSize = 1073741823; - } pc1.createDataChannel('test'); return negotiate(pc1, pc2, patchMaxMessageSize) @@ -155,12 +136,6 @@ describe('maxMessageSize', () => { return new Promise((resolve, reject) => { const dc = pc1.createDataChannel('test2'); const send = () => { - // Note: The local MMS is determined incorrectly by FF >= 57 - // See: https://bugzilla.mozilla.org/show_bug.cgi?id=1413140 - if (window.adapter.browserDetails.browser === 'firefox' && - window.adapter.browserDetails.version >= 57) { - maxMessageSize = 1073741823; - } dc.send(new Uint8Array(maxMessageSize + 1)); }; dc.onopen = () => { From d6cf288757daf5d756f9547c1bdc505a5b8527a7 Mon Sep 17 00:00:00 2001 From: Lennart Grahl Date: Fri, 3 Nov 2017 21:47:52 +0100 Subject: [PATCH 13/23] Fix also apply the 'TypeError on send' shim to FF >= 57 for consistency reasons --- src/js/common_shim.js | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/src/js/common_shim.js b/src/js/common_shim.js index 24f644935..1aad7cf39 100644 --- a/src/js/common_shim.js +++ b/src/js/common_shim.js @@ -228,7 +228,8 @@ module.exports = { } else if (browserDetails.browser === 'firefox' && remoteIsFirefox !== -1) { // If the maximum message size is not present in the remote SDP and - // both local and remote are Firefox, we can receive up to 1 GiB. + // both local and remote are Firefox, the remote peer can receive up + // to 1 GiB. maxMessageSize = 1073741823; } return maxMessageSize; @@ -274,13 +275,10 @@ module.exports = { }, shimSendThrowTypeError: function(window) { - var browserDetails = utils.detectBrowser(window); - - // Only Firefox 57 has support for this atm - if (browserDetails.browser === 'firefox' && browserDetails.version >= 57) { - return; - } - + // Note: Firefox 57 has support for this but for consistency, we will also + // apply this patch to FF >= 57. The reason is that FF >= 57 will + // allow sending even more than 1 GiB towards remote peers that are + // FF < 57... which is confusing. So, we're limiting to 1 GiB. var origCreateDataChannel = window.RTCPeerConnection.prototype.createDataChannel; window.RTCPeerConnection.prototype.createDataChannel = function() { From 8bfca85021c377eca199d88dba6619af3b1c6ee1 Mon Sep 17 00:00:00 2001 From: Lennart Grahl Date: Thu, 9 Nov 2017 12:49:40 +0100 Subject: [PATCH 14/23] Fix expect tests to pass that were accidentally changed to expect to error --- test/e2e/expectations/chrome-beta | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/test/e2e/expectations/chrome-beta b/test/e2e/expectations/chrome-beta index f5ee90180..afca9866a 100644 --- a/test/e2e/expectations/chrome-beta +++ b/test/e2e/expectations/chrome-beta @@ -2,12 +2,12 @@ PASS addIceCandidate after setRemoteDescription resolves when called with null PASS addIceCandidate after setRemoteDescription resolves when called with undefined PASS addTrack throws an exception if the track has already been added PASS addTrack throws an exception if the track has already been added via addStream -ERR addTrack throws an exception if addStream is called with a stream containing a track already added AssertionError +PASS addTrack throws an exception if addStream is called with a stream containing a track already added PASS addTrack throws an exception if the peerconnection has been closed already PASS addTrack and getSenders creates a sender -ERR addTrack and getLocalStreams returns a stream with audio and video even if just an audio track was added AssertionError -ERR addTrack and getLocalStreams adds another track to the same stream AssertionError -ERR addTrack and getLocalStreams plays together nicely AssertionError +PASS addTrack and getLocalStreams returns a stream with audio and video even if just an audio track was added +PASS addTrack and getLocalStreams adds another track to the same stream +PASS addTrack and getLocalStreams plays together nicely PASS window.adapter exists PASS window.adapter browserDetails exists PASS window.adapter browserDetails detects a browser type @@ -28,7 +28,7 @@ PASS URL.createObjectURL shim works for video using setAttribute PASS dtmf RTCRtpSender.dtmf exists on audio senders PASS dtmf RTCRtpSender.dtmf does not exist on video senders PASS dtmf inserts DTMF when using addStream -ERR dtmf inserts DTMF when using addTrack timeout +PASS dtmf inserts DTMF when using addTrack PASS getStats returns a Promise PASS getStats resolves the Promise with a Map(like) PASS getUserMedia navigator.getUserMedia exists @@ -60,15 +60,15 @@ PASS track event the event has a set of streams PASS track event the event has a receiver that is contained in the set of receivers ERR track event the event has a transceiver that has a receiver timeout PASS removeTrack allows removeTrack twice -ERR removeTrack throws an exception if the argument is a track, not a sender AssertionError +PASS removeTrack throws an exception if the argument is a track, not a sender PASS removeTrack throws an exception if the sender does not belong to the peerconnection PASS removeTrack throws an exception if the peerconnection has been closed already PASS removeTrack after addStream for an audio/video track after removing a single track only a single sender remains PASS removeTrack after addStream for an audio/video track after removing a single track the local stream remains untouched PASS removeTrack after addStream for an audio/video track after removing all tracks no senders remain -ERR removeTrack after addStream for an audio/video track after removing all tracks no local streams remain AssertionError +PASS removeTrack after addStream for an audio/video track after removing all tracks no local streams remain PASS removeTrack after addTrack for an audio/video track after removing a single track only a single sender remains -ERR removeTrack after addTrack for an audio/video track after removing a single track the local stream remains untouched AssertionError +PASS removeTrack after addTrack for an audio/video track after removing a single track the local stream remains untouched PASS removeTrack after addTrack for an audio/video track after removing all tracks no senders remain PASS removeTrack after addTrack for an audio/video track after removing all tracks no local streams remain PASS RTCIceCandidate window.RTCIceCandidate exists From c5c683bb70487e98eea59e3b0f0cfdbce216fec2 Mon Sep 17 00:00:00 2001 From: Lennart Grahl Date: Thu, 9 Nov 2017 12:51:48 +0100 Subject: [PATCH 15/23] Rename `getFirefoxVersion` to `getRemoteFirefoxVersion` --- src/js/common_shim.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/js/common_shim.js b/src/js/common_shim.js index 1aad7cf39..1fb23d33f 100644 --- a/src/js/common_shim.js +++ b/src/js/common_shim.js @@ -183,7 +183,7 @@ module.exports = { return (match !== null && match.length >= 1); }; - var getFirefoxVersion = function(description) { + var getRemoteFirefoxVersion = function(description) { // TODO: Is there a better solution for detecting Firefox? var match = description.sdp.match(/mozilla...THIS_IS_SDPARTA-(\d+)/); if (match === null || match.length < 2) { @@ -243,7 +243,7 @@ module.exports = { if (sctpInDescription(arguments[0])) { // Check if the remote is FF. - var isFirefox = getFirefoxVersion(arguments[0]); + var isFirefox = getRemoteFirefoxVersion(arguments[0]); // Get the maximum message size the local peer is capable of sending var canSendMMS = getCanSendMaxMessageSize(arguments[0], isFirefox); From 0711e9d29cc5c1fd6dcf8c85278af0d04fdd7804 Mon Sep 17 00:00:00 2001 From: Lennart Grahl Date: Thu, 9 Nov 2017 13:40:23 +0100 Subject: [PATCH 16/23] Replace regex with SDPUtils for checking whether SCTP is being negotiated --- src/js/common_shim.js | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/js/common_shim.js b/src/js/common_shim.js index 1fb23d33f..aa0988473 100644 --- a/src/js/common_shim.js +++ b/src/js/common_shim.js @@ -179,8 +179,13 @@ module.exports = { } var sctpInDescription = function(description) { - var match = description.sdp.match(/m=application\s+\d+\s+[\w/]*SCTP/); - return (match !== null && match.length >= 1); + var sections = SDPUtils.splitSections(description.sdp); + sections.shift(); + return sections.some(function(mediaSection) { + var mLine = SDPUtils.parseMLine(mediaSection); + return mLine && mLine.kind === 'application' + && mLine.protocol.indexOf('SCTP') !== -1; + }); }; var getRemoteFirefoxVersion = function(description) { From 64600a691086f39592e63366ac9ba824fdd128a7 Mon Sep 17 00:00:00 2001 From: Lennart Grahl Date: Thu, 9 Nov 2017 16:24:40 +0100 Subject: [PATCH 17/23] Reference Chrome data channel send issue (cannot reliably send more than 64 KiB) --- src/js/common_shim.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/js/common_shim.js b/src/js/common_shim.js index aa0988473..7f7736540 100644 --- a/src/js/common_shim.js +++ b/src/js/common_shim.js @@ -203,6 +203,7 @@ module.exports = { // Every implementation we know can send at least 64 KiB. // Note: Although Chrome is technically able to send up to 256 KiB, the // data does not reach the other peer reliably. + // See: https://bugs.chromium.org/p/webrtc/issues/detail?id=8419 var canSendMaxMessageSize = 65535; if (browserDetails.browser === 'firefox') { if (browserDetails.version < 57) { From 5604ef3cd325094f324ab2631a8059b1d5c6e3a5 Mon Sep 17 00:00:00 2001 From: Lennart Grahl Date: Fri, 8 Dec 2017 11:34:34 +0100 Subject: [PATCH 18/23] Set maxMessageSize to positive infinity in case both peers can handle messages of arbitrary size --- src/js/common_shim.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/js/common_shim.js b/src/js/common_shim.js index 7f7736540..160420ab0 100644 --- a/src/js/common_shim.js +++ b/src/js/common_shim.js @@ -259,7 +259,9 @@ module.exports = { // Determine final maximum message size var maxMessageSize; - if (canSendMMS === 0 || remoteMMS === 0) { + if (canSendMMS === 0 && remoteMMS === 0) { + maxMessageSize = Number.POSITIVE_INFINITY; + } else if (canSendMMS === 0 || remoteMMS === 0) { maxMessageSize = Math.max(canSendMMS, remoteMMS); } else { maxMessageSize = Math.min(canSendMMS, remoteMMS); From dac3ecf21cd4d49b1afab1a186dedad96ee8bf6c Mon Sep 17 00:00:00 2001 From: Lennart Grahl Date: Sat, 16 Dec 2017 23:01:55 +0100 Subject: [PATCH 19/23] Fix default remote maximum message size (65535 -> 65536) --- src/js/common_shim.js | 8 ++++---- test/e2e/maxMessageSize.js | 12 ++++++------ 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/js/common_shim.js b/src/js/common_shim.js index 160420ab0..0c1920165 100644 --- a/src/js/common_shim.js +++ b/src/js/common_shim.js @@ -204,7 +204,7 @@ module.exports = { // Note: Although Chrome is technically able to send up to 256 KiB, the // data does not reach the other peer reliably. // See: https://bugs.chromium.org/p/webrtc/issues/detail?id=8419 - var canSendMaxMessageSize = 65535; + var canSendMaxMessageSize = 65536; if (browserDetails.browser === 'firefox') { if (browserDetails.version < 57) { if (remoteIsFirefox === -1) { @@ -225,9 +225,9 @@ module.exports = { }; var getMaxMessageSize = function(description, remoteIsFirefox) { - // Note: 65535 bytes is the default value from the SDP spec. Also, - // every implementation we know supports receiving 65535 bytes. - var maxMessageSize = 65535; + // Note: 65536 bytes is the default value from the SDP spec. Also, + // every implementation we know supports receiving 65536 bytes. + var maxMessageSize = 65536; var match = SDPUtils.matchPrefix(description.sdp, 'a=max-message-size:'); if (match.length > 0) { maxMessageSize = parseInt(match[0].substr(19), 10); diff --git a/test/e2e/maxMessageSize.js b/test/e2e/maxMessageSize.js index 141198a9f..b06f4e1dd 100644 --- a/test/e2e/maxMessageSize.js +++ b/test/e2e/maxMessageSize.js @@ -85,8 +85,8 @@ describe('maxMessageSize', () => { .then(() => { expect(pc1.sctp).to.have.property('maxMessageSize'); expect(pc2.sctp).to.have.property('maxMessageSize'); - expect(pc1.sctp.maxMessageSize).to.be.at.least(65535); - expect(pc2.sctp.maxMessageSize).to.be.at.least(65535); + expect(pc1.sctp.maxMessageSize).to.be.at.least(65536); + expect(pc2.sctp.maxMessageSize).to.be.at.least(65536); if (browserDetails.browser === 'firefox') { expect(pc1.sctp.maxMessageSize).to.equal(1073741823); expect(pc2.sctp.maxMessageSize).to.equal(1073741823); @@ -95,8 +95,8 @@ describe('maxMessageSize', () => { }); it('send largest possible single message', () => { - // Note: Patching to 65535 here as anything beyond that will take too long. - const maxMessageSize = 65535; + // Note: Patching to 65536 here as anything beyond that will take too long. + const maxMessageSize = 65536; const patchMaxMessageSize = patchMaxMessageSizeFactory(maxMessageSize); pc1.createDataChannel('test'); @@ -121,9 +121,9 @@ describe('maxMessageSize', () => { describe('throws an exception', () => { it('if the message is too large', () => { - // Note: Patching to 65535 here as anything beyond that will take too + // Note: Patching to 65536 here as anything beyond that will take too // long (including creation of a large array). - const maxMessageSize = 65535; + const maxMessageSize = 65536; const patchMaxMessageSize = patchMaxMessageSizeFactory(maxMessageSize); pc1.createDataChannel('test'); From ded85225d9ea5f571f6031ed100434583e72206f Mon Sep 17 00:00:00 2001 From: Lennart Grahl Date: Thu, 21 Dec 2017 22:39:21 +0100 Subject: [PATCH 20/23] Add test cases for the expected and negotiated maximum message size in various combinations Fix default remote maximum message size for Firefox Fix default remote message size for Firefox 57 Don't apply the 'send' shim to Firefox >= 57 Export commonShim to window.adapter as well --- src/js/adapter_factory.js | 17 +-- src/js/common_shim.js | 38 ++++--- test/e2e/expectations/chrome-beta | 7 ++ .../expectations/chrome-beta-no-experimental | 7 ++ test/e2e/expectations/chrome-stable | 7 ++ .../chrome-stable-no-experimental | 7 ++ test/e2e/expectations/chrome-unstable | 7 ++ test/e2e/expectations/firefox-beta | 7 ++ test/e2e/expectations/firefox-esr | 7 ++ test/e2e/expectations/firefox-nightly | 7 ++ test/e2e/expectations/firefox-stable | 7 ++ test/e2e/maxMessageSize.js | 104 +++++++++++++++++- 12 files changed, 199 insertions(+), 23 deletions(-) diff --git a/src/js/adapter_factory.js b/src/js/adapter_factory.js index 5ba4f8c01..ca6e7162c 100644 --- a/src/js/adapter_factory.js +++ b/src/js/adapter_factory.js @@ -31,14 +31,6 @@ module.exports = function(dependencies, opts) { var logging = utils.log; var browserDetails = utils.detectBrowser(window); - // Export to the adapter global object visible in the browser. - var adapter = { - browserDetails: browserDetails, - extractVersion: utils.extractVersion, - disableLog: utils.disableLog, - disableWarnings: utils.disableWarnings - }; - // Uncomment the line below if you want logging to occur, including logging // for the switch statement below. Can also be turned on in the browser via // adapter.disableLog(false), but then logging from the switch statement below @@ -52,6 +44,15 @@ module.exports = function(dependencies, opts) { var safariShim = require('./safari/safari_shim') || null; var commonShim = require('./common_shim') || null; + // Export to the adapter global object visible in the browser. + var adapter = { + browserDetails: browserDetails, + commonShim: commonShim, + extractVersion: utils.extractVersion, + disableLog: utils.disableLog, + disableWarnings: utils.disableWarnings + }; + // Shim browser if found. switch (browserDetails.browser) { case 'chrome': diff --git a/src/js/common_shim.js b/src/js/common_shim.js index 0c1920165..2984d40d7 100644 --- a/src/js/common_shim.js +++ b/src/js/common_shim.js @@ -199,7 +199,7 @@ module.exports = { return version !== version ? -1 : version; }; - var getCanSendMaxMessageSize = function(description, remoteIsFirefox) { + var getCanSendMaxMessageSize = function(remoteIsFirefox) { // Every implementation we know can send at least 64 KiB. // Note: Although Chrome is technically able to send up to 256 KiB, the // data does not reach the other peer reliably. @@ -213,12 +213,12 @@ module.exports = { canSendMaxMessageSize = 16384; } else { // However, other FF (and RAWRTC) can reassemble PPID-fragmented - // messages. Thus, supporting at least 1 GiB when sending. - canSendMaxMessageSize = 1073741823; + // messages. Thus, supporting ~2 GiB when sending. + canSendMaxMessageSize = 2147483637; } } else { - // FF >= 57 supports up to 1 GiB. - canSendMaxMessageSize = 1073741823; + // FF >= 57 supports sending ~2 GiB. + canSendMaxMessageSize = 2147483637; } } return canSendMaxMessageSize; @@ -228,15 +228,24 @@ module.exports = { // Note: 65536 bytes is the default value from the SDP spec. Also, // every implementation we know supports receiving 65536 bytes. var maxMessageSize = 65536; + + // FF 57 has a slightly incorrect default remote max message size, so + // we need to adjust it here to avoid a failure when sending. + // See: https://bugzilla.mozilla.org/show_bug.cgi?id=1425697 + if (browserDetails.browser === 'firefox' && + browserDetails.version === 57) { + maxMessageSize = 65535; + } + var match = SDPUtils.matchPrefix(description.sdp, 'a=max-message-size:'); if (match.length > 0) { maxMessageSize = parseInt(match[0].substr(19), 10); } else if (browserDetails.browser === 'firefox' && remoteIsFirefox !== -1) { // If the maximum message size is not present in the remote SDP and - // both local and remote are Firefox, the remote peer can receive up - // to 1 GiB. - maxMessageSize = 1073741823; + // both local and remote are Firefox, the remote peer can receive + // ~2 GiB. + maxMessageSize = 2147483637; } return maxMessageSize; }; @@ -252,7 +261,7 @@ module.exports = { var isFirefox = getRemoteFirefoxVersion(arguments[0]); // Get the maximum message size the local peer is capable of sending - var canSendMMS = getCanSendMaxMessageSize(arguments[0], isFirefox); + var canSendMMS = getCanSendMaxMessageSize(isFirefox); // Get the maximum message size of the remote peer. var remoteMMS = getMaxMessageSize(arguments[0], isFirefox); @@ -283,10 +292,13 @@ module.exports = { }, shimSendThrowTypeError: function(window) { - // Note: Firefox 57 has support for this but for consistency, we will also - // apply this patch to FF >= 57. The reason is that FF >= 57 will - // allow sending even more than 1 GiB towards remote peers that are - // FF < 57... which is confusing. So, we're limiting to 1 GiB. + var browserDetails = utils.detectBrowser(window); + + // Only Firefox 57 has support for this atm + if (browserDetails.browser === 'firefox' && browserDetails.version >= 57) { + return; + } + var origCreateDataChannel = window.RTCPeerConnection.prototype.createDataChannel; window.RTCPeerConnection.prototype.createDataChannel = function() { diff --git a/test/e2e/expectations/chrome-beta b/test/e2e/expectations/chrome-beta index afca9866a..b254e6474 100644 --- a/test/e2e/expectations/chrome-beta +++ b/test/e2e/expectations/chrome-beta @@ -39,6 +39,13 @@ PASS maxMessageSize sctp attribute is null if SCTP not negotiated PASS maxMessageSize sctp and maxMessageSize set if SCTP negotiated PASS maxMessageSize send largest possible single message PASS maxMessageSize throws an exception if the message is too large +PASS maxMessageSize is as expected for chrome>=0 and chrome>=0 -> 65536 +PASS maxMessageSize is as expected for chrome>=0 and firefox<=56 -> 65536 +PASS maxMessageSize is as expected for chrome>=0 and firefox>=57 -> 65536 +PASS maxMessageSize is as expected for chrome>=0 and 64 KiB -> 65536 +PASS maxMessageSize is as expected for chrome>=0 and 1.5 GiB -> 65536 +PASS maxMessageSize is as expected for chrome>=0 and 2 GiB -> 65536 +PASS maxMessageSize is as expected for chrome>=0 and Unlimited -> 65536 PASS navigator.mediaDevices exists PASS navigator.mediaDevices is an EventTarget PASS navigator.mediaDevices implements the devicechange event diff --git a/test/e2e/expectations/chrome-beta-no-experimental b/test/e2e/expectations/chrome-beta-no-experimental index 7dfe6cd4c..7d71efe25 100644 --- a/test/e2e/expectations/chrome-beta-no-experimental +++ b/test/e2e/expectations/chrome-beta-no-experimental @@ -39,6 +39,13 @@ PASS maxMessageSize sctp attribute is null if SCTP not negotiated PASS maxMessageSize sctp and maxMessageSize set if SCTP negotiated PASS maxMessageSize send largest possible single message PASS maxMessageSize throws an exception if the message is too large +PASS maxMessageSize is as expected for chrome>=0 and chrome>=0 -> 65536 +PASS maxMessageSize is as expected for chrome>=0 and firefox<=56 -> 65536 +PASS maxMessageSize is as expected for chrome>=0 and firefox>=57 -> 65536 +PASS maxMessageSize is as expected for chrome>=0 and 64 KiB -> 65536 +PASS maxMessageSize is as expected for chrome>=0 and 1.5 GiB -> 65536 +PASS maxMessageSize is as expected for chrome>=0 and 2 GiB -> 65536 +PASS maxMessageSize is as expected for chrome>=0 and Unlimited -> 65536 PASS navigator.mediaDevices exists PASS navigator.mediaDevices is an EventTarget PASS navigator.mediaDevices implements the devicechange event diff --git a/test/e2e/expectations/chrome-stable b/test/e2e/expectations/chrome-stable index afca9866a..b254e6474 100644 --- a/test/e2e/expectations/chrome-stable +++ b/test/e2e/expectations/chrome-stable @@ -39,6 +39,13 @@ PASS maxMessageSize sctp attribute is null if SCTP not negotiated PASS maxMessageSize sctp and maxMessageSize set if SCTP negotiated PASS maxMessageSize send largest possible single message PASS maxMessageSize throws an exception if the message is too large +PASS maxMessageSize is as expected for chrome>=0 and chrome>=0 -> 65536 +PASS maxMessageSize is as expected for chrome>=0 and firefox<=56 -> 65536 +PASS maxMessageSize is as expected for chrome>=0 and firefox>=57 -> 65536 +PASS maxMessageSize is as expected for chrome>=0 and 64 KiB -> 65536 +PASS maxMessageSize is as expected for chrome>=0 and 1.5 GiB -> 65536 +PASS maxMessageSize is as expected for chrome>=0 and 2 GiB -> 65536 +PASS maxMessageSize is as expected for chrome>=0 and Unlimited -> 65536 PASS navigator.mediaDevices exists PASS navigator.mediaDevices is an EventTarget PASS navigator.mediaDevices implements the devicechange event diff --git a/test/e2e/expectations/chrome-stable-no-experimental b/test/e2e/expectations/chrome-stable-no-experimental index 7dfe6cd4c..7d71efe25 100644 --- a/test/e2e/expectations/chrome-stable-no-experimental +++ b/test/e2e/expectations/chrome-stable-no-experimental @@ -39,6 +39,13 @@ PASS maxMessageSize sctp attribute is null if SCTP not negotiated PASS maxMessageSize sctp and maxMessageSize set if SCTP negotiated PASS maxMessageSize send largest possible single message PASS maxMessageSize throws an exception if the message is too large +PASS maxMessageSize is as expected for chrome>=0 and chrome>=0 -> 65536 +PASS maxMessageSize is as expected for chrome>=0 and firefox<=56 -> 65536 +PASS maxMessageSize is as expected for chrome>=0 and firefox>=57 -> 65536 +PASS maxMessageSize is as expected for chrome>=0 and 64 KiB -> 65536 +PASS maxMessageSize is as expected for chrome>=0 and 1.5 GiB -> 65536 +PASS maxMessageSize is as expected for chrome>=0 and 2 GiB -> 65536 +PASS maxMessageSize is as expected for chrome>=0 and Unlimited -> 65536 PASS navigator.mediaDevices exists PASS navigator.mediaDevices is an EventTarget PASS navigator.mediaDevices implements the devicechange event diff --git a/test/e2e/expectations/chrome-unstable b/test/e2e/expectations/chrome-unstable index 778fdfdc1..1b238a81b 100644 --- a/test/e2e/expectations/chrome-unstable +++ b/test/e2e/expectations/chrome-unstable @@ -39,6 +39,13 @@ PASS maxMessageSize sctp attribute is null if SCTP not negotiated PASS maxMessageSize sctp and maxMessageSize set if SCTP negotiated PASS maxMessageSize send largest possible single message PASS maxMessageSize throws an exception if the message is too large +PASS maxMessageSize is as expected for chrome>=0 and chrome>=0 -> 65536 +PASS maxMessageSize is as expected for chrome>=0 and firefox<=56 -> 65536 +PASS maxMessageSize is as expected for chrome>=0 and firefox>=57 -> 65536 +PASS maxMessageSize is as expected for chrome>=0 and 64 KiB -> 65536 +PASS maxMessageSize is as expected for chrome>=0 and 1.5 GiB -> 65536 +PASS maxMessageSize is as expected for chrome>=0 and 2 GiB -> 65536 +PASS maxMessageSize is as expected for chrome>=0 and Unlimited -> 65536 PASS navigator.mediaDevices exists PASS navigator.mediaDevices is an EventTarget PASS navigator.mediaDevices implements the devicechange event diff --git a/test/e2e/expectations/firefox-beta b/test/e2e/expectations/firefox-beta index 0e41794c8..de5e64db9 100644 --- a/test/e2e/expectations/firefox-beta +++ b/test/e2e/expectations/firefox-beta @@ -39,6 +39,13 @@ PASS maxMessageSize sctp attribute is null if SCTP not negotiated PASS maxMessageSize sctp and maxMessageSize set if SCTP negotiated PASS maxMessageSize send largest possible single message PASS maxMessageSize throws an exception if the message is too large +PASS maxMessageSize is as expected for firefox>=57 and firefox<=56 -> 2147483637 +PASS maxMessageSize is as expected for firefox>=57 and firefox>=57 -> 1073741823 +PASS maxMessageSize is as expected for firefox>=57 and 64 KiB -> 65536 +PASS maxMessageSize is as expected for firefox>=57 and 1.5 GiB -> 1610612736 +PASS maxMessageSize is as expected for firefox>=57 and 2 GiB -> 2147483637 +PASS maxMessageSize is as expected for firefox>=57 and Unlimited -> 2147483637 +PASS maxMessageSize is as expected for firefox>=58 and chrome>=0 -> 65536 PASS navigator.mediaDevices exists PASS navigator.mediaDevices is an EventTarget PASS navigator.mediaDevices implements the devicechange event diff --git a/test/e2e/expectations/firefox-esr b/test/e2e/expectations/firefox-esr index 207d79baf..d35f38f2d 100644 --- a/test/e2e/expectations/firefox-esr +++ b/test/e2e/expectations/firefox-esr @@ -39,6 +39,13 @@ PASS maxMessageSize sctp attribute is null if SCTP not negotiated PASS maxMessageSize sctp and maxMessageSize set if SCTP negotiated PASS maxMessageSize send largest possible single message PASS maxMessageSize throws an exception if the message is too large +PASS maxMessageSize is as expected for firefox<=56 and chrome>=0 -> 16384 +PASS maxMessageSize is as expected for firefox<=56 and firefox<=56 -> 2147483637 +PASS maxMessageSize is as expected for firefox<=56 and firefox>=57 -> 1073741823 +PASS maxMessageSize is as expected for firefox<=56 and 64 KiB -> 16384 +PASS maxMessageSize is as expected for firefox<=56 and 1.5 GiB -> 16384 +PASS maxMessageSize is as expected for firefox<=56 and 2 GiB -> 16384 +PASS maxMessageSize is as expected for firefox<=56 and Unlimited -> 16384 PASS navigator.mediaDevices exists PASS navigator.mediaDevices is an EventTarget PASS navigator.mediaDevices implements the devicechange event diff --git a/test/e2e/expectations/firefox-nightly b/test/e2e/expectations/firefox-nightly index 0e41794c8..de5e64db9 100644 --- a/test/e2e/expectations/firefox-nightly +++ b/test/e2e/expectations/firefox-nightly @@ -39,6 +39,13 @@ PASS maxMessageSize sctp attribute is null if SCTP not negotiated PASS maxMessageSize sctp and maxMessageSize set if SCTP negotiated PASS maxMessageSize send largest possible single message PASS maxMessageSize throws an exception if the message is too large +PASS maxMessageSize is as expected for firefox>=57 and firefox<=56 -> 2147483637 +PASS maxMessageSize is as expected for firefox>=57 and firefox>=57 -> 1073741823 +PASS maxMessageSize is as expected for firefox>=57 and 64 KiB -> 65536 +PASS maxMessageSize is as expected for firefox>=57 and 1.5 GiB -> 1610612736 +PASS maxMessageSize is as expected for firefox>=57 and 2 GiB -> 2147483637 +PASS maxMessageSize is as expected for firefox>=57 and Unlimited -> 2147483637 +PASS maxMessageSize is as expected for firefox>=58 and chrome>=0 -> 65536 PASS navigator.mediaDevices exists PASS navigator.mediaDevices is an EventTarget PASS navigator.mediaDevices implements the devicechange event diff --git a/test/e2e/expectations/firefox-stable b/test/e2e/expectations/firefox-stable index 0e41794c8..231ed2bb0 100644 --- a/test/e2e/expectations/firefox-stable +++ b/test/e2e/expectations/firefox-stable @@ -39,6 +39,13 @@ PASS maxMessageSize sctp attribute is null if SCTP not negotiated PASS maxMessageSize sctp and maxMessageSize set if SCTP negotiated PASS maxMessageSize send largest possible single message PASS maxMessageSize throws an exception if the message is too large +PASS maxMessageSize is as expected for firefox==57 and chrome>=0 -> 65535 +PASS maxMessageSize is as expected for firefox>=57 and firefox<=56 -> 2147483637 +PASS maxMessageSize is as expected for firefox>=57 and firefox>=57 -> 1073741823 +PASS maxMessageSize is as expected for firefox>=57 and 64 KiB -> 65536 +PASS maxMessageSize is as expected for firefox>=57 and 1.5 GiB -> 1610612736 +PASS maxMessageSize is as expected for firefox>=57 and 2 GiB -> 2147483637 +PASS maxMessageSize is as expected for firefox>=57 and Unlimited -> 2147483637 PASS navigator.mediaDevices exists PASS navigator.mediaDevices is an EventTarget PASS navigator.mediaDevices implements the devicechange event diff --git a/test/e2e/maxMessageSize.js b/test/e2e/maxMessageSize.js index b06f4e1dd..7e411dd49 100644 --- a/test/e2e/maxMessageSize.js +++ b/test/e2e/maxMessageSize.js @@ -88,8 +88,12 @@ describe('maxMessageSize', () => { expect(pc1.sctp.maxMessageSize).to.be.at.least(65536); expect(pc2.sctp.maxMessageSize).to.be.at.least(65536); if (browserDetails.browser === 'firefox') { - expect(pc1.sctp.maxMessageSize).to.equal(1073741823); - expect(pc2.sctp.maxMessageSize).to.equal(1073741823); + let expectedMMS = 2147483637; + if (browserDetails.version >= 57) { + expectedMMS = 1073741823; + } + expect(pc1.sctp.maxMessageSize).to.equal(expectedMMS); + expect(pc2.sctp.maxMessageSize).to.equal(expectedMMS); } }); }); @@ -146,4 +150,100 @@ describe('maxMessageSize', () => { }); }); }); + + // Note: These run in e2e as a browser is needed for them to run + describe('is as expected for', () => { + const browserDetails = window.adapter.browserDetails; + const fakeWindow = Object.assign({}, window); + fakeWindow.RTCPeerConnection = function() {}; + fakeWindow.RTCPeerConnection.prototype.setRemoteDescription = () => {}; + window.adapter.commonShim.shimMaxMessageSize(fakeWindow); + + // Map specific browser versions to a test case. + // You can use the following version comparators: '<=', '>=' and '=='. + // + // The innermost array contains the other browser's version, the expected + // maximum message size and the offer SDP. + // + // Note: Be aware that you MUST store expected results for both browsers! + /* eslint-disable max-len */ + const testCases = { + 'firefox<=56': [ + ['chrome>=0', 16384, 'v=0\r\no=- 6575128786484314789 2 IN IP4 127.0.0.1\r\ns=-\r\nt=0 0\r\na=group:BUNDLE data\r\na=msid-semantic: WMS\r\nm=application 9 DTLS/SCTP 5000\r\nc=IN IP4 0.0.0.0\r\na=ice-ufrag:oZF1\r\na=ice-pwd:8+qEgoDOiFd49nDG9oNSYYaz\r\na=ice-options:trickle\r\na=fingerprint:sha-256 F2:01:D6:88:9E:0C:F1:CE:EE:85:9C:B4:A5:B7:36:D4:CB:29:F2:4F:E0:97:81:25:34:00:71:65:2B:39:C1:C1\r\na=setup:actpass\r\na=mid:data\r\na=sctpmap:5000 webrtc-datachannel 1024\r\n'], + ['firefox<=56', 2147483637, 'v=0\r\no=mozilla...THIS_IS_SDPARTA-56.0.2 3250009914871290350 0 IN IP4 0.0.0.0\r\ns=-\r\nt=0 0\r\na=fingerprint:sha-256 C8:36:D3:FD:E6:9A:B8:4E:7C:FB:61:03:22:E5:8E:E1:7D:17:AF:D2:EB:0F:87:BA:28:6C:9A:2E:76:D9:B3:0C\r\na=group:BUNDLE sdparta_0\r\na=ice-options:trickle\r\na=msid-semantic:WMS *\r\nm=application 9 DTLS/SCTP 5000\r\nc=IN IP4 0.0.0.0\r\na=sendrecv\r\na=ice-pwd:bb3ee909b8452eb93722d223b26d6193\r\na=ice-ufrag:1c03e3ae\r\na=mid:sdparta_0\r\na=sctpmap:5000 webrtc-datachannel 256\r\na=setup:actpass\r\n'], + ['firefox>=57', 1073741823, 'v=0\r\no=mozilla...THIS_IS_SDPARTA-57.0 169150732617742973 0 IN IP4 0.0.0.0\r\ns=-\r\nt=0 0\r\na=fingerprint:sha-256 8C:EB:14:5C:60:1E:E8:1E:FA:C7:D8:90:38:E9:EB:05:A8:2B:32:9F:FE:2B:D9:1C:85:3D:59:70:A9:6D:3A:17\r\na=group:BUNDLE sdparta_0\r\na=ice-options:trickle\r\na=msid-semantic:WMS *\r\nm=application 9 DTLS/SCTP 5000\r\nc=IN IP4 0.0.0.0\r\na=sendrecv\r\na=ice-pwd:c224ece79b15dcb92de87e2b67e62d7a\r\na=ice-ufrag:96c030e8\r\na=mid:sdparta_0\r\na=sctpmap:5000 webrtc-datachannel 256\r\na=setup:actpass\r\na=max-message-size:1073741823\r\n'], + ['64 KiB', 16384, 'v=0\r\no=- 6575128786484314789 2 IN IP4 127.0.0.1\r\ns=-\r\nt=0 0\r\na=group:BUNDLE data\r\na=msid-semantic: WMS\r\nm=application 9 DTLS/SCTP 5000\r\nc=IN IP4 0.0.0.0\r\na=ice-ufrag:oZF1\r\na=ice-pwd:8+qEgoDOiFd49nDG9oNSYYaz\r\na=ice-options:trickle\r\na=fingerprint:sha-256 F2:01:D6:88:9E:0C:F1:CE:EE:85:9C:B4:A5:B7:36:D4:CB:29:F2:4F:E0:97:81:25:34:00:71:65:2B:39:C1:C1\r\na=setup:actpass\r\na=mid:data\r\na=sctpmap:5000 webrtc-datachannel 1024\r\na=max-message-size:65536\r\n'], + ['1.5 GiB', 16384, 'v=0\r\no=1.5 GiB 169150732617742973 0 IN IP4 0.0.0.0\r\ns=-\r\nt=0 0\r\na=fingerprint:sha-256 8C:EB:14:5C:60:1E:E8:1E:FA:C7:D8:90:38:E9:EB:05:A8:2B:32:9F:FE:2B:D9:1C:85:3D:59:70:A9:6D:3A:17\r\na=group:BUNDLE sdparta_0\r\na=ice-options:trickle\r\na=msid-semantic:WMS *\r\nm=application 9 DTLS/SCTP 5000\r\nc=IN IP4 0.0.0.0\r\na=sendrecv\r\na=ice-pwd:c224ece79b15dcb92de87e2b67e62d7a\r\na=ice-ufrag:96c030e8\r\na=mid:sdparta_0\r\na=sctpmap:5000 webrtc-datachannel 256\r\na=setup:actpass\r\na=max-message-size:1610612736\r\n'], + ['2 GiB', 16384, 'v=0\r\no=2 GiB 169150732617742973 0 IN IP4 0.0.0.0\r\ns=-\r\nt=0 0\r\na=fingerprint:sha-256 8C:EB:14:5C:60:1E:E8:1E:FA:C7:D8:90:38:E9:EB:05:A8:2B:32:9F:FE:2B:D9:1C:85:3D:59:70:A9:6D:3A:17\r\na=group:BUNDLE sdparta_0\r\na=ice-options:trickle\r\na=msid-semantic:WMS *\r\nm=application 9 DTLS/SCTP 5000\r\nc=IN IP4 0.0.0.0\r\na=sendrecv\r\na=ice-pwd:c224ece79b15dcb92de87e2b67e62d7a\r\na=ice-ufrag:96c030e8\r\na=mid:sdparta_0\r\na=sctpmap:5000 webrtc-datachannel 256\r\na=setup:actpass\r\na=max-message-size:2147483648\r\n'], + ['Unlimited', 16384, 'v=0\r\no=Unlimited 169150732617742973 0 IN IP4 0.0.0.0\r\ns=-\r\nt=0 0\r\na=fingerprint:sha-256 8C:EB:14:5C:60:1E:E8:1E:FA:C7:D8:90:38:E9:EB:05:A8:2B:32:9F:FE:2B:D9:1C:85:3D:59:70:A9:6D:3A:17\r\na=group:BUNDLE sdparta_0\r\na=ice-options:trickle\r\na=msid-semantic:WMS *\r\nm=application 9 DTLS/SCTP 5000\r\nc=IN IP4 0.0.0.0\r\na=sendrecv\r\na=ice-pwd:c224ece79b15dcb92de87e2b67e62d7a\r\na=ice-ufrag:96c030e8\r\na=mid:sdparta_0\r\na=sctpmap:5000 webrtc-datachannel 256\r\na=setup:actpass\r\na=max-message-size:0\r\n'], + ], + 'firefox==57': [ + ['chrome>=0', 65535, 'v=0\r\no=- 6575128786484314789 2 IN IP4 127.0.0.1\r\ns=-\r\nt=0 0\r\na=group:BUNDLE data\r\na=msid-semantic: WMS\r\nm=application 9 DTLS/SCTP 5000\r\nc=IN IP4 0.0.0.0\r\na=ice-ufrag:oZF1\r\na=ice-pwd:8+qEgoDOiFd49nDG9oNSYYaz\r\na=ice-options:trickle\r\na=fingerprint:sha-256 F2:01:D6:88:9E:0C:F1:CE:EE:85:9C:B4:A5:B7:36:D4:CB:29:F2:4F:E0:97:81:25:34:00:71:65:2B:39:C1:C1\r\na=setup:actpass\r\na=mid:data\r\na=sctpmap:5000 webrtc-datachannel 1024\r\n'], + ], + 'firefox>=57': [ + ['firefox<=56', 2147483637, 'v=0\r\no=mozilla...THIS_IS_SDPARTA-56.0.2 3250009914871290350 0 IN IP4 0.0.0.0\r\ns=-\r\nt=0 0\r\na=fingerprint:sha-256 C8:36:D3:FD:E6:9A:B8:4E:7C:FB:61:03:22:E5:8E:E1:7D:17:AF:D2:EB:0F:87:BA:28:6C:9A:2E:76:D9:B3:0C\r\na=group:BUNDLE sdparta_0\r\na=ice-options:trickle\r\na=msid-semantic:WMS *\r\nm=application 9 DTLS/SCTP 5000\r\nc=IN IP4 0.0.0.0\r\na=sendrecv\r\na=ice-pwd:bb3ee909b8452eb93722d223b26d6193\r\na=ice-ufrag:1c03e3ae\r\na=mid:sdparta_0\r\na=sctpmap:5000 webrtc-datachannel 256\r\na=setup:actpass\r\n'], + ['firefox>=57', 1073741823, 'v=0\r\no=mozilla...THIS_IS_SDPARTA-57.0 169150732617742973 0 IN IP4 0.0.0.0\r\ns=-\r\nt=0 0\r\na=fingerprint:sha-256 8C:EB:14:5C:60:1E:E8:1E:FA:C7:D8:90:38:E9:EB:05:A8:2B:32:9F:FE:2B:D9:1C:85:3D:59:70:A9:6D:3A:17\r\na=group:BUNDLE sdparta_0\r\na=ice-options:trickle\r\na=msid-semantic:WMS *\r\nm=application 9 DTLS/SCTP 5000\r\nc=IN IP4 0.0.0.0\r\na=sendrecv\r\na=ice-pwd:c224ece79b15dcb92de87e2b67e62d7a\r\na=ice-ufrag:96c030e8\r\na=mid:sdparta_0\r\na=sctpmap:5000 webrtc-datachannel 256\r\na=setup:actpass\r\na=max-message-size:1073741823\r\n'], + ['64 KiB', 65536, 'v=0\r\no=- 6575128786484314789 2 IN IP4 127.0.0.1\r\ns=-\r\nt=0 0\r\na=group:BUNDLE data\r\na=msid-semantic: WMS\r\nm=application 9 DTLS/SCTP 5000\r\nc=IN IP4 0.0.0.0\r\na=ice-ufrag:oZF1\r\na=ice-pwd:8+qEgoDOiFd49nDG9oNSYYaz\r\na=ice-options:trickle\r\na=fingerprint:sha-256 F2:01:D6:88:9E:0C:F1:CE:EE:85:9C:B4:A5:B7:36:D4:CB:29:F2:4F:E0:97:81:25:34:00:71:65:2B:39:C1:C1\r\na=setup:actpass\r\na=mid:data\r\na=sctpmap:5000 webrtc-datachannel 1024\r\na=max-message-size:65536\r\n'], + ['1.5 GiB', 1610612736, 'v=0\r\no=1.5 GiB 169150732617742973 0 IN IP4 0.0.0.0\r\ns=-\r\nt=0 0\r\na=fingerprint:sha-256 8C:EB:14:5C:60:1E:E8:1E:FA:C7:D8:90:38:E9:EB:05:A8:2B:32:9F:FE:2B:D9:1C:85:3D:59:70:A9:6D:3A:17\r\na=group:BUNDLE sdparta_0\r\na=ice-options:trickle\r\na=msid-semantic:WMS *\r\nm=application 9 DTLS/SCTP 5000\r\nc=IN IP4 0.0.0.0\r\na=sendrecv\r\na=ice-pwd:c224ece79b15dcb92de87e2b67e62d7a\r\na=ice-ufrag:96c030e8\r\na=mid:sdparta_0\r\na=sctpmap:5000 webrtc-datachannel 256\r\na=setup:actpass\r\na=max-message-size:1610612736\r\n'], + ['2 GiB', 2147483637, 'v=0\r\no=2 GiB 169150732617742973 0 IN IP4 0.0.0.0\r\ns=-\r\nt=0 0\r\na=fingerprint:sha-256 8C:EB:14:5C:60:1E:E8:1E:FA:C7:D8:90:38:E9:EB:05:A8:2B:32:9F:FE:2B:D9:1C:85:3D:59:70:A9:6D:3A:17\r\na=group:BUNDLE sdparta_0\r\na=ice-options:trickle\r\na=msid-semantic:WMS *\r\nm=application 9 DTLS/SCTP 5000\r\nc=IN IP4 0.0.0.0\r\na=sendrecv\r\na=ice-pwd:c224ece79b15dcb92de87e2b67e62d7a\r\na=ice-ufrag:96c030e8\r\na=mid:sdparta_0\r\na=sctpmap:5000 webrtc-datachannel 256\r\na=setup:actpass\r\na=max-message-size:2147483648\r\n'], + ['Unlimited', 2147483637, 'v=0\r\no=Unlimited 169150732617742973 0 IN IP4 0.0.0.0\r\ns=-\r\nt=0 0\r\na=fingerprint:sha-256 8C:EB:14:5C:60:1E:E8:1E:FA:C7:D8:90:38:E9:EB:05:A8:2B:32:9F:FE:2B:D9:1C:85:3D:59:70:A9:6D:3A:17\r\na=group:BUNDLE sdparta_0\r\na=ice-options:trickle\r\na=msid-semantic:WMS *\r\nm=application 9 DTLS/SCTP 5000\r\nc=IN IP4 0.0.0.0\r\na=sendrecv\r\na=ice-pwd:c224ece79b15dcb92de87e2b67e62d7a\r\na=ice-ufrag:96c030e8\r\na=mid:sdparta_0\r\na=sctpmap:5000 webrtc-datachannel 256\r\na=setup:actpass\r\na=max-message-size:0\r\n'], + ], + 'firefox>=58': [ + ['chrome>=0', 65536, 'v=0\r\no=- 6575128786484314789 2 IN IP4 127.0.0.1\r\ns=-\r\nt=0 0\r\na=group:BUNDLE data\r\na=msid-semantic: WMS\r\nm=application 9 DTLS/SCTP 5000\r\nc=IN IP4 0.0.0.0\r\na=ice-ufrag:oZF1\r\na=ice-pwd:8+qEgoDOiFd49nDG9oNSYYaz\r\na=ice-options:trickle\r\na=fingerprint:sha-256 F2:01:D6:88:9E:0C:F1:CE:EE:85:9C:B4:A5:B7:36:D4:CB:29:F2:4F:E0:97:81:25:34:00:71:65:2B:39:C1:C1\r\na=setup:actpass\r\na=mid:data\r\na=sctpmap:5000 webrtc-datachannel 1024\r\n'], + ], + 'chrome>=0': [ + ['chrome>=0', 65536, 'v=0\r\no=- 6575128786484314789 2 IN IP4 127.0.0.1\r\ns=-\r\nt=0 0\r\na=group:BUNDLE data\r\na=msid-semantic: WMS\r\nm=application 9 DTLS/SCTP 5000\r\nc=IN IP4 0.0.0.0\r\na=ice-ufrag:oZF1\r\na=ice-pwd:8+qEgoDOiFd49nDG9oNSYYaz\r\na=ice-options:trickle\r\na=fingerprint:sha-256 F2:01:D6:88:9E:0C:F1:CE:EE:85:9C:B4:A5:B7:36:D4:CB:29:F2:4F:E0:97:81:25:34:00:71:65:2B:39:C1:C1\r\na=setup:actpass\r\na=mid:data\r\na=sctpmap:5000 webrtc-datachannel 1024\r\n'], + ['firefox<=56', 65536, 'v=0\r\no=mozilla...THIS_IS_SDPARTA-56.0.2 3250009914871290350 0 IN IP4 0.0.0.0\r\ns=-\r\nt=0 0\r\na=fingerprint:sha-256 C8:36:D3:FD:E6:9A:B8:4E:7C:FB:61:03:22:E5:8E:E1:7D:17:AF:D2:EB:0F:87:BA:28:6C:9A:2E:76:D9:B3:0C\r\na=group:BUNDLE sdparta_0\r\na=ice-options:trickle\r\na=msid-semantic:WMS *\r\nm=application 9 DTLS/SCTP 5000\r\nc=IN IP4 0.0.0.0\r\na=sendrecv\r\na=ice-pwd:bb3ee909b8452eb93722d223b26d6193\r\na=ice-ufrag:1c03e3ae\r\na=mid:sdparta_0\r\na=sctpmap:5000 webrtc-datachannel 256\r\na=setup:actpass\r\n'], + ['firefox>=57', 65536, 'v=0\r\no=mozilla...THIS_IS_SDPARTA-57.0 169150732617742973 0 IN IP4 0.0.0.0\r\ns=-\r\nt=0 0\r\na=fingerprint:sha-256 8C:EB:14:5C:60:1E:E8:1E:FA:C7:D8:90:38:E9:EB:05:A8:2B:32:9F:FE:2B:D9:1C:85:3D:59:70:A9:6D:3A:17\r\na=group:BUNDLE sdparta_0\r\na=ice-options:trickle\r\na=msid-semantic:WMS *\r\nm=application 9 DTLS/SCTP 5000\r\nc=IN IP4 0.0.0.0\r\na=sendrecv\r\na=ice-pwd:c224ece79b15dcb92de87e2b67e62d7a\r\na=ice-ufrag:96c030e8\r\na=mid:sdparta_0\r\na=sctpmap:5000 webrtc-datachannel 256\r\na=setup:actpass\r\na=max-message-size:1073741823\r\n'], + ['64 KiB', 65536, 'v=0\r\no=- 6575128786484314789 2 IN IP4 127.0.0.1\r\ns=-\r\nt=0 0\r\na=group:BUNDLE data\r\na=msid-semantic: WMS\r\nm=application 9 DTLS/SCTP 5000\r\nc=IN IP4 0.0.0.0\r\na=ice-ufrag:oZF1\r\na=ice-pwd:8+qEgoDOiFd49nDG9oNSYYaz\r\na=ice-options:trickle\r\na=fingerprint:sha-256 F2:01:D6:88:9E:0C:F1:CE:EE:85:9C:B4:A5:B7:36:D4:CB:29:F2:4F:E0:97:81:25:34:00:71:65:2B:39:C1:C1\r\na=setup:actpass\r\na=mid:data\r\na=sctpmap:5000 webrtc-datachannel 1024\r\na=max-message-size:65536\r\n'], + ['1.5 GiB', 65536, 'v=0\r\no=1.5 GiB 169150732617742973 0 IN IP4 0.0.0.0\r\ns=-\r\nt=0 0\r\na=fingerprint:sha-256 8C:EB:14:5C:60:1E:E8:1E:FA:C7:D8:90:38:E9:EB:05:A8:2B:32:9F:FE:2B:D9:1C:85:3D:59:70:A9:6D:3A:17\r\na=group:BUNDLE sdparta_0\r\na=ice-options:trickle\r\na=msid-semantic:WMS *\r\nm=application 9 DTLS/SCTP 5000\r\nc=IN IP4 0.0.0.0\r\na=sendrecv\r\na=ice-pwd:c224ece79b15dcb92de87e2b67e62d7a\r\na=ice-ufrag:96c030e8\r\na=mid:sdparta_0\r\na=sctpmap:5000 webrtc-datachannel 256\r\na=setup:actpass\r\na=max-message-size:1610612736\r\n'], + ['2 GiB', 65536, 'v=0\r\no=2 GiB 169150732617742973 0 IN IP4 0.0.0.0\r\ns=-\r\nt=0 0\r\na=fingerprint:sha-256 8C:EB:14:5C:60:1E:E8:1E:FA:C7:D8:90:38:E9:EB:05:A8:2B:32:9F:FE:2B:D9:1C:85:3D:59:70:A9:6D:3A:17\r\na=group:BUNDLE sdparta_0\r\na=ice-options:trickle\r\na=msid-semantic:WMS *\r\nm=application 9 DTLS/SCTP 5000\r\nc=IN IP4 0.0.0.0\r\na=sendrecv\r\na=ice-pwd:c224ece79b15dcb92de87e2b67e62d7a\r\na=ice-ufrag:96c030e8\r\na=mid:sdparta_0\r\na=sctpmap:5000 webrtc-datachannel 256\r\na=setup:actpass\r\na=max-message-size:2147483648\r\n'], + ['Unlimited', 65536, 'v=0\r\no=Unlimited 169150732617742973 0 IN IP4 0.0.0.0\r\ns=-\r\nt=0 0\r\na=fingerprint:sha-256 8C:EB:14:5C:60:1E:E8:1E:FA:C7:D8:90:38:E9:EB:05:A8:2B:32:9F:FE:2B:D9:1C:85:3D:59:70:A9:6D:3A:17\r\na=group:BUNDLE sdparta_0\r\na=ice-options:trickle\r\na=msid-semantic:WMS *\r\nm=application 9 DTLS/SCTP 5000\r\nc=IN IP4 0.0.0.0\r\na=sendrecv\r\na=ice-pwd:c224ece79b15dcb92de87e2b67e62d7a\r\na=ice-ufrag:96c030e8\r\na=mid:sdparta_0\r\na=sctpmap:5000 webrtc-datachannel 256\r\na=setup:actpass\r\na=max-message-size:0\r\n'], + ], + // TODO: Safari test cases! + }; + /* eslint-enable max-len */ + + const matchesVersion = ((comparator, left, right) => { + switch (comparator) { + case '==': return left === right; + case '<=': return left <= right; + case '>=': return left >= right; + default: throw 'Invalid comparator: ' + comparator; + } + }); + + const matchesBrowser = (browserVersion, browserDetails_) => { + return ['==', '<=', '>='].some((comparator) => { + if (browserVersion.indexOf(comparator) !== -1) { + let [browser, version] = browserVersion.split(comparator); + version = parseInt(version, 10); + return browser === browserDetails_.browser + && matchesVersion(comparator, browserDetails_.version, version); + } + return false; + }); + }; + + Object.keys(testCases) + .filter((browserVersion) => { + return matchesBrowser(browserVersion, browserDetails); + }) + .forEach((browserVersion) => { + testCases[browserVersion].forEach((testCase) => { + const [otherVersion, expectedMMS, sdp] = testCase; + const description = browserVersion + ' and ' + otherVersion + + ' -> ' + expectedMMS; + it(description, () => { + // Check if adapter determines the expected maximum message size + const pc = new fakeWindow.RTCPeerConnection(); + pc.setRemoteDescription({ + type: 'offer', + sdp: sdp + }); + expect(pc.sctp.maxMessageSize).to.equal(expectedMMS); + }); + }); + }); + }); }); From 9aa3d155681dea4e86b17e8eede06c76af9c7c97 Mon Sep 17 00:00:00 2001 From: Lennart Grahl Date: Fri, 22 Dec 2017 14:36:54 +0100 Subject: [PATCH 21/23] Re-enable the send shim for Firefox >= 57 Add a MMS test for subsequent data channels The send shim has been re-enabled for Firefox >= 57 due to the following bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1426831 --- src/js/common_shim.js | 9 +++------ test/e2e/maxMessageSize.js | 27 +++++++++++++++++++++++++++ 2 files changed, 30 insertions(+), 6 deletions(-) diff --git a/src/js/common_shim.js b/src/js/common_shim.js index 2984d40d7..710d2b841 100644 --- a/src/js/common_shim.js +++ b/src/js/common_shim.js @@ -292,12 +292,9 @@ module.exports = { }, shimSendThrowTypeError: function(window) { - var browserDetails = utils.detectBrowser(window); - - // Only Firefox 57 has support for this atm - if (browserDetails.browser === 'firefox' && browserDetails.version >= 57) { - return; - } + // Note: Although Firefox >= 57 has a native implementation, the maximum + // message size is not applied correctly to all data channels. + // See: https://bugzilla.mozilla.org/show_bug.cgi?id=1426831 var origCreateDataChannel = window.RTCPeerConnection.prototype.createDataChannel; diff --git a/test/e2e/maxMessageSize.js b/test/e2e/maxMessageSize.js index 7e411dd49..77f957664 100644 --- a/test/e2e/maxMessageSize.js +++ b/test/e2e/maxMessageSize.js @@ -130,6 +130,33 @@ describe('maxMessageSize', () => { const maxMessageSize = 65536; const patchMaxMessageSize = patchMaxMessageSizeFactory(maxMessageSize); + const dc = pc1.createDataChannel('test'); + return negotiate(pc1, pc2, patchMaxMessageSize) + .then(() => { + expect(pc1.sctp.maxMessageSize).to.equal(maxMessageSize); + expect(pc2.sctp.maxMessageSize).to.equal(maxMessageSize); + + // Ensure TypeError is thrown when sending a message that's too large + return new Promise((resolve, reject) => { + const send = () => { + dc.send(new Uint8Array(maxMessageSize + 1)); + }; + dc.onopen = () => { + expect(send).to.throw().with.property('name', 'TypeError'); + resolve(); + }; + }); + }); + }); + + it('if the message is too large (using a secondary data channel)', () => { + // Background of this test: + // https://bugzilla.mozilla.org/show_bug.cgi?id=1426831 + // Note: Patching to 65536 here as anything beyond that will take too + // long (including creation of a large array). + const maxMessageSize = 65536; + const patchMaxMessageSize = patchMaxMessageSizeFactory(maxMessageSize); + pc1.createDataChannel('test'); return negotiate(pc1, pc2, patchMaxMessageSize) .then(() => { From 6aea672920240d18d583aef9d6acbc236b6c78ef Mon Sep 17 00:00:00 2001 From: Lennart Grahl Date: Fri, 22 Dec 2017 14:44:41 +0100 Subject: [PATCH 22/23] Update e2e test expectations --- test/e2e/expectations/chrome-beta | 1 + test/e2e/expectations/chrome-beta-no-experimental | 1 + test/e2e/expectations/chrome-stable | 1 + test/e2e/expectations/chrome-stable-no-experimental | 1 + test/e2e/expectations/chrome-unstable | 1 + test/e2e/expectations/firefox-beta | 1 + test/e2e/expectations/firefox-esr | 1 + test/e2e/expectations/firefox-nightly | 1 + test/e2e/expectations/firefox-stable | 1 + 9 files changed, 9 insertions(+) diff --git a/test/e2e/expectations/chrome-beta b/test/e2e/expectations/chrome-beta index b254e6474..9d537a9a9 100644 --- a/test/e2e/expectations/chrome-beta +++ b/test/e2e/expectations/chrome-beta @@ -39,6 +39,7 @@ PASS maxMessageSize sctp attribute is null if SCTP not negotiated PASS maxMessageSize sctp and maxMessageSize set if SCTP negotiated PASS maxMessageSize send largest possible single message PASS maxMessageSize throws an exception if the message is too large +PASS maxMessageSize throws an exception if the message is too large (using a secondary data channel) PASS maxMessageSize is as expected for chrome>=0 and chrome>=0 -> 65536 PASS maxMessageSize is as expected for chrome>=0 and firefox<=56 -> 65536 PASS maxMessageSize is as expected for chrome>=0 and firefox>=57 -> 65536 diff --git a/test/e2e/expectations/chrome-beta-no-experimental b/test/e2e/expectations/chrome-beta-no-experimental index 7d71efe25..c0264ae8a 100644 --- a/test/e2e/expectations/chrome-beta-no-experimental +++ b/test/e2e/expectations/chrome-beta-no-experimental @@ -39,6 +39,7 @@ PASS maxMessageSize sctp attribute is null if SCTP not negotiated PASS maxMessageSize sctp and maxMessageSize set if SCTP negotiated PASS maxMessageSize send largest possible single message PASS maxMessageSize throws an exception if the message is too large +PASS maxMessageSize throws an exception if the message is too large (using a secondary data channel) PASS maxMessageSize is as expected for chrome>=0 and chrome>=0 -> 65536 PASS maxMessageSize is as expected for chrome>=0 and firefox<=56 -> 65536 PASS maxMessageSize is as expected for chrome>=0 and firefox>=57 -> 65536 diff --git a/test/e2e/expectations/chrome-stable b/test/e2e/expectations/chrome-stable index b254e6474..9d537a9a9 100644 --- a/test/e2e/expectations/chrome-stable +++ b/test/e2e/expectations/chrome-stable @@ -39,6 +39,7 @@ PASS maxMessageSize sctp attribute is null if SCTP not negotiated PASS maxMessageSize sctp and maxMessageSize set if SCTP negotiated PASS maxMessageSize send largest possible single message PASS maxMessageSize throws an exception if the message is too large +PASS maxMessageSize throws an exception if the message is too large (using a secondary data channel) PASS maxMessageSize is as expected for chrome>=0 and chrome>=0 -> 65536 PASS maxMessageSize is as expected for chrome>=0 and firefox<=56 -> 65536 PASS maxMessageSize is as expected for chrome>=0 and firefox>=57 -> 65536 diff --git a/test/e2e/expectations/chrome-stable-no-experimental b/test/e2e/expectations/chrome-stable-no-experimental index 7d71efe25..c0264ae8a 100644 --- a/test/e2e/expectations/chrome-stable-no-experimental +++ b/test/e2e/expectations/chrome-stable-no-experimental @@ -39,6 +39,7 @@ PASS maxMessageSize sctp attribute is null if SCTP not negotiated PASS maxMessageSize sctp and maxMessageSize set if SCTP negotiated PASS maxMessageSize send largest possible single message PASS maxMessageSize throws an exception if the message is too large +PASS maxMessageSize throws an exception if the message is too large (using a secondary data channel) PASS maxMessageSize is as expected for chrome>=0 and chrome>=0 -> 65536 PASS maxMessageSize is as expected for chrome>=0 and firefox<=56 -> 65536 PASS maxMessageSize is as expected for chrome>=0 and firefox>=57 -> 65536 diff --git a/test/e2e/expectations/chrome-unstable b/test/e2e/expectations/chrome-unstable index 1b238a81b..796b7c9a5 100644 --- a/test/e2e/expectations/chrome-unstable +++ b/test/e2e/expectations/chrome-unstable @@ -39,6 +39,7 @@ PASS maxMessageSize sctp attribute is null if SCTP not negotiated PASS maxMessageSize sctp and maxMessageSize set if SCTP negotiated PASS maxMessageSize send largest possible single message PASS maxMessageSize throws an exception if the message is too large +PASS maxMessageSize throws an exception if the message is too large (using a secondary data channel) PASS maxMessageSize is as expected for chrome>=0 and chrome>=0 -> 65536 PASS maxMessageSize is as expected for chrome>=0 and firefox<=56 -> 65536 PASS maxMessageSize is as expected for chrome>=0 and firefox>=57 -> 65536 diff --git a/test/e2e/expectations/firefox-beta b/test/e2e/expectations/firefox-beta index de5e64db9..8a08df6fc 100644 --- a/test/e2e/expectations/firefox-beta +++ b/test/e2e/expectations/firefox-beta @@ -39,6 +39,7 @@ PASS maxMessageSize sctp attribute is null if SCTP not negotiated PASS maxMessageSize sctp and maxMessageSize set if SCTP negotiated PASS maxMessageSize send largest possible single message PASS maxMessageSize throws an exception if the message is too large +PASS maxMessageSize throws an exception if the message is too large (using a secondary data channel) PASS maxMessageSize is as expected for firefox>=57 and firefox<=56 -> 2147483637 PASS maxMessageSize is as expected for firefox>=57 and firefox>=57 -> 1073741823 PASS maxMessageSize is as expected for firefox>=57 and 64 KiB -> 65536 diff --git a/test/e2e/expectations/firefox-esr b/test/e2e/expectations/firefox-esr index d35f38f2d..a50a8e8e8 100644 --- a/test/e2e/expectations/firefox-esr +++ b/test/e2e/expectations/firefox-esr @@ -39,6 +39,7 @@ PASS maxMessageSize sctp attribute is null if SCTP not negotiated PASS maxMessageSize sctp and maxMessageSize set if SCTP negotiated PASS maxMessageSize send largest possible single message PASS maxMessageSize throws an exception if the message is too large +PASS maxMessageSize throws an exception if the message is too large (using a secondary data channel) PASS maxMessageSize is as expected for firefox<=56 and chrome>=0 -> 16384 PASS maxMessageSize is as expected for firefox<=56 and firefox<=56 -> 2147483637 PASS maxMessageSize is as expected for firefox<=56 and firefox>=57 -> 1073741823 diff --git a/test/e2e/expectations/firefox-nightly b/test/e2e/expectations/firefox-nightly index de5e64db9..8a08df6fc 100644 --- a/test/e2e/expectations/firefox-nightly +++ b/test/e2e/expectations/firefox-nightly @@ -39,6 +39,7 @@ PASS maxMessageSize sctp attribute is null if SCTP not negotiated PASS maxMessageSize sctp and maxMessageSize set if SCTP negotiated PASS maxMessageSize send largest possible single message PASS maxMessageSize throws an exception if the message is too large +PASS maxMessageSize throws an exception if the message is too large (using a secondary data channel) PASS maxMessageSize is as expected for firefox>=57 and firefox<=56 -> 2147483637 PASS maxMessageSize is as expected for firefox>=57 and firefox>=57 -> 1073741823 PASS maxMessageSize is as expected for firefox>=57 and 64 KiB -> 65536 diff --git a/test/e2e/expectations/firefox-stable b/test/e2e/expectations/firefox-stable index 231ed2bb0..7557fa730 100644 --- a/test/e2e/expectations/firefox-stable +++ b/test/e2e/expectations/firefox-stable @@ -39,6 +39,7 @@ PASS maxMessageSize sctp attribute is null if SCTP not negotiated PASS maxMessageSize sctp and maxMessageSize set if SCTP negotiated PASS maxMessageSize send largest possible single message PASS maxMessageSize throws an exception if the message is too large +PASS maxMessageSize throws an exception if the message is too large (using a secondary data channel) PASS maxMessageSize is as expected for firefox==57 and chrome>=0 -> 65535 PASS maxMessageSize is as expected for firefox>=57 and firefox<=56 -> 2147483637 PASS maxMessageSize is as expected for firefox>=57 and firefox>=57 -> 1073741823 From 359e6df3c1bb098c9f14f3a4a2a089c158fde27c Mon Sep 17 00:00:00 2001 From: Lennart Grahl Date: Sat, 23 Dec 2017 12:36:18 +0100 Subject: [PATCH 23/23] Add workaround for https://bugzilla.mozilla.org/show_bug.cgi?id=1426831 Update expected MMS for FF >= 57 --- src/js/common_shim.js | 14 ++++--- test/e2e/expectations/firefox-beta | 12 +++--- test/e2e/expectations/firefox-nightly | 12 +++--- test/e2e/expectations/firefox-stable | 12 +++--- test/e2e/maxMessageSize.js | 57 +++++++++++++-------------- 5 files changed, 55 insertions(+), 52 deletions(-) diff --git a/src/js/common_shim.js b/src/js/common_shim.js index 710d2b841..c164060ef 100644 --- a/src/js/common_shim.js +++ b/src/js/common_shim.js @@ -217,8 +217,12 @@ module.exports = { canSendMaxMessageSize = 2147483637; } } else { - // FF >= 57 supports sending ~2 GiB. - canSendMaxMessageSize = 2147483637; + // Currently, all FF >= 57 will reset the remote maximum message size + // to the default value when a data channel is created at a later + // stage. :( + // See: https://bugzilla.mozilla.org/show_bug.cgi?id=1426831 + canSendMaxMessageSize = + browserDetails.version === 57 ? 65535 : 65536; } } return canSendMaxMessageSize; @@ -232,8 +236,8 @@ module.exports = { // FF 57 has a slightly incorrect default remote max message size, so // we need to adjust it here to avoid a failure when sending. // See: https://bugzilla.mozilla.org/show_bug.cgi?id=1425697 - if (browserDetails.browser === 'firefox' && - browserDetails.version === 57) { + if (browserDetails.browser === 'firefox' + && browserDetails.version === 57) { maxMessageSize = 65535; } @@ -293,7 +297,7 @@ module.exports = { shimSendThrowTypeError: function(window) { // Note: Although Firefox >= 57 has a native implementation, the maximum - // message size is not applied correctly to all data channels. + // message size can be reset for all data channels at a later stage. // See: https://bugzilla.mozilla.org/show_bug.cgi?id=1426831 var origCreateDataChannel = diff --git a/test/e2e/expectations/firefox-beta b/test/e2e/expectations/firefox-beta index 8a08df6fc..0beb010fd 100644 --- a/test/e2e/expectations/firefox-beta +++ b/test/e2e/expectations/firefox-beta @@ -40,13 +40,13 @@ PASS maxMessageSize sctp and maxMessageSize set if SCTP negotiated PASS maxMessageSize send largest possible single message PASS maxMessageSize throws an exception if the message is too large PASS maxMessageSize throws an exception if the message is too large (using a secondary data channel) -PASS maxMessageSize is as expected for firefox>=57 and firefox<=56 -> 2147483637 -PASS maxMessageSize is as expected for firefox>=57 and firefox>=57 -> 1073741823 -PASS maxMessageSize is as expected for firefox>=57 and 64 KiB -> 65536 -PASS maxMessageSize is as expected for firefox>=57 and 1.5 GiB -> 1610612736 -PASS maxMessageSize is as expected for firefox>=57 and 2 GiB -> 2147483637 -PASS maxMessageSize is as expected for firefox>=57 and Unlimited -> 2147483637 PASS maxMessageSize is as expected for firefox>=58 and chrome>=0 -> 65536 +PASS maxMessageSize is as expected for firefox>=58 and firefox<=56 -> 65536 +PASS maxMessageSize is as expected for firefox>=58 and firefox>=57 -> 65536 +PASS maxMessageSize is as expected for firefox>=58 and 64 KiB -> 65536 +PASS maxMessageSize is as expected for firefox>=58 and 1.5 GiB -> 65536 +PASS maxMessageSize is as expected for firefox>=58 and 2 GiB -> 65536 +PASS maxMessageSize is as expected for firefox>=58 and Unlimited -> 65536 PASS navigator.mediaDevices exists PASS navigator.mediaDevices is an EventTarget PASS navigator.mediaDevices implements the devicechange event diff --git a/test/e2e/expectations/firefox-nightly b/test/e2e/expectations/firefox-nightly index 8a08df6fc..0beb010fd 100644 --- a/test/e2e/expectations/firefox-nightly +++ b/test/e2e/expectations/firefox-nightly @@ -40,13 +40,13 @@ PASS maxMessageSize sctp and maxMessageSize set if SCTP negotiated PASS maxMessageSize send largest possible single message PASS maxMessageSize throws an exception if the message is too large PASS maxMessageSize throws an exception if the message is too large (using a secondary data channel) -PASS maxMessageSize is as expected for firefox>=57 and firefox<=56 -> 2147483637 -PASS maxMessageSize is as expected for firefox>=57 and firefox>=57 -> 1073741823 -PASS maxMessageSize is as expected for firefox>=57 and 64 KiB -> 65536 -PASS maxMessageSize is as expected for firefox>=57 and 1.5 GiB -> 1610612736 -PASS maxMessageSize is as expected for firefox>=57 and 2 GiB -> 2147483637 -PASS maxMessageSize is as expected for firefox>=57 and Unlimited -> 2147483637 PASS maxMessageSize is as expected for firefox>=58 and chrome>=0 -> 65536 +PASS maxMessageSize is as expected for firefox>=58 and firefox<=56 -> 65536 +PASS maxMessageSize is as expected for firefox>=58 and firefox>=57 -> 65536 +PASS maxMessageSize is as expected for firefox>=58 and 64 KiB -> 65536 +PASS maxMessageSize is as expected for firefox>=58 and 1.5 GiB -> 65536 +PASS maxMessageSize is as expected for firefox>=58 and 2 GiB -> 65536 +PASS maxMessageSize is as expected for firefox>=58 and Unlimited -> 65536 PASS navigator.mediaDevices exists PASS navigator.mediaDevices is an EventTarget PASS navigator.mediaDevices implements the devicechange event diff --git a/test/e2e/expectations/firefox-stable b/test/e2e/expectations/firefox-stable index 7557fa730..7cfe4cca0 100644 --- a/test/e2e/expectations/firefox-stable +++ b/test/e2e/expectations/firefox-stable @@ -41,12 +41,12 @@ PASS maxMessageSize send largest possible single message PASS maxMessageSize throws an exception if the message is too large PASS maxMessageSize throws an exception if the message is too large (using a secondary data channel) PASS maxMessageSize is as expected for firefox==57 and chrome>=0 -> 65535 -PASS maxMessageSize is as expected for firefox>=57 and firefox<=56 -> 2147483637 -PASS maxMessageSize is as expected for firefox>=57 and firefox>=57 -> 1073741823 -PASS maxMessageSize is as expected for firefox>=57 and 64 KiB -> 65536 -PASS maxMessageSize is as expected for firefox>=57 and 1.5 GiB -> 1610612736 -PASS maxMessageSize is as expected for firefox>=57 and 2 GiB -> 2147483637 -PASS maxMessageSize is as expected for firefox>=57 and Unlimited -> 2147483637 +PASS maxMessageSize is as expected for firefox==57 and firefox<=56 -> 65535 +PASS maxMessageSize is as expected for firefox==57 and firefox>=57 -> 65535 +PASS maxMessageSize is as expected for firefox==57 and 64 KiB -> 65535 +PASS maxMessageSize is as expected for firefox==57 and 1.5 GiB -> 65535 +PASS maxMessageSize is as expected for firefox==57 and 2 GiB -> 65535 +PASS maxMessageSize is as expected for firefox==57 and Unlimited -> 65535 PASS navigator.mediaDevices exists PASS navigator.mediaDevices is an EventTarget PASS navigator.mediaDevices implements the devicechange event diff --git a/test/e2e/maxMessageSize.js b/test/e2e/maxMessageSize.js index 77f957664..e9963530a 100644 --- a/test/e2e/maxMessageSize.js +++ b/test/e2e/maxMessageSize.js @@ -11,6 +11,11 @@ describe('maxMessageSize', () => { let pc1; let pc2; + const browserDetails = window.adapter.browserDetails; + let defaultRemoteMMS = 65536; + if (browserDetails.browser === 'firefox' && browserDetails.version === 57) { + defaultRemoteMMS = 65535; + } function negotiate(pc, otherPc, mapRemoteDescriptionCallback) { return pc.createOffer() @@ -79,28 +84,19 @@ describe('maxMessageSize', () => { }); it('sctp and maxMessageSize set if SCTP negotiated', () => { - const browserDetails = window.adapter.browserDetails; pc1.createDataChannel('test'); return negotiate(pc1, pc2) .then(() => { expect(pc1.sctp).to.have.property('maxMessageSize'); expect(pc2.sctp).to.have.property('maxMessageSize'); - expect(pc1.sctp.maxMessageSize).to.be.at.least(65536); - expect(pc2.sctp.maxMessageSize).to.be.at.least(65536); - if (browserDetails.browser === 'firefox') { - let expectedMMS = 2147483637; - if (browserDetails.version >= 57) { - expectedMMS = 1073741823; - } - expect(pc1.sctp.maxMessageSize).to.equal(expectedMMS); - expect(pc2.sctp.maxMessageSize).to.equal(expectedMMS); - } + expect(pc1.sctp.maxMessageSize).to.be.at.least(defaultRemoteMMS); + expect(pc2.sctp.maxMessageSize).to.be.at.least(defaultRemoteMMS); }); }); it('send largest possible single message', () => { - // Note: Patching to 65536 here as anything beyond that will take too long. - const maxMessageSize = 65536; + // Note: Patching MMS here to prevent creation of large arrays. + const maxMessageSize = defaultRemoteMMS; const patchMaxMessageSize = patchMaxMessageSizeFactory(maxMessageSize); pc1.createDataChannel('test'); @@ -125,9 +121,8 @@ describe('maxMessageSize', () => { describe('throws an exception', () => { it('if the message is too large', () => { - // Note: Patching to 65536 here as anything beyond that will take too - // long (including creation of a large array). - const maxMessageSize = 65536; + // Note: Patching MMS here to prevent creation of large arrays. + const maxMessageSize = defaultRemoteMMS; const patchMaxMessageSize = patchMaxMessageSizeFactory(maxMessageSize); const dc = pc1.createDataChannel('test'); @@ -152,9 +147,9 @@ describe('maxMessageSize', () => { it('if the message is too large (using a secondary data channel)', () => { // Background of this test: // https://bugzilla.mozilla.org/show_bug.cgi?id=1426831 - // Note: Patching to 65536 here as anything beyond that will take too - // long (including creation of a large array). - const maxMessageSize = 65536; + + // Note: Patching MMS here to prevent creation of large arrays. + const maxMessageSize = defaultRemoteMMS; const patchMaxMessageSize = patchMaxMessageSizeFactory(maxMessageSize); pc1.createDataChannel('test'); @@ -180,7 +175,6 @@ describe('maxMessageSize', () => { // Note: These run in e2e as a browser is needed for them to run describe('is as expected for', () => { - const browserDetails = window.adapter.browserDetails; const fakeWindow = Object.assign({}, window); fakeWindow.RTCPeerConnection = function() {}; fakeWindow.RTCPeerConnection.prototype.setRemoteDescription = () => {}; @@ -192,7 +186,8 @@ describe('maxMessageSize', () => { // The innermost array contains the other browser's version, the expected // maximum message size and the offer SDP. // - // Note: Be aware that you MUST store expected results for both browsers! + // Note: Be aware that you MUST store expected results for both browsers + // where the object's key resembles the sending peer. /* eslint-disable max-len */ const testCases = { 'firefox<=56': [ @@ -206,17 +201,21 @@ describe('maxMessageSize', () => { ], 'firefox==57': [ ['chrome>=0', 65535, 'v=0\r\no=- 6575128786484314789 2 IN IP4 127.0.0.1\r\ns=-\r\nt=0 0\r\na=group:BUNDLE data\r\na=msid-semantic: WMS\r\nm=application 9 DTLS/SCTP 5000\r\nc=IN IP4 0.0.0.0\r\na=ice-ufrag:oZF1\r\na=ice-pwd:8+qEgoDOiFd49nDG9oNSYYaz\r\na=ice-options:trickle\r\na=fingerprint:sha-256 F2:01:D6:88:9E:0C:F1:CE:EE:85:9C:B4:A5:B7:36:D4:CB:29:F2:4F:E0:97:81:25:34:00:71:65:2B:39:C1:C1\r\na=setup:actpass\r\na=mid:data\r\na=sctpmap:5000 webrtc-datachannel 1024\r\n'], - ], - 'firefox>=57': [ - ['firefox<=56', 2147483637, 'v=0\r\no=mozilla...THIS_IS_SDPARTA-56.0.2 3250009914871290350 0 IN IP4 0.0.0.0\r\ns=-\r\nt=0 0\r\na=fingerprint:sha-256 C8:36:D3:FD:E6:9A:B8:4E:7C:FB:61:03:22:E5:8E:E1:7D:17:AF:D2:EB:0F:87:BA:28:6C:9A:2E:76:D9:B3:0C\r\na=group:BUNDLE sdparta_0\r\na=ice-options:trickle\r\na=msid-semantic:WMS *\r\nm=application 9 DTLS/SCTP 5000\r\nc=IN IP4 0.0.0.0\r\na=sendrecv\r\na=ice-pwd:bb3ee909b8452eb93722d223b26d6193\r\na=ice-ufrag:1c03e3ae\r\na=mid:sdparta_0\r\na=sctpmap:5000 webrtc-datachannel 256\r\na=setup:actpass\r\n'], - ['firefox>=57', 1073741823, 'v=0\r\no=mozilla...THIS_IS_SDPARTA-57.0 169150732617742973 0 IN IP4 0.0.0.0\r\ns=-\r\nt=0 0\r\na=fingerprint:sha-256 8C:EB:14:5C:60:1E:E8:1E:FA:C7:D8:90:38:E9:EB:05:A8:2B:32:9F:FE:2B:D9:1C:85:3D:59:70:A9:6D:3A:17\r\na=group:BUNDLE sdparta_0\r\na=ice-options:trickle\r\na=msid-semantic:WMS *\r\nm=application 9 DTLS/SCTP 5000\r\nc=IN IP4 0.0.0.0\r\na=sendrecv\r\na=ice-pwd:c224ece79b15dcb92de87e2b67e62d7a\r\na=ice-ufrag:96c030e8\r\na=mid:sdparta_0\r\na=sctpmap:5000 webrtc-datachannel 256\r\na=setup:actpass\r\na=max-message-size:1073741823\r\n'], - ['64 KiB', 65536, 'v=0\r\no=- 6575128786484314789 2 IN IP4 127.0.0.1\r\ns=-\r\nt=0 0\r\na=group:BUNDLE data\r\na=msid-semantic: WMS\r\nm=application 9 DTLS/SCTP 5000\r\nc=IN IP4 0.0.0.0\r\na=ice-ufrag:oZF1\r\na=ice-pwd:8+qEgoDOiFd49nDG9oNSYYaz\r\na=ice-options:trickle\r\na=fingerprint:sha-256 F2:01:D6:88:9E:0C:F1:CE:EE:85:9C:B4:A5:B7:36:D4:CB:29:F2:4F:E0:97:81:25:34:00:71:65:2B:39:C1:C1\r\na=setup:actpass\r\na=mid:data\r\na=sctpmap:5000 webrtc-datachannel 1024\r\na=max-message-size:65536\r\n'], - ['1.5 GiB', 1610612736, 'v=0\r\no=1.5 GiB 169150732617742973 0 IN IP4 0.0.0.0\r\ns=-\r\nt=0 0\r\na=fingerprint:sha-256 8C:EB:14:5C:60:1E:E8:1E:FA:C7:D8:90:38:E9:EB:05:A8:2B:32:9F:FE:2B:D9:1C:85:3D:59:70:A9:6D:3A:17\r\na=group:BUNDLE sdparta_0\r\na=ice-options:trickle\r\na=msid-semantic:WMS *\r\nm=application 9 DTLS/SCTP 5000\r\nc=IN IP4 0.0.0.0\r\na=sendrecv\r\na=ice-pwd:c224ece79b15dcb92de87e2b67e62d7a\r\na=ice-ufrag:96c030e8\r\na=mid:sdparta_0\r\na=sctpmap:5000 webrtc-datachannel 256\r\na=setup:actpass\r\na=max-message-size:1610612736\r\n'], - ['2 GiB', 2147483637, 'v=0\r\no=2 GiB 169150732617742973 0 IN IP4 0.0.0.0\r\ns=-\r\nt=0 0\r\na=fingerprint:sha-256 8C:EB:14:5C:60:1E:E8:1E:FA:C7:D8:90:38:E9:EB:05:A8:2B:32:9F:FE:2B:D9:1C:85:3D:59:70:A9:6D:3A:17\r\na=group:BUNDLE sdparta_0\r\na=ice-options:trickle\r\na=msid-semantic:WMS *\r\nm=application 9 DTLS/SCTP 5000\r\nc=IN IP4 0.0.0.0\r\na=sendrecv\r\na=ice-pwd:c224ece79b15dcb92de87e2b67e62d7a\r\na=ice-ufrag:96c030e8\r\na=mid:sdparta_0\r\na=sctpmap:5000 webrtc-datachannel 256\r\na=setup:actpass\r\na=max-message-size:2147483648\r\n'], - ['Unlimited', 2147483637, 'v=0\r\no=Unlimited 169150732617742973 0 IN IP4 0.0.0.0\r\ns=-\r\nt=0 0\r\na=fingerprint:sha-256 8C:EB:14:5C:60:1E:E8:1E:FA:C7:D8:90:38:E9:EB:05:A8:2B:32:9F:FE:2B:D9:1C:85:3D:59:70:A9:6D:3A:17\r\na=group:BUNDLE sdparta_0\r\na=ice-options:trickle\r\na=msid-semantic:WMS *\r\nm=application 9 DTLS/SCTP 5000\r\nc=IN IP4 0.0.0.0\r\na=sendrecv\r\na=ice-pwd:c224ece79b15dcb92de87e2b67e62d7a\r\na=ice-ufrag:96c030e8\r\na=mid:sdparta_0\r\na=sctpmap:5000 webrtc-datachannel 256\r\na=setup:actpass\r\na=max-message-size:0\r\n'], + ['firefox<=56', 65535, 'v=0\r\no=mozilla...THIS_IS_SDPARTA-56.0.2 3250009914871290350 0 IN IP4 0.0.0.0\r\ns=-\r\nt=0 0\r\na=fingerprint:sha-256 C8:36:D3:FD:E6:9A:B8:4E:7C:FB:61:03:22:E5:8E:E1:7D:17:AF:D2:EB:0F:87:BA:28:6C:9A:2E:76:D9:B3:0C\r\na=group:BUNDLE sdparta_0\r\na=ice-options:trickle\r\na=msid-semantic:WMS *\r\nm=application 9 DTLS/SCTP 5000\r\nc=IN IP4 0.0.0.0\r\na=sendrecv\r\na=ice-pwd:bb3ee909b8452eb93722d223b26d6193\r\na=ice-ufrag:1c03e3ae\r\na=mid:sdparta_0\r\na=sctpmap:5000 webrtc-datachannel 256\r\na=setup:actpass\r\n'], + ['firefox>=57', 65535, 'v=0\r\no=mozilla...THIS_IS_SDPARTA-57.0 169150732617742973 0 IN IP4 0.0.0.0\r\ns=-\r\nt=0 0\r\na=fingerprint:sha-256 8C:EB:14:5C:60:1E:E8:1E:FA:C7:D8:90:38:E9:EB:05:A8:2B:32:9F:FE:2B:D9:1C:85:3D:59:70:A9:6D:3A:17\r\na=group:BUNDLE sdparta_0\r\na=ice-options:trickle\r\na=msid-semantic:WMS *\r\nm=application 9 DTLS/SCTP 5000\r\nc=IN IP4 0.0.0.0\r\na=sendrecv\r\na=ice-pwd:c224ece79b15dcb92de87e2b67e62d7a\r\na=ice-ufrag:96c030e8\r\na=mid:sdparta_0\r\na=sctpmap:5000 webrtc-datachannel 256\r\na=setup:actpass\r\na=max-message-size:1073741823\r\n'], + ['64 KiB', 65535, 'v=0\r\no=- 6575128786484314789 2 IN IP4 127.0.0.1\r\ns=-\r\nt=0 0\r\na=group:BUNDLE data\r\na=msid-semantic: WMS\r\nm=application 9 DTLS/SCTP 5000\r\nc=IN IP4 0.0.0.0\r\na=ice-ufrag:oZF1\r\na=ice-pwd:8+qEgoDOiFd49nDG9oNSYYaz\r\na=ice-options:trickle\r\na=fingerprint:sha-256 F2:01:D6:88:9E:0C:F1:CE:EE:85:9C:B4:A5:B7:36:D4:CB:29:F2:4F:E0:97:81:25:34:00:71:65:2B:39:C1:C1\r\na=setup:actpass\r\na=mid:data\r\na=sctpmap:5000 webrtc-datachannel 1024\r\na=max-message-size:65536\r\n'], + ['1.5 GiB', 65535, 'v=0\r\no=1.5 GiB 169150732617742973 0 IN IP4 0.0.0.0\r\ns=-\r\nt=0 0\r\na=fingerprint:sha-256 8C:EB:14:5C:60:1E:E8:1E:FA:C7:D8:90:38:E9:EB:05:A8:2B:32:9F:FE:2B:D9:1C:85:3D:59:70:A9:6D:3A:17\r\na=group:BUNDLE sdparta_0\r\na=ice-options:trickle\r\na=msid-semantic:WMS *\r\nm=application 9 DTLS/SCTP 5000\r\nc=IN IP4 0.0.0.0\r\na=sendrecv\r\na=ice-pwd:c224ece79b15dcb92de87e2b67e62d7a\r\na=ice-ufrag:96c030e8\r\na=mid:sdparta_0\r\na=sctpmap:5000 webrtc-datachannel 256\r\na=setup:actpass\r\na=max-message-size:1610612736\r\n'], + ['2 GiB', 65535, 'v=0\r\no=2 GiB 169150732617742973 0 IN IP4 0.0.0.0\r\ns=-\r\nt=0 0\r\na=fingerprint:sha-256 8C:EB:14:5C:60:1E:E8:1E:FA:C7:D8:90:38:E9:EB:05:A8:2B:32:9F:FE:2B:D9:1C:85:3D:59:70:A9:6D:3A:17\r\na=group:BUNDLE sdparta_0\r\na=ice-options:trickle\r\na=msid-semantic:WMS *\r\nm=application 9 DTLS/SCTP 5000\r\nc=IN IP4 0.0.0.0\r\na=sendrecv\r\na=ice-pwd:c224ece79b15dcb92de87e2b67e62d7a\r\na=ice-ufrag:96c030e8\r\na=mid:sdparta_0\r\na=sctpmap:5000 webrtc-datachannel 256\r\na=setup:actpass\r\na=max-message-size:2147483648\r\n'], + ['Unlimited', 65535, 'v=0\r\no=Unlimited 169150732617742973 0 IN IP4 0.0.0.0\r\ns=-\r\nt=0 0\r\na=fingerprint:sha-256 8C:EB:14:5C:60:1E:E8:1E:FA:C7:D8:90:38:E9:EB:05:A8:2B:32:9F:FE:2B:D9:1C:85:3D:59:70:A9:6D:3A:17\r\na=group:BUNDLE sdparta_0\r\na=ice-options:trickle\r\na=msid-semantic:WMS *\r\nm=application 9 DTLS/SCTP 5000\r\nc=IN IP4 0.0.0.0\r\na=sendrecv\r\na=ice-pwd:c224ece79b15dcb92de87e2b67e62d7a\r\na=ice-ufrag:96c030e8\r\na=mid:sdparta_0\r\na=sctpmap:5000 webrtc-datachannel 256\r\na=setup:actpass\r\na=max-message-size:0\r\n'], ], 'firefox>=58': [ ['chrome>=0', 65536, 'v=0\r\no=- 6575128786484314789 2 IN IP4 127.0.0.1\r\ns=-\r\nt=0 0\r\na=group:BUNDLE data\r\na=msid-semantic: WMS\r\nm=application 9 DTLS/SCTP 5000\r\nc=IN IP4 0.0.0.0\r\na=ice-ufrag:oZF1\r\na=ice-pwd:8+qEgoDOiFd49nDG9oNSYYaz\r\na=ice-options:trickle\r\na=fingerprint:sha-256 F2:01:D6:88:9E:0C:F1:CE:EE:85:9C:B4:A5:B7:36:D4:CB:29:F2:4F:E0:97:81:25:34:00:71:65:2B:39:C1:C1\r\na=setup:actpass\r\na=mid:data\r\na=sctpmap:5000 webrtc-datachannel 1024\r\n'], + ['firefox<=56', 65536, 'v=0\r\no=mozilla...THIS_IS_SDPARTA-56.0.2 3250009914871290350 0 IN IP4 0.0.0.0\r\ns=-\r\nt=0 0\r\na=fingerprint:sha-256 C8:36:D3:FD:E6:9A:B8:4E:7C:FB:61:03:22:E5:8E:E1:7D:17:AF:D2:EB:0F:87:BA:28:6C:9A:2E:76:D9:B3:0C\r\na=group:BUNDLE sdparta_0\r\na=ice-options:trickle\r\na=msid-semantic:WMS *\r\nm=application 9 DTLS/SCTP 5000\r\nc=IN IP4 0.0.0.0\r\na=sendrecv\r\na=ice-pwd:bb3ee909b8452eb93722d223b26d6193\r\na=ice-ufrag:1c03e3ae\r\na=mid:sdparta_0\r\na=sctpmap:5000 webrtc-datachannel 256\r\na=setup:actpass\r\n'], + ['firefox>=57', 65536, 'v=0\r\no=mozilla...THIS_IS_SDPARTA-57.0 169150732617742973 0 IN IP4 0.0.0.0\r\ns=-\r\nt=0 0\r\na=fingerprint:sha-256 8C:EB:14:5C:60:1E:E8:1E:FA:C7:D8:90:38:E9:EB:05:A8:2B:32:9F:FE:2B:D9:1C:85:3D:59:70:A9:6D:3A:17\r\na=group:BUNDLE sdparta_0\r\na=ice-options:trickle\r\na=msid-semantic:WMS *\r\nm=application 9 DTLS/SCTP 5000\r\nc=IN IP4 0.0.0.0\r\na=sendrecv\r\na=ice-pwd:c224ece79b15dcb92de87e2b67e62d7a\r\na=ice-ufrag:96c030e8\r\na=mid:sdparta_0\r\na=sctpmap:5000 webrtc-datachannel 256\r\na=setup:actpass\r\na=max-message-size:1073741823\r\n'], + ['64 KiB', 65536, 'v=0\r\no=- 6575128786484314789 2 IN IP4 127.0.0.1\r\ns=-\r\nt=0 0\r\na=group:BUNDLE data\r\na=msid-semantic: WMS\r\nm=application 9 DTLS/SCTP 5000\r\nc=IN IP4 0.0.0.0\r\na=ice-ufrag:oZF1\r\na=ice-pwd:8+qEgoDOiFd49nDG9oNSYYaz\r\na=ice-options:trickle\r\na=fingerprint:sha-256 F2:01:D6:88:9E:0C:F1:CE:EE:85:9C:B4:A5:B7:36:D4:CB:29:F2:4F:E0:97:81:25:34:00:71:65:2B:39:C1:C1\r\na=setup:actpass\r\na=mid:data\r\na=sctpmap:5000 webrtc-datachannel 1024\r\na=max-message-size:65536\r\n'], + ['1.5 GiB', 65536, 'v=0\r\no=1.5 GiB 169150732617742973 0 IN IP4 0.0.0.0\r\ns=-\r\nt=0 0\r\na=fingerprint:sha-256 8C:EB:14:5C:60:1E:E8:1E:FA:C7:D8:90:38:E9:EB:05:A8:2B:32:9F:FE:2B:D9:1C:85:3D:59:70:A9:6D:3A:17\r\na=group:BUNDLE sdparta_0\r\na=ice-options:trickle\r\na=msid-semantic:WMS *\r\nm=application 9 DTLS/SCTP 5000\r\nc=IN IP4 0.0.0.0\r\na=sendrecv\r\na=ice-pwd:c224ece79b15dcb92de87e2b67e62d7a\r\na=ice-ufrag:96c030e8\r\na=mid:sdparta_0\r\na=sctpmap:5000 webrtc-datachannel 256\r\na=setup:actpass\r\na=max-message-size:1610612736\r\n'], + ['2 GiB', 65536, 'v=0\r\no=2 GiB 169150732617742973 0 IN IP4 0.0.0.0\r\ns=-\r\nt=0 0\r\na=fingerprint:sha-256 8C:EB:14:5C:60:1E:E8:1E:FA:C7:D8:90:38:E9:EB:05:A8:2B:32:9F:FE:2B:D9:1C:85:3D:59:70:A9:6D:3A:17\r\na=group:BUNDLE sdparta_0\r\na=ice-options:trickle\r\na=msid-semantic:WMS *\r\nm=application 9 DTLS/SCTP 5000\r\nc=IN IP4 0.0.0.0\r\na=sendrecv\r\na=ice-pwd:c224ece79b15dcb92de87e2b67e62d7a\r\na=ice-ufrag:96c030e8\r\na=mid:sdparta_0\r\na=sctpmap:5000 webrtc-datachannel 256\r\na=setup:actpass\r\na=max-message-size:2147483648\r\n'], + ['Unlimited', 65536, 'v=0\r\no=Unlimited 169150732617742973 0 IN IP4 0.0.0.0\r\ns=-\r\nt=0 0\r\na=fingerprint:sha-256 8C:EB:14:5C:60:1E:E8:1E:FA:C7:D8:90:38:E9:EB:05:A8:2B:32:9F:FE:2B:D9:1C:85:3D:59:70:A9:6D:3A:17\r\na=group:BUNDLE sdparta_0\r\na=ice-options:trickle\r\na=msid-semantic:WMS *\r\nm=application 9 DTLS/SCTP 5000\r\nc=IN IP4 0.0.0.0\r\na=sendrecv\r\na=ice-pwd:c224ece79b15dcb92de87e2b67e62d7a\r\na=ice-ufrag:96c030e8\r\na=mid:sdparta_0\r\na=sctpmap:5000 webrtc-datachannel 256\r\na=setup:actpass\r\na=max-message-size:0\r\n'], ], 'chrome>=0': [ ['chrome>=0', 65536, 'v=0\r\no=- 6575128786484314789 2 IN IP4 127.0.0.1\r\ns=-\r\nt=0 0\r\na=group:BUNDLE data\r\na=msid-semantic: WMS\r\nm=application 9 DTLS/SCTP 5000\r\nc=IN IP4 0.0.0.0\r\na=ice-ufrag:oZF1\r\na=ice-pwd:8+qEgoDOiFd49nDG9oNSYYaz\r\na=ice-options:trickle\r\na=fingerprint:sha-256 F2:01:D6:88:9E:0C:F1:CE:EE:85:9C:B4:A5:B7:36:D4:CB:29:F2:4F:E0:97:81:25:34:00:71:65:2B:39:C1:C1\r\na=setup:actpass\r\na=mid:data\r\na=sctpmap:5000 webrtc-datachannel 1024\r\n'],