Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Move lib to top level

  • Loading branch information...
commit cd43a69d4e419474198d0e280dde7cfe962e38f3 1 parent 83a4059
@kriszyp authored
Showing with 643 additions and 182 deletions.
  1. +85 −0 compatibility/require-uri.js
  2. +52 −0 facet/jsgi.js
  3. 0  {lib → }/html-transform.js
  4. 0  {lib → }/jsgi/README.md
  5. 0  {lib → }/jsgi/auth.js
  6. 0  {lib → }/jsgi/cache.js
  7. 0  {lib → }/jsgi/cascade.js
  8. 0  {lib → }/jsgi/class-alias.js
  9. 0  {lib → }/jsgi/compress.js
  10. 0  {lib → }/jsgi/conditional.js
  11. 0  {lib → }/jsgi/context.js
  12. 0  {lib → }/jsgi/csrf.js
  13. 0  {lib → }/jsgi/error.js
  14. 0  {lib → }/jsgi/extension.js
  15. 0  {lib → }/jsgi/head.js
  16. 0  {lib → }/jsgi/http-params.js
  17. 0  {lib → }/jsgi/media.js
  18. 0  {lib → }/jsgi/metadata.js
  19. 0  {lib → }/jsgi/methods.js
  20. +174 −0 jsgi/mime.js
  21. 0  {lib → }/jsgi/pintura-headers.js
  22. +23 −0 jsgi/put.js
  23. +127 −0 jsgi/querystring.js
  24. 0  {lib → }/jsgi/response.js
  25. 0  {lib → }/jsgi/rest-store.js
  26. 0  {lib → }/jsgi/rewriter.js
  27. 0  {lib → }/jsgi/routes.js
  28. 0  {lib → }/jsgi/session.js
  29. +174 −0 jsgi/static.js
  30. 0  {lib → }/jsgi/templated.js
  31. +1 −1  {lib → }/jsgi/xsite.js
  32. +0 −174 lib/jsgi/static.js
  33. 0  {lib → }/media.js
  34. 0  {lib → }/media/README.md
  35. 0  {lib → }/media/atom.js
  36. 0  {lib → }/media/auto-type.js
  37. 0  {lib → }/media/css.js
  38. 0  {lib → }/media/csv.js
  39. 0  {lib → }/media/hatom.js
  40. +2 −2 {lib → }/media/html.js
  41. 0  {lib → }/media/http.js
  42. 0  {lib → }/media/javascript.js
  43. 0  {lib → }/media/json.js
  44. 0  {lib → }/media/message/json.js
  45. +1 −1  {lib → }/media/multipart-form-data.js
  46. 0  {lib → }/media/plain.js
  47. 0  {lib → }/media/uri-list.js
  48. 0  {lib → }/media/url-encoded.js
  49. 0  {lib → }/media/xml.js
  50. +2 −2 package.json
  51. 0  {lib → }/pintura.js
  52. 0  {lib → }/require.js
  53. 0  {lib → }/security.js
  54. +2 −2 {lib → }/start-node.js
  55. 0  {lib → }/util/README.md
  56. 0  {lib → }/util/atom-util.js
  57. 0  {lib → }/util/html.js
  58. 0  {lib → }/util/repl.js
