const { createReadStream, readFileSync, readFile, stat } = require( 'fs' ); const { join, extname } = require( 'path' ); const mimes = JSON.parse( readFileSync( join( __dirname, 'mimes.json' ) ) ); module.exports = ( baseDir, indexFile ) => { if (!baseDir) throw new Error('The argument "baseDir" is required for the extension "kirbe:static"'); indexFile = typeof indexFile === 'string' ? indexFile : 'index.html'; return( req, res, next ) => { if( req.method !== 'GET' ) { next(); return; } let requestedPath = req.parsedUrl.pathname.replace( /\/.\.\//g, '' ); let requestedExt = extname( requestedPath ); const filePath = join( baseDir, requestedPath ); stat( filePath, ( err, stats ) => { if( err ) { next(); return; } if( stats.isFile() ) { stats.mtime.setMilliseconds( 0 ); if ( stats.mtime <= new Date( req.headers[ 'if-modified-since' ] ) ) res.status( 304 ).end(); else createReadStream( filePath ).pipe( res.status( 200 ).coreRes ); } else { if ( req.parsedUrl.pathname.charAt( req.parsedUrl.pathname.length -1 ) !== '/' ) { res.status(302).header({ 'Location': `${req.parsedUrl.pathname}/` }).end(); return; } requestedPath = join( filePath, indexFile ); requestedExt = extname( requestedPath ); readFile( requestedPath, ( err, data ) => { if (err) next(); else { res.body( data ).status(200).header({ 'Content-Type': ( mimes.hasOwnProperty( requestedExt ) ? mimes[ requestedExt ] : 'application/octet-stream' ), 'Last-Modified': stats.mtime.toString() }).end(); } }); } }); }; };