Browse Source

browser prefixes in CSS, proper Content-Type headers, caching and compressing favicon

master
mort 8 years ago
parent
commit
caf908c107
8 changed files with 74 additions and 37 deletions
  1. 2
    2
      conf.json.example
  2. 28
    15
      lib/loader.js
  3. 1
    0
      package.json
  4. 8
    4
      server.js
  5. 4
    4
      templates/head.html
  6. 25
    9
      web/favicon.node.js
  7. 3
    3
      web/global.css
  8. 3
    0
      web/index/style.css

+ 2
- 2
conf.json.example View File

@@ -1,7 +1,6 @@
{
"title": "Spus",
"base_url": "http://example.com",
"webroot": "web",
"port": 8081,
"db": {
"host": "localhost",
@@ -20,7 +19,8 @@
"minify": true,
"session_timeout": 1800000,
"dir": {
"imgs": "imgs"
"imgs": "imgs",
"web": "web
},
"debug": false,
"max_runs": 9999,

+ 28
- 15
lib/loader.js View File

@@ -1,5 +1,6 @@
var fs = require("fs");
var zlib = require("zlib");
var browserPrefix = require("browser-prefix");
var minify = require("./minify.js");
var includeHtml = require("./includeHtml.js");

@@ -12,31 +13,38 @@ exports.load = function(endpoints, conf) {

//Prepare endpoints
var errs = false;
Object.keys(endpoints).forEach(function(i) {
var ep = endpoints[i];
var eps = Object.keys(endpoints).map(function(i) {
var ep = {
path: endpoints[i],
url: i
}

try {

//The endpoint is a function if the file ends with .node.js
if (/\.node\.js$/.test(ep)) {
res.endpoints[i] = require("../"+conf.webroot+"/"+ep);
if (/\.node\.js$/.test(ep.path)) {
ep.func = require("../"+conf.dir.web+"/"+ep.path);
return ep;

//If it doesn't end with .node.js, it's a regular text file and will
//just be served as is
} else {
var str = fs.readFileSync(conf.webroot+"/"+ep, "utf8");
ep.str = fs.readFileSync(conf.dir.web+"/"+ep.path, "utf8");

//If it's an HTML file, we minify it
if (!conf.minify) {
//Don't minify unless the conf tells us to
} else if (/\.html$/.test(ep)) {
str = minify.html(str);
} else if (/\.js$/.test(ep)) {
str = minify.js(str);
} else if (/\.css$/.test(ep)) {
str = minify.css(str);
//Add browser prefixes
if (/\.css$/.test(ep.path)) {
ep.str = browserPrefix(ep.str);
ep.mimeType = "text/css";
if (conf.minify) ep.str = minify.css(ep.str);
} else if (/\.html$/.test(ep.path)) {
ep.mimeType = "text/html";
if (conf.minify) ep.str = minify.html(ep.str);
} else if (/\.js$/.test(ep.path)) {
ep.mimeType = "application/javascript";
if (conf.minify) ep.str = minify.js(ep.str);
}

res.endpoints[i] = str;
return ep;
}

//Errors will usually be because an endpoint doesn't exist
@@ -53,6 +61,11 @@ exports.load = function(endpoints, conf) {
//No need to proceed if some endpoints don't exist
if (errs) process.exit();

eps.forEach(function(ep) {
res.endpoints[ep.url] = ep;
});


//Prepare all templates
var templates = {};
fs.readdirSync("templates").forEach(function(f) {

+ 1
- 0
package.json View File

@@ -16,6 +16,7 @@
},
"license": "GPLv2",
"dependencies": {
"browser-prefix": "^0.1.0",
"formidable": "^1.0.17",
"html-minifier": "^0.7.2",
"pg": "^4.4.0",

+ 8
- 4
server.js View File

@@ -99,23 +99,27 @@ function onRequest(req, res) {
}

//Execute if it's a .node.js, or just respond with the contents of the file
if (typeof ep == "function") {
ep(ctx);
if (ep.func) {
ep.func(ctx);
} else {

//Cache content for a while
ctx.setHeader("Cache-Control", "public, max-age="+conf.cache_max_age);

//Set appropriate content-type headers
if (ep.mimeType)
ctx.setHeader("Content-Type", ep.mimeType);

//Gzip and such
if (ctx.shouldGzip && gzipCache[req.url]) {
ctx.end(gzipCache[req.url], true);
} else if (ctx.shouldGzip) {
zlib.gzip(ep, function(err, res) {
zlib.gzip(ep.str, function(err, res) {
gzipCache[req.url] = res;
ctx.end(res, true);
});
} else {
ctx.end(ep);
ctx.end(ep.str);
}
}
}

+ 4
- 4
templates/head.html View File

@@ -6,7 +6,7 @@
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">
<link rel="stylesheet" href="/{{env#view}}/style.css?{{conf#current_run}}">

<script src="https://code.jquery.com/jquery-2.1.4.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
<script src="/global.js?{{conf#current_run}}"></script>
<script src="/{{env#view}}/script.js?{{conf#current_run}}"></script>
<script src="https://code.jquery.com/jquery-2.1.4.min.js" defer></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js" defer></script>
<script src="/global.js?{{conf#current_run}}" defer></script>
<script src="/{{env#view}}/script.js?{{conf#current_run}}" defer></script>

+ 25
- 9
web/favicon.node.js View File

@@ -1,13 +1,29 @@
var fs = require("fs");
var zlib = require("zlib");

var gzipped;

var favicon = fs.readFileSync("favicon.ico");

zlib.gzip(favicon, function(err, res) {
gzipped = res;
});

module.exports = function(ctx) {
var readStream = fs.createReadStream("favicon.ico");
readStream.pipe(ctx.res);

readStream.on("error", function(err) {
if (err.code === "ENOENT")
ctx.end(ctx.view("404"));
else
ctx.end(err.toString());
});
if (favicon) {
ctx.res.setHeader(
"Cache-Control",
"public, max-age="+ctx.conf.cache_max_age
);
}

if (gzipped && ctx.shouldGzip) {
ctx.res.setHeader("Content-Encoding", "gzip");
ctx.res.end(gzipped);
} else if (favicon) {
ctx.res.end(favicon);
} else {
ctx.res.writeHead(404);
ctx.end(ctx.view("404"));
}
}

+ 3
- 3
web/global.css View File

@@ -60,7 +60,7 @@ form.container {
}

#notify-box {
transition: max-height 0.2s;
@prefix transition: max-height 0.2s;
max-height: 0px;

background-color: #F8F8F8;
@@ -70,7 +70,7 @@ form.container {
position: fixed;
bottom: 0px;
width: 100%;
box-sizing: content-box;
@prefix box-sizing: content-box;
}

#notify-box .close {
@@ -100,6 +100,6 @@ form.container {
max-height: 48px;
}
#notify-box.active:hover {
transition: max-height 0.6s;
@prefix transition: max-height 0.6s;
max-height: 200px;
}

+ 3
- 0
web/index/style.css View File

@@ -36,3 +36,6 @@
border-radius: 4px;
padding: 6px 12px;
}
#uploader-select-files, #uploader-collection-name, #uploader-upload {
height: 34px;
}

Loading…
Cancel
Save