diff --git a/lib/vhost-sni-server.js b/lib/vhost-sni-server.js index 74a4bfd..f0510ab 100644 --- a/lib/vhost-sni-server.js +++ b/lib/vhost-sni-server.js @@ -207,6 +207,13 @@ module.exports.create = function (securePort, certsPath, vhostsdir) { }); } + function suckItDubDubDub(req, res) { + var newLoc = 'https://' + (req.headers.host||'').replace(/^www\./) + req.url; + res.statusCode = 301; + res.setHeader('Location', newLoc); + res.end(""); + } + function nextify() { if (!appContext) { appContext = loadThatApp(); @@ -231,17 +238,27 @@ module.exports.create = function (securePort, certsPath, vhostsdir) { connectContext.static = serveStatic(path.join(vhostsdir, domaininfo.dirname, 'public')); } - if (/^\/api\//.test(req.url)) { - nextify(); + if (/^www\./.test(req.headers.host)) { + if (/\.appcache\b/.test(req.url)) { + res.setHeader('Content-Type', 'text/cache-manifest'); + res.end('CACHE MANIFEST\n\n# v0__DELETE__CACHE__MANIFEST__\n\nNETWORK:\n*'); + return; + } + suckItDubDubDub(req, res); return; } - connectContext.static(req, res, nextify); + if (/^\/api\//.test(req.url)) { + nextify(); + return; + } + + connectContext.static(req, res, nextify); }; domainMergeMap[domaininfo.hostname].apps.use( - '/' + domaininfo.pathname - , domainMergeMap[domaininfo.hostname].mountsMap['/' + domaininfo.dirpathname] - ); + '/' + domaininfo.pathname + , domainMergeMap[domaininfo.hostname].mountsMap['/' + domaininfo.dirpathname] + ); return PromiseA.resolve(); } @@ -288,9 +305,9 @@ module.exports.create = function (securePort, certsPath, vhostsdir) { // TODO pass in websocket localApp = localApp.create(secureServer, { dummyCerts: dummyCerts - , hostname: domaininfo.hostname - , port: securePort - , url: domaininfo.pathname + , hostname: domaininfo.hostname + , port: securePort + , url: domaininfo.pathname }); if (!localApp) { @@ -325,7 +342,38 @@ module.exports.create = function (securePort, certsPath, vhostsdir) { console.log('[log] [once] Loading all mounts for ' + domainApp.hostname); domainApp._loaded = true; app.use(vhost(domainApp.hostname, domainApp.apps)); - app.use(vhost('www.' + domainApp.hostname, domainApp.apps)); + app.use(vhost('www.' + domainApp.hostname, function (req, res, next) { + if (/\.appcache\b/.test(req.url)) { + res.setHeader('Content-Type', 'text/cache-manifest'); + res.end('CACHE MANIFEST\n\n# v0__DELETE__CACHE__MANIFEST__\n\nNETWORK:\n*'); + //domainApp.apps(req, res, next); + return; + } + // TODO XXX this is in the api section, so it should hard break + //res.statusCode = 301; + //res.setHeader('Location', newLoc); + + // TODO port number for non-443 + var escapeHtml = require('escape-html'); + var newLocation = 'https://' + domainApp.hostname + req.url; + var safeLocation = escapeHtml(newLocation); + + var metaRedirect = '' + + '\n' + + '\n' + + ' \n' + + ' \n' + + '\n' + + '\n' + + '

You requested an old resource. Please use this instead: \n' + + ' ' + safeLocation + '

\n' + + '\n' + + '\n' + ; + + // 301 redirects will not work for appcache + res.end(metaRedirect); + })); }); } @@ -472,6 +520,8 @@ module.exports.create = function (securePort, certsPath, vhostsdir) { function addSniWorkaroundCallback() { //SNICallback is passed the domain name, see NodeJS docs on TLS secureOpts.SNICallback = function (domainname, cb) { + domainname = domainname.replace(/^www\./, '') + if (/(^|\.)proxyable\./.test(domainname)) { // device-id-12345678.proxyable.myapp.mydomain.com => myapp.mydomain.com // proxyable.myapp.mydomain.com => myapp.mydomain.com