зеркало из https://github.com/mozilla/gecko-dev.git
Bug 852848 - Add support for app-specific redirections r=bz,ferjm
This commit is contained in:
Родитель
cd2be6d401
Коммит
d97443504d
|
@ -202,6 +202,8 @@
|
|||
#include "nsIAppShellService.h"
|
||||
#include "nsAppShellCID.h"
|
||||
|
||||
#include "nsIAppsService.h"
|
||||
|
||||
static NS_DEFINE_CID(kDOMScriptObjectFactoryCID,
|
||||
NS_DOM_SCRIPT_OBJECT_FACTORY_CID);
|
||||
static NS_DEFINE_CID(kAppShellCID, NS_APPSHELL_CID);
|
||||
|
@ -6436,6 +6438,30 @@ nsDocShell::OnRedirectStateChange(nsIChannel* aOldChannel,
|
|||
if (!oldURI || !newURI) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if we have a redirect registered for this url.
|
||||
uint32_t appId;
|
||||
nsresult rv = GetAppId(&appId);
|
||||
if (NS_FAILED(rv)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (appId != nsIScriptSecurityManager::NO_APP_ID &&
|
||||
appId != nsIScriptSecurityManager::UNKNOWN_APP_ID) {
|
||||
nsCOMPtr<nsIAppsService> appsService =
|
||||
do_GetService(APPS_SERVICE_CONTRACTID);
|
||||
NS_ASSERTION(appsService, "No AppsService available");
|
||||
nsCOMPtr<nsIURI> redirect;
|
||||
rv = appsService->GetRedirect(appId, newURI, getter_AddRefs(redirect));
|
||||
if (NS_SUCCEEDED(rv) && redirect) {
|
||||
aNewChannel->Cancel(NS_BINDING_ABORTED);
|
||||
rv = LoadURI(redirect, nullptr, 0, false);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// On session restore we get a redirect from page to itself. Don't count it.
|
||||
bool equals = false;
|
||||
if (mTiming &&
|
||||
|
|
|
@ -13,6 +13,7 @@ const Ci = Components.interfaces;
|
|||
const Cu = Components.utils;
|
||||
|
||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
Cu.import("resource://gre/modules/Services.jsm");
|
||||
|
||||
const APPS_SERVICE_CID = Components.ID("{05072afa-92fe-45bf-ae22-39b69c117058}");
|
||||
|
||||
|
@ -78,6 +79,42 @@ AppsService.prototype = {
|
|||
return DOMApplicationRegistry.getAppInfo(aAppId);
|
||||
},
|
||||
|
||||
getRedirect: function getRedirect(aLocalId, aURI) {
|
||||
debug("getRedirect for " + aLocalId + " " + aURI.spec);
|
||||
if (aLocalId == Ci.nsIScriptSecurityManager.NO_APP_ID ||
|
||||
aLocalId == Ci.nsIScriptSecurityManager.UNKNOWN_APP_ID) {
|
||||
return null;
|
||||
}
|
||||
|
||||
let app = DOMApplicationRegistry.getAppByLocalId(aLocalId);
|
||||
if (app && app.redirects) {
|
||||
let spec = aURI.spec;
|
||||
for (let i = 0; i < app.redirects.length; i++) {
|
||||
let redirect = app.redirects[i];
|
||||
if (spec.startsWith(redirect.from)) {
|
||||
// Prepend the app origin to the redirection. We need that since
|
||||
// the origin of packaged apps is a uuid created at install time.
|
||||
let to = app.origin + redirect.to;
|
||||
// If we have a ? or a # in the current URL, add this part to the
|
||||
// redirection.
|
||||
let index = -1;
|
||||
index = spec.indexOf('?');
|
||||
if (index == -1) {
|
||||
index = spec.indexOf('#');
|
||||
}
|
||||
|
||||
if (index != -1) {
|
||||
to += spec.substring(index);
|
||||
}
|
||||
debug('App specific redirection from ' + spec + ' to ' + to);
|
||||
return Services.io.newURI(to, null, null);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
},
|
||||
|
||||
classID : APPS_SERVICE_CID,
|
||||
QueryInterface : XPCOMUtils.generateQI([Ci.nsIAppsService])
|
||||
}
|
||||
|
|
|
@ -20,13 +20,13 @@ XPCOMUtils.defineLazyGetter(this, "NetUtil", function() {
|
|||
|
||||
// Shared code for AppsServiceChild.jsm, Webapps.jsm and Webapps.js
|
||||
|
||||
this.EXPORTED_SYMBOLS = ["AppsUtils", "ManifestHelper"];
|
||||
this.EXPORTED_SYMBOLS = ["AppsUtils", "ManifestHelper", "isAbsoluteURI"];
|
||||
|
||||
function debug(s) {
|
||||
//dump("-*- AppsUtils.jsm: " + s + "\n");
|
||||
}
|
||||
|
||||
function isAbsoluteURI(aURI) {
|
||||
this.isAbsoluteURI = function(aURI) {
|
||||
let foo = Services.io.newURI("http://foo", null, null);
|
||||
let bar = Services.io.newURI("http://bar", null, null);
|
||||
return Services.io.newURI(aURI, null, foo).prePath != foo.prePath ||
|
||||
|
@ -92,7 +92,8 @@ this.AppsUtils = {
|
|||
installerAppId: aApp.installerAppId || Ci.nsIScriptSecurityManager.NO_APP_ID,
|
||||
installerIsBrowser: !!aApp.installerIsBrowser,
|
||||
storeId: aApp.storeId || "",
|
||||
storeVersion: aApp.storeVersion || 0
|
||||
storeVersion: aApp.storeVersion || 0,
|
||||
redirects: aApp.redirects
|
||||
};
|
||||
},
|
||||
|
||||
|
|
|
@ -196,6 +196,24 @@ this.DOMApplicationRegistry = {
|
|||
this._saveApps();
|
||||
},
|
||||
|
||||
// Ensure that the .to property in redirects is a relative URL.
|
||||
sanitizeRedirects: function sanitizeRedirects(aSource) {
|
||||
if (!aSource) {
|
||||
return null;
|
||||
}
|
||||
|
||||
let res = [];
|
||||
for (let i = 0; i < aSource.length; i++) {
|
||||
let redirect = aSource[i];
|
||||
if (redirect.from && redirect.to &&
|
||||
isAbsoluteURI(redirect.from) &&
|
||||
!isAbsoluteURI(redirect.to)) {
|
||||
res.push(redirect);
|
||||
}
|
||||
}
|
||||
return res.length > 0 ? res : null;
|
||||
},
|
||||
|
||||
// Registers all the activities and system messages.
|
||||
registerAppsHandlers: function registerAppsHandlers(aRunUpdate) {
|
||||
this.notifyAppsRegistryStart();
|
||||
|
@ -211,7 +229,11 @@ this.DOMApplicationRegistry = {
|
|||
// twice
|
||||
this._readManifests(ids, (function readCSPs(aResults) {
|
||||
aResults.forEach(function registerManifest(aResult) {
|
||||
this.webapps[aResult.id].csp = aResult.manifest.csp || "";
|
||||
let app = this.webapps[aResult.id];
|
||||
app.csp = aResult.manifest.csp || "";
|
||||
if (app.appStatus >= Ci.nsIPrincipal.APP_STATUS_PRIVILEGED) {
|
||||
app.redirects = this.sanitizeRedirects(aResult.redirects);
|
||||
}
|
||||
}, this);
|
||||
}).bind(this));
|
||||
|
||||
|
@ -673,6 +695,9 @@ this.DOMApplicationRegistry = {
|
|||
let manifest = aResult.manifest;
|
||||
app.name = manifest.name;
|
||||
app.csp = manifest.csp || "";
|
||||
if (app.appStatus >= Ci.nsIPrincipal.APP_STATUS_PRIVILEGED) {
|
||||
app.redirects = this.sanitizeRedirects(manifest.redirects);
|
||||
}
|
||||
this._registerSystemMessages(manifest, app);
|
||||
appsToRegister.push({ manifest: manifest, app: app });
|
||||
}, this);
|
||||
|
@ -1327,11 +1352,14 @@ this.DOMApplicationRegistry = {
|
|||
return [toHexString(hash.charCodeAt(i)) for (i in hash)].join("");
|
||||
},
|
||||
|
||||
// Updates the activities and system message handlers.
|
||||
// Updates the redirect mapping, activities and system message handlers.
|
||||
// aOldManifest can be null if we don't have any handler to unregister.
|
||||
updateAppHandlers: function(aOldManifest, aNewManifest, aApp) {
|
||||
debug("updateAppHandlers: old=" + aOldManifest + " new=" + aNewManifest);
|
||||
this.notifyAppsRegistryStart();
|
||||
if (aApp.appStatus >= Ci.nsIPrincipal.APP_STATUS_PRIVILEGED) {
|
||||
aApp.redirects = this.sanitizeRedirects(aNewManifest.redirects);
|
||||
}
|
||||
|
||||
if (supportSystemMessages()) {
|
||||
if (aOldManifest) {
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
|
||||
interface mozIDOMApplication;
|
||||
interface mozIApplication;
|
||||
interface nsIURI;
|
||||
|
||||
%{C++
|
||||
#define APPS_SERVICE_CID { 0x05072afa, 0x92fe, 0x45bf, { 0xae, 0x22, 0x39, 0xb6, 0x9c, 0x11, 0x70, 0x58 } }
|
||||
|
@ -16,7 +17,7 @@ interface mozIApplication;
|
|||
* This service allows accessing some DOMApplicationRegistry methods from
|
||||
* non-javascript code.
|
||||
*/
|
||||
[scriptable, uuid(1113c6e3-28a2-4315-be10-8b3230eecc0f)]
|
||||
[scriptable, uuid(27b995cf-bec8-47de-aa48-6117c950fce3)]
|
||||
interface nsIAppsService : nsISupports
|
||||
{
|
||||
mozIDOMApplication getAppByManifestURL(in DOMString manifestURL);
|
||||
|
@ -63,6 +64,12 @@ interface nsIAppsService : nsISupports
|
|||
|
||||
jsval getAppInfo(in DOMString appId);
|
||||
|
||||
/**
|
||||
* Returns a URI to redirect to when we get a redirection to 'uri'.
|
||||
* Returns null if no redirection is declared for this uri.
|
||||
*/
|
||||
nsIURI getRedirect(in unsigned long localId, in nsIURI uri);
|
||||
|
||||
/**
|
||||
* Returns the localId if the app was installed from a store
|
||||
*/
|
||||
|
|
Загрузка…
Ссылка в новой задаче