Skip to content

Commit

Permalink
[FIX] Improve library request handling (#251)
Browse files Browse the repository at this point in the history
  • Loading branch information
matz3 committed Oct 7, 2020
1 parent 3d6ac56 commit 762cde2
Show file tree
Hide file tree
Showing 3 changed files with 252 additions and 168 deletions.
150 changes: 86 additions & 64 deletions lib/framework.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,16 @@ const httpProxy = require("http-proxy");
const fs = require("fs");
const path = require("path");
const yaml = require("js-yaml");
const {Router} = require("express");
const stat = fs.statSync;
const {ErrorMessage} = require("./errors");


class Framework {
constructor() {
this.isPaused = true;
this.queue = [];
this._serveResources = null;
this._serveThemes = null;
this.config = {};
this.beforeMiddleware = new Router();
this.middleware = new Router();
}

createPluginFilesPattern(pattern) {
Expand Down Expand Up @@ -120,7 +119,6 @@ class Framework {
this.config.client.ui5 = {};
this.config.client.ui5.useIframe = true; // for now only allow using iframes in HTML mode
this.config.ui5 = config.ui5 || {};
this.config.proxies = config.proxies || {};
this.config.middleware = config.middleware || [];
this.config.files = config.files || [];
this.config.beforeMiddleware = config.beforeMiddleware || [];
Expand Down Expand Up @@ -263,7 +261,6 @@ class Framework {
this.config.files.push(
this.createProjectFilesPattern(config.basePath + `/{${webappFolder}/**,${webappFolder}/**/.*}`)
);
// No proxy required here, local files will be loaded via karma first
} else if (config.ui5.type === "library") {
const srcFolder = this.config.ui5.paths.src;
const testFolder = this.config.ui5.paths.test;
Expand All @@ -281,12 +278,6 @@ class Framework {
this.createProjectFilesPattern(`${config.basePath}/{${srcFolder}/**,${srcFolder}/**/.*}`),
this.createProjectFilesPattern(`${config.basePath}/{${testFolder}/**,${testFolder}/**/.*}`),
);
// Configure proxies to first load files from karma server (e.g. library under test)
// Otherwise the coverage reporting won't work
this.config.proxies[`/base/${this.replaceLast(srcFolder, "resources")}/`] = `/base/${srcFolder}/`;
this.config.proxies[`/base/${this.replaceLast(srcFolder, "test-resources")}/`] = `/base/${testFolder}/`;
this.config.proxies[`/base/${this.replaceLast(testFolder, "resources")}/`] = `/base/${srcFolder}/`;
this.config.proxies[`/base/${this.replaceLast(testFolder, "test-resources")}/`] = `/base/${testFolder}/`;
} else {
this.logger.log("error", ErrorMessage.invalidProjectType(config.ui5.type) );
throw new Error(ErrorMessage.failure());
Expand Down Expand Up @@ -370,6 +361,20 @@ class Framework {
// }
// }

/**
* Rewrites the given url to use a virtual path that can be resolved
* by the UI5 Tooling middleware or to conform with the UI5 CDN.
*
* Example (application):
* /base/webapp/resources/sap-ui-core.js -> /resources/sap-ui-core.js
*
* Example (library):
* /base/src/resources/sap-ui-core.js -> /resources/sap-ui-core.js
* /base/test/test-resources/sap-ui-core.js -> /test-resources/sap-ui-core.js
*
* @param {string} url
* @returns {string}
*/
rewriteUrl(url) {
const type = this.config.ui5.type;
const webappFolder = this.config.ui5.paths.webapp;
Expand Down Expand Up @@ -402,22 +407,50 @@ class Framework {
return url;
}

processRequests() {
this.isPaused = false;
this.queue.forEach(function(next) {
next();
});
this.queue = [];
}

pauseRequests() {
return (req, res, next) => {
if (this.isPaused) {
this.queue.push(next);
} else {
next();
}
};
/**
* Rewrites the given url from a virtual path (resources / test-resources)
* to a filesystem path so that the request can be handled by the karma
* middleware that serves the project files.
*
* This is only relevant for type "library", as it has two separate folders (src / test).
*
* Example:
* /base/resources/sap-ui-core.js -> /base/src/sap-ui-core.js
* /base/test-resources/sap/ui/test/ -> /base/test/sap/ui/test/
*
* @param {string} url
* @returns {string}
*/
rewriteUrlBefore(url) {
const type = this.config.ui5.type;
if (type !== "library") {
// Only rewrite "before" for type library
return url;
}
const srcFolder = this.config.ui5.paths.src;
const testFolder = this.config.ui5.paths.test;
const resourcesSrcPattern = new RegExp(
`/base/${this.replaceLast(srcFolder, "resources")}/`
);
const resourcesTestPattern = new RegExp(
`/base/${this.replaceLast(testFolder, "resources")}/`
);
const testResourcesSrcPattern = new RegExp(
`/base/${this.replaceLast(srcFolder, "test-resources")}/`
);
const testResourcesTestPattern = new RegExp(
`/base/${this.replaceLast(testFolder, "test-resources")}/`
);
if (resourcesSrcPattern.test(url)) {
return url.replace(resourcesSrcPattern, `/base/${srcFolder}/`);
} else if (resourcesTestPattern.test(url)) {
return url.replace(resourcesTestPattern, `/base/${srcFolder}/`);
} else if (testResourcesSrcPattern.test(url)) {
return url.replace(testResourcesSrcPattern, `/base/${testFolder}/`);
} else if (testResourcesTestPattern.test(url)) {
return url.replace(testResourcesTestPattern, `/base/${testFolder}/`);
}
return url;
}

async setupUI5Server({basePath, configPath}) {
Expand Down Expand Up @@ -447,8 +480,7 @@ class Framework {
all
};

// eslint-disable-next-line new-cap
const router = require("express").Router();
const router = new Router();

// TODO: rework ui5-server API and make public
const MiddlewareManager = require("@ui5/server/lib/middleware/MiddlewareManager");
Expand All @@ -459,9 +491,7 @@ class Framework {

await middlewareManager.applyMiddleware(router);

return {
serveResources: router
};
return router;
}

setupProxy({url}) {
Expand All @@ -474,50 +504,42 @@ class Framework {
agent
});

return {
serveResources: (req, res, next) => proxy.web(req, res, next),
serveThemes: undefined
};
return (req, res, next) => proxy.web(req, res, next);
}

beforeMiddlewareRewriteUrl(req, res, next) {
req.url = this.rewriteUrlBefore(req.url);
next();
}

middlewareRewriteUrl(req, res, next) {
req.url = this.rewriteUrl(req.url);
next();
}

async setupMiddleware() {
const config = this.config;

let server = {
serveResources: undefined,
serveThemes: undefined
};
if (config.ui5.type === "library") {
this.beforeMiddleware.use(this.beforeMiddlewareRewriteUrl.bind(this));
config.beforeMiddleware.push("ui5--beforeMiddleware");
}

let middleware;
if (config.ui5.url) {
config.middleware.push("ui5--serveResources");
server = await this.setupProxy(config.ui5);
middleware = this.setupProxy(config.ui5);
} else if (config.ui5.useMiddleware !== false) {
config.beforeMiddleware.push("ui5--pauseRequests");
config.middleware.push("ui5--serveResources");
// config.middleware.push("ui5--serveThemes");
server = await this.setupUI5Server({
middleware = await this.setupUI5Server({
basePath: config.basePath,
configPath: config.ui5.configPath
});
}

this._serveResources = server.serveResources;
this._serveThemes = server.serveThemes;
this.processRequests();
return this;
}

serveResources() {
return (req, res, next) => {
req.url = this.rewriteUrl(req.url);
this._serveResources(req, res, next);
};
}

serveThemes() {
return (req, res, next) => {
this._serveThemes(req, res, next);
};
if (middleware) {
this.middleware.use(this.middlewareRewriteUrl.bind(this));
this.middleware.use(middleware);
config.middleware.push("ui5--middleware");
}
}
}

Expand Down
14 changes: 3 additions & 11 deletions lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,7 @@ async function init(config, logger) {
await framework.init({config, logger});
} catch (error) {
const _logger = logger.create("ui5.framework");
_logger.log("error", error.message);
_logger.log("debug", error.stack);
_logger.log("error", error.stack);
throw new Error(ErrorMessage.failure());
}
}
Expand All @@ -17,13 +16,6 @@ init.$inject = ["config", "logger"];

module.exports = {
"framework:ui5": ["factory", init],
"middleware:ui5--pauseRequests": ["factory", function() {
return framework.pauseRequests();
}],
"middleware:ui5--serveResources": ["factory", function() {
return framework.serveResources();
}],
"middleware:ui5--serveThemes": ["factory", function() {
return framework.serveThemes();
}]
"middleware:ui5--beforeMiddleware": ["value", framework.beforeMiddleware],
"middleware:ui5--middleware": ["value", framework.middleware]
};

0 comments on commit 762cde2

Please sign in to comment.