diff --git a/lib/handlers/post.js b/lib/handlers/post.js index 928528417..c0cd9a321 100644 --- a/lib/handlers/post.js +++ b/lib/handlers/post.js @@ -86,7 +86,7 @@ async function handler (req, res, next) { const extension = mimeType in extensions ? `.${extensions[mimeType][0]}` : '' ldp.post(req.hostname, containerPath, req, - { slug, extension, container: links.isBasicContainer }).then( + { slug, extension, container: links.isBasicContainer, contentType }).then( resourcePath => { debug('File stored in ' + resourcePath) header.addLinks(res, links) diff --git a/lib/ldp.js b/lib/ldp.js index 3f178c924..2cef477db 100644 --- a/lib/ldp.js +++ b/lib/ldp.js @@ -18,8 +18,8 @@ const parse = require('./utils').parse const fetch = require('node-fetch') const { promisify } = require('util') const URL = require('url') -const URI = require('urijs') const withLock = require('./lock') +const utilPath = require('path') const RDF_MIME_TYPES = new Set([ 'text/turtle', // .ttl @@ -129,7 +129,7 @@ class LDP { } } - async post (host, containerPath, stream, { container, slug, extension }) { + async post (hostname, containerPath, stream, { container, slug, extension, contentType }) { const ldp = this debug.handlers('POST -- On parent: ' + containerPath) // prepare slug @@ -144,17 +144,17 @@ class LDP { extension = '' } // TODO: possibly package this in ldp.post - let resourcePath = await ldp.getAvailablePath(host, containerPath, { slug, extension }) - debug.handlers('POST -- Will create at: ' + resourcePath) - let originalPath = resourcePath + let resourceUrl = await ldp.getAvailableUrl(hostname, containerPath, { slug, extension }) + debug.handlers('POST -- Will create at: ' + resourceUrl) + let originalUrl = resourceUrl if (container) { // Create directory by an LDP PUT to the container's .meta resource - resourcePath = join(originalPath, ldp.suffixMeta) - if (originalPath && !originalPath.endsWith('/')) { - originalPath += '/' + resourceUrl = `${resourceUrl}${resourceUrl.endsWith('/') ? '' : '/'}${ldp.suffixMeta}` + if (originalUrl && !originalUrl.endsWith('/')) { + originalUrl += '/' } } - const { url: putUrl, contentType } = await this.resourceMapper.mapFileToUrl({ path: resourcePath, hostname: host }) + // const { url: putUrl } = await this.resourceMapper.mapFileToUrl({ path: resourceUrl, hostname }) // HACK: the middleware in webid-oidc.js uses body-parser, thus ending the stream of data // for JSON bodies. So, the stream needs to be reset @@ -162,8 +162,8 @@ class LDP { stream = intoStream(JSON.stringify(stream.body)) } - await ldp.put(putUrl, stream, contentType) - return originalPath + await ldp.put(resourceUrl, stream, contentType) + return URL.parse(originalUrl).path } /** @@ -432,19 +432,17 @@ class LDP { } } - getAvailablePath (host, containerURI, { slug = uuid.v1(), extension }) { - const path = slug + extension - function ensureNotExists (self, newPath) { - // Verify whether the new path already exists - return self.exists(host, newPath).then( - // If it does, generate another one - () => ensureNotExists(self, URI.joinPaths(containerURI, - `${uuid.v1().split('-')[0]}-${path}`).toString()), - // If not, we found an appropriate path - () => newPath - ) + async getAvailableUrl (hostname, containerURI, { slug = uuid.v1(), extension }) { + let requestUrl = this.resourceMapper.resolveUrl(hostname, containerURI) + requestUrl = requestUrl.replace(/\/*$/, '/') + + const { path: containerFilePath } = await this.resourceMapper.mapUrlToFile({ url: requestUrl }) + let fileName = slug + extension + if (await promisify(fs.exists)(utilPath.join(containerFilePath, fileName))) { + fileName = `${uuid.v1()}-${fileName}` } - return ensureNotExists(this, URI.joinPaths(containerURI, path).toString()) + + return requestUrl + fileName } getTrustedOrigins (req) {