From b7ca339f10307bd74a5b64d4c2da31eb27dd5a2e Mon Sep 17 00:00:00 2001 From: Fernando Piancastelli Date: Mon, 9 Nov 2015 19:43:22 -0200 Subject: [PATCH 1/7] Adding travis --- .gitignore | 2 +- .travis.yml | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) create mode 100644 .travis.yml diff --git a/.gitignore b/.gitignore index 073cfe2..d95a66e 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,3 @@ npm-debug.log node_modules - +.idea diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..6998e32 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,3 @@ +language: node_js +node_js: + - "stable" \ No newline at end of file From 33211f494787264c2e41125f9e1e0c30aeafb7f0 Mon Sep 17 00:00:00 2001 From: Fernando Piancastelli Date: Mon, 9 Nov 2015 20:01:00 -0200 Subject: [PATCH 2/7] Trying to finish the run --- .travis.yml | 1 + test/integration/node-static-test.js | 11 +++++++++++ 2 files changed, 12 insertions(+) diff --git a/.travis.yml b/.travis.yml index 6998e32..c89b579 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,3 +1,4 @@ language: node_js node_js: + - "0.12" - "stable" \ No newline at end of file diff --git a/test/integration/node-static-test.js b/test/integration/node-static-test.js index 14c591d..f321b70 100644 --- a/test/integration/node-static-test.js +++ b/test/integration/node-static-test.js @@ -386,5 +386,16 @@ suite.addBatch({ assert.equal(body, 'hello world'); } } +}).addBatch({ + 'terminate server': { + topic: function () { + server.close(); + }, + 'should be listening' : function(){ + /* This test is necessary to ensure the topic execution. + * A topic without tests will be not executed */ + assert.isTrue(true); + } + } }).export(module); From 73bcc939a7127593bc7d19f6d5d0642cf4601d64 Mon Sep 17 00:00:00 2001 From: Fernando Piancastelli Date: Mon, 9 Nov 2015 20:03:29 -0200 Subject: [PATCH 3/7] Test bugfix --- test/integration/node-static-test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/integration/node-static-test.js b/test/integration/node-static-test.js index f321b70..9fe7742 100644 --- a/test/integration/node-static-test.js +++ b/test/integration/node-static-test.js @@ -389,7 +389,7 @@ suite.addBatch({ }).addBatch({ 'terminate server': { topic: function () { - server.close(); + server.close(this.callback); }, 'should be listening' : function(){ /* This test is necessary to ensure the topic execution. From d3552ad6f2106f4bf2b88a7416fb43b478758836 Mon Sep 17 00:00:00 2001 From: Fernando Piancastelli Date: Tue, 10 Nov 2015 16:11:17 -0200 Subject: [PATCH 4/7] New fileServer option: defaultExtension Tests added --- lib/node-static.js | 20 +++++++++++-- test/integration/node-static-test.js | 43 +++++++++++++++++++++------- 2 files changed, 50 insertions(+), 13 deletions(-) diff --git a/lib/node-static.js b/lib/node-static.js index 6ba88ed..95c58af 100644 --- a/lib/node-static.js +++ b/lib/node-static.js @@ -37,6 +37,12 @@ var Server = function (root, options) { this.serverInfo = 'node-static/' + version.join('.'); } + if ('defaultExtension' in this.options) { + this.defaultExtension = '.'+this.options.defaultExtension; + } else { + this.defaultExtension = null; + } + this.defaultHeaders['server'] = this.serverInfo; if (this.cache !== false) { @@ -146,7 +152,17 @@ Server.prototype.servePath = function (pathname, status, headers, req, res, fini that.respond(null, status, headers, [pathname], stat, req, res, finish); } else if (stat.isDirectory()) { // Stream a directory of files. that.serveDir(pathname, req, res, finish); - } else { + } else if (that.defaultExtension) { + fs.stat(pathname+that.defaultExtension, function(e2, stat2) { + if (e2) { + finish(404, {}); + } else if (stat2.isFile()) { + that.respond(null, status, headers, [pathname+that.defaultExtension], stat2, req, res, finish); + } else { + finish(400, {}); + } + }); + } else { finish(400, {}); } }); @@ -204,7 +220,7 @@ Server.prototype.gzipOk = function(req, contentType) { } /* Send a gzipped version of the file if the options and the client indicate gzip is enabled and - * we find a .gz file mathing the static resource requested. + * we find a .gz file matching the static resource requested. */ Server.prototype.respondGzip = function(pathname, status, contentType, _headers, files, stat, req, res, finish) { var that = this; diff --git a/test/integration/node-static-test.js b/test/integration/node-static-test.js index 9fe7742..a289e7b 100644 --- a/test/integration/node-static-test.js +++ b/test/integration/node-static-test.js @@ -387,15 +387,36 @@ suite.addBatch({ } } }).addBatch({ - 'terminate server': { - topic: function () { - server.close(this.callback); - }, - 'should be listening' : function(){ - /* This test is necessary to ensure the topic execution. - * A topic without tests will be not executed */ - assert.isTrue(true); - } - } -}).export(module); + 'finding a file by default extension': { + topic: function() { + server.close(); + + fileServer = new static.Server(__dirname+'/../fixtures', {defaultExtension: ".txt"}); + server = require('http').createServer(function(request, response) { + fileServer.serve(request, response); + }).listen(TEST_PORT); + request.get(TEST_SERVER + '/hello', this.callback); + }, + 'should respond with 200': function(error, response, body) { + assert.equal(response.statusCode, 200); + }, + 'should respond with text/plain': function(error, response, body) { + assert.equal(response.headers['content-type'], 'text/plain'); + }, + 'should respond with hello world': function(error, response, body) { + assert.equal(body, 'hello world'); + } + } +}).addBatch({ + 'terminate server': { + topic: function() { + server.close(this.callback); + }, + 'should be listening': function() { + /* This test is necessary to ensure the topic execution. + * A topic without tests will be not executed */ + assert.isTrue(true); + } + } +}).export(module); \ No newline at end of file From bd637f3cc1802a307898545bdab27faa62549af4 Mon Sep 17 00:00:00 2001 From: Fernando Piancastelli Date: Tue, 10 Nov 2015 17:11:10 -0200 Subject: [PATCH 5/7] Test validation of new option "defaultExtension" --- lib/node-static.js | 28 ++++++++++++++++------------ test/integration/node-static-test.js | 2 +- 2 files changed, 17 insertions(+), 13 deletions(-) diff --git a/lib/node-static.js b/lib/node-static.js index 95c58af..1a30293 100644 --- a/lib/node-static.js +++ b/lib/node-static.js @@ -147,22 +147,26 @@ Server.prototype.servePath = function (pathname, status, headers, req, res, fini if (pathname.indexOf(that.root) === 0) { fs.stat(pathname, function (e, stat) { if (e) { - finish(404, {}); + // possibly not found, check default extension + if (that.defaultExtension) { + fs.stat(pathname+that.defaultExtension, function(e2, stat2) { + if (e2) { + // really not found + finish(404, {'console':e2.message}); + } else if (stat2.isFile()) { + that.respond(null, status, headers, [pathname+that.defaultExtension], stat2, req, res, finish); + } else { + finish(400, {}); + } + }); + } else { + finish(404, {}); + } } else if (stat.isFile()) { // Stream a single file. that.respond(null, status, headers, [pathname], stat, req, res, finish); } else if (stat.isDirectory()) { // Stream a directory of files. that.serveDir(pathname, req, res, finish); - } else if (that.defaultExtension) { - fs.stat(pathname+that.defaultExtension, function(e2, stat2) { - if (e2) { - finish(404, {}); - } else if (stat2.isFile()) { - that.respond(null, status, headers, [pathname+that.defaultExtension], stat2, req, res, finish); - } else { - finish(400, {}); - } - }); - } else { + } else { finish(400, {}); } }); diff --git a/test/integration/node-static-test.js b/test/integration/node-static-test.js index a289e7b..014916a 100644 --- a/test/integration/node-static-test.js +++ b/test/integration/node-static-test.js @@ -391,7 +391,7 @@ suite.addBatch({ topic: function() { server.close(); - fileServer = new static.Server(__dirname+'/../fixtures', {defaultExtension: ".txt"}); + fileServer = new static.Server(__dirname+'/../fixtures', {defaultExtension: "txt"}); server = require('http').createServer(function(request, response) { fileServer.serve(request, response); From f086f9a39dca81767fcd78194efa556076330ac7 Mon Sep 17 00:00:00 2001 From: Fernando Piancastelli Date: Tue, 10 Nov 2015 17:32:20 -0200 Subject: [PATCH 6/7] Test added: default extension does not interfere with folders Updated README --- README.md | 9 +++++++++ test/fixtures/there.html | 8 ++++++++ test/integration/node-static-test.js | 22 ++++++++++++++++++++++ 3 files changed, 39 insertions(+) create mode 100644 test/fixtures/there.html diff --git a/README.md b/README.md index 70eec00..6829269 100644 --- a/README.md +++ b/README.md @@ -194,6 +194,15 @@ example: `{ indexFile: "index.htm" }` > Defaults to `index.html` +#### `defaultExtension` # + +Choose a default extension when serving files. +A request to '/myFile' would check for a `myFile` folder (first) then a `myFile.html` (second). + +example: `{ defaultExtension: "html" }` + +> Defaults to `null` + Command Line Interface ---------------------- diff --git a/test/fixtures/there.html b/test/fixtures/there.html new file mode 100644 index 0000000..bb2a3c4 --- /dev/null +++ b/test/fixtures/there.html @@ -0,0 +1,8 @@ + + + Awesome page + + + hello there! + + diff --git a/test/integration/node-static-test.js b/test/integration/node-static-test.js index 014916a..476bb70 100644 --- a/test/integration/node-static-test.js +++ b/test/integration/node-static-test.js @@ -408,6 +408,28 @@ suite.addBatch({ assert.equal(body, 'hello world'); } } +}).addBatch({ + 'default extension does not interfere with folders': { + topic : function(){ + server.close(); + + fileServer = new static.Server(__dirname+'/../fixtures', {defaultExtension: "html"}); + + server = require('http').createServer(function(request, response) { + fileServer.serve(request, response); + }).listen(TEST_PORT); + request.get({ url: TEST_SERVER + '/there', followRedirect: false }, this.callback); // without trailing slash + }, + 'should respond with 301' : function(error, response, body){ + assert.equal(response.statusCode, 301); + }, + 'should respond with location header': function(error, response, body){ + assert.equal(response.headers['location'], '/there/'); // now with trailing slash + }, + 'should respond with empty string body' : function(error, response, body){ + assert.equal(body, ''); + } + } }).addBatch({ 'terminate server': { topic: function() { From bd5d0444b2ef0d9709920f87e34f0a02c6411bdc Mon Sep 17 00:00:00 2001 From: Fernando Piancastelli Date: Tue, 10 Nov 2015 17:39:59 -0200 Subject: [PATCH 7/7] Small fix --- lib/node-static.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/node-static.js b/lib/node-static.js index 1a30293..01e0711 100644 --- a/lib/node-static.js +++ b/lib/node-static.js @@ -152,7 +152,7 @@ Server.prototype.servePath = function (pathname, status, headers, req, res, fini fs.stat(pathname+that.defaultExtension, function(e2, stat2) { if (e2) { // really not found - finish(404, {'console':e2.message}); + finish(404, {}); } else if (stat2.isFile()) { that.respond(null, status, headers, [pathname+that.defaultExtension], stat2, req, res, finish); } else {