diff --git a/lib/handlers/get.mjs b/lib/handlers/get.mjs index a76b42527..b65ca616e 100644 --- a/lib/handlers/get.mjs +++ b/lib/handlers/get.mjs @@ -77,13 +77,16 @@ export default async function handler (req, res, next) { let contentRange let chunksize - if (ret) { - stream = ret.stream - contentType = ret.contentType - container = ret.container - contentRange = ret.contentRange - chunksize = ret.chunksize - } + if (ret) { + stream = ret.stream + contentType = ret.contentType + container = ret.container + contentRange = ret.contentRange + chunksize = ret.chunksize + if (ret.modified) { + res.header('Last-Modified', ret.modified.toUTCString()) + } + } // Till here it must exist if (!includeBody) { diff --git a/lib/ldp.mjs b/lib/ldp.mjs index 83dc25904..83f5f9264 100644 --- a/lib/ldp.mjs +++ b/lib/ldp.mjs @@ -451,7 +451,7 @@ class LDP { } if (!options.includeBody) { - return { stream: stats, contentType, container: stats.isDirectory() } + return { stream: stats, contentType, container: stats.isDirectory(), modified: stats.mtime } } if (stats.isDirectory()) { @@ -465,7 +465,7 @@ class LDP { throw err } const stream = stringToStream(data) - return { stream, contentType, container: true } + return { stream, contentType, container: true, modified: stats.mtime } } else { let chunksize, contentRange, start, end if (options.range) { @@ -487,7 +487,7 @@ class LDP { }) .on('open', function () { debug.handlers(`GET -- Reading ${pathLocal}`) - return resolve({ stream, contentType, container: false, contentRange, chunksize }) + return resolve({ stream, contentType, container: false, contentRange, chunksize, modified: stats.mtime }) }) })) } diff --git a/test/integration/http-test.mjs b/test/integration/http-test.mjs index cac2c886f..9c4b944c9 100644 --- a/test/integration/http-test.mjs +++ b/test/integration/http-test.mjs @@ -9,9 +9,9 @@ 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 server = setupSupertestServer({ live: true, dataBrowserPath: 'default', root: path.join(__dirname, '../resources'), @@ -253,13 +253,20 @@ describe('HTTP APIs', function () { .expect('content-type', /text\/turtle/) .expect('Access-Control-Allow-Origin', 'http://example.com') .expect(200, done) - }) - it('should have set Link as resource', function (done) { - server.get('/sampleContainer2/example1.ttl') - .expect('content-type', /text\/turtle/) - .expect('Link', /; rel="type"/) - .expect(200, done) - }) + }) + it('should have set Link as resource', function (done) { + server.get('/sampleContainer2/example1.ttl') + .expect('content-type', /text\/turtle/) + .expect('Link', /; rel="type"/) + .expect(200, done) + }) + it('should have set Last-Modified for resource', function (done) { + const modified = fs.statSync(path.join(__dirname, + '../resources/sampleContainer2/example1.ttl')).mtime.toUTCString() + server.get('/sampleContainer2/example1.ttl') + .expect('Last-Modified', modified) + .expect(200, done) + }) it('should have set Updates-Via to use WebSockets', function (done) { server.get('/sampleContainer2/example1.ttl') .expect('updates-via', /wss?:\/\//) @@ -273,13 +280,20 @@ describe('HTTP APIs', function () { .expect(hasHeader('describedBy', 'example1.ttl' + suffixMeta)) .end(done) }) - it('should have set Link as Container/BasicContainer', function (done) { - server.get('/sampleContainer2/') - .expect('content-type', /text\/turtle/) - .expect('Link', /; rel="type"/) - .expect('Link', /; rel="type"/) - .expect(200, done) - }) + it('should have set Link as Container/BasicContainer', function (done) { + server.get('/sampleContainer2/') + .expect('content-type', /text\/turtle/) + .expect('Link', /; rel="type"/) + .expect('Link', /; rel="type"/) + .expect(200, done) + }) + it('should have set Last-Modified for container', function (done) { + const modified = fs.statSync(path.join(__dirname, + '../resources/sampleContainer2')).mtime.toUTCString() + server.get('/sampleContainer2/') + .expect('Last-Modified', modified) + .expect(200, done) + }) it('should load skin (mashlib) if resource was requested as text/html', function (done) { server.get('/sampleContainer2/example1.ttl') .set('Accept', 'text/html') @@ -505,11 +519,18 @@ describe('HTTP APIs', function () { .expect('updates-via', /wss?:\/\//) .expect(200, done) }) - it('should have set Link as Resource', function (done) { - server.head('/sampleContainer2/example1.ttl') - .expect('Link', /; rel="type"/) - .expect(200, done) - }) + it('should have set Link as Resource', function (done) { + server.head('/sampleContainer2/example1.ttl') + .expect('Link', /; rel="type"/) + .expect(200, done) + }) + it('should have set Last-Modified for resource', function (done) { + const modified = fs.statSync(path.join(__dirname, + '../resources/sampleContainer2/example1.ttl')).mtime.toUTCString() + server.head('/sampleContainer2/example1.ttl') + .expect('Last-Modified', modified) + .expect(200, done) + }) it('should have set acl and describedBy Links for resource', function (done) { server.head('/sampleContainer2/example1.ttl') @@ -523,13 +544,20 @@ describe('HTTP APIs', function () { .expect('Content-Type', /text\/turtle/) .expect(200, done) }) - it('should have set Link as Container/BasicContainer', - function (done) { - server.head('/sampleContainer2/') - .expect('Link', /; rel="type"/) - .expect('Link', /; rel="type"/) - .expect(200, done) - }) + it('should have set Link as Container/BasicContainer', + function (done) { + server.head('/sampleContainer2/') + .expect('Link', /; rel="type"/) + .expect('Link', /; rel="type"/) + .expect(200, done) + }) + it('should have set Last-Modified for container', function (done) { + const modified = fs.statSync(path.join(__dirname, + '../resources/sampleContainer2')).mtime.toUTCString() + server.head('/sampleContainer2/') + .expect('Last-Modified', modified) + .expect(200, done) + }) it('should have set acl and describedBy Links for container', function (done) { server.head('/sampleContainer2/')