123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163 |
- var fs = require( 'fs' ),
- mime = require( 'mime' ),
- zlib = require( 'zlib' );
- function hash( str ) {
- return require( 'crypto' ).createHash( 'md5' ).update( str ).digest( "hex" );
- }
- function _FileCache( ) {
- this.files = [ ];
- this.enabled = true;
- this.clear = function ( ) {
- this.files.length = 0;
- };
-
-
-
- this.getDataType = function ( file ) {
- var type = file.substr( file.lastIndexOf( '.' ) + 1 ).toLowerCase( );
- if ( type === 'js' || type === 'html' || type === 'xml' || type === 'txt' || type === 'xhtml' || type === 'css' ) {
- return "utf8";
- }
- else return "binary";
- };
-
-
-
- this.getFile = function ( path, callback ) {
-
-
-
- for ( var i = 0; i < this.files.length; i++ ) {
- if( this.files[ i ].path == path ) {
- global.log( 'serving from cache: ' + path, 2 );
- callback( this.files[ i ] );
- return;
- }
- }
-
- var datatype = this.getDataType( path );
- var file = fs.readFileSync( path );
- var stats = fs.statSync( path );
- if ( file ) {
-
-
-
- var self = this;
- zlib.gzip( file, function ( _, zippeddata ) {
-
- var newentry = { };
- newentry.path = path;
- newentry.data = file;
- newentry.stats = stats;
- newentry.zippeddata = zippeddata;
- newentry.contentlength = file.length;
- newentry.datatype = datatype;
- newentry.hash = hash( file );
-
- global.log( newentry.hash, 2 );
- global.log( 'loading into cache: ' + path, 2 );
- if ( self.enabled == true ) {
- self.files.push( newentry );
- var watcher = fs.watchFile( path, { }, function ( event, filename ) {
- global.log( this.entry.path + ' has changed on disk', 2 );
- self.files.splice( self.files.indexOf( this.entry ), 1 );
- fs.unwatchFile(path);
- } );
- watcher.entry = newentry;
- }
- callback( newentry );
- return;
- } );
-
- return;
- }
-
- callback( null );
- };
-
-
- this.ServeFile = function ( request, filename, response, URL ) {
- FileCache.getFile( filename, function ( file ) {
- if ( !file ) {
- response.writeHead( 500, {
- "Content-Type": "text/plain"
- } );
- response.write( 'file load error' + '\n');
- response.end( );
- return;
- }
- var type = mime.lookup( filename );
- if ( request.headers[ 'if-none-match' ] === file.hash ) {
- response.writeHead( 304, {
- "Content-Type": type,
- "Last-Modified": encodeURIComponent(file.stats.mtime),
- "ETag": file.hash,
- "Cache-Control":"public; max-age=31536000" ,
- } );
- response.end( );
- return;
- }
- if ( request.headers[ 'accept-encoding' ] && request.headers[ 'accept-encoding' ].indexOf( 'gzip' ) >= 0 ) {
- response.writeHead( 200, {
- "Content-Type": type,
- "Last-Modified": encodeURIComponent(file.stats.mtime),
- "ETag": file.hash,
- "Cache-Control":"public; max-age=31536000" ,
- 'Content-Encoding': 'gzip'
- } );
- response.write(file.zippeddata, file.datatype);
- }
- else if ( request.headers['range'] ) {
-
- var range = request.headers['range'];
- range = range.split('=')[1];
- var ranges = range.split('-');
- var start = parseInt(ranges[0]);
- var end = parseInt(ranges[1]) || (file.contentlength - 1);
- var bytesheader = 'bytes ' + start + '-' + end + '/' + file.contentlength;
- response.writeHead(206, {
- "Content-Type": type,
- "Content-Length": (end - start) + 1,
- "Last-Modified": encodeURIComponent(file.stats.mtime),
- "ETag": file.hash,
- "Cache-Control": "public; max-age=31536000",
- "Accept-Ranges": "bytes",
- "Content-Range": bytesheader
- });
- var newdata = file.data.slice(start, end + 1);
- response.write(newdata, file.datatype);
- }
- else {
- response.writeHead( 200, {
- "Content-Type": type,
- "Last-Modified": encodeURIComponent(file.stats.mtime),
- "ETag": file.hash,
- "Cache-Control":"public; max-age=31536000"
- } );
- response.write( file.data, file.datatype );
- }
- response.end( );
- } );
- };
- }
- exports._FileCache = _FileCache;
|