Skip to content

Commit

Permalink
Handle local dependencies correctly
Browse files Browse the repository at this point in the history
Especially libraries where not handled correctly.
ABAP URI retrieval now moved to type formatters
  • Loading branch information
RandomByte committed Dec 10, 2019
1 parent 6156f13 commit dff548b
Show file tree
Hide file tree
Showing 2 changed files with 73 additions and 21 deletions.
28 changes: 18 additions & 10 deletions lib/middleware/proxyRewrite.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
const log = require("@ui5/logger").getLogger("server:middleware:proxyRewrite");

function createMiddleware({resources, configuration, cdnUrl}) {
const resourceRootPath = !configuration.appOnly && configuration.destination.ui5Root;
const applicationRootPath = configuration.destination.appRoot;
const rewriteRootPaths = configuration.rewriteRootPaths;

const cacheBusterRegex = /~.*~[A-Z0-9]?\/?/;
const preloadRegex = /^.*(?:Component-preload\.js|library-preload\.js|library-preload\.json)$/i;

return function proxyRewrite(req, res, next) {
if ((!resourceRootPath || req.path.indexOf(resourceRootPath) === -1) &&
(!applicationRootPath || req.path.indexOf(applicationRootPath) === -1)) {
const rewriteApplicable = Object.keys(rewriteRootPaths).some((resourceRootPath) => {
return req.path.indexOf(resourceRootPath) !== -1;
});

if (!rewriteApplicable) {
// No normalization applicable
next();
return;
Expand Down Expand Up @@ -82,14 +85,19 @@ function createMiddleware({resources, configuration, cdnUrl}) {
async function normalizeRequestPath(reqPath) {
let normalizedPath = reqPath;

if (resourceRootPath && normalizedPath.indexOf(resourceRootPath) !== -1) {
normalizedPath = normalizedPath.substr(resourceRootPath.length);
} else if (applicationRootPath && normalizedPath.indexOf(applicationRootPath) !== -1) {
normalizedPath = normalizedPath.substr(applicationRootPath.length);
// Strip off first matching rewrite root path
for (const rootPath in rewriteRootPaths) {
if (rewriteRootPaths.hasOwnProperty(rootPath)) {
if (normalizedPath.indexOf(rootPath) !== -1) {
normalizedPath = normalizedPath.substr(rootPath.length);
if (rewriteRootPaths[rootPath].rewriteTo) {
normalizedPath = rewriteRootPaths[rootPath].rewriteTo + normalizedPath;
}
break;
}
}
}

normalizedPath = normalizedPath.replace(cacheBusterRegex, "");

return rewriteSpecials(normalizedPath);
}

Expand Down
66 changes: 55 additions & 11 deletions lib/proxyConfiguration.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
const log = require("@ui5/logger").getLogger("proxyConfiguration");
const {resourceFactory} = require("@ui5/fs");
const log = require("@ui5/logger").getLogger("server:proxyConfiguration");

const proxyConfigurations = {};

Expand All @@ -10,6 +9,9 @@ function addConfiguration(name, proxyConfig) {
if (proxyConfigurations[name]) {
throw new Error(`proxyConfiguration: A configuration with name ${name} is already known`);
}
if (proxyConfig.rewriteRootPaths) {
throw new Error(`Proxy Configuration ${name} must not define "rewriteRootPaths"`);
}

if (!proxyConfig.destination) {
proxyConfig.destination = {};
Expand All @@ -26,23 +28,65 @@ async function getConfigurationForProject(project) {
throw new Error(`Found multiple proxy configurations. ` +
`This is not yet supported.`); // TODO
}

log.verbose(`Applying proxy configuration ${configNames[0]} to project ${project.metadata.name}...`);
const config = JSON.parse(JSON.stringify(proxyConfigurations[configNames[0]]));
config.rewriteRootPaths = {};

if (config.destination.ui5Root && !config.appOnly) {
log.verbose(`Using configured "destination.ui5Root": ${config.destination.ui5Root}`);
config.rewriteRootPaths[config.destination.ui5Root] = {
rewriteTo: ""
};
}

mapProjectDependencies(project, (proj) => {
if (proj.specVersion !== "1.1a") {
log.warn(`Project ${project.metadata.name} defines specification version ${proj.specVersion}. ` +
`Some proxy configuration features require projects to define specification version 1.1a`);
}
log.verbose(`Using ABAP URI ${proj.metadata.abapUri} from metadata of project ${proj.metadata.name}`);
let prefix = "";
if (proj.type !== "application") {
if (project.resources.pathMappings["/resources"]) {
// If the project defines a /resources path mapping,
// we expect this to match the ABAP URI deployment path
prefix += "/resources/";

// If this is not an application and there is no /resources path mapping, somebody does something wild
// and hopefully knows what he/she does
}
prefix += proj.metadata.namespace;
}
config.rewriteRootPaths[proj.metadata.abapUri] = {
rewriteTo: prefix
};
});

const {source} = resourceFactory.createCollectionsForTree(project);
const manifestResource = await source.byPath("/manifest.json");
if (manifestResource) {
const manifest = JSON.parse(await manifestResource.getBuffer());
if (manifest["sap.platform.abap"] && manifest["sap.platform.abap"].uri) {
log.verbose(`Using sap.platform.abap URI configuration as application root ` +
`path: ${manifest["sap.platform.abap"].uri}`);
config.destination.appRoot = manifest["sap.platform.abap"].uri;
if (log.isLevelEnabled("verbose")) {
log.verbose(`Configured ${config.rewriteRootPaths.length} root paths to rewrite for ` +
`project ${project.metadata.name};`);
for (const abapUri in config.rewriteRootPaths) {
if (config.rewriteRootPaths.hasOwnProperty(abapUri)) {
if (config.rewriteRootPaths[abapUri].rewriteTo) {
log.verbose(`Rewriting ${abapUri} to ${config.rewriteRootPaths[abapUri].rewriteTo}`);
} else {
log.verbose(`Rewriting ${abapUri}`);
}
}
}
}
log.verbose(`UI5 root path configured as: ${config.destination.ui5Root}`);

return config;
}

function mapProjectDependencies(tree, handler) {
handler(tree);
tree.dependencies.map((dep) => {
mapProjectDependencies(dep, handler);
});
}

module.exports = {
addConfiguration,
getConfigurationForProject
Expand Down

0 comments on commit dff548b

Please sign in to comment.