({ url, contentType, createIfNotExists, searchIndex = true })
| 90 | // Maps the request for a given resource and representation format to a server file |
| 91 | // Will look for an index file if a folder is given and searchIndex is true |
| 92 | async mapUrlToFile ({ url, contentType, createIfNotExists, searchIndex = true }) { |
| 93 | // map contentType to mimeType part |
| 94 | contentType = contentType ? contentType.replace(/\s*;.*/, '') : '' |
| 95 | // Parse the URL and find the base file path |
| 96 | const { pathname, hostname } = this._parseUrl(url) |
| 97 | const filePath = this.resolveFilePath(hostname, this._decodePath(pathname)) |
| 98 | if (filePath.indexOf('/..') >= 0) { |
| 99 | throw new Error('Disallowed /.. segment in URL') |
| 100 | } |
| 101 | const isFolder = filePath.endsWith('/') |
| 102 | const isIndex = searchIndex && filePath.endsWith('/') |
| 103 | |
| 104 | // Create the path for a new resource |
| 105 | let path |
| 106 | if (createIfNotExists) { |
| 107 | path = filePath |
| 108 | // Append index filename if needed |
| 109 | if (isIndex) { |
| 110 | if (contentType !== this._indexContentType) { |
| 111 | throw new Error(`Index file needs to have ${this._indexContentType} as content type`) |
| 112 | } |
| 113 | path += this._indexFilename |
| 114 | } |
| 115 | // If the extension is not correct for the content type, append the correct extension |
| 116 | if (!isFolder) { |
| 117 | path = this._addContentTypeExtension(path, contentType) |
| 118 | } |
| 119 | // Determine the path of an existing file |
| 120 | } else { |
| 121 | // Read all files in the corresponding folder |
| 122 | const filename = filePath.substr(filePath.lastIndexOf('/') + 1) |
| 123 | const folder = filePath.substr(0, filePath.length - filename.length) |
| 124 | |
| 125 | // Find a file with the same name (minus the dollar extension) |
| 126 | let match = '' |
| 127 | try { |
| 128 | const files = await this._readdir(folder) |
| 129 | // Search for files with the same name (disregarding a dollar extension) |
| 130 | if (!isFolder) { |
| 131 | match = files.find(f => this._removeDollarExtension(f) === filename) |
| 132 | // Check if the index file exists |
| 133 | } else if (searchIndex && files.includes(this._indexFilename)) { |
| 134 | match = this._indexFilename |
| 135 | } |
| 136 | } catch (err) { |
| 137 | throw new HTTPError(404, `${filePath} Resource not found`) |
| 138 | } |
| 139 | // Error if no match was found (unless URL ends with '/', then fall back to the folder) |
| 140 | if (match === undefined) { |
| 141 | if (isIndex) { |
| 142 | match = '' |
| 143 | } else { |
| 144 | throw new HTTPError(404, `${pathname} Resource not found`) |
| 145 | } |
| 146 | } |
| 147 | path = `${folder}${match}` |
| 148 | contentType = this._getContentTypeFromExtension(match) |
| 149 | } |
no test coverage detected