jsdav-ext
Version:
jsDAV allows you to easily add WebDAV support to a NodeJS application. jsDAV is meant to cover the entire standard, and attempts to allow integration using an easy to understand API.
176 lines (159 loc) • 5.35 kB
JavaScript
/*
* @package jsDAV
* @subpackage DAV
* @copyright Copyright(c) 2011 Ajax.org B.V. <info AT ajax DOT org>
* @author Mike de Boer <info AT mikedeboer DOT nl>
* @license http://github.com/mikedeboer/jsDAV/blob/master/LICENSE MIT License
*/
;
var jsDAV_FS_Node = require("./node");
var jsDAV_File = require("./../../file");
var Fs = require("fs");
var Exc = require("./../../../shared/exceptions");
var Util = require("./../../../shared/util");
var jsDAV_FS_File = module.exports = jsDAV_FS_Node.extend(jsDAV_File, {
initialize: function(path,mountedPath) {
this.path = path;
mountedPath = mountedPath.replace(/\\/g,"/");
this.mountedPath = mountedPath;
},
/**
* Updates the data
*
* @param {mixed} data
* @return void
*/
put: function(data, type, cbfsput) {
Fs.writeFile(this.path, data, type || "utf8", cbfsput);
},
/**
* Updates the data whilst writing to a stream instead of from Buffer objects
* that reside in memory.
*
* @param {mixed} data
* @return void
*/
putStream: function(handler, type, cbfsput) {
var path = this.path;
// is it a chunked upload?
var size = handler.httpRequest.headers["x-file-size"];
if (size) {
var parts = Util.splitPath(this.path);
if (!handler.httpRequest.headers["x-file-name"])
handler.httpRequest.headers["x-file-name"] = parts[1];
handler.getNodeForPath(parts[0], function(err, parent) {
if (!Util.empty(err))
return cbfsput(err);
parent.writeFileChunk(handler, type, cbfsput);
});
}
else {
var stream = Fs.createWriteStream(path, {
encoding: type
});
handler.getRequestBody(type, stream, false, cbfsput);
}
},
/**
* Returns the data
*
* @return Buffer
*/
get: function(cbfsfileget) {
if (this.$buffer)
return cbfsfileget(null, this.$buffer);
//var _self = this;
var onRead = function(err, buff) {
if (err)
return cbfsfileget(err);
// For older versions of node convert the string to a buffer.
if (typeof buff === "string") {
var b = new Buffer(buff.length);
b.write(buff, "binary");
buff = b;
}
// Zero length buffers act funny, use a string
if (buff.length === 0)
buff = "";
//_self.$buffer = buff;
cbfsfileget(null, buff);
};
// Node before 0.1.95 doesn't do buffers for fs.readFile
if (process.version < "0.1.95" && process.version > "0.1.100") {
// sys.debug("Warning: Old node version has slower static file loading");
Fs.readFile(this.path, "binary", onRead);
}
else {
Fs.readFile(this.path, onRead);
}
},
/**
* Returns the data whilst using a ReadStream so that excessive memory usage
* is prevented.
*
* @return Buffer
*/
getStream: function(start, end, cbfsfileget) {
var options;
if (typeof start == "number" && typeof end == "number")
options = { start: start, end: end };
var stream = Fs.createReadStream(this.path, options);
stream.on("data", function(data) {
cbfsfileget(null, data);
});
stream.on("error", function(err) {
cbfsfileget(err);
});
stream.on("end", function() {
// Invoking the callback without error and data means that the callee
// can continue handling the request.
cbfsfileget();
});
},
/**
* Delete the current file
*
* @return void
*/
"delete": function(cbfsfiledel) {
Fs.unlink(this.path, cbfsfiledel);
},
/**
* Returns the size of the node, in bytes
*
* @return int
*/
getSize: function(cbfsgetsize) {
if (this.$stat)
return cbfsgetsize(null, this.$stat.size);
var self = this;
return Fs.stat(this.path, function(err, stat) {
if (err || !stat) {
return cbfsgetsize(new Exc.FileNotFound("File at location "
+ self.path + " not found"));
}
//_self.$stat = stat;
cbfsgetsize(null, stat.size);
});
},
/**
* Returns the ETag for a file
* An ETag is a unique identifier representing the current version of the file.
* If the file changes, the ETag MUST change.
* Return null if the ETag can not effectively be determined
*
* @return mixed
*/
getETag: function(cbfsgetetag) {
cbfsgetetag(null, null);
},
/**
* Returns the mime-type for a file
* If null is returned, we'll assume application/octet-stream
*
* @return mixed
*/
getContentType: function(cbfsmime) {
return cbfsmime(null, Util.mime.type(this.path));
}
});