diff --git a/lib/resource-mapper.js b/lib/resource-mapper.js index 54514cfa6..0d21eeb42 100644 --- a/lib/resource-mapper.js +++ b/lib/resource-mapper.js @@ -4,6 +4,7 @@ const { promisify } = require('util') const { types, extensions } = require('mime-types') const readdir = promisify(fs.readdir) const HTTPError = require('./http-error') +const pathUtil = require('path') /* * A ResourceMapper maintains the mapping between HTTP URLs and server filenames, @@ -78,7 +79,9 @@ class ResourceMapper { // Determine the URL by chopping off everything after the dollar sign const pathname = this._removeDollarExtension(path) - const url = `${this.resolveUrl(hostname)}${encodeURI(pathname)}` + const url = `${this.resolveUrl(hostname)}${ + pathname.split(pathUtil.sep).map((component) => encodeURIComponent(component)).join('/') + }` return { url, contentType: this._getContentTypeFromExtension(path) } } diff --git a/test/unit/resource-mapper-test.js b/test/unit/resource-mapper-test.js index b0c7b7630..65d66a58a 100644 --- a/test/unit/resource-mapper-test.js +++ b/test/unit/resource-mapper-test.js @@ -489,6 +489,13 @@ describe('ResourceMapper', () => { url: 'http://localhost/space/foo%20bar%20bar.html', contentType: 'text/html' }) + + itMapsFile(mapper, 'a file with even stranger disallowed IRI characters', + { path: `${rootPath}space/Blog discovery for the future? · Issue #96 · scripting:Scripting-News · GitHub.pdf` }, + { + url: 'http://localhost/space/Blog%20discovery%20for%20the%20future%3F%20%C2%B7%20Issue%20%2396%20%C2%B7%20scripting%3AScripting-News%20%C2%B7%20GitHub.pdf', + contentType: 'application/pdf' + }) }) describe('A ResourceMapper instance for a multi-host setup', () => {