Skip to content

Commit 4c3a68e

Browse files
authored
feat: improve 404 error handling in Puter sites with custom page support (#1466)
- Implement a new method to serve a custom 404.html file if it exists in the subdomain root path. - Update existing error responses to utilize the new custom 404 handling. - Ensure fallback to default error handling if the custom file is not found or an error occurs during reading.
1 parent 090d1af commit 4c3a68e

File tree

1 file changed

+45
-2
lines changed

1 file changed

+45
-2
lines changed

src/backend/src/routers/hosting/puter-site.js

Lines changed: 45 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -190,7 +190,7 @@ class PuterSiteMiddleware extends AdvancedBase {
190190
await target_node.fetchEntry();
191191

192192
if ( ! await target_node.exists() ) {
193-
return this.respond_html_error_({ path }, req, res, next);
193+
return await this.respond_404_({ path }, req, res, next, subdomain_root_path);
194194
}
195195

196196
const target_is_dir = await target_node.get('type') === TYPE_DIRECTORY;
@@ -200,7 +200,7 @@ class PuterSiteMiddleware extends AdvancedBase {
200200
}
201201

202202
if ( target_is_dir ) {
203-
return this.respond_html_error_({ path }, req, res, next);
203+
return await this.respond_404_({ path }, req, res, next, subdomain_root_path);
204204
}
205205

206206
const contentType = this.modules.mime.contentType(
@@ -337,6 +337,49 @@ class PuterSiteMiddleware extends AdvancedBase {
337337
}
338338
}
339339

340+
async respond_404_ ({ path, html }, req, res, next, subdomain_root_path) {
341+
// Check for custom 404.html file in site root
342+
if (subdomain_root_path) {
343+
const context = Context.get();
344+
const services = context.get('services');
345+
const svc_fs = services.get('filesystem');
346+
347+
const custom_404_filepath = subdomain_root_path + '/404.html';
348+
const custom_404_node = await svc_fs.node(new NodePathSelector(custom_404_filepath));
349+
await custom_404_node.fetchEntry();
350+
351+
if (await custom_404_node.exists()) {
352+
// Serve the custom 404.html file
353+
res.status(404);
354+
355+
const contentType = this.modules.mime.contentType('404.html');
356+
res.set('Content-Type', contentType);
357+
358+
const ll_read = new LLRead();
359+
const stream = await ll_read.run({
360+
no_acl: true,
361+
actor: null,
362+
fsNode: custom_404_node,
363+
});
364+
365+
// Destroy the stream if the client disconnects
366+
req.on('close', () => {
367+
stream.destroy();
368+
});
369+
370+
try {
371+
return stream.pipe(res);
372+
} catch (e) {
373+
// If there's an error reading the custom 404 file, fall back to default
374+
return this.respond_html_error_({ path, html }, req, res, next);
375+
}
376+
}
377+
}
378+
379+
// Fall back to default error if no custom 404.html found
380+
return this.respond_html_error_({ path, html }, req, res, next);
381+
}
382+
340383
respond_html_error_ ({ path, html }, req, res, next) {
341384
res.status(404);
342385
res.set('Content-Type', 'text/html; charset=UTF-8');

0 commit comments

Comments
 (0)