ラック
Home > ブログ > 記事 > 2015年2月 > 星の白金

星の白金

カテゴリ: プログラム

前回、node.jsのresponse.writeHeadで遊べるという話をしました。

それでさらに遊んでみようという試み。

pmg.js

var http = require('http');
var fs = require('fs');
var url = require('url');

var server = http.createServer(); //httpサーバ準備
server.on('request', doRequest);
server.listen(8080);
console.log('Server running at http://127.0.0.1:8080/');

function doRequest(request, response) {
	var flag = false;
	if(request.method=='GET') { //GETメソッドが送信されてきた場合
		var url_parts = url.parse(request.url,true);
		if('star' in url_parts['query']) { //連想配列url_partsの中に「star」というキーが存在するか
			if(url_parts['query']['star'] === '17') { //starというキーに17という値がセットされているか
				fs.readFile('./557.html', 'UTF-8',
					function (err, data) {
						response.writeHead(557, 'Letter Frome Home', {'Content-Type': 'text/html'});
						response.write(data);
						response.end();
					}
				);
			}
			else {
				flag = starPlatina(request, response);
			}
		}
		else {
			flag = starPlatina(request, response);
		}
	}
	else {
		flag = starPlatina(request, response);
	}
};

//GETメソッドでstar=17が送信されてきたとき以外は全部こっち
function starPlatina(request, response) {
	switch(request.url) {
	case '/':
		fs.readFile('./200.html', 'UTF-8',
			function (err, data) {
				response.writeHead(200, {'Content-Type': 'text/html'});
				response.write(data);
				response.end();
			}
		);
		break;

	case '/example_desert.jpg':
		fs.readFile('./example_desert.jpg', 'binary',
			function (err, data) {
				response.writeHead(200, {'Content-Type': 'image/jpeg'});
				response.write(data, 'binary');
				response.end();
			}
		);
		break;

	default:
		fs.readFile('./200.html', 'UTF-8',
			function (err, data) {
				response.writeHead(200, {'Content-Type': 'text/html'});
				response.write(data);
				response.end();
			}
		);
		break;
	}
	return true;
};

パスの処理って自前でやらないといけないのですね…わりと面倒な…。

中ではGETメソッドでstar=17と送られてきたときに特殊なレスポンスを返して557.htmlというhtmlファイルを読み込みます。
それ以外は普通に200 OKで200.htmlを読み込みます。背景画像があるのでそれも読み込むようにパス処理してますが。

ということで、「http://localhost:8080/」等でアクセスすると200.html、「http://localhost:8080/?star=17」でアクセスすると557.htmlが読み込まれるスクリプトです。

 

200.html

<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8" />
<title>Last Train Home</title>
<meta name="viewport" content="width=device-width, initial-scale=1" />

<style type="text/css">
<!--
* {
	color: #fff;
}
header h1 {
	position: fixed;
	left: 10px;
	top: 5px;
	font-family: 'Lucida Grande','Hiragino Kaku Gothic ProN','ヒラギノ角ゴ ProN W3', Meiryo, sans-serif;
	font-style: oblique;
	text-shadow: 1px 1px 3px #500;
}
section h3 {
	position: fixed;
	bottom: 20px;
	right: 50px;
	font-family: 'Lucida Grande','Hiragino Kaku Gothic ProN','ヒラギノ角ゴ ProN W3', Meiryo, sans-serif;
}
/* Responsive Full Background Image Using CSS
 * Tutorial URL: http://sixrevisions.com/css/responsive-background-image/
*/
body {
  /* Location of the image */
  background-image: url(example_desert.jpg);
  
  /* Image is centered vertically and horizontally at all times */
  background-position: center top;
  
  /* Image doesn't repeat */
  background-repeat: no-repeat;
  
  /* Makes the image fixed in the viewport so that it doesn't move when 
     the content height is greater than the image height */
  background-attachment: fixed;
  
  /* This is what makes the background image rescale based on its container's size */
  background-size: cover;
  
  /* Pick a solid background color that will be displayed while the background image is loading */
  background-color:#464646;
  
  /* SHORTHAND CSS NOTATION
   * background: url(background-photo.jpg) center center cover no-repeat fixed;
   */
}
-->
</style>
</head>
<body>
	<header>
		<h1>Last Train Home</h1>
	</header>
	<section>
		<h3>To Be Continued...</h3>
	</section>
</body>
</html>

画面いっぱいに背景画像が表示されるというのを見かけたのでそれの実験も兼ねてます。
「example_desert.jpg」っていうのは適当に用意してください。砂漠の画像だと良いかも知れません。

参考サイトはこちら。

ただ、パスの処理が面倒くさかったので上記のcssをhtmlの中にそのままコピペしてbackground-imageのURLだけ変更しました。

557.html

<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8" />
<title>Letter From Home</title>
<meta name="viewport" content="width=device-width, initial-scale=1" />
<style type="text/css">
<!--
* {
	color: #fff;
	background-color:#464646;
}
header h1 {
	position: fixed;
	left: 10px;
	top: 5px;
	font-family: 'Lucida Grande','Hiragino Kaku Gothic ProN','ヒラギノ角ゴ ProN W3', Meiryo, sans-serif;
	font-style: oblique;
	text-shadow: 1px 1px 3px #005;
}
section h3 {
	position: fixed;
	bottom: 20px;
	right: 50px;
	font-family: 'Lucida Grande','Hiragino Kaku Gothic ProN','ヒラギノ角ゴ ProN W3', Meiryo, sans-serif;
}
-->
</style>
</head>
<body>
	<header>
		<h1>Letter From Home</h1>
	</header>
	<section>
		<h3>5-5-7</h3>
	</section>
</body>
</html>

こちらが正しいGETでパラメータを渡したときだけ読み込まれるhtmlファイル。

中身は背景画像関連の処理を端折ってちょっと表示される文字を変えただけの簡単なものです(手抜き

 

では、これらをnode.jsインストール済みのサーバにアップして「node pmg.js」というように起動させてからアクセスしてみましょう。


ブラウザで普通にアクセスするとこんな感じ。背景画像は適当に用意しました。


telnetクライアント機能をインストール済のWindowsで、DOSプロンプトから「telnet <サーバのIP or ホスト名> 8080」とアクセスしてから「GET / HTTP/1.1」でルートディレクトリを表示させようとすると、ちゃんと200.htmlが読み込まれています。

日本語が文字化けしているのはDOSプロンプトがshift-jisなのにファイルの中身がUTF-8だからでしょう。気にしない。

応答も「200 OK」ですね。まあ、当然です。

 


では、ブラウザで「star=17」付きでリクエストすると…はい、味気ない画面になりました。


問題はこっち。先ほどと同じようにtelnetで接続しましたが、今度は「GET /?star=17 HTTP/1.1」としました。

すると、きちんと「557 Letter From Home」の応答を伴って557.htmlが返されたことが分かりますね。

これで目的達成です。

…そうです、パット・メセニー・グループがやりたかっただけです。
普通なら『Still Life (Talking)』の「Last Train Home」、そうでなければ『Letter from Home』の「5-5-7」を返す、しかもHTTPステータスコードが本来定義されてない557というオリジナルの数値で、と!

…使えるかどうかじゃなくて、やりたかっただけですよ、本当…。

タグ: javascript, 音楽, ネタ

 



関連する記事一覧