古くなったんで、[Node.js][TypeScript] Webサーバーを作り直すw(3)に書き直した。

------- ここから下は、古いんで注意 ----------

wwwフォルダにあるファイルを返すようにしいてみた。
説明はソースのコメントにしておいたので省略(^^;)

/// <reference path="./typings/node/node-0.11.d.ts" />

import http = require('http');
import fs = require('fs');
import url = require('url');
import path = require('path');
import querystring = require('querystring');

var port = 9999;				// 待ち受けポート番号
var contentsDir = "www";		// コンテンツフォルダ
var defaultHtml = "index.html";	// ファイル名が省略された場合(ディレクトリを指定された場合)
								// 読み込むファイル名
// 拡張子とMIMEタイプの対応表
var mimeTypes = {
	".html":"text/html",
	".htm":"text/html",
	".pdf":"application/pdf",
	".js":"text/javascript",
	".zip":"application/zip",
	".mid":"audio/midi",
	".midi":"audio/midi",
	".mp2":"audio/mpeg",
	".mp3":"audio/mpeg",
	".wav":"audio/x-wav",
	".txt":"text/plain",
	".mpeg":"video/mpeg",
	".mpg":"video/mpeg",
	".css":"text/css",
	".gif":"image/gif",
	".jpg":"image/jpeg",
	".jpeg":"image/jpeg",
	".png":"image/png",
	".ico":"image/vnd.microsoft.icon",
	".mp4":"video/mp4",
	".webm":"video/webm",
	".ogg":"video/ogg",
	".mov":"video/quicktime",
	".qt":"video/quicktime",
	".avi":"video/x-msvideo",
	".doc":"application/msword",
	".xls":"application/msexcel"
}

// コンテンツフォルダのフルパスを生成
var wwwRoot = path.join(__dirname, contentsDir);
console.log("wwwRoot=" + wwwRoot);

// サーバー起動
var server = http.createServer(requestServer)
	.listen(port);

// 接続されたときに呼ばれる関数
function requestServer(req:http.ServerRequest, res:http.ServerResponse):void {
	var uri = url.parse(req.url, true);
	var contentsFile = path.join(wwwRoot, querystring.unescape(uri.pathname));
		
	// ファイルの情報を取得する。そして、コールバック関数でファイルやエラーをクライアントに返す。
	fs.stat(contentsFile, makeResponseFunc(contentsFile, res));
}

// fs.statに渡すコールバック関数を返す関数
// 	コールバック関数では、ファイルがあればファイルをエラーならエラーをクライアントに返す。
// 	ディレクトリなら、defaultHtml(index.html)のファイルを返す。
function makeResponseFunc(contentsFile:string, res:http.ServerResponse)
			:(err:NodeJS.ErrnoException, stats:fs.Stats)=>any {
	return (err, stats) => {
		if(err) {	// エラーなら、404エラーをクライアントに返す。
			console.log(err);
			responseError404(res);
			return;
		}
		console.log(path.relative(wwwRoot, contentsFile));
		if(stats.isDirectory()) {	// ディレクトリなら、defaultHtml(index.html)を追加して
									// fs.statを呼ぶ。
			var indexFile = path.join(contentsFile, defaultHtml);
			fs.stat(indexFile, makeResponseFunc(indexFile, res));
			return;
		} else if(stats.isFile()) {	// ファイルなら、ファイルを返す。
			// 拡張子からMIMEタイプを取得してヘッダに設定する。
			var extname = path.extname(contentsFile).toLocaleLowerCase();
			var mimeType = mimeTypes[extname];
			if(mimeType !== undefined) {
				res.writeHead(200, { "Content-Type" : mimeType });
			}
			// ファイルのストリームを作って、クライアントに返す。
			//		pipe()でresにデータを流すようにする。
	        // 		resはWritableインターフェイスが実装されているのでpipe()に渡すことができる。
			fs.createReadStream(contentsFile)
				.pipe(res);
		} else {	// ファイルでもディレクトリでもないなら
			// ファイルがなかったことにする。(404エラーをクライアントに返す)
			responseError404(res);
		}
	}
}

// 404エラーをクライアントに返す。
function responseError404(res:http.ServerResponse):void {
	res.writeHead(404, { "Content-Type":"text/plain" });
	res.write("404 Not Found.\n");
	res.end();
}