Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 18 additions & 9 deletions lib/header.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,10 @@ import debug from './debug.mjs'
import { pathBasename } from './utils.mjs'
import HTTPError from './http-error.mjs'

const MODES = ['Read', 'Write', 'Append', 'Control']
const PERMISSIONS = MODES.map(m => m.toLowerCase())
const MODES = ['Read', 'Write', 'Append', 'Control']
const PERMISSIONS = MODES.map(m => m.toLowerCase())
const STORAGE_DESCRIPTION = 'http://www.w3.org/ns/solid/terms#storageDescription'
const STORAGE_DESCRIPTION_METHODS = ['GET', 'HEAD', 'OPTIONS']

export function addLink (res, value, rel) {
const oldLink = res.get('Link')
Expand Down Expand Up @@ -72,13 +74,20 @@ export async function linksHandler (req, res, next) {
if (fileMetadata.isContainer && req.method === 'OPTIONS') {
res.header('Accept-Post', '*/*')
}
// Add ACL and Meta Link in header
addLink(res, pathBasename(req.path) + ldp.suffixAcl, 'acl')
addLink(res, pathBasename(req.path) + ldp.suffixMeta, 'describedBy')
// Add other Link headers
addLinks(res, fileMetadata)
next()
}
// Add ACL and Meta Link in header
addLink(res, pathBasename(req.path) + ldp.suffixAcl, 'acl')
addLink(res, pathBasename(req.path) + ldp.suffixMeta, 'describedBy')
if (STORAGE_DESCRIPTION_METHODS.includes(req.method) && !isAuxiliaryResource(req.path, ldp)) {
addLink(res, ldp.resourceMapper.resolveUrl(req.hostname, '/' + ldp.suffixMeta), STORAGE_DESCRIPTION)
}
// Add other Link headers
addLinks(res, fileMetadata)
next()
}

function isAuxiliaryResource (resourcePath, ldp) {
return resourcePath.endsWith(ldp.suffixAcl) || resourcePath.endsWith(ldp.suffixMeta)
}

