Skip to content

Commit

Permalink
Fixed rewriting behavior (#11)
Browse files Browse the repository at this point in the history
* Copy array when rewriting

* Test for new case

* Apply rewrites only if path doesn't exist on disk
  • Loading branch information
leo authored May 29, 2018
1 parent 83269a1 commit 3ee9f54
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 18 deletions.
44 changes: 26 additions & 18 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -65,25 +65,32 @@ const toTarget = (source, destination, previousPath) => {
return toPath(props);
};

const applyRewrites = (requestPath, rewrites = []) => {
if (rewrites.length === 0) {
return requestPath;
const applyRewrites = (requestPath, rewrites = [], repetitive) => {
// We need to copy the array, since we're going to modify it.
const rewritesCopy = rewrites.slice();

// If the method was called again, the path was already rewritten
// so we need to make sure to return it.
const fallback = repetitive ? requestPath : null;

if (rewritesCopy.length === 0) {
return fallback;
}

for (let index = 0; index < rewrites.length; index++) {
for (let index = 0; index < rewritesCopy.length; index++) {
const {source, destination} = rewrites[index];
const target = toTarget(source, destination, requestPath);

if (target) {
// Remove rules that were already applied
rewrites.splice(index, 1);
rewritesCopy.splice(index, 1);

// Check if there are remaining ones to be applied
return applyRewrites(slasher(target), rewrites);
return applyRewrites(slasher(target), rewritesCopy, true);
}
}

return requestPath;
return fallback;
};

const shouldRedirect = (decodedPath, {redirects = [], trailingSlash}, cleanUrl) => {
Expand Down Expand Up @@ -213,8 +220,8 @@ const getPossiblePaths = (relativePath, extension) => [
relativePath.endsWith('/') ? relativePath.replace(/\/$/g, extension) : (relativePath + extension)
];

const findRelated = async (current, relativePath, originalStat, extension = '.html') => {
const possible = getPossiblePaths(relativePath, extension);
const findRelated = async (current, relativePath, rewrittenPath, originalStat, extension = '.html') => {
const possible = rewrittenPath ? [rewrittenPath] : getPossiblePaths(relativePath, extension);

let stats = null;

Expand Down Expand Up @@ -244,7 +251,7 @@ const findRelated = async (current, relativePath, originalStat, extension = '.ht

// At this point, no `.html` files have been found, so we
// need to check for the existance of `.htm` ones.
return findRelated(current, relativePath, originalStat, '.htm');
return findRelated(current, relativePath, rewrittenPath, originalStat, '.htm');
};

const canBeListed = (excluded, file) => {
Expand Down Expand Up @@ -388,9 +395,11 @@ module.exports = async (request, response, config = {}, methods = {}) => {
const current = config.public ? path.join(cwd, config.public) : cwd;
const handlers = getHandlers(methods);

const decodedPath = decodeURIComponent(url.parse(request.url).pathname);
const cleanUrl = applicable(decodedPath, config.cleanUrls);
const redirect = shouldRedirect(decodedPath, config, cleanUrl);
let relativePath = decodeURIComponent(url.parse(request.url).pathname);
let absolutePath = path.join(current, relativePath);

const cleanUrl = applicable(relativePath, config.cleanUrls);
const redirect = shouldRedirect(relativePath, config, cleanUrl);

if (redirect) {
response.writeHead(redirect.statusCode, {
Expand All @@ -401,9 +410,6 @@ module.exports = async (request, response, config = {}, methods = {}) => {
return;
}

let relativePath = applyRewrites(decodedPath, config.rewrites);
let absolutePath = path.join(current, relativePath);

let stats = null;

try {
Expand All @@ -417,9 +423,11 @@ module.exports = async (request, response, config = {}, methods = {}) => {
}
}

if ((!stats || stats.isDirectory()) && cleanUrl) {
const rewrittenPath = applyRewrites(relativePath, config.rewrites);

if ((!stats || stats.isDirectory()) && (cleanUrl || rewrittenPath)) {
try {
const related = await findRelated(current, relativePath, handlers.stat);
const related = await findRelated(current, relativePath, rewrittenPath, handlers.stat);

if (related) {
({stats, absolutePath} = related);
Expand Down
18 changes: 18 additions & 0 deletions test/integration.js
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,24 @@ test('set `rewrites` config property to wildcard path', async t => {
t.is(text, content);
});

test('set `rewrites` config property to non-matching path', async t => {
const destination = '404.html';
const related = path.join(fixturesFull, destination);
const content = await fs.readFile(related, 'utf8');

const url = await getUrl({
rewrites: [{
source: 'face/**',
destination
}]
});

const response = await fetch(`${url}/mask/delete`);
const text = await response.text();

t.is(text, content);
});

test('set `rewrites` config property to one-star wildcard path', async t => {
const destination = '.dotfile';
const related = path.join(fixturesFull, destination);
Expand Down

0 comments on commit 3ee9f54

Please sign in to comment.