ai generated solutions to our ai generated problems
This commit is contained in:
+61
-7
@@ -158,7 +158,7 @@ const CSP_DIRECTIVES = [
|
|||||||
"style-src-elem 'self'",
|
"style-src-elem 'self'",
|
||||||
"style-src-attr 'unsafe-inline'",
|
"style-src-attr 'unsafe-inline'",
|
||||||
"img-src 'self' data: blob: https://*.basemaps.cartocdn.com https://basemaps.cartocdn.com",
|
"img-src 'self' data: blob: https://*.basemaps.cartocdn.com https://basemaps.cartocdn.com",
|
||||||
"media-src https://*.dzcdn.net https://*.deezer.com",
|
"media-src 'self' https://*.dzcdn.net https://*.deezer.com",
|
||||||
"font-src 'self' data:",
|
"font-src 'self' data:",
|
||||||
"connect-src 'self' https://challenges.cloudflare.com",
|
"connect-src 'self' https://challenges.cloudflare.com",
|
||||||
"frame-src https://challenges.cloudflare.com",
|
"frame-src https://challenges.cloudflare.com",
|
||||||
@@ -190,6 +190,11 @@ const mimeTypes = {
|
|||||||
'.png': 'image/png',
|
'.png': 'image/png',
|
||||||
'.svg': 'image/svg+xml',
|
'.svg': 'image/svg+xml',
|
||||||
'.webp': 'image/webp',
|
'.webp': 'image/webp',
|
||||||
|
'.mp4': 'video/mp4',
|
||||||
|
'.webm': 'video/webm',
|
||||||
|
'.ogg': 'video/ogg',
|
||||||
|
'.mp3': 'audio/mpeg',
|
||||||
|
'.wav': 'audio/wav',
|
||||||
}
|
}
|
||||||
|
|
||||||
function send(res, status, body, headers = {}) {
|
function send(res, status, body, headers = {}) {
|
||||||
@@ -2429,8 +2434,8 @@ function serveStatic(req, res) {
|
|||||||
return send(res, 403, 'Forbidden', { 'content-type': 'text/plain; charset=utf-8' })
|
return send(res, 403, 'Forbidden', { 'content-type': 'text/plain; charset=utf-8' })
|
||||||
}
|
}
|
||||||
|
|
||||||
fs.readFile(filePath, (error, data) => {
|
fs.stat(filePath, (error, stat) => {
|
||||||
if (error) {
|
if (error || !stat.isFile()) {
|
||||||
fs.readFile(path.join(DIST_DIR, 'index.html'), (indexError, indexData) => {
|
fs.readFile(path.join(DIST_DIR, 'index.html'), (indexError, indexData) => {
|
||||||
if (indexError) {
|
if (indexError) {
|
||||||
return send(res, 404, 'Build not found. Run npm run build first.', {
|
return send(res, 404, 'Build not found. Run npm run build first.', {
|
||||||
@@ -2445,14 +2450,63 @@ function serveStatic(req, res) {
|
|||||||
|
|
||||||
const ext = path.extname(filePath)
|
const ext = path.extname(filePath)
|
||||||
if (ext === '.html') {
|
if (ext === '.html') {
|
||||||
sendHtml(req, res, data)
|
fs.readFile(filePath, (htmlError, htmlData) => {
|
||||||
|
if (htmlError) {
|
||||||
|
return send(res, 500, 'Error reading file', { 'content-type': 'text/plain; charset=utf-8' })
|
||||||
|
}
|
||||||
|
sendHtml(req, res, htmlData)
|
||||||
|
})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
send(res, 200, data, {
|
const contentType = mimeTypes[ext] || 'application/octet-stream'
|
||||||
'content-type': mimeTypes[ext] || 'application/octet-stream',
|
const range = req.headers.range
|
||||||
'cache-control': 'public, max-age=31536000, immutable',
|
|
||||||
|
if (range) {
|
||||||
|
const parts = range.replace(/bytes=/, '').split('-')
|
||||||
|
const start = parseInt(parts[0], 10)
|
||||||
|
const end = parts[1] ? parseInt(parts[1], 10) : stat.size - 1
|
||||||
|
|
||||||
|
if (isNaN(start) || start < 0 || start >= stat.size || end >= stat.size || start > end) {
|
||||||
|
res.writeHead(416, {
|
||||||
|
...securityHeaders(req),
|
||||||
|
'Content-Range': `bytes */${stat.size}`,
|
||||||
|
'Accept-Ranges': 'bytes',
|
||||||
|
'content-type': 'text/plain',
|
||||||
})
|
})
|
||||||
|
return res.end('Requested Range Not Satisfiable')
|
||||||
|
}
|
||||||
|
|
||||||
|
const chunksize = end - start + 1
|
||||||
|
const fileStream = fs.createReadStream(filePath, { start, end })
|
||||||
|
const headers = {
|
||||||
|
...securityHeaders(req),
|
||||||
|
'Content-Range': `bytes ${start}-${end}/${stat.size}`,
|
||||||
|
'Accept-Ranges': 'bytes',
|
||||||
|
'Content-Length': String(chunksize),
|
||||||
|
'content-type': contentType,
|
||||||
|
'cache-control': 'public, max-age=31536000, immutable',
|
||||||
|
}
|
||||||
|
res.writeHead(206, headers)
|
||||||
|
fileStream.pipe(res)
|
||||||
|
fileStream.on('error', (err) => {
|
||||||
|
console.error(`Stream error serving ${filePath}:`, err)
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
const fileStream = fs.createReadStream(filePath)
|
||||||
|
const headers = {
|
||||||
|
...securityHeaders(req),
|
||||||
|
'Accept-Ranges': 'bytes',
|
||||||
|
'Content-Length': String(stat.size),
|
||||||
|
'content-type': contentType,
|
||||||
|
'cache-control': 'public, max-age=31536000, immutable',
|
||||||
|
}
|
||||||
|
res.writeHead(200, headers)
|
||||||
|
fileStream.pipe(res)
|
||||||
|
fileStream.on('error', (err) => {
|
||||||
|
console.error(`Stream error serving ${filePath}:`, err)
|
||||||
|
})
|
||||||
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user