Skip to content

Commit

Permalink
[embedlite-components] Add support for site specific UA override. Con…
Browse files Browse the repository at this point in the history
…tributes to JB#34904

This makes possible to use general.useragent.override.* overrides
with simple replace syntax given that complex override is not applied.

Instantiation of the UserAgent is deferred a bit so that we do not
end up initializing UserAgentOverrides before general.useragent.override
is applied. As UserAgent was initialized on that application startup,
the simple hash separated user agent fixing did not work. This happened
because nsIHttpProtocolHandler was not yet aware of the override.
Thus, causing UserAgentOverrides to fail to replace ua.
  • Loading branch information
rainemak committed May 6, 2016
1 parent 043b560 commit 879e8d7
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 23 deletions.
1 change: 1 addition & 0 deletions jscomps/EmbedLiteJSComponents.manifest
Expand Up @@ -59,6 +59,7 @@ category app-startup EmbedLiteErrorPageHandler service,@mozilla.org/embedlite-er
# UserAgentOverrideHelper.js
component {69d68654-b5a0-11e2-bb91-2b8ad5eb98ac} UserAgentOverrideHelper.js
contract @mozilla.org/embedlite-uahelper-component;1 {69d68654-b5a0-11e2-bb91-2b8ad5eb98ac}
contract @mozilla.org/dom/site-specific-user-agent;1 {69d68654-b5a0-11e2-bb91-2b8ad5eb98ac}
category app-startup UserAgentOverrideHelper service,@mozilla.org/embedlite-uahelper-component;1

# XPIDialogService.js
Expand Down
93 changes: 70 additions & 23 deletions jscomps/UserAgentOverrideHelper.js
Expand Up @@ -25,10 +25,22 @@ UserAgentOverrideHelper.prototype = {
// Engine DownloadManager notifications
case "app-startup": {
dump("UserAgentOverrideHelper app-startup\n");
UserAgent.init();
Services.obs.addObserver(this, "embedliteviewcreated", true);
Services.obs.addObserver(this, "xpcom-shutdown", false);
Services.prefs.addObserver("general.useragent.override", this, false);
break;
}
case "nsPref:changed": {
if (aData == "general.useragent.override") {
UserAgent.init();
}
break;
}
case "embedliteviewcreated": {
UserAgent.init();
break;
}

case "xpcom-shutdown": {
dump("UserAgentOverrideHelper xpcom-shutdown\n");
Services.obs.removeObserver(this, "xpcom-shutdown", false);
Expand All @@ -38,29 +50,31 @@ UserAgentOverrideHelper.prototype = {
}
},

QueryInterface: XPCOMUtils.generateQI([Ci.nsIObserver, Ci.nsISupportsWeakReference, Ci.nsIFormSubmitObserver])
getUserAgentForURIAndWindow: function ssua_getUserAgentForURIAndWindow(aURI, aWindow) {
// aWindow is unused / not needed.
return UserAgent.getUserAgentForWindow(aURI)
},

QueryInterface: XPCOMUtils.generateQI([Ci.nsISiteSpecificUserAgent, Ci.nsIObserver,
Ci.nsISupportsWeakReference, Ci.nsIFormSubmitObserver])
};

var UserAgent = {
_desktopMode: false,
_customUA: null,
overrideMap: new Map,
initilized: false,
DESKTOP_UA: null,
GOOGLE_DOMAIN: /(^|\.)google\.com$/,
GOOGLE_MAPS_DOMAIN: /(^|\.)maps\.google\.com$/,
YOUTUBE_DOMAIN: /(^|\.)youtube\.com$/,
NOKIA_HERE_DOMAIN: /(^|\.)here\.com$/,
_customUA: null,

getCustomUserAgent: function() {
if (Services.prefs.prefHasUserValue("general.useragent.override")) {
let ua = Services.prefs.getCharPref("general.useragent.override");
return ua;
}
else {
return null;
init: function ua_init() {
if (this.initilized) {
return
}
},

init: function ua_init() {
Services.obs.addObserver(this, "DesktopMode:Change", false);
Services.prefs.addObserver("general.useragent.override", this, false);
this._customUA = this.getCustomUserAgent();
Expand All @@ -71,15 +85,28 @@ var UserAgent = {
.getService(Ci.nsIHttpProtocolHandler).userAgent
.replace(/Android; [a-zA-Z]+/, "X11; Linux x86_64")
.replace(/Gecko\/[0-9\.]+/, "Gecko/20100101");
this.initilized = true;
},

getUserAgentForUriAndTab: function ua_getUserAgentForUriAndTab(aUri, defaultUA) {
getCustomUserAgent: function() {
if (Services.prefs.prefHasUserValue("general.useragent.override")) {
let ua = Services.prefs.getCharPref("general.useragent.override");
return ua;
} else {
return null;
}
},

getDefaultUserAgent : function ua_getDefaultUserAgent() {
// Send desktop UA if "Request Desktop Site" is enabled.
if (this._desktopMode)
return this.DESKTOP_UA;

let ua = this._customUA ? this._customUA : defaultUA;
return this._customUA ? this._customUA : defaultUA;
},

getUserAgentForUriAndTab: function ua_getUserAgentForUriAndTab(aUri) {
let ua = this.getDefaultUserAgent();
// Not all schemes have a host member.
if (aUri.schemeIs("http") || aUri.schemeIs("https")) {
if (this.GOOGLE_DOMAIN.test(aUri.host)) {
Expand Down Expand Up @@ -108,7 +135,7 @@ var UserAgent = {
}
}

return ua;
return "";
},

uninit: function ua_uninit() {
Expand All @@ -117,18 +144,38 @@ var UserAgent = {
UserAgentOverrides.uninit();
},

// Complex override calls this first.
onRequest: function(channel, defaultUA) {
let channelWindow = this._getWindowForRequest(channel);
let ua = this.getUserAgentForUriAndTab(channel.URI, defaultUA);
if (ua)
channel.setRequestHeader("User-Agent", ua, false);
let ua = "";
let host = channel.URI.asciiHost
let windowHost = channelWindow && channelWindow.location.hostname || "";

if (this.overrideMap.has(host)) {
ua = this.overrideMap.get(host);
} else if (this.overrideMap.has(windowHost)) {
ua = this.overrideMap.get(windowHost);
} else {
ua = this.getUserAgentForWindow(channel.URI);
}

return ua
},

getUserAgentForWindow: function ua_getUserAgentForWindow(aWindow, defaultUA) {
let tab = BrowserApp.getTabForWindow(aWindow.top);
if (tab)
return this.getUserAgentForUriAndTab(tab.browser.currentURI, tab, defaultUA);
return defaultUA;
// Called if onRequest returns empty user-agent.
getUserAgentForWindow: function ua_getUserAgentForWindow(aUri) {
// Try to pick 'general.useragent.override.*'
let ua = UserAgentOverrides.getOverrideForURI(aUri)
if (!ua) {
ua = this.getUserAgentForUriAndTab(aUri);
}

if (ua) {
this.overrideMap.set(aUri.asciiHost, ua)
return ua
}

return this.getDefaultUserAgent();
},

_getRequestLoadContext: function ua_getRequestLoadContext(aRequest) {
Expand Down

0 comments on commit 879e8d7

Please sign in to comment.