var fs=require("fs"),events=require("events"),buffer=require("buffer"),http=require("http"),url=require("url"),path=require("path"),mime=require("mime"),util=require("./node-static/util"),version=[0,7,3];Server=function(e,t){if(e&&"object"==typeof e){t=e;e=null}this.root=path.resolve(e||".");this.options=t||{};this.cache=3600;this.defaultHeaders={};this.options.headers=this.options.headers||{};"cache"in this.options&&("number"==typeof this.options.cache?this.cache=this.options.cache:this.options.cache||(this.cache=!1));this.serverInfo="serverInfo"in this.options?this.options.serverInfo.toString():"node-static/"+version.join(".");this.defaultHeaders.server=this.serverInfo;this.cache!==!1&&(this.defaultHeaders["cache-control"]="max-age="+this.cache);for(var r in this.defaultHeaders)this.options.headers[r]=this.options.headers[r]||this.defaultHeaders[r]};Server.prototype.serveDir=function(e,t,r,n){function i(i){util.mstat(e,i,function(o,a){if(o)return n(404,{});s.respond(e,200,{},i,a,t,r,n);return void 0})}var o=path.join(e,"index.html"),s=this;fs.stat(o,function(a,p){if(a)fs.readFile(path.join(e,"index.json"),function(e,t){if(e)return n(404,{});var r=JSON.parse(t);i(r.files)});else{var h=200,f={},c=decodeURI(url.parse(t.url).pathname);if(c.length&&"/"!==c.charAt(c.length-1))return n(301,{Location:encodeURI(c+"/")});s.respond(null,h,f,[o],p,t,r,n)}})};Server.prototype.serveFile=function(e,t,r,n,i){var o=this,s=new events.EventEmitter;e=this.resolve(e);fs.stat(e,function(a,p){if(a)return s.emit("error",a);o.respond(null,t,r,[e],p,n,i,function(e,t){o.finish(e,t,n,i,s)});return void 0});return s};Server.prototype.finish=function(e,t,r,n,i,o){var s={status:e,headers:t,message:http.STATUS_CODES[e]};t.server=this.serverInfo;if(!e||e>=400)if(o)o(s);else if(i.listeners("error").length>0)i.emit("error",s);else{n.writeHead(e,t);n.end()}else{if(200!==e||"GET"!==r.method){n.writeHead(e,t);n.end()}o&&o(null,s);i.emit("success",s)}};Server.prototype.servePath=function(e,t,r,n,i,o){var s=this,a=new events.EventEmitter;e=n.resolvedPath||this.resolve(e);n.resolvedPath||0===e.indexOf(s.root)?fs.stat(e,function(a,p){a?o(404,{}):p.isFile()?s.respond(null,t,r,[e],p,n,i,o):p.isDirectory()?s.serveDir(e,n,i,o):o(400,{})}):o(403,{});return a};Server.prototype.resolve=function(e){return path.resolve(path.join(this.root,e))};Server.prototype.serve=function(e,t,r){var n,i=this,o=new events.EventEmitter,s=function(n,s){i.finish(n,s,e,t,o,r)};try{n=e.resolvedPath||decodeURI(url.parse(e.url).pathname)}catch(a){return process.nextTick(function(){return s(400,{})})}process.nextTick(function(){i.servePath(n,200,{},e,t,s).on("success",function(e){o.emit("success",e)}).on("error",function(){o.emit("error")})});return r?void 0:o};Server.prototype.gzipOk=function(e,t){var r=this.options.gzip;if(r&&("boolean"==typeof r||t&&r instanceof RegExp&&r.test(t))){var n=e.headers["accept-encoding"];return n&&n.indexOf("gzip")>=0}return!1};Server.prototype.respondGzip=function(e,t,r,n,i,o,s,a,p){var h=this;if(1==i.length&&this.gzipOk(s,r)){var f=i[0]+".gz";fs.stat(f,function(c,u){if(!c&&u.isFile()){var d=n.Vary;n.Vary=(d&&"Accept-Encoding"!=d?d+", ":"")+"Accept-Encoding";n["Content-Encoding"]="gzip";o.size=u.size;i=[f]}h.respondNoGzip(e,t,r,n,i,o,s,a,p)})}else h.respondNoGzip(e,t,r,n,i,o,s,a,p)};Server.prototype.respondNoGzip=function(e,t,r,n,i,o,s,a,p){var h=Date.parse(o.mtime),f=(e||i[0],{}),c=s.headers["if-none-match"],u=Date.parse(s.headers["if-modified-since"]);for(var d in this.options.headers)f[d]=this.options.headers[d];for(var d in n)f[d]=n[d];f.Etag=JSON.stringify([o.ino,o.size,h].join("-"));f.Date=(new Date).toUTCString();f["Last-Modified"]=new Date(o.mtime).toUTCString();f["Content-Type"]=r;f["Content-Length"]=o.size;for(var d in n)f[d]=n[d];if(!u&&!c||c&&c!==f.Etag||u&&!(u>=h)){a.writeHead(t,f);this.stream(e,i,new buffer.Buffer(o.size),a,function(e){if(e)return p(500,{});p(t,f);return void 0})}else{["Content-Encoding","Content-Language","Content-Length","Content-Location","Content-MD5","Content-Range","Content-Type","Expires","Last-Modified"].forEach(function(e){delete f[e]});p(304,f)}};Server.prototype.respond=function(e,t,r,n,i,o,s,a){var p=r["Content-Type"]||mime.lookup(n[0])||"application/octet-stream";this.options.gzip?this.respondGzip(e,t,p,r,n,i,o,s,a):this.respondNoGzip(e,t,p,r,n,i,o,s,a)};Server.prototype.stream=function(e,t,r,n,i){!function o(t,s){var a=t.shift();if(a){a="/"===a[0]?a:path.join(e||".",a);fs.createReadStream(a,{flags:"r",mode:438}).on("data",function(e){if(e.length&&s<r.length&&s>=0){e.copy(r,s);s+=e.length}}).on("close",function(){o(t,s)}).on("error",function(e){i(e);console.error(e)}).pipe(n,{end:!1})}else{n.end();i(null,r,s)}}(t.slice(0),0)};exports.Server=Server;exports.version=version;exports.mime=mime;