From a19f2d87a1344e85f98b7cec757a2790ba342a47 Mon Sep 17 00:00:00 2001 From: Brian White Date: Wed, 28 Dec 2011 16:34:42 -0500 Subject: [PATCH] Fix Windows support for mapped and built-in URLs like "/users/1/edit" and "/users/1/foo" --- index.js | 51 +++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 49 insertions(+), 2 deletions(-) diff --git a/index.js b/index.js index 5926796..ec1ba57 100644 --- a/index.js +++ b/index.js @@ -11,7 +11,6 @@ */ var express = require('express') - , join = require('path').join , lingo = require('lingo') , en = lingo.en , orderedActions = [ @@ -119,7 +118,7 @@ Resource.prototype.map = function(method, path, fn){ if ('function' == typeof path) fn = path, path = ''; if ('object' == typeof path) fn = path, path = ''; if ('/' == path[0]) path = path.substr(1); - else path = join(this.param, path); + else path = posixPathJoin(this.param, path); method = method.toLowerCase(); // setup route pathname @@ -256,3 +255,51 @@ express.HTTPSServer.prototype.resource = function(name, actions, opts){ var res = this.resources[name] = new Resource(name, actions, this); return res; }; + +/** + * Use posix path module methods on Windows so that URLs do not contain \ + instead of / when using functions like path.join. These posix methods are + ripped from the path module. + */ + +function pathNormalizeArray(parts, allowAboveRoot) { + var up = 0; + for (var i = parts.length - 1; i >= 0; i--) { + var last = parts[i]; + if (last == '.') { + parts.splice(i, 1); + } else if (last === '..') { + parts.splice(i, 1); + up++; + } else if (up) { + parts.splice(i, 1); + up--; + } + } + if (allowAboveRoot) { + for (; up--; up) { + parts.unshift('..'); + } + } + return parts; +} +function posixPathNormalize(path) { + var isAbsolute = path.charAt(0) === '/', + trailingSlash = path.slice(-1) === '/'; + path = pathNormalizeArray(path.split('/').filter(function(p) { + return !!p; + }), !isAbsolute).join('/'); + if (!path && !isAbsolute) { + path = '.'; + } + if (path && trailingSlash) { + path += '/'; + } + return (isAbsolute ? '/' : '') + path; +}; +function posixPathJoin() { + var paths = Array.prototype.slice.call(arguments, 0); + return posixPathNormalize(paths.filter(function(p, index) { + return p && typeof p === 'string'; + }).join('/')); +};