Merge pull request #977 from cweider/loopback-avoidance

Loopback avoidance
This commit is contained in:
John McLear 2012-09-03 14:56:55 -07:00
commit c5be2eb418
3 changed files with 79 additions and 76 deletions

View File

@ -7,74 +7,8 @@ var Yajsml = require('yajsml');
var fs = require("fs"); var fs = require("fs");
var ERR = require("async-stacktrace"); var ERR = require("async-stacktrace");
var _ = require("underscore"); var _ = require("underscore");
var urlutil = require('url');
exports.expressCreateServer = function (hook_name, args, cb) { exports.expressCreateServer = function (hook_name, args, cb) {
// What follows is a terrible hack to avoid loop-back within the server.
// TODO: Serve files from another service, or directly from the file system.
function requestURI(url, method, headers, callback, redirectCount) {
var parsedURL = urlutil.parse(url);
var status = 500, headers = {}, content = [];
var mockRequest = {
url: url
, method: method
, params: {filename: parsedURL.path.replace(/^\/static\//, '')}
, headers: headers
};
var mockResponse = {
writeHead: function (_status, _headers) {
status = _status;
for (var header in _headers) {
if (Object.prototype.hasOwnProperty.call(_headers, header)) {
headers[header] = _headers[header];
}
}
}
, setHeader: function (header, value) {
headers[header.toLowerCase()] = value.toString();
}
, header: function (header, value) {
headers[header.toLowerCase()] = value.toString();
}
, write: function (_content) {
_content && content.push(_content);
}
, end: function (_content) {
_content && content.push(_content);
callback(status, headers, content.join(''));
}
};
minify.minify(mockRequest, mockResponse);
}
function requestURIs(locations, method, headers, callback) {
var pendingRequests = locations.length;
var responses = [];
function respondFor(i) {
return function (status, headers, content) {
responses[i] = [status, headers, content];
if (--pendingRequests == 0) {
completed();
}
};
}
for (var i = 0, ii = locations.length; i < ii; i++) {
requestURI(locations[i], method, headers, respondFor(i));
}
function completed() {
var statuss = responses.map(function (x) {return x[0]});
var headerss = responses.map(function (x) {return x[1]});
var contentss = responses.map(function (x) {return x[2]});
callback(statuss, headerss, contentss);
};
}
// Cache both minified and static. // Cache both minified and static.
var assetCache = new CachingMiddleware; var assetCache = new CachingMiddleware;
@ -91,7 +25,7 @@ exports.expressCreateServer = function (hook_name, args, cb) {
, rootURI: 'http://localhost:' + settings.port + '/static/js/' , rootURI: 'http://localhost:' + settings.port + '/static/js/'
, libraryPath: 'javascripts/lib/' , libraryPath: 'javascripts/lib/'
, libraryURI: 'http://localhost:' + settings.port + '/static/plugins/' , libraryURI: 'http://localhost:' + settings.port + '/static/plugins/'
, requestURIs: requestURIs // Loop-back is causing problems, this is a workaround. , requestURIs: minify.requestURIs // Loop-back is causing problems, this is a workaround.
}); });
var StaticAssociator = Yajsml.associators.StaticAssociator; var StaticAssociator = Yajsml.associators.StaticAssociator;

View File

@ -29,6 +29,7 @@ var pro = require("uglify-js").uglify;
var path = require('path'); var path = require('path');
var plugins = require("ep_etherpad-lite/static/js/pluginfw/plugins"); var plugins = require("ep_etherpad-lite/static/js/pluginfw/plugins");
var RequireKernel = require('require-kernel'); var RequireKernel = require('require-kernel');
var urlutil = require('url');
var ROOT_DIR = path.normalize(__dirname + "/../../static/"); var ROOT_DIR = path.normalize(__dirname + "/../../static/");
var TAR_PATH = path.join(__dirname, 'tar.json'); var TAR_PATH = path.join(__dirname, 'tar.json');
@ -46,12 +47,76 @@ for (var key in tar) {
); );
} }
// What follows is a terrible hack to avoid loop-back within the server.
// TODO: Serve files from another service, or directly from the file system.
function requestURI(url, method, headers, callback, redirectCount) {
var parsedURL = urlutil.parse(url);
var status = 500, headers = {}, content = [];
var mockRequest = {
url: url
, method: method
, params: {filename: parsedURL.path.replace(/^\/static\//, '')}
, headers: headers
};
var mockResponse = {
writeHead: function (_status, _headers) {
status = _status;
for (var header in _headers) {
if (Object.prototype.hasOwnProperty.call(_headers, header)) {
headers[header] = _headers[header];
}
}
}
, setHeader: function (header, value) {
headers[header.toLowerCase()] = value.toString();
}
, header: function (header, value) {
headers[header.toLowerCase()] = value.toString();
}
, write: function (_content) {
_content && content.push(_content);
}
, end: function (_content) {
_content && content.push(_content);
callback(status, headers, content.join(''));
}
};
minify(mockRequest, mockResponse);
}
function requestURIs(locations, method, headers, callback) {
var pendingRequests = locations.length;
var responses = [];
function respondFor(i) {
return function (status, headers, content) {
responses[i] = [status, headers, content];
if (--pendingRequests == 0) {
completed();
}
};
}
for (var i = 0, ii = locations.length; i < ii; i++) {
requestURI(locations[i], method, headers, respondFor(i));
}
function completed() {
var statuss = responses.map(function (x) {return x[0]});
var headerss = responses.map(function (x) {return x[1]});
var contentss = responses.map(function (x) {return x[2]});
callback(statuss, headerss, contentss);
};
}
/** /**
* creates the minifed javascript for the given minified name * creates the minifed javascript for the given minified name
* @param req the Express request * @param req the Express request
* @param res the Express response * @param res the Express response
*/ */
exports.minify = function(req, res, next) function minify(req, res, next)
{ {
var filename = req.params['filename']; var filename = req.params['filename'];
@ -174,10 +239,11 @@ function getAceFile(callback) {
var resourceURI = baseURI + path.normalize(path.join('/static/', filename)); var resourceURI = baseURI + path.normalize(path.join('/static/', filename));
resourceURI = resourceURI.replace(/\\/g, '/'); // Windows (safe generally?) resourceURI = resourceURI.replace(/\\/g, '/'); // Windows (safe generally?)
request(resourceURI, function (error, response, body) { requestURI(resourceURI, 'GET', {}, function (status, headers, body) {
if (!error && response.statusCode == 200) { var error = !(status == 200 || status == 404);
if (!error) {
data += 'Ace2Editor.EMBEDED[' + JSON.stringify(filename) + '] = ' data += 'Ace2Editor.EMBEDED[' + JSON.stringify(filename) + '] = '
+ JSON.stringify(body || '') + ';\n'; + JSON.stringify(status == 200 ? body || '' : null) + ';\n';
} else { } else {
// Silence? // Silence?
} }
@ -319,3 +385,8 @@ function compressCSS(values)
var complete = values.join("\n"); var complete = values.join("\n");
return cleanCSS.process(complete); return cleanCSS.process(complete);
} }
exports.minify = minify;
exports.requestURI = requestURI;
exports.requestURIs = requestURIs;

View File

@ -168,11 +168,9 @@ require.setGlobalKeyPath("require");\n\
buffer.push(KERNEL_BOOT); buffer.push(KERNEL_BOOT);
buffer.push('<\/script>'); buffer.push('<\/script>');
} else { } else {
file = KERNEL_SOURCE; // Remotely src'd script tag will not work in IE; it must be embedded, so
buffer.push('<script type="application/javascript" src="' + KERNEL_SOURCE + '"><\/script>'); // throw an error if it is not.
buffer.push('<script type="text/javascript">'); throw new Error("Require script could not be embedded.");
buffer.push(KERNEL_BOOT);
buffer.push('<\/script>');
} }
} }
function pushScriptsTo(buffer) { function pushScriptsTo(buffer) {