waffle
Version:
シンプルなWEBアプリケーションフレームワークです。(ALL YOUR NODE ARE BELONG TO US)
103 lines (92 loc) • 3.05 kB
JavaScript
/*
* Copyright 2012 Katsunori Koyanagi
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
/**
* @overview 静的にfavicon.icoを返すコントローラのファクトリです。
*/
;
var crypto = require("crypto");
var fs = require("fs");
function md5(buf) {
return crypto.createHash('md5').update(buf).digest('hex');
}
/**
* 静的にfavicon.icoを返すコントローラを作成して返します。
*
* @example <code>
* var waffle = require("waffle");
* config.router.on("/favicon", waffle.entensions.favicon("./public/favicon.ico"));
* </code>
* @function
* @name Extensions#favicon
* @param {String}
* path アプリケーションルートを起点としたfavicon.icoファイルのパス、省略時は内部のアイコンが使用される
* @param {Number}
* maxAge キャッシュの生存時間を示すミリ秒の時間、省略時は1日(86400000ミリ秒)
* @return {Function} コントローラ
*/
module.exports = function(path, maxAge) {
var internal = false;
if (!path) {
path = fs.join(__dirname, "../assets/favicon.ico");
internal = true;
}
maxAge = maxAge || 86400000;
return (function(path, maxAge, internal) {
var iconInfo = null;
return function(context) {
if (iconInfo !== null) {
if (context.req.headers["if-none-match"] === iconInfo.headers.ETag
|| Date.parse(context.req.headers['if-modified-since']) >= iconInfo.mtime) {
context.res.writeHead(304, iconInfo.headers);
context.complete();
return;
}
context.res.writeHead(200, iconInfo.headers);
context.res.end(iconInfo.data);
context.complete();
return;
}
var p = path;
if (!internal) {
p = fs.join(context.app.approot, path);
}
var stat = fs.stat(p, function(err, stats) {
if (err) {
context.error(404, err);
return;
}
fs.readFile(p, function(err, buf) {
if (err) {
context.error(404, err);
return;
}
iconInfo = {};
iconInfo.headers = {
"Content-Type" : "image/x-icon",
"Content-Length" : buf.length,
"ETag" : "\"" + md5(buf) + "\"",
"Cache-Control" : "public, max-age=" + (maxAge / 1000)
};
iconInfo.mtime = stats.mtime.getTime();
iconInfo.data = buf;
context.res.writeHead(200, iconInfo.headers);
context.res.end(iconInfo.data);
context.complete();
});
});
};
})(path, maxAge, internal);
};