Skip to content

Commit dabea82

Browse files
committed
Merge branch 'issue#1743' into alain-global
2 parents 47100fc + 9fe8003 commit dabea82

File tree

6 files changed

+5180
-24476
lines changed

6 files changed

+5180
-24476
lines changed

lib/handlers/patch.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,11 @@ async function patchHandler (req, res, next) {
5353
({ path, contentType } = await ldp.resourceMapper.mapUrlToFile(
5454
{ url: req, createIfNotExists: true, contentType: contentTypeForNew(req) }))
5555
// check if a folder with same name exists
56-
await ldp.checkItemName(req)
56+
try {
57+
await ldp.checkItemName(req)
58+
} catch (err) {
59+
return next(err)
60+
}
5761
resourceExists = false
5862
}
5963
const { url } = await ldp.resourceMapper.mapFileToUrl({ path, hostname: req.hostname })

lib/handlers/put.js

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,15 @@ const { stringToStream } = require('../utils')
99
async function handler (req, res, next) {
1010
debug(req.originalUrl)
1111
res.header('MS-Author-Via', 'SPARQL')
12-
1312
const contentType = req.get('content-type')
13+
14+
// check if a folder or resource with same name exists
15+
try {
16+
const ldp = req.app.locals.ldp
17+
await ldp.checkItemName(req)
18+
} catch (e) {
19+
return next(e)
20+
}
1421
// check for valid rdf content for auxiliary resource and /profile/card
1522
// TODO check that /profile/card is a minimal valid WebID card
1623
if (isAuxiliary(req) || req.originalUrl === '/profile/card') {

lib/ldp.js

Lines changed: 25 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -157,37 +157,13 @@ class LDP {
157157
if (container) {
158158
extension = ''
159159
}
160-
// Check for file or folder with same name
161-
let testName, fileName
162-
try {
163-
// check for defaulted slug in NSS POST (slug with extension)
164-
fileName = slug.endsWith(extension) || slug.endsWith(this.suffixAcl) || slug.endsWith(this.suffixMeta) ? slug : slug + extension
165-
fileName = container ? fileName : fileName + '/'
166-
const { url: testUrl } = await this.resourceMapper.mapFileToUrl({ hostname, path: containerPath + fileName })
167-
const { path: testPath } = await this.resourceMapper.mapUrlToFile({ url: testUrl })
168-
testName = container ? fs.lstatSync(testPath).isFile() : fs.lstatSync(testPath).isDirectory()
169-
} catch (err) { testName = false }
170-
171-
if (testName) {
172-
throw error(404, 'Container and resource cannot have the same name in URI')
173-
}
174160

175-
// TODO: possibly package this in ldp.post
176-
let resourceUrl = await ldp.getAvailableUrl(hostname, containerPath, { slug, extension })
161+
// allways return a valid URL.
162+
const resourceUrl = await ldp.getAvailableUrl(hostname, containerPath, { slug, extension, container })
177163
debug.handlers('POST -- Will create at: ' + resourceUrl)
178-
let originalUrl = resourceUrl
179-
180-
if (container) {
181-
// Create directory by an LDP PUT to the container's .meta resource
182-
resourceUrl = `${resourceUrl}${resourceUrl.endsWith('/') ? '' : '/'}` // ${ldp.suffixMeta}`
183-
if (originalUrl && !originalUrl.endsWith('/')) {
184-
originalUrl += '/'
185-
}
186-
}
187-
// const { url: putUrl } = await this.resourceMapper.mapFileToUrl({ path: resourceUrl, hostname })
188164

189165
await ldp.put(resourceUrl, stream, contentType)
190-
return URL.parse(originalUrl).path
166+
return URL.parse(resourceUrl).path
191167
}
192168

193169
isAuxResource (slug, extension) {
@@ -249,10 +225,6 @@ class LDP {
249225
throw error(400, 'Resource with a $.ext is not allowed by the server')
250226
}
251227

252-
// check if a folder or file with same name exists
253-
// const urlItem = url.url || url
254-
await this.checkItemName(url)
255-
256228
// First check if we are above quota
257229
let isOverQuota
258230
// Someone had a reason to make url actually a req sometimes but not
@@ -355,8 +327,9 @@ class LDP {
355327
} catch (err) { }
356328
}
357329

330+
// check if a document (or container) has the same name than a document (or container)
358331
async checkItemName (url) {
359-
let testName
332+
let testName, testPath
360333
const { hostname, pathname } = this.resourceMapper._parseUrl(url) // (url.url || url)
361334
let itemUrl = this.resourceMapper.resolveUrl(hostname, pathname)
362335
const container = itemUrl.endsWith('/')
@@ -373,11 +346,11 @@ class LDP {
373346
const { pathname } = this.resourceMapper._parseUrl(itemUrl) // (url.url || url)
374347
// check not at root
375348
if (pathname !== '/') {
376-
await this.checkItemName(itemUrl)
349+
return await this.checkItemName(itemUrl)
377350
}
378351
}
379352
if (testName) {
380-
throw error(404, 'Container and resource cannot have the same name in URI')
353+
throw error(404, `${testPath}: Container and resource cannot have the same name in URI`)
381354
}
382355
}
383356

@@ -606,17 +579,26 @@ class LDP {
606579
}
607580
}
608581

609-
async getAvailableUrl (hostname, containerURI, { slug = uuid.v1(), extension }) {
582+
async getAvailableUrl (hostname, containerURI, { slug = uuid.v1(), extension, container }) {
610583
let requestUrl = this.resourceMapper.resolveUrl(hostname, containerURI)
611-
requestUrl = requestUrl.replace(/\/*$/, '/')
584+
requestUrl = requestUrl.replace(/\/*$/, '/') // ??? what for
612585

613-
const { path: containerFilePath } = await this.resourceMapper.mapUrlToFile({ url: requestUrl })
614-
let fileName = slug.endsWith(extension) || slug.endsWith(this.suffixAcl) || slug.endsWith(this.suffixMeta) ? slug : slug + extension
615-
if (await promisify(fs.exists)(utilPath.join(containerFilePath, fileName))) {
616-
fileName = `${uuid.v1()}-${fileName}`
617-
}
618-
619-
return requestUrl + fileName
586+
let itemName = slug.endsWith(extension) || slug.endsWith(this.suffixAcl) || slug.endsWith(this.suffixMeta) ? slug : slug + extension
587+
try {
588+
// check resource exists
589+
const context = container ? '/' : ''
590+
await this.resourceMapper.mapUrlToFile({ url: (requestUrl + itemName + context) })
591+
itemName = `${uuid.v1()}-${itemName}`
592+
} catch (e) {
593+
try {
594+
// check resource with same name exists
595+
const context = !container ? '/' : ''
596+
await this.resourceMapper.mapUrlToFile({ url: (requestUrl + itemName + context) })
597+
itemName = `${uuid.v1()}-${itemName}`
598+
} catch (e) {}
599+
}
600+
if (container) itemName += '/'
601+
return requestUrl + itemName
620602
}
621603

622604
getTrustedOrigins (req) {

0 commit comments

Comments
 (0)