Bug 1115998 - Support RTCIceServer.urls (plural) array form. r=smaug, r=mt

This commit is contained in:
Jan-Ivar Bruaroey 2015-01-20 10:08:00 -05:00
Родитель eb37c238cf
Коммит dd25a84c04
8 изменённых файлов: 101 добавлений и 83 удалений

Просмотреть файл

@ -22,5 +22,4 @@
# changes to stick? As of bug 928195, this shouldn't be necessary! Please
# don't change CLOBBER for WebIDL changes any more.
Bug 1100184 - Lots of file moves from the /netwerk flattening and zero faith
in the build system to properly handle them.
Bug 1115998 - (DOMString or sequence<DOMString>) needs binding flush (Bug 1103153)

Просмотреть файл

@ -323,13 +323,24 @@ RTCPeerConnection.prototype = {
init: function(win) { this._win = win; },
__init: function(rtcConfig) {
this._winID = this._win.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIDOMWindowUtils).currentInnerWindowID;
if (!rtcConfig.iceServers ||
!Services.prefs.getBoolPref("media.peerconnection.use_document_iceservers")) {
rtcConfig.iceServers =
JSON.parse(Services.prefs.getCharPref("media.peerconnection.default_iceservers"));
}
this._winID = this._win.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIDOMWindowUtils).currentInnerWindowID;
// Normalize iceServers input
rtcConfig.iceServers.forEach(server => {
if (typeof server.urls === "string") {
server.urls = [server.urls];
} else if (!server.urls && server.url) {
// TODO: Remove support for legacy iceServer.url eventually (Bug 1116766)
server.urls = [server.url];
this.logWarning("RTCIceServer.url is deprecated! Use urls instead.", null, 0);
}
});
this._mustValidateRTCConfiguration(rtcConfig,
"RTCPeerConnection constructor passed invalid RTCConfiguration");
if (_globalPCList._networkdown || !this._win.navigator.onLine) {
@ -432,10 +443,11 @@ RTCPeerConnection.prototype = {
},
/**
* An RTCConfiguration looks like this:
* An RTCConfiguration may look like this:
*
* { "iceServers": [ { url:"stun:stun.example.org" },
* { url:"turn:turn.example.org",
* { "iceServers": [ { urls: "stun:stun.example.org", },
* { url: "stun:stun.example.org", }, // deprecated version
* { urls: ["turn:turn1.x.org", "turn:turn2.x.org"],
* username:"jib", credential:"mypass"} ] }
*
* WebIDL normalizes structure for us, so we test well-formed stun/turn urls,
@ -456,27 +468,29 @@ RTCPeerConnection.prototype = {
};
rtcConfig.iceServers.forEach(server => {
if (!server.url) {
throw new this._win.DOMException(msg + " - missing url", "InvalidAccessError");
if (!server.urls) {
throw new this._win.DOMException(msg + " - missing urls", "InvalidAccessError");
}
let url = nicerNewURI(server.url);
if (url.scheme in { turn:1, turns:1 }) {
if (!server.username) {
throw new this._win.DOMException(msg + " - missing username: " + server.url,
"InvalidAccessError");
server.urls.forEach(urlStr => {
let url = nicerNewURI(urlStr);
if (url.scheme in { turn:1, turns:1 }) {
if (!server.username) {
throw new this._win.DOMException(msg + " - missing username: " + urlStr,
"InvalidAccessError");
}
if (!server.credential) {
throw new this._win.DOMException(msg + " - missing credential: " + urlStr,
"InvalidAccessError");
}
}
if (!server.credential) {
throw new this._win.DOMException(msg + " - missing credential: " + server.url,
"InvalidAccessError");
else if (!(url.scheme in { stun:1, stuns:1 })) {
throw new this._win.DOMException(msg + " - improper scheme: " + url.scheme,
"SyntaxError");
}
}
else if (!(url.scheme in { stun:1, stuns:1 })) {
throw new this._win.DOMException(msg + " - improper scheme: " + url.scheme,
"SyntaxError");
}
if (url.scheme in { stuns:1, turns:1 }) {
this.logWarning(url.scheme.toUpperCase() + " is not yet supported.", null, 0);
}
if (url.scheme in { stuns:1, turns:1 }) {
this.logWarning(url.scheme.toUpperCase() + " is not yet supported.", null, 0);
}
});
});
},

Просмотреть файл

@ -14,78 +14,66 @@
title: "RTCConfiguration valid/invalid permutations"
});
makePC = function (config, expect_success) {
var exception = null;
var pc = null;
try {
pc = new mozRTCPeerConnection(config);
} catch (e) {
exception = e;
}
if (pc !== null) {
pc.close();
}
pc = null
if (expect_success) {
ok(!exception, "mozRTCPeerConnection(" +
JSON.stringify(config) + ") succeeds");
} else {
ok(exception, "mozRTCPeerConnection(" +
JSON.stringify(config) + ") throws");
}
makePC = (config, expected_error) => {
var exception;
try {
new mozRTCPeerConnection(config).close();
} catch (e) {
exception = e;
}
is((exception? exception.name : "success"), expected_error || "success",
"mozRTCPeerConnection(" + JSON.stringify(config) + ")");
}
// This is a test of the iceServers parsing code + readable errors
runNetworkTest(function () {
var pcs = null;
var exception = null;
var config;
try {
pcs = new mozRTCPeerConnection();
new mozRTCPeerConnection().close();
} catch (e) {
exception = e;
}
ok(!exception, "mozRTCPeerConnection() succeeds");
if (pcs !== null) {
pcs.close();
}
pcs = null;
exception = null;
makePC(1, false);
makePC();
makePC({}, true);
makePC(1, "TypeError");
makePC({ iceServers: [] }, true);
makePC({});
makePC({ iceServers: [{ url:"" }] }, false);
makePC({ iceServers: [] });
makePC({ iceServers: [{ urls:"" }] }, "SyntaxError");
makePC({ iceServers: [
{ url:"stun:127.0.0.1" },
{ url:"stuns:localhost", foo:"" },
{ url:"turn:[::1]:3478", username:"p", credential:"p" },
{ url:"turns:localhost:3478?transport=udp", username:"p", credential:"p" }
]}, true);
{ urls:"stun:127.0.0.1" },
{ urls:"stun:localhost", foo:"" },
{ urls: ["stun:127.0.0.1", "stun:localhost"] },
{ urls:"stuns:localhost", foo:"" },
{ urls:"turn:[::1]:3478", username:"p", credential:"p" },
{ urls:"turn:localhost:3478?transport=udp", username:"p", credential:"p" },
{ urls: ["turn:[::1]:3478", "turn:localhost"], username:"p", credential:"p" },
{ urls:"turns:localhost:3478?transport=udp", username:"p", credential:"p" },
{ url:"stun:localhost", foo:"" },
{ url:"turn:localhost", username:"p", credential:"p" }
]});
makePC({ iceServers: [{ url:"turns:localhost:3478", username:"p" }] }, false);
makePC({ iceServers: [{ urls: ["stun:127.0.0.1", ""] }] }, "SyntaxError");
makePC({ iceServers: [{ url:"turns:localhost:3478", credential:"p" }] }, false);
makePC({ iceServers: [{ urls:"turns:localhost:3478", username:"p" }] }, "InvalidAccessError");
makePC({ iceServers: [{ url:"http:0.0.0.0" }] }, false);
makePC({ iceServers: [{ url:"turns:localhost:3478", credential:"p" }] }, "InvalidAccessError");
makePC({ iceServers: [{ urls:"http:0.0.0.0" }] }, "SyntaxError");
try {
pcs = new mozRTCPeerConnection({ iceServers: [{ url:"http:0.0.0.0" }] });
new mozRTCPeerConnection({ iceServers: [{ url:"http:0.0.0.0" }] }).close();
} catch (e) {
ok(e.message.indexOf("http") > 0,
"mozRTCPeerConnection() constructor has readable exceptions");
ok(e.message.indexOf("http") > 0,
"mozRTCPeerConnection() constructor has readable exceptions");
}
if (pcs !== null) {
pcs.close();
}
pcs = null;
networkTestFinished();
});

Просмотреть файл

@ -8,7 +8,8 @@
*/
dictionary RTCIceServer {
DOMString url;
(DOMString or sequence<DOMString>) urls;
DOMString url; //deprecated
DOMString? credential = null;
DOMString? username = null;
};

Просмотреть файл

@ -468,20 +468,32 @@ PeerConnectionImpl::ConvertRTCConfiguration(const RTCConfiguration& aSrc,
IceConfiguration *aDst)
{
#ifdef MOZILLA_INTERNAL_API
if (!aSrc.mIceServers.WasPassed()) {
return NS_OK;
if (aSrc.mIceServers.WasPassed()) {
for (size_t i = 0; i < aSrc.mIceServers.Value().Length(); i++) {
nsresult rv = AddIceServer(aSrc.mIceServers.Value()[i], aDst);
NS_ENSURE_SUCCESS(rv, rv);
}
}
for (uint32_t i = 0; i < aSrc.mIceServers.Value().Length(); i++) {
const RTCIceServer& server = aSrc.mIceServers.Value()[i];
NS_ENSURE_TRUE(server.mUrl.WasPassed(), NS_ERROR_UNEXPECTED);
#endif
return NS_OK;
}
nsresult
PeerConnectionImpl::AddIceServer(const RTCIceServer &aServer,
IceConfiguration *aDst)
{
#ifdef MOZILLA_INTERNAL_API
NS_ENSURE_STATE(aServer.mUrls.WasPassed());
NS_ENSURE_STATE(aServer.mUrls.Value().IsStringSequence());
auto &urls = aServer.mUrls.Value().GetAsStringSequence();
for (size_t i = 0; i < urls.Length(); i++) {
// Without STUN/TURN handlers, NS_NewURI returns nsSimpleURI rather than
// nsStandardURL. To parse STUN/TURN URI's to spec
// http://tools.ietf.org/html/draft-nandakumar-rtcweb-stun-uri-02#section-3
// http://tools.ietf.org/html/draft-petithuguenin-behave-turn-uri-03#section-3
// we parse out the query-string, and use ParseAuthority() on the rest
nsRefPtr<nsIURI> url;
nsresult rv = NS_NewURI(getter_AddRefs(url), server.mUrl.Value());
nsresult rv = NS_NewURI(getter_AddRefs(url), urls[i]);
NS_ENSURE_SUCCESS(rv, rv);
bool isStun = false, isStuns = false, isTurn = false, isTurns = false;
url->SchemeIs("stun", &isStun);
@ -542,8 +554,8 @@ PeerConnectionImpl::ConvertRTCConfiguration(const RTCConfiguration& aSrc,
port = (isStuns || isTurns)? 5349 : 3478;
if (isTurn || isTurns) {
NS_ConvertUTF16toUTF8 credential(server.mCredential);
NS_ConvertUTF16toUTF8 username(server.mUsername);
NS_ConvertUTF16toUTF8 credential(aServer.mCredential);
NS_ConvertUTF16toUTF8 username(aServer.mUsername);
// Bug 1039655 - TURN TCP is not e10s ready
if ((transport == kNrIceTransportTcp) &&

Просмотреть файл

@ -78,6 +78,7 @@ class DOMMediaStream;
namespace dom {
struct RTCConfiguration;
struct RTCIceServer;
struct RTCOfferOptions;
#ifdef USE_FAKE_MEDIA_STREAMS
typedef Fake_MediaStreamTrack MediaStreamTrack;
@ -118,6 +119,7 @@ namespace mozilla {
using mozilla::dom::PeerConnectionObserver;
using mozilla::dom::RTCConfiguration;
using mozilla::dom::RTCIceServer;
using mozilla::dom::RTCOfferOptions;
using mozilla::DOMMediaStream;
using mozilla::NrIceCtx;
@ -259,6 +261,8 @@ public:
static PeerConnectionImpl* CreatePeerConnection();
static nsresult ConvertRTCConfiguration(const RTCConfiguration& aSrc,
IceConfiguration *aDst);
static nsresult AddIceServer(const RTCIceServer& aServer,
IceConfiguration* aDst);
already_AddRefed<DOMMediaStream> MakeMediaStream(uint32_t aHint);
nsresult CreateRemoteSourceStreamInfo(nsRefPtr<RemoteSourceStreamInfo>* aInfo,

Просмотреть файл

@ -7,7 +7,7 @@ const { classes: Cc, interfaces: Ci, utils: Cu } = Components;
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/Messaging.jsm");
const CONFIG = { iceServers: [{ "url": "stun:stun.services.mozilla.com" }] };
const CONFIG = { iceServers: [{ "urls": ["stun:stun.services.mozilla.com"] }] };
let log = Cu.import("resource://gre/modules/AndroidLog.jsm",
{}).AndroidLog.d.bind(null, "TabMirror");

Просмотреть файл

@ -360,7 +360,7 @@ pref("media.peerconnection.video.start_bitrate", 300);
pref("media.peerconnection.video.max_bitrate", 2000);
#endif
pref("media.navigator.permission.disabled", false);
pref("media.peerconnection.default_iceservers", "[{\"url\": \"stun:stun.services.mozilla.com\"}]");
pref("media.peerconnection.default_iceservers", "[{\"urls\": [\"stun:stun.services.mozilla.com\"]}]");
pref("media.peerconnection.ice.loopback", false); // Set only for testing in offline environments.
pref("media.peerconnection.use_document_iceservers", true);
// Do not enable identity before ensuring that the UX cannot be spoofed