1. Magnus Hoff
  2. resource-tree

Commits

Magnus Hoff  committed 991ce7e

Added DirectoryResource and updated FileLookup to be able to serve out directory listings and in any case not crash on directory urls. Thanks, Michael Mortensen.

  • Participants
  • Parent commits dc7b173
  • Branches default

Comments (0)

Files changed (5)

File directoryresource.js

View file
  • Ignore whitespace
+var fs = require('fs');
+var verifyNew = require('./util').verifyNew;
+var Resource = require('./resource').Resource;
+
+
+function DirectoryResource(fullpath) {
+    verifyNew(this, this.constructor.name);
+	Resource.call(this);
+
+	this.http_GET = function(req, res) {
+		if (req.url.slice(-1) !== '/') {
+			res.writeHead(500, {'Content-Type': 'text/plain'});
+			res.end("DirectoryResource served from URL without trailing /");
+			return;
+		}
+
+		fs.readdir(fullpath, function(err, files) {
+			if (err) {
+				res.writeHead(500, {'Content-Type': 'text/plain'});
+				res.end('Failed to list directory.');
+			} else {
+				res.writeHead(200, {'Content-Type': 'text/html'});
+				res.write('<!DOCTYPE html>\n<html><body><ul>');
+				files.forEach(function (relpath, index) {
+					res.write('<li><a href="'+relpath+'">'+relpath+'</a></li>');
+				});
+				res.end('</ul></body></html>');
+			}
+		});
+	};
+}
+
+
+exports.DirectoryResource = DirectoryResource;

File example-directory.js

View file
  • Ignore whitespace
 
 var resource_tree = require("./resource-tree");
 
-resource_tree.createServer(new resource_tree.FileLookup(".")).listen(8080);
+// To enable naive directory listing:
+var directoryResourceFactory = function (fullpath) { return new resource_tree.DirectoryResource(fullpath); };
+
+resource_tree.createServer(new resource_tree.FileLookup(".", directoryResourceFactory)).listen(8080);
 
 console.log("Now you can GET everything in the current directory under http://127.0.0.1:8080/\n");
 
 console.log("For example:");
+console.log("  * http://127.0.0.1:8080/");
 console.log("  * http://127.0.0.1:8080/example-directory.js");
 console.log("  * http://127.0.0.1:8080/README.md");

File filelookup.js

View file
  • Ignore whitespace
 var fs = require('fs');
 var verifyNew = require('./util').verifyNew;
 var Lookup = require('./lookup').Lookup;
+var DirectoryResource = require('./directoryresource').DirectoryResource;
 var FileResource = require('./fileresource').FileResource;
+var redirect = require('./redirectresource');
 
 
-function FileLookup(root) {
+function FileLookup(root, directoryResourceFactory, fileResourceFactory) {
     verifyNew(this, this.constructor.name);
     Lookup.call(this);
 
+    directoryResourceFactory = directoryResourceFactory || function (fullpath) { return null; };
+    fileResourceFactory = fileResourceFactory || function (fullpath) { return new FileResource(fullpath); };
+
     this.lookup = function(reqpath, callback) {
+        if (reqpath.split('/').indexOf('..') !== -1) {
+            callback(null);
+            return;
+        }
+
         var fullpath = path.join(root, reqpath);
+
         fs.exists(fullpath, function(exists) {
             if (exists) {
-                callback(new FileResource(fullpath));
+                fs.stat(fullpath, function(err, stats) {
+                    if (stats.isDirectory()) {
+                        if (reqpath.slice(-1) === '/') {
+                            callback(directoryResourceFactory(fullpath));
+                        } else {
+                            var targetUrl = reqpath.slice(reqpath.lastIndexOf('/') + 1) + '/';
+                            callback(new redirect.RedirectResource(redirect.TEMPORARY_REDIRECT, targetUrl));
+                        }
+                    } else {
+                        callback(fileResourceFactory(fullpath));
+                    }
+                });
             } else {
                 callback(null);
             }

File permanentredirectresource.js

View file
  • Ignore whitespace
 var verifyNew = require('./util').verifyNew;
-var RedirectResource = require('./redirectresource').RedirectResource;
+var redirect = require('./redirectresource');
 
 
 function PermanentRedirectResource(relativeTargetUrl) {
     verifyNew(this, this.constructor.name);
-    RedirectResource.call(this, RedirectResource.MOVED_PERMANENTLY, relativeTargetUrl);
+    redirect.RedirectResource.call(this, redirect.RedirectResource.MOVED_PERMANENTLY, relativeTargetUrl);
 
     console.log("DEPRECATED: PermanentRedirectResource is deprecated in favor of " +
         "'new RedirectResource(RedirectResource.MOVED_PERMANENTLY, targetUrl)'");
 }
-PermanentRedirectResource.prototype = new RedirectResource();
+PermanentRedirectResource.prototype = new redirect.RedirectResource();
 PermanentRedirectResource.constructor = PermanentRedirectResource;
 
 

File resource-tree.js

View file
  • Ignore whitespace
 exports.FileLookup = require('./filelookup').FileLookup;
 exports.DirectLookup = require('./directlookup').DirectLookup;
 exports.OneLevelLookup = require('./onelevellookup').OneLevelLookup;
+exports.SerialLookup = require('./seriallookup').SerialLookup;
 
 exports.Resource = require('./resource').Resource;
 exports.FileResource = require('./fileresource').FileResource;
+exports.DirectoryResource = require('./directoryresource').DirectoryResource;
+exports.RedirectResource = require('./redirectresource').RedirectResource;
 exports.PermanentRedirectResource = require('./permanentredirectresource').PermanentRedirectResource;
 
 exports.handleRequest = handleRequest;