fix(hono): replace serveStatic/Bun.file with explicit Content-Length routes
serveStatic returns content-length: 0 with Bun v1.3.x causing Nginx
12-30s stall. Replaced all HTML static routes with explicit:
- app.get('/admin/*.html') with c.header(Content-Length, Buffer.byteLength())
- fallback routes (/, /admin, /login, /catalog, /property/*) with c.html()
- all explicitly set Content-Length before returning text body
Refs: production server, Content-Length bug
Resolves: Admin 404, 30s load, DOMException abort
This commit is contained in:
@@ -1801,22 +1801,24 @@ app.get('/images/*', serveStatic({ root: './public' }))
|
||||
app.get('/uploads/*', serveStatic({ root: './public' }))
|
||||
app.get('/src/i18n/*', serveStatic({ root: '.' }))
|
||||
|
||||
// Admin HTML components - read file text explicitly to force Content-Length
|
||||
app.get('/admin/*', async (c) => {
|
||||
const path = c.req.path
|
||||
// If path ends with /, it's a directory → serve admin SPA
|
||||
const filePath = path.endsWith('/') ? './public/admin.html' : `./public${path}`
|
||||
const file = Bun.file(filePath)
|
||||
const text = await file.text()
|
||||
c.header('Content-Length', String(Buffer.byteLength(text, 'utf8')))
|
||||
c.header('Content-Type', 'text/html; charset=utf-8')
|
||||
return c.body(text)
|
||||
// Admin HTML components - explicit routes with forced Content-Length
|
||||
// (serveStatic has a content-length bug in this version of Bun/Hono)
|
||||
const adminComponents = [
|
||||
'sidebar', 'topbar', 'dashboard', 'properties', 'leads',
|
||||
'testimonials', 'faq', 'services', 'settings', 'users',
|
||||
'analytics', 'traffic'
|
||||
]
|
||||
adminComponents.forEach(name => {
|
||||
app.get(`/admin/${name}.html`, async (c) => {
|
||||
const file = Bun.file(`./public/admin/${name}.html`)
|
||||
const text = await file.text()
|
||||
c.header('Content-Length', String(Buffer.byteLength(text, 'utf8')))
|
||||
c.header('Content-Type', 'text/html; charset=utf-8')
|
||||
return c.body(text)
|
||||
})
|
||||
})
|
||||
|
||||
// Static HTML pages where URL path directly matches filename
|
||||
app.get('/catalog.html', serveStatic({ root: './public' }))
|
||||
|
||||
// SPA fallback routes (dynamic paths) - read file text to force Content-Length
|
||||
// SPA fallback routes (dynamic paths) with forced Content-Length
|
||||
app.get('/property/*', async (c) => {
|
||||
const text = await Bun.file('./public/property.html').text()
|
||||
c.header('Content-Length', String(Buffer.byteLength(text, 'utf8')))
|
||||
@@ -1827,6 +1829,11 @@ app.get('/catalog', async (c) => {
|
||||
c.header('Content-Length', String(Buffer.byteLength(text, 'utf8')))
|
||||
return c.html(text)
|
||||
})
|
||||
app.get('/catalog.html', async (c) => {
|
||||
const text = await Bun.file('./public/catalog.html').text()
|
||||
c.header('Content-Length', String(Buffer.byteLength(text, 'utf8')))
|
||||
return c.html(text)
|
||||
})
|
||||
app.get('/admin', async (c) => {
|
||||
const text = await Bun.file('./public/admin.html').text()
|
||||
c.header('Content-Length', String(Buffer.byteLength(text, 'utf8')))
|
||||
@@ -1839,7 +1846,11 @@ app.get('/login', async (c) => {
|
||||
})
|
||||
|
||||
// Fallback to index.html for all other routes
|
||||
app.get('*', async (c) => c.html(await Bun.file('./public/index.html').text()))
|
||||
app.get('*', async (c) => {
|
||||
const text = await Bun.file('./public/index.html').text()
|
||||
c.header('Content-Length', String(Buffer.byteLength(text, 'utf8')))
|
||||
return c.html(text)
|
||||
})
|
||||
|
||||
// Start server
|
||||
const port = parseInt(process.env.PORT || '8080')
|
||||
|
||||
Reference in New Issue
Block a user