diff --git a/lib/ldp.js b/lib/ldp.js index 7a22bfa2..2c4e849f 100644 --- a/lib/ldp.js +++ b/lib/ldp.js @@ -137,6 +137,7 @@ class LDP { } async post (hostname, containerPath, stream, { container, slug, extension, contentType }) { + console.log('container:', container) // POST without content type is forbidden if (!contentType) { throw error(400, @@ -155,7 +156,13 @@ class LDP { if (container) { // the name of a container cannot be a valid auxiliary resource document - if (this._containsInvalidSuffixes(slug + '/')) slug = slug.split('.')[0] + while (this._containsInvalidSuffixes(slug + '/')) { + console.log('splitting slug', slug) + // slug = slug.split('.')[0] + const idx = slug.lastIndexOf('.') + slug = slug.substr(0, idx) + console.log('new slug', slug) + } } else if (this.isAuxResource(slug, extension)) throw error(403, 'POST is not allowed for auxiliary resources') if (slug.match(/\/|\||:/)) { diff --git a/package.json b/package.json index 54a9041d..8aa3514b 100644 --- a/package.json +++ b/package.json @@ -146,6 +146,7 @@ "validate": "node ./test/validate-turtle.js", "nyc": "cross-env NODE_TLS_REJECT_UNAUTHORIZED=0 nyc --reporter=text-summary mocha --recursive test/integration/ test/unit/", "mocha": "cross-env NODE_TLS_REJECT_UNAUTHORIZED=0 mocha --recursive test/integration/ test/unit/", + "mocha-integration": "cross-env NODE_TLS_REJECT_UNAUTHORIZED=0 mocha --recursive test/integration/http-test.js", "prepublishOnly": "npm test", "postpublish": "git push --follow-tags", "test": "npm run standard && npm run validate && npm run nyc", diff --git a/test/integration/http-test.js b/test/integration/http-test.js index f4f5c82d..6c256e3d 100644 --- a/test/integration/http-test.js +++ b/test/integration/http-test.js @@ -891,13 +891,6 @@ describe('HTTP APIs', function () { .set('content-type', 'text/turtle') .expect(403, done) }) - it('should not error with 400 if slug contains invalid suffix', function (done) { // TODO find better name - server.post('/post-tests/') - .set('slug', 'put-resource.acl.ttl') - .send(postRequest1Body) - .set('content-type', 'text-turtle') - .expect(201, done) - }) it('should error with 400 if the body is empty and no content type is provided', function (done) { server.post('/post-tests/') .set('slug', 'post-resource-empty-fail') @@ -921,6 +914,24 @@ describe('HTTP APIs', function () { .expect(hasHeader('acl', suffixAcl)) .expect(201, done) }) + it('should create new resource even if slug contains invalid suffix', function (done) { + server.post('/post-tests/') + .set('slug', 'put-resource.acl.ttl') + .send(postRequest1Body) + .set('content-type', 'text-turtle') + .expect(hasHeader('describedBy', suffixMeta)) + .expect(hasHeader('acl', suffixAcl)) + .expect(201, done) + }) + it('create container with recursive example', function (done) { + server.post('/post-tests/') + .set('content-type', 'text/turtle') + .set('slug', 'foo.bar.acl.meta') + .set('link', '; rel="type"') + .send(postRequest2Body) + .expect('location', /\/post-tests\/foo.bar\//) + .expect(201, done) + }) it('should fail return 404 if no parent container found', function (done) { server.post('/hello.html/') .send(postRequest1Body) diff --git a/test/integration/patch-test.js b/test/integration/patch-test.js index 38594fb0..846f0480 100644 --- a/test/integration/patch-test.js +++ b/test/integration/patch-test.js @@ -131,7 +131,7 @@ describe('PATCH through text/n3', () => { result: '@prefix : .\n@prefix tim: .\n\ntim:x tim:y tim:z.\n\n' })) - describe('on an N3 file that has an invalid uri', describePatch({ + describe('on an N3 file that has an invalid uri (*.acl)', describePatch({ path: '/foo/bar.acl/test.n3', exists: false, patch: `<> a solid:InsertDeletePatch; @@ -141,6 +141,16 @@ describe('PATCH through text/n3', () => { text: 'contained reserved suffixes in path' })) + describe('on an N3 file that has an invalid uri (*.meta)', describePatch({ + path: '/foo/bar/xyz.meta/test.n3', + exists: false, + patch: `<> a solid:InsertDeletePatch; + solid:insers { . }.` + }, { + status: 400, + text: 'contained reserved suffixes in path' + })) + describe('on a resource with read-only access', describePatch({ path: '/read-only.ttl', patch: `<> a solid:InsertDeletePatch;