mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-01-27 07:34:20 +00:00
Bug 959870 - Error reporting improvements to WebRTC IdP. r=jib
This commit is contained in:
parent
935ec01a10
commit
dcf290639e
@ -227,7 +227,7 @@ const kEventConstructors = {
|
||||
},
|
||||
},
|
||||
MozApplicationEvent: { create: function (aName, aProps) {
|
||||
return new MozApplicationEvent(aName, aProps);
|
||||
return new MozApplicationEvent(aName, aProps);
|
||||
},
|
||||
},
|
||||
MozCellBroadcastEvent: { create: function (aName, aProps) {
|
||||
@ -326,6 +326,10 @@ const kEventConstructors = {
|
||||
return new RTCPeerConnectionIdentityEvent(aName, aProps);
|
||||
},
|
||||
},
|
||||
RTCPeerConnectionIdentityErrorEvent: { create: function (aName, aProps) {
|
||||
return new RTCPeerConnectionIdentityErrorEvent(aName, aProps);
|
||||
},
|
||||
},
|
||||
ScrollAreaEvent: { create: function (aName, aProps) {
|
||||
var e = document.createEvent("scrollareaevent");
|
||||
e.initScrollAreaEvent(aName, aProps.bubbles, aProps.cancelable,
|
||||
|
@ -53,8 +53,8 @@ IdpChannel.prototype = {
|
||||
|
||||
_sandboxReady: function(aCallback, aSandbox) {
|
||||
// Inject a message channel into the subframe.
|
||||
this.messagechannel = new aSandbox._frame.contentWindow.MessageChannel();
|
||||
try {
|
||||
this.messagechannel = new aSandbox._frame.contentWindow.MessageChannel();
|
||||
Object.defineProperty(
|
||||
aSandbox._frame.contentWindow.wrappedJSObject,
|
||||
"rtcwebIdentityPort",
|
||||
@ -254,13 +254,13 @@ IdpProxy.prototype = {
|
||||
|
||||
// dump a message of type "ERROR" in response to all outstanding
|
||||
// messages to the IdP
|
||||
let error = { type: "ERROR", message: "IdP closed" };
|
||||
let error = { type: "ERROR", error: "IdP closed" };
|
||||
Object.keys(trackingCopy).forEach(function(k) {
|
||||
this.trackingCopy[k](error);
|
||||
}, this);
|
||||
trackingCopy[k](error);
|
||||
});
|
||||
pendingCopy.forEach(function(p) {
|
||||
p.callback(error);
|
||||
}, this);
|
||||
});
|
||||
},
|
||||
|
||||
toString: function() {
|
||||
|
@ -313,6 +313,8 @@ RTCPeerConnection.prototype = {
|
||||
this.makeGetterSetterEH("oniceconnectionstatechange");
|
||||
this.makeGetterSetterEH("onidentityresult");
|
||||
this.makeGetterSetterEH("onpeeridentity");
|
||||
this.makeGetterSetterEH("onidpassertionerror");
|
||||
this.makeGetterSetterEH("onidpvalidationerror");
|
||||
|
||||
this._pc = new this._win.PeerConnectionImpl();
|
||||
|
||||
@ -350,8 +352,10 @@ RTCPeerConnection.prototype = {
|
||||
let prefName = "media.peerconnection.identity.timeout";
|
||||
let idpTimeout = Services.prefs.getIntPref(prefName);
|
||||
let warningFunc = this.reportWarning.bind(this);
|
||||
this._localIdp = new PeerConnectionIdp(this._win, idpTimeout, warningFunc);
|
||||
this._remoteIdp = new PeerConnectionIdp(this._win, idpTimeout, warningFunc);
|
||||
this._localIdp = new PeerConnectionIdp(this._win, idpTimeout, warningFunc,
|
||||
this.dispatchEvent.bind(this));
|
||||
this._remoteIdp = new PeerConnectionIdp(this._win, idpTimeout, warningFunc,
|
||||
this.dispatchEvent.bind(this));
|
||||
},
|
||||
|
||||
/**
|
||||
@ -700,34 +704,17 @@ RTCPeerConnection.prototype = {
|
||||
this.dispatchEvent(ev);
|
||||
},
|
||||
|
||||
// we're going off spec with the error callback here.
|
||||
getIdentityAssertion: function(errorCallback) {
|
||||
getIdentityAssertion: function() {
|
||||
this._checkClosed();
|
||||
if (typeof errorCallback !== "function") {
|
||||
if (errorCallback) {
|
||||
let message ="getIdentityAssertion argument must be a function";
|
||||
throw new this._win.DOMError("", message);
|
||||
}
|
||||
errorCallback = function() {
|
||||
this.reportWarning("getIdentityAssertion: no error callback set");
|
||||
}.bind(this);
|
||||
}
|
||||
|
||||
function gotAssertion(assertion) {
|
||||
if (assertion) {
|
||||
this._gotIdentityAssertion(assertion);
|
||||
} else {
|
||||
errorCallback("IdP did not produce an assertion");
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
this._localIdp.getIdentityAssertion(this._impl.fingerprint,
|
||||
gotAssertion.bind(this));
|
||||
}
|
||||
catch (e) {
|
||||
errorCallback("Could not get identity assertion: " + e.message);
|
||||
}
|
||||
this._localIdp.getIdentityAssertion(this._impl.fingerprint,
|
||||
gotAssertion.bind(this));
|
||||
},
|
||||
|
||||
updateIce: function(config, constraints) {
|
||||
|
@ -18,11 +18,13 @@ XPCOMUtils.defineLazyModuleGetter(this, "IdpProxy",
|
||||
* @param window (object) the window object to use for miscellaneous goodies
|
||||
* @param timeout (int) the timeout in milliseconds
|
||||
* @param warningFunc (function) somewhere to dump warning messages
|
||||
* @param dispatchEventFunc (function) somewhere to dump error events
|
||||
*/
|
||||
function PeerConnectionIdp(window, timeout, warningFunc) {
|
||||
function PeerConnectionIdp(window, timeout, warningFunc, dispatchEventFunc) {
|
||||
this._win = window;
|
||||
this._timeout = timeout || 5000;
|
||||
this._warning = warningFunc;
|
||||
this._dispatchEvent = dispatchEventFunc;
|
||||
|
||||
this.assertion = null;
|
||||
this.provider = null;
|
||||
@ -40,6 +42,7 @@ function PeerConnectionIdp(window, timeout, warningFunc) {
|
||||
PeerConnectionIdp.prototype = {
|
||||
setIdentityProvider: function(provider, protocol, username) {
|
||||
this.provider = provider;
|
||||
this.protocol = protocol;
|
||||
this.username = username;
|
||||
if (this._idpchannel) {
|
||||
if (this._idpchannel.isSame(provider, protocol)) {
|
||||
@ -59,6 +62,25 @@ PeerConnectionIdp.prototype = {
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Generate an error event of the identified type;
|
||||
* and put a little more precise information in the console.
|
||||
*/
|
||||
reportError: function(type, message, extra) {
|
||||
let args = {
|
||||
idp: this.provider,
|
||||
protocol: this.protocol
|
||||
};
|
||||
if (extra) {
|
||||
Object.keys(extra).forEach(function(k) {
|
||||
args[k] = extra[k];
|
||||
});
|
||||
}
|
||||
this._warning("RTC identity: " + message, null, 0);
|
||||
let ev = new this._win.RTCPeerConnectionIdentityErrorEvent('idp' + type + 'error', args);
|
||||
this._dispatchEvent(ev);
|
||||
},
|
||||
|
||||
_getFingerprintFromSdp: function(sdp) {
|
||||
let sections = sdp.split(PeerConnectionIdp._mLinePattern);
|
||||
let attributes = sections.map(function(sect) {
|
||||
@ -68,8 +90,8 @@ PeerConnectionIdp.prototype = {
|
||||
if (!remainder.match(PeerConnectionIdp._fingerprintPattern)) {
|
||||
return { algorithm: m[1], digest: m[2] };
|
||||
}
|
||||
this._warning("RTC identity: two fingerprint values in same media " +
|
||||
"section are not supported", null, 0);
|
||||
this.reportError("validation", "two fingerprint values" +
|
||||
" in same media section are not supported");
|
||||
// we have to return non-falsy here so that a media section doesn't
|
||||
// accidentally fall back to the session-level stuff (which is bad)
|
||||
return "error";
|
||||
@ -96,8 +118,7 @@ PeerConnectionIdp.prototype = {
|
||||
},
|
||||
|
||||
_getIdentityFromSdp: function(sdp) {
|
||||
// we only pull from the session level right now
|
||||
// TODO allow for per-m=-section identity
|
||||
// a=identity is session level
|
||||
let mLineMatch = sdp.match(PeerConnectionIdp._mLinePattern);
|
||||
let sessionLevel = sdp.substring(0, mLineMatch.index);
|
||||
let idMatch = sessionLevel.match(PeerConnectionIdp._identityPattern);
|
||||
@ -106,15 +127,17 @@ PeerConnectionIdp.prototype = {
|
||||
try {
|
||||
assertion = JSON.parse(atob(idMatch[1]));
|
||||
} catch (e) {
|
||||
this._warning("RTC identity: invalid identity assertion: " + e, null, 0);
|
||||
this.reportError("validation",
|
||||
"invalid identity assertion: " + e);
|
||||
} // for JSON.parse
|
||||
if (typeof assertion.idp === "object" &&
|
||||
typeof assertion.idp.domain === "string" &&
|
||||
typeof assertion.assertion === "string") {
|
||||
return assertion;
|
||||
}
|
||||
this._warning("RTC identity: assertion missing idp/idp.domain/assertion",
|
||||
null, 0);
|
||||
|
||||
this.reportError("validation", "assertion missing" +
|
||||
" idp/idp.domain/assertion");
|
||||
}
|
||||
// undefined!
|
||||
},
|
||||
@ -128,14 +151,14 @@ PeerConnectionIdp.prototype = {
|
||||
verifyIdentityFromSDP: function(sdp, callback) {
|
||||
let identity = this._getIdentityFromSdp(sdp);
|
||||
let fingerprint = this._getFingerprintFromSdp(sdp);
|
||||
// it's safe to use the fingerprint from the SDP here,
|
||||
// it's safe to use the fingerprint we got from the SDP here,
|
||||
// only because we ensure that there is only one
|
||||
if (!fingerprint || !identity) {
|
||||
callback(null);
|
||||
return;
|
||||
}
|
||||
this.setIdentityProvider(identity.idp.domain, identity.idp.protocol);
|
||||
|
||||
this.setIdentityProvider(identity.idp.domain, identity.idp.protocol);
|
||||
this._verifyIdentity(identity.assertion, fingerprint, callback);
|
||||
},
|
||||
|
||||
@ -160,7 +183,7 @@ PeerConnectionIdp.prototype = {
|
||||
if (providerPortIdx > 0) {
|
||||
provider = provider.substring(0, providerPortIdx);
|
||||
}
|
||||
var idnService = Components.classes["@mozilla.org/network/idn-service;1"].
|
||||
let idnService = Components.classes["@mozilla.org/network/idn-service;1"].
|
||||
getService(Components.interfaces.nsIIDNService);
|
||||
if (idnService.convertUTF8toACE(tail) !==
|
||||
idnService.convertUTF8toACE(provider)) {
|
||||
@ -174,10 +197,10 @@ PeerConnectionIdp.prototype = {
|
||||
|
||||
// we are very defensive here when handling the message from the IdP
|
||||
// proxy so that broken IdPs can only do as little harm as possible.
|
||||
_checkVerifyResponse: function(
|
||||
message, fingerprint) {
|
||||
let warn = function(message) {
|
||||
this._warning("RTC identity: VERIFY error: " + message, null, 0);
|
||||
_checkVerifyResponse: function(message, fingerprint) {
|
||||
let warn = function(msg) {
|
||||
this.reportError("validation",
|
||||
"assertion validation failure: " + msg);
|
||||
}.bind(this);
|
||||
|
||||
try {
|
||||
@ -207,14 +230,10 @@ PeerConnectionIdp.prototype = {
|
||||
_verifyIdentity: function(
|
||||
assertion, fingerprint, callback) {
|
||||
function onVerification(message) {
|
||||
if (!message) {
|
||||
this._warning("RTC identity: verification failure", null, 0);
|
||||
callback(null);
|
||||
return;
|
||||
}
|
||||
if (this._checkVerifyResponse(message, fingerprint)) {
|
||||
if (message && this._checkVerifyResponse(message, fingerprint)) {
|
||||
callback(message);
|
||||
} else {
|
||||
this._warning("RTC identity: assertion validation failure", null, 0);
|
||||
callback(null);
|
||||
}
|
||||
}
|
||||
@ -223,7 +242,7 @@ PeerConnectionIdp.prototype = {
|
||||
type: "VERIFY",
|
||||
message: assertion
|
||||
};
|
||||
this._sendToIdp(request, onVerification.bind(this));
|
||||
this._sendToIdp(request, "validation", onVerification.bind(this));
|
||||
},
|
||||
|
||||
/**
|
||||
@ -233,21 +252,16 @@ PeerConnectionIdp.prototype = {
|
||||
* line) is passed to the callback.
|
||||
*/
|
||||
appendIdentityToSDP: function(sdp, fingerprint, callback) {
|
||||
if (!this._idpchannel) {
|
||||
callback(sdp);
|
||||
let onAssertion = function() {
|
||||
callback(this.wrapSdp(sdp), this.assertion);
|
||||
}.bind(this);
|
||||
|
||||
if (!this._idpchannel || this.assertion) {
|
||||
onAssertion();
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.assertion) {
|
||||
callback(this.wrapSdp(sdp));
|
||||
return;
|
||||
}
|
||||
|
||||
function onAssertion(assertion) {
|
||||
callback(this.wrapSdp(sdp), assertion);
|
||||
}
|
||||
|
||||
this._getIdentityAssertion(fingerprint, onAssertion.bind(this));
|
||||
this._getIdentityAssertion(fingerprint, onAssertion);
|
||||
},
|
||||
|
||||
/**
|
||||
@ -267,7 +281,9 @@ PeerConnectionIdp.prototype = {
|
||||
|
||||
getIdentityAssertion: function(fingerprint, callback) {
|
||||
if (!this._idpchannel) {
|
||||
throw new Error("IdP not set");
|
||||
this.reportError("assertion", "IdP not set");
|
||||
callback(null);
|
||||
return;
|
||||
}
|
||||
|
||||
this._getIdentityAssertion(fingerprint, callback);
|
||||
@ -298,19 +314,33 @@ PeerConnectionIdp.prototype = {
|
||||
callback(this.assertion);
|
||||
}
|
||||
|
||||
this._sendToIdp(request, trapAssertion.bind(this));
|
||||
this._sendToIdp(request, "assertion", trapAssertion.bind(this));
|
||||
},
|
||||
|
||||
/**
|
||||
* Packages a message and sends it to the IdP.
|
||||
* @param request (dictionary) the message to send
|
||||
* @param type (DOMString) the type of message (assertion/validation)
|
||||
* @param callback (function) the function to call with the results
|
||||
*/
|
||||
_sendToIdp: function(request, callback) {
|
||||
// this is not secure
|
||||
// but there are no good alternatives until bug 968335 lands
|
||||
// when that happens, change this to use the new mechanism
|
||||
request.origin = this._win.document.nodePrincipal.origin;
|
||||
_sendToIdp: function(request, type, callback) {
|
||||
request.origin = Cu.getWebIDLCallerPrincipal().origin;
|
||||
this._idpchannel.send(request, this._wrapCallback(type, callback));
|
||||
},
|
||||
|
||||
this._idpchannel.send(request, this._wrapCallback(callback));
|
||||
_reportIdpError: function(type, message) {
|
||||
let args = {};
|
||||
let msg = "";
|
||||
if (message.type === "ERROR") {
|
||||
msg = message.error;
|
||||
} else {
|
||||
msg = JSON.stringify(message.message);
|
||||
if (message.type === "LOGINNEEDED") {
|
||||
args.loginUrl = message.loginUrl;
|
||||
}
|
||||
}
|
||||
this.reportError(type, "received response of type '" +
|
||||
message.type + "' from IdP: " + msg, args);
|
||||
},
|
||||
|
||||
/**
|
||||
@ -318,10 +348,10 @@ PeerConnectionIdp.prototype = {
|
||||
* receive any message other than one where the IdP generated a "SUCCESS"
|
||||
* response.
|
||||
*/
|
||||
_wrapCallback: function(callback) {
|
||||
_wrapCallback: function(type, callback) {
|
||||
let timeout = this._win.setTimeout(function() {
|
||||
this._warning("RTC identity: IdP timeout for " + this._idpchannel + " " +
|
||||
(this._idpchannel.ready ? "[ready]" : "[not ready]"), null, 0);
|
||||
this.reportError(type, "IdP timeout for " + this._idpchannel + " " +
|
||||
(this._idpchannel.ready ? "[ready]" : "[not ready]"));
|
||||
timeout = null;
|
||||
callback(null);
|
||||
}.bind(this), this._timeout);
|
||||
@ -332,12 +362,12 @@ PeerConnectionIdp.prototype = {
|
||||
}
|
||||
this._win.clearTimeout(timeout);
|
||||
timeout = null;
|
||||
var content = null;
|
||||
|
||||
let content = null;
|
||||
if (message.type === "SUCCESS") {
|
||||
content = message.message;
|
||||
} else {
|
||||
this._warning("RTC Identity: received response of type '" +
|
||||
message.type + "' from IdP: " + message.message, null, 0);
|
||||
this._reportIdpError(type, message);
|
||||
}
|
||||
callback(content);
|
||||
}.bind(this);
|
||||
|
15
dom/media/tests/identity/identityevent.js
Normal file
15
dom/media/tests/identity/identityevent.js
Normal file
@ -0,0 +1,15 @@
|
||||
(function(g) {
|
||||
'use strict';
|
||||
|
||||
g.trapIdentityEvents = function(target) {
|
||||
var state = {};
|
||||
var identityEvents = ['idpassertionerror', 'idpvalidationerror',
|
||||
'identityresult', 'peeridentity'];
|
||||
identityEvents.forEach(function(name) {
|
||||
target.addEventListener(name, function(e) {
|
||||
state[name] = e;
|
||||
}, false);
|
||||
});
|
||||
return state;
|
||||
};
|
||||
}(this));
|
@ -3,6 +3,8 @@
|
||||
|
||||
function IDPJS() {
|
||||
this.domain = window.location.host;
|
||||
var p = window.location.pathname;
|
||||
this.protocol = p.substring(p.lastIndexOf('/') + 1) + window.location.hash;
|
||||
this.username = "someone@" + this.domain;
|
||||
// so rather than create a million different IdP configurations and litter
|
||||
// the world with files all containing near-identical code, let's use the
|
||||
@ -70,7 +72,7 @@
|
||||
message : {
|
||||
idp : {
|
||||
domain : this.domain,
|
||||
protocol : "idp.html"
|
||||
protocol : this.protocol
|
||||
},
|
||||
assertion : JSON.stringify({
|
||||
username : this.username,
|
||||
@ -82,12 +84,16 @@
|
||||
|
||||
case "VERIFY":
|
||||
var payload = JSON.parse(message.message);
|
||||
var contents = payload.contents;
|
||||
if (this.instructions.some(is("bad"))) {
|
||||
contents = {};
|
||||
}
|
||||
this.sendResponse({
|
||||
type : "SUCCESS",
|
||||
id : message.id,
|
||||
message : {
|
||||
identity : payload.username,
|
||||
contents : payload.contents
|
||||
contents : contents
|
||||
}
|
||||
});
|
||||
break;
|
||||
|
@ -3,6 +3,7 @@ skip-if = e10s
|
||||
support-files =
|
||||
/.well-known/idp-proxy/idp.html
|
||||
/.well-known/idp-proxy/idp-proxy.js
|
||||
identityevent.js
|
||||
|
||||
# All tests are disabled on android due to lack of https support in mochitest
|
||||
# (Bug 975149)
|
||||
|
@ -30,10 +30,11 @@ function theTest() {
|
||||
[
|
||||
"GET_IDENTITY_ASSERTION_FAILS_WITHOUT_PROVIDER",
|
||||
function(test) {
|
||||
test.pcLocal._pc.getIdentityAssertion(function(err) {
|
||||
ok(err, "getIdentityAssertion must fail without provider");
|
||||
test.pcLocal._pc.onidpassertionerror = function(e) {
|
||||
ok(e, "getIdentityAssertion must fail without provider");
|
||||
test.next();
|
||||
});
|
||||
};
|
||||
test.pcLocal._pc.getIdentityAssertion();
|
||||
},
|
||||
],
|
||||
[
|
||||
@ -52,6 +53,10 @@ function theTest() {
|
||||
test.next();
|
||||
}
|
||||
};
|
||||
test.pcLocal._pc.onidpassertionerror = function(e) {
|
||||
ok(false, "error event fired");
|
||||
test.next();
|
||||
};
|
||||
test.pcLocal._pc.getIdentityAssertion();
|
||||
test.pcLocal._pc.getIdentityAssertion();
|
||||
}
|
||||
@ -64,10 +69,11 @@ function theTest() {
|
||||
ok(false, "Should not get an identity result");
|
||||
test.next();
|
||||
};
|
||||
test.pcLocal._pc.getIdentityAssertion(function(err) {
|
||||
ok(err, "Got error callback from getIdentityAssertion");
|
||||
test.pcLocal._pc.onidpassertionerror = function(err) {
|
||||
ok(err, "Got error event from getIdentityAssertion");
|
||||
test.next();
|
||||
});
|
||||
};
|
||||
test.pcLocal._pc.getIdentityAssertion();
|
||||
}
|
||||
],
|
||||
[
|
||||
@ -78,10 +84,11 @@ function theTest() {
|
||||
ok(false, "Should not get an identity result");
|
||||
test.next();
|
||||
};
|
||||
test.pcLocal._pc.getIdentityAssertion(function(err) {
|
||||
ok(err, "Got error callback from getIdentityAssertion");
|
||||
test.pcLocal._pc.onidpassertionerror = function(e) {
|
||||
ok(e, "Got error callback from getIdentityAssertion");
|
||||
test.next();
|
||||
});
|
||||
};
|
||||
test.pcLocal._pc.getIdentityAssertion();
|
||||
}
|
||||
],
|
||||
[
|
||||
@ -92,10 +99,11 @@ function theTest() {
|
||||
checkIdentity(e.assertion, 'user@example.com');
|
||||
test.next();
|
||||
};
|
||||
test.pcLocal._pc.getIdentityAssertion(function(err) {
|
||||
test.pcLocal._pc.onidpassertionerror = function(e) {
|
||||
ok(false, "Got error callback from getIdentityAssertion");
|
||||
test.next();
|
||||
});
|
||||
};
|
||||
test.pcLocal._pc.getIdentityAssertion();
|
||||
}
|
||||
]
|
||||
]);
|
||||
|
@ -55,19 +55,16 @@ function handleFailure(done) {
|
||||
ok(false, "IdP error" + error);
|
||||
done();
|
||||
}
|
||||
setTimeout(failure, 5000);
|
||||
return failure;
|
||||
}
|
||||
|
||||
function test_success_response(done) {
|
||||
var idp;
|
||||
var failure = handleFailure(done);
|
||||
var timeout = setTimeout(failure, 5000);;
|
||||
|
||||
function handleResponse(response) {
|
||||
is(SpecialPowers.wrap(response).type, "SUCCESS", "IdP responds with SUCCESS");
|
||||
idp.close();
|
||||
clearTimeout(timeout);
|
||||
done();
|
||||
}
|
||||
|
||||
@ -79,12 +76,10 @@ function test_success_response(done) {
|
||||
function test_error_response(done) {
|
||||
var idp;
|
||||
var failure = handleFailure(done);
|
||||
var timeout = setTimeout(failure, 5000);;
|
||||
|
||||
function handleResponse(response) {
|
||||
is(SpecialPowers.wrap(response).type, "ERROR", "IdP should produce ERROR");
|
||||
idp.close();
|
||||
clearTimeout(timeout);
|
||||
done();
|
||||
}
|
||||
|
||||
@ -96,13 +91,11 @@ function test_error_response(done) {
|
||||
function test_delayed_response(done) {
|
||||
var idp;
|
||||
var failure = handleFailure(done);
|
||||
var timeout = setTimeout(failure, 5000);;
|
||||
|
||||
function handleResponse(response) {
|
||||
is(SpecialPowers.wrap(response).type, "SUCCESS",
|
||||
"IdP should handle delayed response");
|
||||
idp.close();
|
||||
clearTimeout(timeout);
|
||||
done();
|
||||
}
|
||||
|
||||
|
@ -7,6 +7,7 @@
|
||||
<script type="application/javascript" src="../mochitest/head.js"></script>
|
||||
<script type="application/javascript" src="../mochitest/pc.js"></script>
|
||||
<script type="application/javascript" src="../mochitest/templates.js"></script>
|
||||
<script type="application/javascript" src="identityevent.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<pre id="test">
|
||||
@ -21,6 +22,10 @@ function theTest() {
|
||||
test.setMediaConstraints([{audio: true}], [{audio: true}]);
|
||||
test.setIdentityProvider(test.pcLocal, "test1.example.com", "idp.html", "someone");
|
||||
test.setIdentityProvider(test.pcRemote, "test2.example.com", "idp.html", "someone");
|
||||
|
||||
var localEvents = trapIdentityEvents(test.pcLocal._pc);
|
||||
var remoteEvents = trapIdentityEvents(test.pcRemote._pc);
|
||||
|
||||
test.chain.append([
|
||||
[
|
||||
"PEER_IDENTITY_IS_SET_CORRECTLY",
|
||||
@ -33,6 +38,7 @@ function theTest() {
|
||||
|
||||
function checkOrSetupCheck(pc, pfx, idp, name) {
|
||||
function checkIdentity() {
|
||||
ok(pc.peerIdentity, pfx + "peerIdentity is set");
|
||||
is(pc.peerIdentity.idp, idp, pfx + "IdP is correct");
|
||||
is(pc.peerIdentity.name, name + "@" + idp, pfx + "identity is correct");
|
||||
}
|
||||
@ -53,11 +59,6 @@ function theTest() {
|
||||
}
|
||||
}
|
||||
|
||||
setTimeout(function() {
|
||||
ok(false, "Timed out waiting for peerIdentity.");
|
||||
test.next();
|
||||
}, 5000); // probably should be something in the base harness for this
|
||||
|
||||
checkOrSetupCheck(test.pcLocal._pc, "local: ", "test2.example.com", "someone");
|
||||
checkOrSetupCheck(test.pcRemote._pc, "remote: ", "test1.example.com", "someone");
|
||||
if (outstanding <= 0) {
|
||||
@ -65,6 +66,20 @@ function theTest() {
|
||||
}
|
||||
}
|
||||
],
|
||||
[
|
||||
"CHECK_IDENTITY_EVENTS",
|
||||
function(test) {
|
||||
ok(!localEvents.idpassertionerror , "No assertion generation errors on local");
|
||||
ok(!remoteEvents.idpassertionerror, "No assertion generation errors on remote");
|
||||
ok(!localEvents.idpvalidationerror, "No assertion validation errors on local");
|
||||
ok( !remoteEvents.idpvalidationerror, "No assertion validation errors on remote");
|
||||
ok(localEvents.identityresult, "local acquired identity assertions");
|
||||
ok(remoteEvents.identityresult, "remote acquired identity assertions");
|
||||
ok(localEvents.peeridentity, "local got peer identity");
|
||||
ok(remoteEvents.peeridentity, "remote got peer identity");
|
||||
test.next();
|
||||
}
|
||||
],
|
||||
[
|
||||
"OFFERS_AND_ANSWERS_INCLUDE_IDENTITY",
|
||||
function(test) {
|
||||
|
@ -6,6 +6,7 @@
|
||||
<script type="application/javascript" src="../mochitest/head.js"></script>
|
||||
<script type="application/javascript" src="../mochitest/pc.js"></script>
|
||||
<script type="application/javascript" src="../mochitest/templates.js"></script>
|
||||
<script type="application/javascript" src="identityevent.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<pre id="test">
|
||||
@ -20,25 +21,60 @@ runTest(function () {
|
||||
test.setMediaConstraints([{audio: true}], [{audio: true}]);
|
||||
// first example generates an error
|
||||
test.setIdentityProvider(test.pcLocal, 'example.com', 'idp.html#error', 'nobody');
|
||||
// first doesn't even get a ready message from the IdP - results in a timeout
|
||||
test.setIdentityProvider(test.pcRemote, 'example.com', 'idp.html#error:ready', 'nobody');
|
||||
// second generates a bad assertion; which fails to validate
|
||||
test.setIdentityProvider(test.pcRemote, 'example.com', 'idp.html#bad', 'nobody');
|
||||
|
||||
var localEvents = trapIdentityEvents(test.pcLocal._pc);
|
||||
var remoteEvents = trapIdentityEvents(test.pcRemote._pc);
|
||||
|
||||
test.chain.append([
|
||||
[
|
||||
"PEER_IDENTITY_IS_EMPTY",
|
||||
function(test) {
|
||||
ok(!test.pcLocal._pc.peerIdentity, "local peerIdentity is not set");
|
||||
ok(!test.pcRemote._pc.peerIdentity, "remote peerIdentity is not set");
|
||||
test.next();
|
||||
}
|
||||
],
|
||||
[
|
||||
"OFFERS_AND_ANSWERS_DONT_INCLUDE_IDENTITY",
|
||||
function(test) {
|
||||
ok(!test.pcLocal._last_offer.sdp.contains("a=identity"), "a=identity not contained in the offer SDP");
|
||||
ok(!test.pcRemote._last_answer.sdp.contains("a=identity"), "a=identity not contained in the answer SDP");
|
||||
test.next();
|
||||
}
|
||||
],
|
||||
[
|
||||
'CHECK_IDENTITY_EVENTS',
|
||||
function(test) {
|
||||
function checkEvents() {
|
||||
ok(localEvents.idpassertionerror, 'local assertion generation should fail (idpassertionerror)');
|
||||
is(localEvents.idpassertionerror.idp, 'example.com', 'event IdP is correct');
|
||||
is(localEvents.idpassertionerror.protocol, 'idp.html#error', 'event IdP protocol is #error');
|
||||
ok(!remoteEvents.idpassertionerror, 'remote assertion generation should succeed (idpassertionerror)');
|
||||
ok(!localEvents.identityresult, 'local assertion generation should fail (identityresult)');
|
||||
ok(remoteEvents.identityresult, 'remote assertion generation should succeed (identityresult)');
|
||||
|
||||
ok(!localEvents.peeridentity, 'no peer identity event for local peer');
|
||||
ok(!remoteEvents.peeridentity, 'no peer identity event for remote peer');
|
||||
ok(localEvents.idpvalidationerror, 'local fails to validate');
|
||||
is(localEvents.idpvalidationerror.idp, 'example.com', 'event IdP is correct');
|
||||
is(localEvents.idpvalidationerror.protocol, 'idp.html#bad', 'event IdP protocol is #bad');
|
||||
ok(!remoteEvents.idpvalidationerror, 'remote doesn\'t even see an assertion');
|
||||
|
||||
test.next();
|
||||
}
|
||||
|
||||
// we actually have to wait on this because IdP validation happens asynchronously
|
||||
if (localEvents.idpvalidationerror) {
|
||||
checkEvents();
|
||||
} else {
|
||||
// have to let the other event handler have a chance to record success
|
||||
// before we run the checks that rely on that recording
|
||||
test.pcLocal._pc.onidpvalidationerror = setTimeout.bind(window, checkEvents, 1);
|
||||
}
|
||||
}
|
||||
],
|
||||
[
|
||||
'PEER_IDENTITY_IS_EMPTY',
|
||||
function(test) {
|
||||
ok(!test.pcLocal._pc.peerIdentity, 'local peerIdentity is not set');
|
||||
ok(!test.pcRemote._pc.peerIdentity, 'remote peerIdentity is not set');
|
||||
test.next();
|
||||
}
|
||||
],
|
||||
[
|
||||
'ONLY_REMOTE_SDP_INCLUDES_IDENTITY_ASSERTION',
|
||||
function(test) {
|
||||
ok(!test.pcLocal._last_offer.sdp.contains('a=identity'), 'a=identity not contained in the offer SDP');
|
||||
ok(test.pcRemote._last_answer.sdp.contains('a=identity'), 'a=identity is contained in the answer SDP');
|
||||
test.next();
|
||||
}
|
||||
]
|
||||
]);
|
||||
test.run();
|
||||
});
|
||||
|
@ -2,6 +2,8 @@
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
"use strict";
|
||||
|
||||
|
||||
/**
|
||||
* This class mimics a state machine and handles a list of commands by
|
||||
@ -73,7 +75,8 @@ CommandChain.prototype = {
|
||||
var step = self._commands[self._current];
|
||||
self._current++;
|
||||
|
||||
info("Run step: " + step[0]); // Label
|
||||
self.currentStepLabel = step[0];
|
||||
info("Run step: " + self.currentStepLabel);
|
||||
step[1](self._framework); // Execute step
|
||||
}
|
||||
else if (typeof(self.onFinished) === 'function') {
|
||||
@ -505,9 +508,24 @@ PeerConnectionTest.prototype.close = function PCT_close(onSuccess) {
|
||||
* Executes the next command.
|
||||
*/
|
||||
PeerConnectionTest.prototype.next = function PCT_next() {
|
||||
if (this._stepTimeout) {
|
||||
clearTimeout(this._stepTimeout);
|
||||
this._stepTimeout = null;
|
||||
}
|
||||
this.chain.executeNext();
|
||||
};
|
||||
|
||||
/**
|
||||
* Set a timeout for the current step.
|
||||
* @param {long] ms the number of milliseconds to allow for this step
|
||||
*/
|
||||
PeerConnectionTest.prototype.setStepTimeout = function(ms) {
|
||||
this._stepTimeout = setTimeout(function() {
|
||||
ok(false, "Step timed out: " + this.chain.currentStepLabel);
|
||||
this.next();
|
||||
}.bind(this), ms);
|
||||
};
|
||||
|
||||
/**
|
||||
* Creates an answer for the specified peer connection instance
|
||||
* and automatically handles the failure case.
|
||||
@ -1489,7 +1507,7 @@ PeerConnectionWrapper.prototype = {
|
||||
* Checks if the ICE connection state still waits for a connection to get
|
||||
* established.
|
||||
*
|
||||
* @returns {boolean} True if the connection state is "checking" or "new",
|
||||
* @returns {boolean} True if the connection state is "checking" or "new",
|
||||
* otherwise false.
|
||||
*/
|
||||
isIceConnectionPending : function PCW_isIceConnectionPending() {
|
||||
|
@ -92,7 +92,7 @@ interface mozRTCPeerConnection : EventTarget {
|
||||
optional DOMString protocol,
|
||||
optional DOMString username);
|
||||
[Pref="media.peerconnection.identity.enabled"]
|
||||
void getIdentityAssertion(optional RTCPeerConnectionErrorCallback failureCallback);
|
||||
void getIdentityAssertion();
|
||||
void createOffer (RTCSessionDescriptionCallback successCallback,
|
||||
RTCPeerConnectionErrorCallback failureCallback,
|
||||
optional MediaConstraints constraints);
|
||||
@ -145,5 +145,8 @@ interface mozRTCPeerConnection : EventTarget {
|
||||
attribute EventHandler onidentityresult;
|
||||
[Pref="media.peerconnection.identity.enabled"]
|
||||
attribute EventHandler onpeeridentity;
|
||||
[Pref="media.peerconnection.identity.enabled"]
|
||||
attribute EventHandler onidpassertionerror;
|
||||
[Pref="media.peerconnection.identity.enabled"]
|
||||
attribute EventHandler onidpvalidationerror;
|
||||
};
|
||||
|
||||
|
23
dom/webidl/RTCPeerConnectionIdentityErrorEvent.webidl
Normal file
23
dom/webidl/RTCPeerConnectionIdentityErrorEvent.webidl
Normal file
@ -0,0 +1,23 @@
|
||||
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*
|
||||
* Proposed only, not in spec yet:
|
||||
* http://lists.w3.org/Archives/Public/public-webrtc/2013Dec/0104.html
|
||||
*/
|
||||
|
||||
dictionary RTCPeerConnectionIdentityErrorEventInit : EventInit {
|
||||
DOMString idp = "";
|
||||
DOMString protocol = "";
|
||||
DOMString? loginUrl = null;
|
||||
};
|
||||
|
||||
[ChromeOnly,
|
||||
Constructor(DOMString type,
|
||||
optional RTCPeerConnectionIdentityErrorEventInit eventInitDict)]
|
||||
interface RTCPeerConnectionIdentityErrorEvent : Event {
|
||||
readonly attribute DOMString idp;
|
||||
readonly attribute DOMString protocol;
|
||||
readonly attribute DOMString? loginUrl;
|
||||
};
|
@ -597,6 +597,7 @@ GENERATED_EVENTS_WEBIDL_FILES = [
|
||||
'MozStkCommandEvent.webidl',
|
||||
'RTCDataChannelEvent.webidl',
|
||||
'RTCPeerConnectionIceEvent.webidl',
|
||||
'RTCPeerConnectionIdentityErrorEvent.webidl',
|
||||
'RTCPeerConnectionIdentityEvent.webidl',
|
||||
'TrackEvent.webidl',
|
||||
'UserProximityEvent.webidl',
|
||||
|
@ -56,7 +56,7 @@ pref("browser.cache.disk.max_entry_size", 51200); // 50 MB
|
||||
pref("browser.cache.memory.enable", true);
|
||||
// -1 = determine dynamically, 0 = none, n = memory capacity in kilobytes
|
||||
//pref("browser.cache.memory.capacity", -1);
|
||||
// Max-size (in KB) for entries in memory cache. Set to -1 for no limit.
|
||||
// Max-size (in KB) for entries in memory cache. Set to -1 for no limit.
|
||||
// (Note: entries bigger than than 90% of the mem-cache are never cached)
|
||||
pref("browser.cache.memory.max_entry_size", 5120);
|
||||
pref("browser.cache.disk_cache_ssl", true);
|
||||
@ -128,8 +128,8 @@ pref("browser.display.use_system_colors", false);
|
||||
pref("browser.display.foreground_color", "#000000");
|
||||
pref("browser.display.background_color", "#FFFFFF");
|
||||
pref("browser.display.force_inline_alttext", false); // true = force ALT text for missing images to be layed out inline
|
||||
// 0 = no external leading,
|
||||
// 1 = use external leading only when font provides,
|
||||
// 0 = no external leading,
|
||||
// 1 = use external leading only when font provides,
|
||||
// 2 = add extra leading both internal leading and external leading are zero
|
||||
pref("browser.display.normal_lineheight_calc_control", 2);
|
||||
pref("browser.display.show_image_placeholders", true); // true = show image placeholders while image is loaded and when image is broken
|
||||
@ -259,9 +259,9 @@ pref("media.peerconnection.use_document_iceservers", true);
|
||||
// Do not enable identity before fixing domain comparison: see Bug 958741
|
||||
// Do not enable identity before fixing origin spoofing: see Bug 968335
|
||||
pref("media.peerconnection.identity.enabled", false);
|
||||
pref("media.peerconnection.identity.timeout", 5000);
|
||||
pref("media.peerconnection.identity.timeout", 10000);
|
||||
// These values (aec, agc, and noice) are from media/webrtc/trunk/webrtc/common_types.h
|
||||
// kXxxUnchanged = 0, kXxxDefault = 1, and higher values are specific to each
|
||||
// kXxxUnchanged = 0, kXxxDefault = 1, and higher values are specific to each
|
||||
// setting (for Xxx = Ec, Agc, or Ns). Defaults are all set to kXxxDefault here.
|
||||
pref("media.peerconnection.turn.disable", false);
|
||||
pref("media.peerconnection.aec_enabled", true);
|
||||
@ -350,7 +350,7 @@ pref("gfx.hidpi.enabled", 2);
|
||||
pref("gfx.layerscope.enabled", false);
|
||||
pref("gfx.layerscope.port", 23456);
|
||||
|
||||
// 0 = Off, 1 = Full, 2 = Tagged Images Only.
|
||||
// 0 = Off, 1 = Full, 2 = Tagged Images Only.
|
||||
// See eCMSMode in gfx/thebes/gfxPlatform.h
|
||||
pref("gfx.color_management.mode", 2);
|
||||
pref("gfx.color_management.display_profile", "");
|
||||
@ -594,7 +594,7 @@ pref("nglayout.enable_drag_images", true);
|
||||
pref("nglayout.debug.paint_flashing", false);
|
||||
pref("nglayout.debug.paint_flashing_chrome", false);
|
||||
|
||||
// enable/disable widget update area flashing --- only supported with
|
||||
// enable/disable widget update area flashing --- only supported with
|
||||
// BasicLayers (other layer managers always update the entire widget area)
|
||||
pref("nglayout.debug.widget_update_flashing", false);
|
||||
|
||||
@ -666,7 +666,7 @@ pref("print.print_unwriteable_margin_left", -1);
|
||||
pref("print.print_unwriteable_margin_right", -1);
|
||||
pref("print.print_unwriteable_margin_bottom", -1);
|
||||
|
||||
// Enables you to specify the gap from the edge of the paper's
|
||||
// Enables you to specify the gap from the edge of the paper's
|
||||
// unwriteable area to the margin.
|
||||
// This is used by both Printing and Print Preview
|
||||
// Units are in 1/100ths of an inch.
|
||||
@ -675,7 +675,7 @@ pref("print.print_edge_left", 0);
|
||||
pref("print.print_edge_right", 0);
|
||||
pref("print.print_edge_bottom", 0);
|
||||
|
||||
// Pref used by the spellchecker extension to control the
|
||||
// Pref used by the spellchecker extension to control the
|
||||
// maximum number of misspelled words that will be underlined
|
||||
// in a document.
|
||||
pref("extensions.spellcheck.inline.max-misspellings", 500);
|
||||
@ -809,7 +809,7 @@ pref("image.animation_mode", "normal");
|
||||
pref("security.fileuri.strict_origin_policy", true);
|
||||
|
||||
// If there is ever a security firedrill that requires
|
||||
// us to block certian ports global, this is the pref
|
||||
// us to block certian ports global, this is the pref
|
||||
// to use. Is is a comma delimited list of port numbers
|
||||
// for example:
|
||||
// pref("network.security.ports.banned", "1,2,3,4,5");
|
||||
@ -876,7 +876,7 @@ pref("network.warnOnAboutNetworking", true);
|
||||
// pref("network.protocol-handler.expose.imap", true);
|
||||
|
||||
// <http>
|
||||
pref("network.http.version", "1.1"); // default
|
||||
pref("network.http.version", "1.1"); // default
|
||||
// pref("network.http.version", "1.0"); // uncomment this out in case of problems
|
||||
// pref("network.http.version", "0.9"); // it'll work too if you're crazy
|
||||
// keep-alive option is effectively obsolete. Nevertheless it'll work with
|
||||
@ -906,7 +906,7 @@ pref("network.http.response.timeout", 300);
|
||||
// Limit the absolute number of http connections.
|
||||
// Note: the socket transport service will clamp the number below 256 if the OS
|
||||
// cannot allocate that many FDs, and it also always tries to reserve up to 250
|
||||
// file descriptors for things other than sockets.
|
||||
// file descriptors for things other than sockets.
|
||||
pref("network.http.max-connections", 256);
|
||||
|
||||
// If NOT connecting via a proxy, then
|
||||
@ -930,13 +930,13 @@ pref("network.http.accept.default", "text/html,application/xhtml+xml,application
|
||||
|
||||
// Prefs allowing granular control of referers
|
||||
// 0=don't send any, 1=send only on clicks, 2=send on image requests as well
|
||||
pref("network.http.sendRefererHeader", 2);
|
||||
// false=real referer, true=spoof referer (use target URI as referer)
|
||||
pref("network.http.referer.spoofSource", false);
|
||||
pref("network.http.sendRefererHeader", 2);
|
||||
// false=real referer, true=spoof referer (use target URI as referer)
|
||||
pref("network.http.referer.spoofSource", false);
|
||||
// 0=full URI, 1=scheme+host+port+path, 2=scheme+host+port
|
||||
pref("network.http.referer.trimmingPolicy", 0);
|
||||
pref("network.http.referer.trimmingPolicy", 0);
|
||||
// 0=always send, 1=send iff base domains match, 2=send iff hosts match
|
||||
pref("network.http.referer.XOriginPolicy", 0);
|
||||
pref("network.http.referer.XOriginPolicy", 0);
|
||||
|
||||
// Controls whether we send HTTPS referres to other HTTPS sites.
|
||||
// By default this is enabled for compatibility (see bug 141641)
|
||||
@ -1062,7 +1062,7 @@ pref("network.ftp.control.qos", 0);
|
||||
// <ws>: WebSocket
|
||||
pref("network.websocket.enabled", true);
|
||||
|
||||
// 2147483647 == PR_INT32_MAX == ~2 GB
|
||||
// 2147483647 == PR_INT32_MAX == ~2 GB
|
||||
pref("network.websocket.max-message-size", 2147483647);
|
||||
|
||||
// Should we automatically follow http 3xx redirects during handshake
|
||||
@ -1100,7 +1100,7 @@ pref("network.websocket.max-connections", 200);
|
||||
pref("network.websocket.allowInsecureFromHTTPS", false);
|
||||
|
||||
// by default we delay websocket reconnects to same host/port if previous
|
||||
// connection failed, per RFC 6455 section 7.2.3
|
||||
// connection failed, per RFC 6455 section 7.2.3
|
||||
pref("network.websocket.delay-failed-reconnects", true);
|
||||
|
||||
// </ws>
|
||||
@ -1187,7 +1187,7 @@ pref("network.IDN.whitelist.yt", true);
|
||||
|
||||
// IDN ccTLDs
|
||||
// ae, UAE, .<Emarat>
|
||||
pref("network.IDN.whitelist.xn--mgbaam7a8h", true);
|
||||
pref("network.IDN.whitelist.xn--mgbaam7a8h", true);
|
||||
// cn, China, .<China> with variants
|
||||
pref("network.IDN.whitelist.xn--fiqz9s", true); // Traditional
|
||||
pref("network.IDN.whitelist.xn--fiqs8s", true); // Simplified
|
||||
@ -1210,7 +1210,7 @@ pref("network.IDN.whitelist.xn--90a3ac", true);
|
||||
// ru, Russian Federation, .<RF>
|
||||
pref("network.IDN.whitelist.xn--p1ai", true);
|
||||
// sa, Saudi Arabia, .<al-Saudiah> with variants
|
||||
pref("network.IDN.whitelist.xn--mgberp4a5d4ar", true);
|
||||
pref("network.IDN.whitelist.xn--mgberp4a5d4ar", true);
|
||||
pref("network.IDN.whitelist.xn--mgberp4a5d4a87g", true);
|
||||
pref("network.IDN.whitelist.xn--mgbqly7c0a67fbc", true);
|
||||
pref("network.IDN.whitelist.xn--mgbqly7cvafr", true);
|
||||
@ -1248,9 +1248,9 @@ pref("network.IDN.whitelist.xn--jxalpdlp", true);
|
||||
pref("network.IDN.whitelist.xn--kgbechtv", true);
|
||||
pref("network.IDN.whitelist.xn--zckzah", true);
|
||||
|
||||
// If a domain includes any of the following characters, it may be a spoof
|
||||
// attempt and so we always display the domain name as punycode. This would
|
||||
// override the settings "network.IDN_show_punycode" and
|
||||
// If a domain includes any of the following characters, it may be a spoof
|
||||
// attempt and so we always display the domain name as punycode. This would
|
||||
// override the settings "network.IDN_show_punycode" and
|
||||
// "network.IDN.whitelist.*".
|
||||
pref("network.IDN.blacklist_chars", "\u0020\u00A0\u00BC\u00BD\u00BE\u01C3\u02D0\u0337\u0338\u0589\u05C3\u05F4\u0609\u060A\u066A\u06D4\u0701\u0702\u0703\u0704\u115F\u1160\u1735\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u200B\u2024\u2027\u2028\u2029\u202F\u2039\u203A\u2041\u2044\u2052\u205F\u2153\u2154\u2155\u2156\u2157\u2158\u2159\u215A\u215B\u215C\u215D\u215E\u215F\u2215\u2236\u23AE\u2571\u29F6\u29F8\u2AFB\u2AFD\u2FF0\u2FF1\u2FF2\u2FF3\u2FF4\u2FF5\u2FF6\u2FF7\u2FF8\u2FF9\u2FFA\u2FFB\u3000\u3002\u3014\u3015\u3033\u3164\u321D\u321E\u33AE\u33AF\u33C6\u33DF\uA789\uFE14\uFE15\uFE3F\uFE5D\uFE5E\uFEFF\uFF0E\uFF0F\uFF61\uFFA0\uFFF9\uFFFA\uFFFB\uFFFC\uFFFD");
|
||||
|
||||
@ -1343,7 +1343,7 @@ pref("network.negotiate-auth.using-native-gsslib", true);
|
||||
|
||||
#ifdef XP_WIN
|
||||
|
||||
// Default to using the SSPI intead of GSSAPI on windows
|
||||
// Default to using the SSPI intead of GSSAPI on windows
|
||||
pref("network.auth.use-sspi", true);
|
||||
|
||||
#endif
|
||||
@ -1354,7 +1354,7 @@ pref("network.auth.use-sspi", true);
|
||||
// with native NTLM. (See bug 520607 for details.) Using generic NTLM authentication
|
||||
// can expose the user to reflection attack vulnerabilities. Do not change this
|
||||
// unless you know what you're doing!
|
||||
// This pref should be removed 6 months after the release of firefox 3.6.
|
||||
// This pref should be removed 6 months after the release of firefox 3.6.
|
||||
pref("network.auth.force-generic-ntlm", false);
|
||||
|
||||
// The following prefs are used to enable automatic use of the operating
|
||||
@ -1703,7 +1703,7 @@ pref("profile.manage_only_at_launch", false);
|
||||
pref("prefs.converted-to-utf8",false);
|
||||
|
||||
// --------------------------------------------------
|
||||
// IBMBIDI
|
||||
// IBMBIDI
|
||||
// --------------------------------------------------
|
||||
//
|
||||
// ------------------
|
||||
@ -1761,7 +1761,7 @@ pref("layout.word_select.stop_at_punctuation", true);
|
||||
// 0 = use platform default
|
||||
// 1 = caret moves and blinks as when there is no selection; word
|
||||
// delete deselects the selection and then deletes word
|
||||
// 2 = caret moves to selection edge and is not visible during selection;
|
||||
// 2 = caret moves to selection edge and is not visible during selection;
|
||||
// word delete deletes the selection (Mac and Linux default)
|
||||
// 3 = caret moves and blinks as when there is no selection; word delete
|
||||
// deletes the selection
|
||||
@ -1796,7 +1796,7 @@ pref("layout.css.masking.enabled", false);
|
||||
pref("layout.css.masking.enabled", true);
|
||||
#endif
|
||||
|
||||
// Is support for mix-blend-mode enabled?
|
||||
// Is support for mix-blend-mode enabled?
|
||||
pref("layout.css.mix-blend-mode.enabled", false);
|
||||
|
||||
// Is support for the the @supports rule enabled?
|
||||
@ -2002,7 +2002,7 @@ pref("dom.ipc.plugins.parentTimeoutSecs", 0);
|
||||
// we consider it failed.
|
||||
pref("dom.ipc.plugins.processLaunchTimeoutSecs", 45);
|
||||
#ifdef XP_WIN
|
||||
// How long a plugin is allowed to process a synchronous IPC message
|
||||
// How long a plugin is allowed to process a synchronous IPC message
|
||||
// before we display the plugin hang UI
|
||||
pref("dom.ipc.plugins.hangUITimeoutSecs", 11);
|
||||
// Minimum time that the plugin hang UI will be displayed
|
||||
@ -2292,7 +2292,7 @@ pref("font.name-list.monospace.zh-CN", "MS Song, SimSun, SimSun-ExtB");
|
||||
|
||||
// Per Taiwanese users' demand. They don't want to use TC fonts for
|
||||
// rendering Latin letters. (bug 88579)
|
||||
pref("font.name.serif.zh-TW", "Times New Roman");
|
||||
pref("font.name.serif.zh-TW", "Times New Roman");
|
||||
pref("font.name.sans-serif.zh-TW", "Arial");
|
||||
pref("font.name.monospace.zh-TW", "MingLiU");
|
||||
pref("font.name-list.serif.zh-TW", "PMingLiu, MingLiU, MingLiU-ExtB");
|
||||
@ -2331,8 +2331,8 @@ pref("font.name-list.monospace.x-armn", "Arial AMU, Arial Unicode MS, Code2000")
|
||||
pref("font.name.serif.x-beng", "Vrinda");
|
||||
pref("font.name.sans-serif.x-beng", "Vrinda");
|
||||
pref("font.name.monospace.x-beng", "Mitra Mono");
|
||||
pref("font.name-list.serif.x-beng", "Vrinda, Akaash, Likhan, Ekushey Punarbhaba, Code2000, Arial Unicode MS");
|
||||
pref("font.name-list.sans-serif.x-beng", "Vrinda, Akaash, Likhan, Ekushey Punarbhaba, Code2000, Arial Unicode MS");
|
||||
pref("font.name-list.serif.x-beng", "Vrinda, Akaash, Likhan, Ekushey Punarbhaba, Code2000, Arial Unicode MS");
|
||||
pref("font.name-list.sans-serif.x-beng", "Vrinda, Akaash, Likhan, Ekushey Punarbhaba, Code2000, Arial Unicode MS");
|
||||
pref("font.name-list.monospace.x-beng", "Likhan, Mukti Narrow, Code2000, Arial Unicode MS");
|
||||
|
||||
pref("font.name.serif.x-cans", "Aboriginal Serif");
|
||||
@ -2542,7 +2542,7 @@ pref("font.size.fixed.zh-HK", 16);
|
||||
// We have special support for Monotype Symbol on Windows.
|
||||
pref("font.mathfont-family", "MathJax_Main, STIXNonUnicode, STIXSizeOneSym, STIXSize1, STIXGeneral, Asana Math, Symbol, DejaVu Sans, Cambria Math");
|
||||
|
||||
// cleartype settings - false implies default system settings
|
||||
// cleartype settings - false implies default system settings
|
||||
|
||||
// use cleartype rendering for downloadable fonts (win xp only)
|
||||
pref("gfx.font_rendering.cleartype.use_for_downloadable_fonts", true);
|
||||
@ -2557,7 +2557,7 @@ pref("gfx.font_rendering.cleartype.always_use_for_content", false);
|
||||
// HKLM/Software/Microsoft/Avalon.Graphics/<display> (gamma, pixel structure)
|
||||
// and selection of the ClearType/antialiasing mode.
|
||||
//
|
||||
// A value of -1 implies use the default value, otherwise value ranges
|
||||
// A value of -1 implies use the default value, otherwise value ranges
|
||||
// follow registry settings:
|
||||
// gamma [1000, 2200] default: based on screen, typically 2200 (== 2.2)
|
||||
// enhanced contrast [0, 1000] default: 50
|
||||
@ -2574,7 +2574,7 @@ pref("gfx.font_rendering.cleartype.always_use_for_content", false);
|
||||
// See:
|
||||
// http://msdn.microsoft.com/en-us/library/aa970267.aspx
|
||||
// http://msdn.microsoft.com/en-us/library/dd368190%28v=VS.85%29.aspx
|
||||
// Note: DirectWrite uses the "Enhanced Contrast Level" value rather than the
|
||||
// Note: DirectWrite uses the "Enhanced Contrast Level" value rather than the
|
||||
// "Text Contrast Level" value
|
||||
|
||||
pref("gfx.font_rendering.cleartype_params.gamma", -1);
|
||||
@ -2680,7 +2680,7 @@ pref("browser.drag_out_of_frame_style", 1);
|
||||
pref("ui.key.saveLink.shift", false); // true = shift, false = meta
|
||||
|
||||
// default fonts (in UTF8 and using canonical names)
|
||||
// to determine canonical font names, use a debug build and
|
||||
// to determine canonical font names, use a debug build and
|
||||
// enable NSPR logging for module fontInfoLog:5
|
||||
// canonical names immediately follow '(fontinit) family:' in the log
|
||||
|
||||
@ -2719,10 +2719,10 @@ pref("font.name-list.fantasy.he", "Times New Roman");
|
||||
|
||||
pref("font.name.serif.ja", "Hiragino Mincho ProN");
|
||||
pref("font.name.sans-serif.ja", "Hiragino Kaku Gothic ProN");
|
||||
pref("font.name.monospace.ja", "Osaka-Mono");
|
||||
pref("font.name.monospace.ja", "Osaka-Mono");
|
||||
pref("font.name-list.serif.ja", "Hiragino Mincho ProN,Hiragino Mincho Pro");
|
||||
pref("font.name-list.sans-serif.ja", "Hiragino Kaku Gothic ProN,Hiragino Kaku Gothic Pro");
|
||||
pref("font.name-list.monospace.ja", "Osaka-Mono");
|
||||
pref("font.name-list.monospace.ja", "Osaka-Mono");
|
||||
|
||||
pref("font.name.serif.ko", "AppleMyungjo");
|
||||
pref("font.name.sans-serif.ko", "Apple SD Gothic Neo");
|
||||
@ -2755,7 +2755,7 @@ pref("font.name.monospace.x-armn", "Mshtakan");
|
||||
pref("font.name-list.serif.x-armn", "Mshtakan");
|
||||
pref("font.name-list.sans-serif.x-armn", "Mshtakan");
|
||||
pref("font.name-list.monospace.x-armn", "Mshtakan");
|
||||
|
||||
|
||||
pref("font.name.serif.x-baltic", "Times");
|
||||
pref("font.name.sans-serif.x-baltic", "Helvetica");
|
||||
pref("font.name.monospace.x-baltic", "Courier");
|
||||
@ -2826,42 +2826,42 @@ pref("font.name-list.monospace.x-ethi", "Kefa,Abyssinica SIL");
|
||||
pref("font.name.serif.x-geor", "TITUS Cyberbit Basic");
|
||||
pref("font.name.sans-serif.x-geor", "Zuzumbo");
|
||||
pref("font.name.monospace.x-geor", "Zuzumbo");
|
||||
pref("font.name-list.serif.x-geor", "TITUS Cyberbit Basic");
|
||||
pref("font.name-list.serif.x-geor", "TITUS Cyberbit Basic");
|
||||
pref("font.name-list.sans-serif.x-geor", "Zuzumbo");
|
||||
pref("font.name-list.monospace.x-geor", "Zuzumbo");
|
||||
|
||||
pref("font.name.serif.x-gujr", "Gujarati MT");
|
||||
pref("font.name.sans-serif.x-gujr", "Gujarati Sangam MN");
|
||||
pref("font.name.monospace.x-gujr", "Gujarati Sangam MN");
|
||||
pref("font.name-list.serif.x-gujr", "Gujarati MT");
|
||||
pref("font.name-list.serif.x-gujr", "Gujarati MT");
|
||||
pref("font.name-list.sans-serif.x-gujr", "Gujarati Sangam MN,Gujarati MT");
|
||||
pref("font.name-list.monospace.x-gujr", "Gujarati Sangam MN,Gujarati MT");
|
||||
|
||||
pref("font.name.serif.x-guru", "Gurmukhi MT");
|
||||
pref("font.name.sans-serif.x-guru", "Gurmukhi MT");
|
||||
pref("font.name.monospace.x-guru", "Gurmukhi MT");
|
||||
pref("font.name-list.serif.x-guru", "Gurmukhi MT");
|
||||
pref("font.name-list.serif.x-guru", "Gurmukhi MT");
|
||||
pref("font.name-list.sans-serif.x-guru", "Gurmukhi MT");
|
||||
pref("font.name-list.monospace.x-guru", "Gurmukhi MT");
|
||||
|
||||
pref("font.name.serif.x-khmr", "Khmer MN");
|
||||
pref("font.name.sans-serif.x-khmr", "Khmer Sangam MN");
|
||||
pref("font.name.monospace.x-khmr", "Khmer Sangam MN");
|
||||
pref("font.name-list.serif.x-khmr", "Khmer MN");
|
||||
pref("font.name-list.serif.x-khmr", "Khmer MN");
|
||||
pref("font.name-list.sans-serif.x-khmr", "Khmer Sangam MN");
|
||||
pref("font.name-list.monospace.x-khmr", "Khmer Sangam MN");
|
||||
|
||||
pref("font.name.serif.x-mlym", "Malayalam MN");
|
||||
pref("font.name.sans-serif.x-mlym", "Malayalam Sangam MN");
|
||||
pref("font.name.monospace.x-mlym", "Malayalam Sangam MN");
|
||||
pref("font.name-list.serif.x-mlym", "Malayalam MN");
|
||||
pref("font.name-list.serif.x-mlym", "Malayalam MN");
|
||||
pref("font.name-list.sans-serif.x-mlym", "Malayalam Sangam MN");
|
||||
pref("font.name-list.monospace.x-mlym", "Malayalam Sangam MN");
|
||||
|
||||
pref("font.name.serif.x-orya", "Oriya MN");
|
||||
pref("font.name.sans-serif.x-orya", "Oriya Sangam MN");
|
||||
pref("font.name.monospace.x-orya", "Oriya Sangam MN");
|
||||
pref("font.name-list.serif.x-orya", "Oriya MN");
|
||||
pref("font.name-list.serif.x-orya", "Oriya MN");
|
||||
pref("font.name-list.sans-serif.x-orya", "Oriya Sangam MN");
|
||||
pref("font.name-list.monospace.x-orya", "Oriya Sangam MN");
|
||||
|
||||
@ -2932,9 +2932,9 @@ pref("font.name-list.serif.zh-CN", "Times,STSong,Heiti SC");
|
||||
pref("font.name-list.sans-serif.zh-CN", "Helvetica,STHeiti,Heiti SC");
|
||||
pref("font.name-list.monospace.zh-CN", "Courier,STHeiti,Heiti SC");
|
||||
|
||||
pref("font.name.serif.zh-TW", "Times");
|
||||
pref("font.name.sans-serif.zh-TW", "Helvetica");
|
||||
pref("font.name.monospace.zh-TW", "Courier");
|
||||
pref("font.name.serif.zh-TW", "Times");
|
||||
pref("font.name.sans-serif.zh-TW", "Helvetica");
|
||||
pref("font.name.monospace.zh-TW", "Courier");
|
||||
pref("font.name-list.serif.zh-TW", "Times,LiSong Pro,Heiti TC");
|
||||
pref("font.name-list.sans-serif.zh-TW", "Helvetica,Heiti TC,LiHei Pro");
|
||||
pref("font.name-list.monospace.zh-TW", "Courier,Heiti TC,LiHei Pro");
|
||||
@ -3110,7 +3110,7 @@ pref("ui.key.menuAccessKey", 0);
|
||||
pref("ui.key.accelKey", 224);
|
||||
// (pinkerton, joki, saari) IE5 for mac uses Control for access keys. The HTML4 spec
|
||||
// suggests to use command on mac, but this really sucks (imagine someone having a "q"
|
||||
// as an access key and not letting you quit the app!). As a result, we've made a
|
||||
// as an access key and not letting you quit the app!). As a result, we've made a
|
||||
// command decision 1 day before tree lockdown to change it to the control key.
|
||||
pref("ui.key.generalAccessKey", -1);
|
||||
|
||||
@ -3602,7 +3602,7 @@ pref("font.name.serif.zh-CN", "serif");
|
||||
pref("font.name.sans-serif.zh-CN", "sans-serif");
|
||||
pref("font.name.monospace.zh-CN", "monospace");
|
||||
|
||||
// ming_uni.ttf (HKSCS-2001)
|
||||
// ming_uni.ttf (HKSCS-2001)
|
||||
// http://www.info.gov.hk/digital21/eng/hkscs/download/uime.exe
|
||||
pref("font.name.serif.zh-HK", "serif");
|
||||
pref("font.name.sans-serif.zh-HK", "sans-serif");
|
||||
@ -4104,11 +4104,11 @@ pref("device.storage.enabled", false);
|
||||
|
||||
// Toggle which thread the HTML5 parser uses for stream parsing
|
||||
pref("html5.offmainthread", true);
|
||||
// Time in milliseconds between the time a network buffer is seen and the
|
||||
// timer firing when the timer hasn't fired previously in this parse in the
|
||||
// Time in milliseconds between the time a network buffer is seen and the
|
||||
// timer firing when the timer hasn't fired previously in this parse in the
|
||||
// off-the-main-thread HTML5 parser.
|
||||
pref("html5.flushtimer.initialdelay", 120);
|
||||
// Time in milliseconds between the time a network buffer is seen and the
|
||||
// Time in milliseconds between the time a network buffer is seen and the
|
||||
// timer firing when the timer has already fired previously in this parse.
|
||||
pref("html5.flushtimer.subsequentdelay", 120);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user