UNPKG

waffle

Version:

シンプルなWEBアプリケーションフレームワークです。(ALL YOUR NODE ARE BELONG TO US)

103 lines (92 loc) 3.05 kB
/* * 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を返すコントローラのファクトリです。 */ "use strict"; 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); };