diff options
Diffstat (limited to 'dom/base/SiteSpecificUserAgent.js')
-rw-r--r-- | dom/base/SiteSpecificUserAgent.js | 88 |
1 files changed, 88 insertions, 0 deletions
diff --git a/dom/base/SiteSpecificUserAgent.js b/dom/base/SiteSpecificUserAgent.js new file mode 100644 index 000000000..7e1bf44f8 --- /dev/null +++ b/dom/base/SiteSpecificUserAgent.js @@ -0,0 +1,88 @@ +/* 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/. */ + +const Cu = Components.utils; +const Cc = Components.classes; +const Ci = Components.interfaces; + +Cu.import("resource://gre/modules/XPCOMUtils.jsm"); + +const MAX_CACHE_SIZE = 250; +const PREF_UPDATE = "general.useragent.updates."; +const PREF_OVERRIDE = "general.useragent.override."; +const XPCOM_SHUTDOWN = "xpcom-shutdown"; +const HTTP_PROTO_HANDLER = Cc["@mozilla.org/network/protocol;1?name=http"] + .getService(Ci.nsIHttpProtocolHandler); + +XPCOMUtils.defineLazyServiceGetter(this, "cpmm", + "@mozilla.org/childprocessmessagemanager;1", + "nsISyncMessageSender"); + +function SiteSpecificUserAgent() { + this.inParent = Cc["@mozilla.org/xre/app-info;1"].getService(Ci.nsIXULRuntime) + .processType == Ci.nsIXULRuntime.PROCESS_TYPE_DEFAULT; + + if (this.inParent) { + Cu.import("resource://gre/modules/UserAgentOverrides.jsm"); + } else { + Cu.import("resource://gre/modules/Services.jsm"); + Services.prefs.addObserver(PREF_OVERRIDE, this, false); + Services.prefs.addObserver(PREF_UPDATE, this, false); + Services.obs.addObserver(this, XPCOM_SHUTDOWN, false); + this.userAgentCache = new Map; + } +} + +SiteSpecificUserAgent.prototype = { + getUserAgentForURIAndWindow: function ssua_getUserAgentForURIAndWindow(aURI, aWindow) { + if (this.inParent) { + return UserAgentOverrides.getOverrideForURI(aURI) || HTTP_PROTO_HANDLER.userAgent; + } + + let host = aURI.asciiHost; + let cachedResult = this.userAgentCache.get(host); + if (cachedResult) { + return cachedResult; + } + + let data = { uri: aURI.spec }; + let result = cpmm.sendRpcMessage("Useragent:GetOverride", data)[0] || HTTP_PROTO_HANDLER.userAgent; + + if (this.userAgentCache.size >= MAX_CACHE_SIZE) { + this.userAgentCache.clear(); + } + + this.userAgentCache.set(host, result); + return result; + }, + + invalidateCache: function() { + this.userAgentCache.clear(); + }, + + clean: function() { + this.userAgentCache.clear(); + if (!this.inParent) { + Services.obs.removeObserver(this, XPCOM_SHUTDOWN); + Services.prefs.removeObserver(PREF_OVERRIDE, this); + Services.prefs.removeObserver(PREF_UPDATE, this); + } + }, + + observe: function(subject, topic, data) { + switch (topic) { + case "nsPref:changed": + this.invalidateCache(); + break; + case XPCOM_SHUTDOWN: + this.clean(); + break; + } + }, + + classID: Components.ID("{506c680f-3d1c-4954-b351-2c80afbc37d3}"), + QueryInterface: XPCOMUtils.generateQI([Ci.nsISiteSpecificUserAgent]) +}; + +this.NSGetFactory = XPCOMUtils.generateNSGetFactory([SiteSpecificUserAgent]); |