View
85 compatibility/require-uri.js
@@ -0,0 +1,85 @@
+/*
+ * The require-uri module provides a backwards compatible technique for
+ * requiring modules with URLs. This is designed to be used at the top of a module:
+ * require = require("require-uri").getRequire(require);
+ */
+
+
+exports.getRequire = function(require){
+ return function(id){
+ if(module.supportsUri || id.charAt(0) === '.'){
+ // if we support URLs, use the real require
+ return require(id);
+ }
+ id = resolveUri("", id, mappings);
+ if(id.indexOf(":") === -1){
+ return require(id);
+ }
+ // otherwise pray that required module is in the path
+ try{
+ return require(id.split("/lib/")[1]);
+ }
+ catch(e){
+ e.message += " Was trying to load module from " + id +
+ " and failed, check to ensure it is installed locally or use the web-modules asynchronous loader";
+ throw e;
+ }
+ };
+};
+
+
+function resolveUri(currentId, uri, mappings){
+ if(uri.charAt(0) === '.'){
+ currentId = currentId.substring(0, currentId.lastIndexOf('/') + 1);
+ return [(currentId + uri).replace(/\/\.\.\/[^\/]*/g,'').replace(/\.\//g,'')];
+ }
+ else{
+ return (mappings && mappings.some(function(mapping){
+ var from = mapping.from;
+ if(uri.substring(0, from.length) == from){
+ return mapping.to + uri.substring(from.length);
+ }
+ })) || uri;
+ }
+}
+
+var engine = typeof process !== "undefined" ? "node" : "narwhal";
+var mappingsArray = [];
+var allMappings = {};
+exports.installPackage = function(packageData){
+ function addMappings(mappings){
+ if(mappings){
+ mappingsArray = mappingsArray.concat(Object.keys(mappings).filter(function(key){
+ return !(key in allMappings);
+ }).map(function(key){
+ var to = mappings[key];
+ return {
+ from: key,
+ to: resolveUri(packageUri, typeof to == "string" ? to : to.to)
+ };
+ }).sort(function(a, b){
+ return a.from.length < b.from.length ? 1 : -1;
+ }));
+ }
+ }
+ if(packageData.overlay){
+ Object.keys(packageData.overlay).forEach(function(condition){
+ try{
+ var matches = (engine == condition) || eval(condition);
+ }catch(e){}
+ if(matches){
+ addMappings(packageData.overlay[condition].mappings);
+ }
+ });
+ }
+ addMappings(packageData.mappings);
+}
+
+exports.installPackage({
+ mappings:{
+ "perstore/": "",
+ "commonjs-utils/": "",
+ "pintura/": "",
+ "wiky/": ""
+ }
+});
View
52 facet/jsgi.js
@@ -0,0 +1,52 @@
+/** This facet is designed for bundling multiple requests in a single request. This is
+ * based on the JSGI object structure.
+ */
+
+var Facet = require("perstore/facet").Facet,
+ directApp = require("../pintura").directApp,
+ defer = require("promised-io/promise").defer,
+ namedFacets = require("../facet-resolver").namedFacets;
+
+namedFacets["application/jsgi"] = exports.JsgiFacet = Facet(Object, function(store){
+ return {
+ forStore: function(requestedStore){
+ function genericHandler(requests, metadata){
+ requests.forEach(function(request){
+ request.store = requestedStore;
+ (request.headers || (request.headers = {})).__proto__ = metadata;
+ metadata.clientConnection;
+ metadata.streamable;
+ try{
+ var response = directApp(request);
+ if(typeof response.body.observe === "function"){
+ response.body.observe()
+ }
+ var response = {
+
+ body: directApp(request)
+ };
+ }catch(e){
+ response = {
+ error: e
+ };
+ }
+ onResponse(response);
+ });
+ var responses = [];
+ var onResponse;
+ // maybe use lazy-array here
+ responses.forEach = function(callback){
+ onResponse = callback;
+ var deferred = defer();
+ return deferred.promise;
+ };
+ return responses;
+ }
+ return {
+ get: genericHandler,
+ put: genericHandler,
+ post: genericHandler
+ };
+ }
+ };
+});
View
0  lib/html-transform.js → html-transform.js
File renamed without changes
View
0  lib/jsgi/README.md → jsgi/README.md
File renamed without changes
View
0  lib/jsgi/auth.js → jsgi/auth.js
File renamed without changes
View
0  lib/jsgi/cache.js → jsgi/cache.js
File renamed without changes
View
0  lib/jsgi/cascade.js → jsgi/cascade.js
File renamed without changes
View
0  lib/jsgi/class-alias.js → jsgi/class-alias.js
File renamed without changes
View
0  lib/jsgi/compress.js → jsgi/compress.js
File renamed without changes
View
0  lib/jsgi/conditional.js → jsgi/conditional.js
File renamed without changes
View
0  lib/jsgi/context.js → jsgi/context.js
File renamed without changes
View
0  lib/jsgi/csrf.js → jsgi/csrf.js
File renamed without changes
View
0  lib/jsgi/error.js → jsgi/error.js
File renamed without changes
View
0  lib/jsgi/extension.js → jsgi/extension.js
File renamed without changes
View
0  lib/jsgi/head.js → jsgi/head.js
File renamed without changes
View
0  lib/jsgi/http-params.js → jsgi/http-params.js
File renamed without changes
View
0  lib/jsgi/media.js → jsgi/media.js
File renamed without changes
View
0  lib/jsgi/metadata.js → jsgi/metadata.js
File renamed without changes
View
0  lib/jsgi/methods.js → jsgi/methods.js
File renamed without changes
View
174 jsgi/mime.js
@@ -0,0 +1,174 @@
+
+// returns MIME type for extension, or fallback, or octet-steam
+exports.mimeType = function(ext, fallback) {
+ return exports.MIME_TYPES[ext.toLowerCase()] || fallback || 'application/octet-stream';
+},
+
+// List of most common mime-types, stolen from Rack.
+exports.MIME_TYPES = {
+ ".3gp" : "video/3gpp",
+ ".a" : "application/octet-stream",
+ ".ai" : "application/postscript",
+ ".aif" : "audio/x-aiff",
+ ".aiff" : "audio/x-aiff",
+ ".asc" : "application/pgp-signature",
+ ".asf" : "video/x-ms-asf",
+ ".asm" : "text/x-asm",
+ ".asx" : "video/x-ms-asf",
+ ".atom" : "application/atom+xml",
+ ".au" : "audio/basic",
+ ".avi" : "video/x-msvideo",
+ ".bat" : "application/x-msdownload",
+ ".bin" : "application/octet-stream",
+ ".bmp" : "image/bmp",
+ ".bz2" : "application/x-bzip2",
+ ".c" : "text/x-c",
+ ".cab" : "application/vnd.ms-cab-compressed",
+ ".cc" : "text/x-c",
+ ".chm" : "application/vnd.ms-htmlhelp",
+ ".class" : "application/octet-stream",
+ ".com" : "application/x-msdownload",
+ ".conf" : "text/plain",
+ ".cpp" : "text/x-c",
+ ".crt" : "application/x-x509-ca-cert",
+ ".css" : "text/css",
+ ".csv" : "text/csv",
+ ".cxx" : "text/x-c",
+ ".deb" : "application/x-debian-package",
+ ".der" : "application/x-x509-ca-cert",
+ ".diff" : "text/x-diff",
+ ".djv" : "image/vnd.djvu",
+ ".djvu" : "image/vnd.djvu",
+ ".dll" : "application/x-msdownload",
+ ".dmg" : "application/octet-stream",
+ ".doc" : "application/msword",
+ ".dot" : "application/msword",
+ ".dtd" : "application/xml-dtd",
+ ".dvi" : "application/x-dvi",
+ ".ear" : "application/java-archive",
+ ".eml" : "message/rfc822",
+ ".eps" : "application/postscript",
+ ".exe" : "application/x-msdownload",
+ ".f" : "text/x-fortran",
+ ".f77" : "text/x-fortran",
+ ".f90" : "text/x-fortran",
+ ".flv" : "video/x-flv",
+ ".for" : "text/x-fortran",
+ ".gem" : "application/octet-stream",
+ ".gemspec" : "text/x-script.ruby",
+ ".gif" : "image/gif",
+ ".gz" : "application/x-gzip",
+ ".h" : "text/x-c",
+ ".hh" : "text/x-c",
+ ".htm" : "text/html",
+ ".html" : "text/html",
+ ".ico" : "image/vnd.microsoft.icon",
+ ".ics" : "text/calendar",
+ ".ifb" : "text/calendar",
+ ".iso" : "application/octet-stream",
+ ".jar" : "application/java-archive",
+ ".java" : "text/x-java-source",
+ ".jnlp" : "application/x-java-jnlp-file",
+ ".jpeg" : "image/jpeg",
+ ".jpg" : "image/jpeg",
+ ".js" : "application/javascript",
+ ".json" : "application/json",
+ ".log" : "text/plain",
+ ".m3u" : "audio/x-mpegurl",
+ ".m4v" : "video/mp4",
+ ".man" : "text/troff",
+ ".mathml" : "application/mathml+xml",
+ ".mbox" : "application/mbox",
+ ".mdoc" : "text/troff",
+ ".me" : "text/troff",
+ ".mid" : "audio/midi",
+ ".midi" : "audio/midi",
+ ".mime" : "message/rfc822",
+ ".mml" : "application/mathml+xml",
+ ".mng" : "video/x-mng",
+ ".mov" : "video/quicktime",
+ ".mp3" : "audio/mpeg",
+ ".mp4" : "video/mp4",
+ ".mp4v" : "video/mp4",
+ ".mpeg" : "video/mpeg",
+ ".mpg" : "video/mpeg",
+ ".ms" : "text/troff",
+ ".msi" : "application/x-msdownload",
+ ".odp" : "application/vnd.oasis.opendocument.presentation",
+ ".ods" : "application/vnd.oasis.opendocument.spreadsheet",
+ ".odt" : "application/vnd.oasis.opendocument.text",
+ ".ogg" : "application/ogg",
+ ".p" : "text/x-pascal",
+ ".pas" : "text/x-pascal",
+ ".pbm" : "image/x-portable-bitmap",
+ ".pdf" : "application/pdf",
+ ".pem" : "application/x-x509-ca-cert",
+ ".pgm" : "image/x-portable-graymap",
+ ".pgp" : "application/pgp-encrypted",
+ ".pkg" : "application/octet-stream",
+ ".pl" : "text/x-script.perl",
+ ".pm" : "text/x-script.perl-module",
+ ".png" : "image/png",
+ ".pnm" : "image/x-portable-anymap",
+ ".ppm" : "image/x-portable-pixmap",
+ ".pps" : "application/vnd.ms-powerpoint",
+ ".ppt" : "application/vnd.ms-powerpoint",
+ ".ps" : "application/postscript",
+ ".psd" : "image/vnd.adobe.photoshop",
+ ".py" : "text/x-script.python",
+ ".qt" : "video/quicktime",
+ ".ra" : "audio/x-pn-realaudio",
+ ".rake" : "text/x-script.ruby",
+ ".ram" : "audio/x-pn-realaudio",
+ ".rar" : "application/x-rar-compressed",
+ ".rb" : "text/x-script.ruby",
+ ".rdf" : "application/rdf+xml",
+ ".roff" : "text/troff",
+ ".rpm" : "application/x-redhat-package-manager",
+ ".rss" : "application/rss+xml",
+ ".rtf" : "application/rtf",
+ ".ru" : "text/x-script.ruby",
+ ".s" : "text/x-asm",
+ ".sgm" : "text/sgml",
+ ".sgml" : "text/sgml",
+ ".sh" : "application/x-sh",
+ ".sig" : "application/pgp-signature",
+ ".snd" : "audio/basic",
+ ".so" : "application/octet-stream",
+ ".svg" : "image/svg+xml",
+ ".svgz" : "image/svg+xml",
+ ".swf" : "application/x-shockwave-flash",
+ ".t" : "text/troff",
+ ".tar" : "application/x-tar",
+ ".tbz" : "application/x-bzip-compressed-tar",
+ ".tcl" : "application/x-tcl",
+ ".tex" : "application/x-tex",
+ ".texi" : "application/x-texinfo",
+ ".texinfo" : "application/x-texinfo",
+ ".text" : "text/plain",
+ ".tif" : "image/tiff",
+ ".tiff" : "image/tiff",
+ ".torrent" : "application/x-bittorrent",
+ ".tr" : "text/troff",
+ ".txt" : "text/plain",
+ ".vcf" : "text/x-vcard",
+ ".vcs" : "text/x-vcalendar",
+ ".vrml" : "model/vrml",
+ ".war" : "application/java-archive",
+ ".wav" : "audio/x-wav",
+ ".wma" : "audio/x-ms-wma",
+ ".wmv" : "video/x-ms-wmv",
+ ".wmx" : "video/x-ms-wmx",
+ ".wrl" : "model/vrml",
+ ".wsdl" : "application/wsdl+xml",
+ ".xbm" : "image/x-xbitmap",
+ ".xhtml" : "application/xhtml+xml",
+ ".xls" : "application/vnd.ms-excel",
+ ".xml" : "application/xml",
+ ".xpm" : "image/x-xpixmap",
+ ".xsl" : "application/xml",
+ ".xslt" : "application/xslt+xml",
+ ".yaml" : "text/yaml",
+ ".yml" : "text/yaml",
+ ".zip" : "application/zip"
+}
View
0  lib/jsgi/pintura-headers.js → jsgi/pintura-headers.js
File renamed without changes
View
23 jsgi/put.js
@@ -0,0 +1,23 @@
+var when = require("promised-io/promise").when,
+ fs = require("promised-io/fs"),
+ forEachableToString = require("../media").forEachableToString;
+
+module.exports = function(nextApp) {
+ return function(request) {
+ if(request.method === "PUT") {
+ return when(forEachableToString(request.body), function(body){
+ fs.writeFile(request.filePath, body);
+ return {
+ status: 200,
+ headers: {},
+ body: ["successful"]
+ }
+ });
+ }
+ return nextApp ? nextApp(request) : {
+ status: 404,
+ headers: {},
+ body: []
+ };
+ };
+};
View
127 jsgi/querystring.js
@@ -0,0 +1,127 @@
+// Query String Utilities
+
+var DEFAULT_SEP = "&";
+var DEFAULT_EQ = "=";
+
+exports.unescape = function (str, decodeSpaces) {
+ return decodeURIComponent(decodeSpaces ? str.replace(/\+/g, " ") : str);
+};
+
+exports.escape = function (str) {
+ return encodeURIComponent(str);
+};
+
+exports.toQueryString = function (obj, sep, eq, name) {
+ sep = sep || DEFAULT_SEP;
+ eq = eq || DEFAULT_EQ;
+ if (isA(obj, null) || isA(obj, undefined)) {
+ return name ? encodeURIComponent(name) + eq : '';
+ }
+ if (isNumber(obj) || isString(obj)) {
+ return encodeURIComponent(name) + eq + encodeURIComponent(obj);
+ }
+ if (isA(obj, [])) {
+ var s = [];
+ name = name+'[]';
+ for (var i = 0, l = obj.length; i < l; i ++) {
+ s.push( exports.toQueryString(obj[i], sep, eq, name) );
+ }
+ return s.join(sep);
+ }
+ // now we know it's an object.
+ var s = [];
+ var begin = name ? name + '[' : '';
+ var end = name ? ']' : '';
+ for (var i in obj) if (obj.hasOwnProperty(i)) {
+ var n = begin + i + end;
+ s.push(exports.toQueryString(obj[i], sep, eq, n));
+ }
+ return s.join(sep);
+};
+
+exports.parseQuery = function(qs, sep, eq) {
+ return qs
+ .split(sep||DEFAULT_SEP)
+ .map(pieceParser(eq||DEFAULT_EQ))
+ .reduce(mergeParams);
+};
+
+// Parse a key=val string.
+// These can get pretty hairy
+// example flow:
+// parse(foo[bar][][bla]=baz)
+// return parse(foo[bar][][bla],"baz")
+// return parse(foo[bar][], {bla : "baz"})
+// return parse(foo[bar], [{bla:"baz"}])
+// return parse(foo, {bar:[{bla:"baz"}]})
+// return {foo:{bar:[{bla:"baz"}]}}
+var pieceParser = function (eq) {
+ return function parsePiece (key, val) {
+ if (arguments.length !== 2) {
+ // key=val, called from the map/reduce
+ key = key.split(eq);
+ return parsePiece(
+ exports.unescape(key.shift(), true), exports.unescape(key.join(eq), true)
+ );
+ }
+ key = key.replace(/^\s+|\s+$/g, '');
+ if (isString(val)) val = val.replace(/^\s+|\s+$/g, '');
+ var sliced = /(.*)\[([^\]]*)\]$/.exec(key);
+ if (!sliced) {
+ var ret = {};
+ if (key) ret[key] = val;
+ return ret;
+ }
+ // ["foo[][bar][][baz]", "foo[][bar][]", "baz"]
+ var tail = sliced[2], head = sliced[1];
+
+ // array: key[]=val
+ if (!tail) return parsePiece(head, [val]);
+
+ // obj: key[subkey]=val
+ var ret = {};
+ ret[tail] = val;
+ return parsePiece(head, ret);
+ };
+};
+
+// the reducer function that merges each query piece together into one set of params
+function mergeParams (params, addition) {
+ return (
+ // if it's uncontested, then just return the addition.
+ (!params) ? addition
+ // if the existing value is an array, then concat it.
+ : (isA(params, [])) ? params.concat(addition)
+ // if the existing value is not an array, and either are not objects, arrayify it.
+ : (!isA(params, {}) || !isA(addition, {})) ? [params].concat(addition)
+ // else merge them as objects, which is a little more complex
+ : mergeObjects(params, addition)
+ );
+};
+
+// Merge two *objects* together. If this is called, we've already ruled
+// out the simple cases, and need to do the for-in business.
+function mergeObjects (params, addition) {
+ for (var i in addition) if (i && addition.hasOwnProperty(i)) {
+ params[i] = mergeParams(params[i], addition[i]);
+ }
+ return params;
+};
+
+// duck typing
+function isA (thing, canon) {
+ return (
+ // truthiness. you can feel it in your gut.
+ (!thing === !canon)
+ // typeof is usually "object"
+ && typeof(thing) === typeof(canon)
+ // check the constructor
+ && Object.prototype.toString.call(thing) === Object.prototype.toString.call(canon)
+ );
+};
+function isNumber (thing) {
+ return typeof(thing) === "number" && isFinite(thing);
+};
+function isString (thing) {
+ return typeof(thing) === "string";
+};
View
0  lib/jsgi/response.js → jsgi/response.js
File renamed without changes
View
0  lib/jsgi/rest-store.js → jsgi/rest-store.js
File renamed without changes
View
0  lib/jsgi/rewriter.js → jsgi/rewriter.js
File renamed without changes
View
0  lib/jsgi/routes.js → jsgi/routes.js
File renamed without changes
View
0  lib/jsgi/session.js → jsgi/session.js
File renamed without changes
View
174 jsgi/static.js
@@ -0,0 +1,174 @@
+var fs = require("promised-io/fs"),
+ defer = require("promised-io/promise").defer,
+ mime = require("./mime");
+exports.Static = function(options, nextApp){
+ var options = options || {},
+ urls = options.urls || ["/favicon.ico"],
+ root = options.root || (options.roots && options.roots[0]) || "",
+ index = options.index || "index.html",
+ cachePolicy = options.cachePolicy || {},
+ directoryListing = options.directoryListing;
+
+ return function(request) {
+ var path = request.pathInfo;
+ if(path.indexOf("..") > -1){
+ return {
+ status: 403,
+ headers: {},
+ body: ["Parent directory references are not allowed"]
+ }
+ }
+ for (var i = 0; i < urls.length; i++) {
+ if (path.indexOf(urls[i]) === 0) {
+ var relative = path.slice(urls[i].length);
+ var rootIndex = 0;
+ var responseDeferred = defer();
+ tryFile(root + relative, function(){
+ responseDeferred.resolve(nextApp ? nextApp(request) :
+ {
+ status: 404,
+ headers: {},
+ body: [path + " not found"]
+ });
+ });
+ return responseDeferred.promise;
+ }
+ }
+ return nextApp ? nextApp(request) : {
+ status: 404,
+ headers: {},
+ body: [path + " not found"]
+ };
+ function tryFile(filePath, onFail){
+ fs.stat(filePath)
+ .then(function (stat) {
+ var ifModHeader=request['headers']['if-modified-since'];
+ if(stat.isFile()){
+ if(request.method == "GET"){
+ // file exists.
+ var extension = filePath.match(/\.[^\.]+$/);
+ extension = extension && extension[0];
+ var mimeType = extension && mime.mimeType(extension);
+ var modifiedTime=new Date(stat.mtime);
+ if(ifModHeader && new Date(ifModHeader)>=modifiedTime){
+ // If it hasn't changed, do no further work.
+ var headers = {"Date": new Date().toUTCString()};
+ if(mimeType in cachePolicy || "*" in cachePolicy){
+ headers['Expires']=new Date(new Date().valueOf()+
+ (mimeType in cachePolicy ? cachePolicy[mimeType] : cachePolicy["*"]) *1000).toUTCString();
+ }
+ responseDeferred.resolve({
+ status: 304,
+ headers: headers,
+ body: []
+ });
+ } else {
+ // File has changed since last served to this client.
+ fs.open(filePath, "r", 0666)
+ .then(function (file) {
+ var headers = {"content-length": stat.size,
+ "Vary":"Accept-Encoding",
+ "Date": new Date().toUTCString(),
+ "Last-Modified": modifiedTime.toUTCString()};
+ if(mimeType in cachePolicy || "*" in cachePolicy){
+ headers['Expires']=new Date(new Date().valueOf()+
+ (mimeType in cachePolicy ? cachePolicy[mimeType] : cachePolicy["*"]) *1000).toUTCString();
+ }
+ if(mimeType && (mimeType.substr(0,4)=='text' ||
+ mimeType.indexOf('xml')>=0 ||
+ mimeType.indexOf('json')>=0)) {
+ mimeType+='; charset=UTF-8';
+ }
+ headers['content-type']=mimeType;
+ stat = fs.statSync(filePath); // re-retrieve it
+ var bodyDeferred = defer();
+ var write;
+ file.encoding = "binary";
+ responseDeferred.resolve({
+ status: 200,
+ headers: headers,
+ body: file
+ });
+ }, onFail);
+ }
+ }else{
+ request.filePath = filePath;
+ onFail();
+ }
+ }
+ else if(stat.isDirectory()){
+ var modifiedTime=new Date(stat.mtime);
+ if(ifModHeader && new Date(ifModHeader)>=modifiedTime){
+ // If it hasn't changed, do no further work.
+ responseDeferred.resolve({
+ status: 304,
+ headers: {"Date": new Date().toUTCString()},
+ body: []
+ });
+ } else {
+ tryFile(filePath + "/" + index, directoryListing ? function(){
+ if(filePath.charAt(filePath.length - 1) == "/"){
+ fs.readdir(filePath).then(function(paths){
+ responseDeferred.resolve({
+ status: 200,
+ headers: {
+ "content-type": "text/html; charset=UTF-8",
+ "Last-Modified": new Date(stat.mtime).toUTCString()
+ },
+ body: {
+ forEach: function(write){
+ write(DIR_START);
+ paths.sort();
+ paths.forEach(function(path){
+ write(DIR_FILE.replace(/%s/g, path));
+ });
+ write(DIR_END);
+ }
+ }
+ });
+ });
+ }else{
+ responseDeferred.resolve({
+ status: 301,
+ headers: {
+ location: request.scriptName + request.pathInfo + '/'
+ },
+ body: []
+ });
+ }
+ } : onFail);
+ }
+ }
+ else{
+ onFail();
+ }
+
+ }, onFail);
+ }
+ };
+};
+var DIR_FILE =
+'<tr>\n\
+ <td class="name"><a href="%s">%s</a></td>\n\
+</tr>';
+
+var DIR_START =
+'<html><head>\n\
+<meta http-equiv="content-type" content="text/html; charset=utf-8" />\n\
+<style type="text/css">\n\
+ table { width:100%%; }\n\
+ .name { text-align:left; }\n\
+ .size, .mtime { text-align:right; }\n\
+ .type { width:11em; }\n\
+ .mtime { width:15em; }\n\
+</style>\n\
+</head><body>\n\
+<hr />\n\
+<table>\n\
+<tr>\n\
+ <th class="name">Name</th>\n\
+</tr>\n';
+var DIR_END = '\n\
+</table>\n\
+<hr />\n\
+</body>\n</html>';
View
0  lib/jsgi/templated.js → jsgi/templated.js
File renamed without changes
View
2  lib/jsgi/xsite.js → jsgi/xsite.js
@@ -2,7 +2,7 @@
* Combines JsonP, WindowName, and CrossSiteXhr for full support for all common
* of cross-site web app access to resources
*/
-var parseQuery = require("jack/querystring").parseQuery,
+var parseQuery = require("./querystring").parseQuery,
when = require("promised-io/promise").when;
exports.CrossSite = function(nextApp){
View
174 lib/jsgi/static.js
@@ -1,174 +0,0 @@
-var fs = require("promised-io/fs"),
- defer = require("promised-io/promise").defer,
- mime = require("jack/mime");
-exports.Static = function(options, nextApp){
- var options = options || {},
- urls = options.urls || ["/favicon.ico"],
- root = options.root || (options.roots && options.roots[0]) || "",
- index = options.index || "index.html",
- cachePolicy = options.cachePolicy || {},
- directoryListing = options.directoryListing;
-
- return function(request) {
- var path = request.pathInfo;
- if(path.indexOf("..") > -1){
- return {
- status: 403,
- headers: {},
- body: ["Parent directory references are not allowed"]
- }
- }
- for (var i = 0; i < urls.length; i++) {
- if (path.indexOf(urls[i]) === 0) {
- var relative = path.slice(urls[i].length);
- var rootIndex = 0;
- var responseDeferred = defer();
- tryFile(root + relative, function(){
- responseDeferred.resolve(nextApp ? nextApp(request) :
- {
- status: 404,
- headers: {},
- body: [path + " not found"]
- });
- });
- return responseDeferred.promise;
- }
- }
- return nextApp ? nextApp(request) : {
- status: 404,
- headers: {},
- body: [path + " not found"]
- };
- function tryFile(filePath, onFail){
- fs.stat(filePath)
- .then(function (stat) {
- var ifModHeader=request['headers']['if-modified-since'];
- if(stat.isFile()){
- if(request.method == "GET"){
- // file exists.
- var extension = filePath.match(/\.[^\.]+$/);
- extension = extension && extension[0];
- var mimeType = extension && mime.mimeType(extension);
- var modifiedTime=new Date(stat.mtime);
- if(ifModHeader && new Date(ifModHeader)>=modifiedTime){
- // If it hasn't changed, do no further work.
- var headers = {"Date": new Date().toUTCString()};
- if(mimeType in cachePolicy || "*" in cachePolicy){
- headers['Expires']=new Date(new Date().valueOf()+
- (mimeType in cachePolicy ? cachePolicy[mimeType] : cachePolicy["*"]) *1000).toUTCString();
- }
- responseDeferred.resolve({
- status: 304,
- headers: headers,
- body: []
- });
- } else {
- // File has changed since last served to this client.
- fs.open(filePath, "r", 0666)
- .then(function (file) {
- var headers = {"content-length": stat.size,
- "Vary":"Accept-Encoding",
- "Date": new Date().toUTCString(),
- "Last-Modified": modifiedTime.toUTCString()};
- if(mimeType in cachePolicy || "*" in cachePolicy){
- headers['Expires']=new Date(new Date().valueOf()+
- (mimeType in cachePolicy ? cachePolicy[mimeType] : cachePolicy["*"]) *1000).toUTCString();
- }
- if(mimeType && (mimeType.substr(0,4)=='text' ||
- mimeType.indexOf('xml')>=0 ||
- mimeType.indexOf('json')>=0)) {
- mimeType+='; charset=UTF-8';
- }
- headers['content-type']=mimeType;
- stat = fs.statSync(filePath); // re-retrieve it
- var bodyDeferred = defer();
- var write;
- file.encoding = "binary";
- responseDeferred.resolve({
- status: 200,
- headers: headers,
- body: file
- });
- }, onFail);
- }
- }else{
- request.filePath = filePath;
- onFail();
- }
- }
- else if(stat.isDirectory()){
- var modifiedTime=new Date(stat.mtime);
- if(ifModHeader && new Date(ifModHeader)>=modifiedTime){
- // If it hasn't changed, do no further work.
- responseDeferred.resolve({
- status: 304,
- headers: {"Date": new Date().toUTCString()},
- body: []
- });
- } else {
- tryFile(filePath + "/" + index, directoryListing ? function(){
- if(filePath.charAt(filePath.length - 1) == "/"){
- fs.readdir(filePath).then(function(paths){
- responseDeferred.resolve({
- status: 200,
- headers: {
- "content-type": "text/html; charset=UTF-8",
- "Last-Modified": new Date(stat.mtime).toUTCString()
- },
- body: {
- forEach: function(write){
- write(DIR_START);
- paths.sort();
- paths.forEach(function(path){
- write(DIR_FILE.replace(/%s/g, path));
- });
- write(DIR_END);
- }
- }
- });
- });
- }else{
- responseDeferred.resolve({
- status: 301,
- headers: {
- location: request.scriptName + request.pathInfo + '/'
- },
- body: []
- });
- }
- } : onFail);
- }
- }
- else{
- onFail();
- }
-
- }, onFail);
- }
- };
-};
-var DIR_FILE =
-'<tr>\n\
- <td class="name"><a href="%s">%s</a></td>\n\
-</tr>';
-
-var DIR_START =
-'<html><head>\n\
-<meta http-equiv="content-type" content="text/html; charset=utf-8" />\n\
-<style type="text/css">\n\
- table { width:100%%; }\n\
- .name { text-align:left; }\n\
- .size, .mtime { text-align:right; }\n\
- .type { width:11em; }\n\
- .mtime { width:15em; }\n\
-</style>\n\
-</head><body>\n\
-<hr />\n\
-<table>\n\
-<tr>\n\
- <th class="name">Name</th>\n\
-</tr>\n';
-var DIR_END = '\n\
-</table>\n\
-<hr />\n\
-</body>\n</html>';
View
0  lib/media.js → media.js
File renamed without changes
View
0  lib/media/README.md → media/README.md
File renamed without changes
View
0  lib/media/atom.js → media/atom.js
File renamed without changes
View
0  lib/media/auto-type.js → media/auto-type.js
File renamed without changes
View
0  lib/media/css.js → media/css.js
File renamed without changes
View
0  lib/media/csv.js → media/csv.js
File renamed without changes
View
0  lib/media/hatom.js → media/hatom.js
File renamed without changes
View
4 lib/media/html.js → media/html.js
@@ -6,11 +6,11 @@ var Media = require("../media").Media,
filesystem = require("perstore/store/filesystem").FileSystem({dataFolder: "../templates", defaultExtension: "template"}),
transform = require("../html-transform"),
Response=require("../jsgi/response").Response,
- resolver = require("templify/templify").Resolver,
+ resolver = require("templify/lib/templify").Resolver,
toJSON = require("commonjs-utils/json-ext").stringify,
when = require("promised-io/promise").when,
copy = require("commonjs-utils/copy").copy;
-var templateEngine = require('templify/templify').TemplateEngine({resolver: resolver, store: filesystem});
+var templateEngine = require('templify/lib/templify').TemplateEngine({resolver: resolver, store: filesystem});
var defaultHandler = {
mediaType:"text/html",
View
0  lib/media/http.js → media/http.js
File renamed without changes
View
0  lib/media/javascript.js → media/javascript.js
File renamed without changes
View
0  lib/media/json.js → media/json.js
File renamed without changes
View
0  lib/media/message/json.js → media/message/json.js
File renamed without changes
View
2  lib/media/multipart-form-data.js → media/multipart-form-data.js
@@ -32,7 +32,7 @@ var parseMultipart = typeof process == "undefined" ?
return deferred.promise;
};
})(
- require("node-formidable/formidable/incoming_form").IncomingForm,
+ require("node-formidable/lib/formidable/incoming_form").IncomingForm,
require("jsgi-node/jsgi/node").Node);
View
0  lib/media/plain.js → media/plain.js
File renamed without changes
View
0  lib/media/uri-list.js → media/uri-list.js
File renamed without changes
View
0  lib/media/url-encoded.js → media/url-encoded.js
File renamed without changes
View
0  lib/media/xml.js → media/xml.js
File renamed without changes
View
4 package.json
@@ -20,8 +20,8 @@
"descriptor":{"directories":{"lib":"lib/ws"}}
},
"commonjs-utils": "http://github.com/kriszyp/commonjs-utils/zipball/v0.2.2",
- "promised-io": "http://github.com/kriszyp/promised-io/zipball/v0.2.3",
- "patr": "http://github.com/kriszyp/patr/zipball/v0.2.6",
+ "promised-io": "jar:http://github.com/kriszyp/promised-io/zipball/v0.2.3!/",
+ "patr": "jar:http://github.com/kriszyp/patr/zipball/v0.2.6!/",
"tunguska": "http://github.com/kriszyp/tunguska/zipball/v0.2.4",
"jack": {
"archive": "http://github.com/kriszyp/jack/zipball/master",
View
0  lib/pintura.js → pintura.js
File renamed without changes
View
0  lib/require.js → require.js
File renamed without changes
View
0  lib/security.js → security.js
File renamed without changes
View
4 lib/start-node.js → start-node.js
@@ -1,8 +1,8 @@
// helpful for debugging
var settings = require("commonjs-utils/settings"),
- ws = require("ws/server"),
+ ws = require("node-websocket-server"),
messageJson = require("./media/message/json"),
- multiNode = require("multi-node/multi-node");
+ multiNode = require("multi-node");
exports.start = function(jsgiApp, socketApp){
var http = require("http").createServer(
View
0  lib/util/README.md → util/README.md
File renamed without changes
View
0  lib/util/atom-util.js → util/atom-util.js
File renamed without changes
View
0  lib/util/html.js → util/html.js
File renamed without changes
View
0  lib/util/repl.js → util/repl.js
File renamed without changes
Please sign in to comment.
Something went wrong with that request. Please try again.