export function parseMetadataFromHeader (linkHeader) {
const fileMetadata = new metadata.Metadata()
Expand Down
135 changes: 88 additions & 47 deletions test/integration/http-test.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,11 @@ import { assert, expect } from 'chai'
const __filename = fileURLToPath(import.meta.url)
const __dirname = path.dirname(__filename)

const suffixAcl = '.acl'
const suffixMeta = '.meta'
const server = setupSupertestServer({
const suffixAcl = '.acl'
const suffixMeta = '.meta'
const storageDescription = 'http://www.w3.org/ns/solid/terms#storageDescription'
const storageDescriptionResource = 'https://localhost:8443/' + suffixMeta
const server = setupSupertestServer({
live: true,
dataBrowserPath: 'default',
root: path.join(__dirname, '../resources'),
Expand Down Expand Up @@ -162,13 +164,20 @@ describe('HTTP APIs', function () {
.end(done)
})

it('should have set acl and describedBy Links for resource',
function (done) {
server.options('/sampleContainer2/example1.ttl')
.expect(hasHeader('acl', 'example1.ttl' + suffixAcl))
.expect(hasHeader('describedBy', 'example1.ttl' + suffixMeta))
.end(done)
})
it('should have set acl and describedBy Links for resource',
function (done) {
server.options('/sampleContainer2/example1.ttl')
.expect(hasHeader('acl', 'example1.ttl' + suffixAcl))
.expect(hasHeader('describedBy', 'example1.ttl' + suffixMeta))
.end(done)
})

it('should have set storageDescription Link for resource',
function (done) {
server.options('/sampleContainer2/example1.ttl')
.expect(hasHeader(storageDescription, storageDescriptionResource))
.end(done)
})

it('should have set Link as resource', function (done) {
server.options('/sampleContainer2/example1.ttl')
Expand Down Expand Up @@ -198,12 +207,18 @@ describe('HTTP APIs', function () {
.end(done)
})

it('should have set acl and describedBy Links for container', function (done) {
server.options('/sampleContainer2/')
.expect(hasHeader('acl', suffixAcl))
.expect(hasHeader('describedBy', suffixMeta))
.end(done)
})
it('should have set acl and describedBy Links for container', function (done) {
server.options('/sampleContainer2/')
.expect(hasHeader('acl', suffixAcl))
.expect(hasHeader('describedBy', suffixMeta))
.end(done)
})

it('should have set storageDescription Link for container', function (done) {
server.options('/sampleContainer2/')
.expect(hasHeader(storageDescription, storageDescriptionResource))
.end(done)
})
})

describe('Not allowed method should return 405 and allow header', function (done) {
Expand Down Expand Up @@ -265,14 +280,21 @@ describe('HTTP APIs', function () {
.expect('updates-via', /wss?:\/\//)
.expect(200, done)
})
it('should have set acl and describedBy Links for resource',
function (done) {
server.get('/sampleContainer2/example1.ttl')
.expect('content-type', /text\/turtle/)
.expect(hasHeader('acl', 'example1.ttl' + suffixAcl))
.expect(hasHeader('describedBy', 'example1.ttl' + suffixMeta))
.end(done)
})
it('should have set acl and describedBy Links for resource',
function (done) {
server.get('/sampleContainer2/example1.ttl')
.expect('content-type', /text\/turtle/)
.expect(hasHeader('acl', 'example1.ttl' + suffixAcl))
.expect(hasHeader('describedBy', 'example1.ttl' + suffixMeta))
.end(done)
})
it('should have set storageDescription Link for resource',
function (done) {
server.get('/sampleContainer2/example1.ttl')
.expect('content-type', /text\/turtle/)
.expect(hasHeader(storageDescription, storageDescriptionResource))
.end(done)
})
it('should have set Link as Container/BasicContainer', function (done) {
server.get('/sampleContainer2/')
.expect('content-type', /text\/turtle/)
Expand Down Expand Up @@ -383,14 +405,21 @@ describe('HTTP APIs', function () {
})
.end(done)
})
it('should have set acl and describedBy Links for container',
function (done) {
server.get('/sampleContainer2/')
.expect(hasHeader('acl', suffixAcl))
.expect(hasHeader('describedBy', suffixMeta))
.expect('content-type', /text\/turtle/)
.end(done)
})
it('should have set acl and describedBy Links for container',
function (done) {
server.get('/sampleContainer2/')
.expect(hasHeader('acl', suffixAcl))
.expect(hasHeader('describedBy', suffixMeta))
.expect('content-type', /text\/turtle/)
.end(done)
})
it('should have set storageDescription Link for container',
function (done) {
server.get('/sampleContainer2/')
.expect(hasHeader(storageDescription, storageDescriptionResource))
.expect('content-type', /text\/turtle/)
.end(done)
})
it('should return requested index.html resource by default', function (done) {
server.get('/sampleContainer/index.html')
.set('accept', 'text/html')
Expand Down Expand Up @@ -510,13 +539,19 @@ describe('HTTP APIs', function () {
.expect('Link', /<http:\/\/www.w3.org\/ns\/ldp#Resource>; rel="type"/)
.expect(200, done)
})
it('should have set acl and describedBy Links for resource',
function (done) {
server.head('/sampleContainer2/example1.ttl')
.expect(hasHeader('acl', 'example1.ttl' + suffixAcl))
.expect(hasHeader('describedBy', 'example1.ttl' + suffixMeta))
.end(done)
})
it('should have set acl and describedBy Links for resource',
function (done) {
server.head('/sampleContainer2/example1.ttl')
.expect(hasHeader('acl', 'example1.ttl' + suffixAcl))
.expect(hasHeader('describedBy', 'example1.ttl' + suffixMeta))
.end(done)
})
it('should have set storageDescription Link for resource',
function (done) {
server.head('/sampleContainer2/example1.ttl')
.expect(hasHeader(storageDescription, storageDescriptionResource))
.end(done)
})
it('should have set Content-Type as text/turtle for Container',
function (done) {
server.head('/sampleContainer2/')
Expand All @@ -530,14 +565,20 @@ describe('HTTP APIs', function () {
.expect('Link', /<http:\/\/www.w3.org\/ns\/ldp#Container>; rel="type"/)
.expect(200, done)
})
it('should have set acl and describedBy Links for container',
function (done) {
server.head('/sampleContainer2/')
.expect(hasHeader('acl', suffixAcl))
.expect(hasHeader('describedBy', suffixMeta))
.end(done)
})
})
it('should have set acl and describedBy Links for container',
function (done) {
server.head('/sampleContainer2/')
.expect(hasHeader('acl', suffixAcl))
.expect(hasHeader('describedBy', suffixMeta))
.end(done)
})
it('should have set storageDescription Link for container',
function (done) {
server.head('/sampleContainer2/')
.expect(hasHeader(storageDescription, storageDescriptionResource))
.end(done)
})
})

describe('PUT API', function () {
const putRequestBody = fs.readFileSync(path.join(__dirname,
Expand Down