Routing usually involve in module url or querystring
A simple routing example:
var http = require('http');
//pages to be route
var pages = [
{route: '/', output: 'Woohoo!'},
{route: '/about/this', output: 'A simple routing with node example' },
{route: '/another page/this', output: function(){
return 'Here\'s '+this.route;}},
];
http.createServer(function (request, response) {
//get url from request
var lookup = decodeURI( request.url );
pages.forEach( function( page ){
//find a match route
if( page.route === lookup ){
response.writeHead(200, {'Content-Type':'text/html'});
response.end( typeof page.output === 'function'?
page.output() : page.output );
}
});
//match not found
if( !response.finished ){
response.writeHead(404);
response.end( '{page Not Found!' );
}
}).listen(9000);
console.log( "Server started" );
Routing to static content
var http = require( 'http' );
var path = require( 'path' );
var fs = require( 'fs' );
var mimeTypes = {
'.js' : 'text/javascript',
'.html': 'text/html',
'.css': 'text/css'
};
http.createServer( function( request, response ){
if( request.url === '/favicon' ){
response.end();
return;
}
var lookup = path.basename( decodeURI( request.url ))|| 'index.html';
//get file from content folder
var file = 'content/' + lookup;
//return the selected file
fs.exists( file, function( exists ){
if( exists ){
fs.readFile( file, function( err, data ){
if( err ) { response.writeHead(500 );
response.end( 'Server Error!' ); return;
}
var headers = { 'Content-Type': mimeTypes[path.extname( lookup ) ] };
response.writeHead( 200, headers );
response.end( data );
});
}
});
}).listen( 9000 );
console.log( 'server started' );
routing with cache
var http = require( 'http' );
var path = require( 'path' );
var fs = require( 'fs' );
var mimeTypes = {
'.js' : 'text/javascript',
'.html': 'text/html',
'.css': 'text/css'
};
var cache = {}
function cacheAndDeliver( f, cb ){
fs.stat( f, function( err, stats ){
var lastChanged = Date.parse( stats.mtime );
var isUpdated = (cache[f] ) && lastChanged > cache[f].timestamp;
//no cache or updated
if( !cache[f] || isUpdated ) {
fs.readFile( f, function( err, data ){
if( !err ) {
cache[f] = { content : data,
timestamp: Date.now()
};
}
cb( err, data );
});
}else{
//use cache
console.log( 'load ' + f + ' from cache');
cb( null, cache[f].content );
}
});
}
http.createServer( function( request, response ){
if( request.url === '/favicon' ){
response.end();
return;
}
var lookup = path.basename( decodeURI( request.url ))|| 'index.html';
//get file from content folder
var f = 'content/' + lookup;
//return the selected file
fs.exists( f, function( exists ){
if( exists ){
cacheAndDeliver( f, function( err, data ){
if( err ){
response.WriteHead({ 'Status': 404 });
}
response.writeHead(200,{'Content-Type' : mimeTypes[path.extname]});
response.end( data );
});
};
});
}).listen( 9000 );
console.log( 'server started' );
The above routing technique are insecure. users can use ../../ to access files not in the content folder.
secure routing;
To prevent unauthorized access to file. append '-serve' at the end of html, css, js file first, check file name before serving static pages
var http = require( 'http' );
var path = require( 'path' );
var fs = require( 'fs' );
var url = require( 'url');
var mimeTypes = {
'.js' : 'text/javascript',
'.html': 'text/html',
'.css': 'text/css'
};
var cache = {}
http.createServer( function( request, response ){
console.log( request.url );
var lookup = url.parse( decodeURI( request.url )).pathname;
lookup = (lookup === "/")? '/index.html_serve':lookup + '_serve';
//get file from content folder
var f = 'content-pseudosafe' + lookup;
//return the selected file
fs.exists( f, function( exists ){
if( exists ){
var extension = f.substring( f.lastIndexOf('.'), f.lastIndexOf('_') );
var headers = {'Content-Type': mimeTypes[extension]};
console.log( headers );
if( cache[f] ){
response.writeHead(200, headers );
response.end( cache[f].content );
return;
}
//createReadStream creates a ReadStream object
var s = fs.createReadStream(f).once( 'open', function(){
response.writeHead(200, headers );
//stream the ReadStream to network socket via response
this.pipe(response);
}).once('error', function(e){
console.log(e);
response.writeHead(500);
response.end( 'Server Error!' );
});
fs.stat(f, function(err, stats){
var bufferOffset = 0;
cache[f] = { content: new Buffer(stats.size), };
s.on( 'data', function( chunk ){
chunk.copy(cache[f].content, bufferOffset);
bufferOffset += chunk.length;
});
});
return;
}
response.writeHead(404);// no such file found
response.end( 'Page Not Found!' );
});
}).listen( 9000 );
console.log( 'server started' );
Serving static web pages using node-static:
var static = require( 'node-static' );
var fileServer = new static.Server('./content');
require('http').createServer(function( request, response){
request.on('end', function(){
fileServer.serve( request, response );
});
}).listen(9000);
node-static Reference