diff --git a/src/http/output/metadata/AllowAcceptHeaderWriter.ts b/src/http/output/metadata/AllowAcceptHeaderWriter.ts index 268f6aec7..7e2a5b4ae 100644 --- a/src/http/output/metadata/AllowAcceptHeaderWriter.ts +++ b/src/http/output/metadata/AllowAcceptHeaderWriter.ts @@ -50,10 +50,14 @@ export class AllowAcceptHeaderWriter extends MetadataWriter { // POST is only allowed on containers. // Metadata only has the resource URI in case it has resource metadata. - if (this.isPostAllowed(metadata)) { + if (!this.isPostAllowed(metadata)) { allowedMethods.delete('POST'); } + if (!this.isPutAllowed(metadata)) { + allowedMethods.delete('PUT'); + } + if (!this.isDeleteAllowed(metadata)) { allowedMethods.delete('DELETE'); } @@ -76,7 +80,14 @@ export class AllowAcceptHeaderWriter extends MetadataWriter { * otherwise it is just a blank node. */ private isPostAllowed(metadata: RepresentationMetadata): boolean { - return metadata.has(RDF.terms.type, LDP.terms.Resource) && !isContainerPath(metadata.identifier.value); + return !metadata.has(RDF.terms.type, LDP.terms.Resource) || isContainerPath(metadata.identifier.value); + } + + /** + * PUT is not allowed on existing containers. + */ + private isPutAllowed(metadata: RepresentationMetadata): boolean { + return !metadata.has(RDF.terms.type, LDP.terms.Resource) || !isContainerPath(metadata.identifier.value); } /** diff --git a/test/unit/http/output/metadata/AllowAcceptHeaderWriter.test.ts b/test/unit/http/output/metadata/AllowAcceptHeaderWriter.test.ts index f8e526843..ed4c50467 100644 --- a/test/unit/http/output/metadata/AllowAcceptHeaderWriter.test.ts +++ b/test/unit/http/output/metadata/AllowAcceptHeaderWriter.test.ts @@ -49,36 +49,33 @@ describe('An AllowAcceptHeaderWriter', (): void => { expect(headers['accept-post']).toBeUndefined(); }); - it('returns all methods for an empty container.', async(): Promise => { + it('returns all methods except PUT for an empty container.', async(): Promise => { await expect(writer.handleSafe({ response, metadata: emptyContainer })).resolves.toBeUndefined(); const headers = response.getHeaders(); expect(typeof headers.allow).toBe('string'); expect(new Set((headers.allow as string).split(', '))) - .toEqual(new Set([ 'OPTIONS', 'GET', 'HEAD', 'PUT', 'POST', 'PATCH', 'DELETE' ])); + .toEqual(new Set([ 'OPTIONS', 'GET', 'HEAD', 'POST', 'PATCH', 'DELETE' ])); expect(headers['accept-patch']).toBe('text/n3, application/sparql-update'); - expect(headers['accept-put']).toBe('*/*'); expect(headers['accept-post']).toBe('*/*'); }); - it('returns all methods except DELETE for a non-empty container.', async(): Promise => { + it('returns all methods except PUT/DELETE for a non-empty container.', async(): Promise => { await expect(writer.handleSafe({ response, metadata: fullContainer })).resolves.toBeUndefined(); const headers = response.getHeaders(); expect(typeof headers.allow).toBe('string'); expect(new Set((headers.allow as string).split(', '))) - .toEqual(new Set([ 'OPTIONS', 'GET', 'HEAD', 'PUT', 'POST', 'PATCH' ])); + .toEqual(new Set([ 'OPTIONS', 'GET', 'HEAD', 'POST', 'PATCH' ])); expect(headers['accept-patch']).toBe('text/n3, application/sparql-update'); - expect(headers['accept-put']).toBe('*/*'); expect(headers['accept-post']).toBe('*/*'); }); - it('returns all methods except DELETE for a storage container.', async(): Promise => { + it('returns all methods except PUT/DELETE for a storage container.', async(): Promise => { await expect(writer.handleSafe({ response, metadata: storageContainer })).resolves.toBeUndefined(); const headers = response.getHeaders(); expect(typeof headers.allow).toBe('string'); expect(new Set((headers.allow as string).split(', '))) - .toEqual(new Set([ 'OPTIONS', 'GET', 'HEAD', 'PUT', 'POST', 'PATCH' ])); + .toEqual(new Set([ 'OPTIONS', 'GET', 'HEAD', 'POST', 'PATCH' ])); expect(headers['accept-patch']).toBe('text/n3, application/sparql-update'); - expect(headers['accept-put']).toBe('*/*'); expect(headers['accept-post']).toBe('*/*'); });