diff --git a/index.js b/index.js index 3a1a2da..a1821f9 100644 --- a/index.js +++ b/index.js @@ -6,6 +6,9 @@ const electron = require('electron'); const stat = promisify(fs.stat); +// See https://cs.chromium.org/chromium/src/net/base/net_error_list.h +const FILE_NOT_FOUND = -6; + const getPath = async path_ => { try { const result = await stat(path_); @@ -35,10 +38,15 @@ module.exports = options => { const handler = async (request, callback) => { const indexPath = path.join(options.directory, 'index.html'); const filePath = path.join(options.directory, decodeURIComponent(new URL(request.url).pathname)); + const resolvedPath = await getPath(filePath); - callback({ - path: (await getPath(filePath)) || indexPath - }); + if (resolvedPath || !path.extname(filePath) || path.extname(filePath) === '.html') { + callback({ + path: resolvedPath || indexPath + }); + } else { + callback({error: FILE_NOT_FOUND}); + } }; if (electron.protocol.registerStandardSchemes) { diff --git a/package.json b/package.json index ffc1d9b..aa107f2 100644 --- a/package.json +++ b/package.json @@ -36,7 +36,7 @@ "url" ], "devDependencies": { - "ava": "^1.4.1", + "ava": "^2.1.0", "electron": "^3.0.0", "spectron": "^5.0.0", "tsd": "^0.7.3", diff --git a/test/fixture-404-error.js b/test/fixture-404-error.js new file mode 100644 index 0000000..5c65d2e --- /dev/null +++ b/test/fixture-404-error.js @@ -0,0 +1,14 @@ +'use strict'; +const {app, BrowserWindow} = require('electron'); +const serve = require('..'); + +serve({directory: __dirname}); + +let mainWindow; + +(async () => { + await app.whenReady(); + + mainWindow = new BrowserWindow(); + mainWindow.loadURL('app://-/subdir/page.pdf'); +})(); diff --git a/test/fixture-dir-fallback.js b/test/fixture-dir-fallback.js new file mode 100644 index 0000000..3521683 --- /dev/null +++ b/test/fixture-dir-fallback.js @@ -0,0 +1,14 @@ +'use strict'; +const {app, BrowserWindow} = require('electron'); +const serve = require('..'); + +serve({directory: __dirname}); + +let mainWindow; + +(async () => { + await app.whenReady(); + + mainWindow = new BrowserWindow(); + mainWindow.loadURL('app://-/subdir/page.html'); +})(); diff --git a/test/test.js b/test/test.js index 0b90e85..e63f196 100644 --- a/test/test.js +++ b/test/test.js @@ -30,3 +30,27 @@ test('allows special characters in file paths', async t => { await client.waitUntilTextExists('h1', '🚀', 5000); t.pass(); }); + +test('fallbacks to root index if unresolved path has .html extension or no extension', async t => { + t.context.spectron = new Application({ + path: electron, + args: ['fixture-dir-fallback.js'] + }); + await t.context.spectron.start(); + const {client} = t.context.spectron; + await client.waitUntilWindowLoaded(); + await client.waitUntilTextExists('h1', '🦄', 5000); + t.pass(); +}); + +test('throws error if unresolved path has an extension other than .html', async t => { + t.context.spectron = new Application({ + path: electron, + args: ['fixture-404-error.js'] + }); + await t.context.spectron.start(); + const {client} = t.context.spectron; + await client.waitUntilWindowLoaded(); + await t.throwsAsync(client.waitUntilTextExists('h1', '🦄', 5000)); + t.pass(); +});