――Webサーバを作ってみよう――
このページの目的は、 Webアプリケーションの基礎の基礎を説明することです。
さて、ここから下のぐだぐだは読み飛ばして、 いきなり実装の説明に 行ってもらってもかまいませんが、一応趣旨を書いておきます。
現在、プロのプログラマーの方々には、日々の仕事でせっせと 「Webアプリケーション」を作っている人が多いと思います。
そして、いまどきWebアプリケーションを作るのに、 CGIとかあり得ないでしょうから、 それなりの高級言語で、 それなりのフレームワーク等を使用して作っているのだと思います。 私自身、現状、仕事では主にC#とASP.NETを使っています。
そうやって生産性を上げるのは大変よいことだと思うのですが、 ことWebアプリケーションにおいては、 そのような「一見簡単そう」なフレームワークを使っても、 ちょっとややこしいことをやろうとするとすぐにうまくいかなくなって、 職場の先輩に聞いても「Webサーバのログを見ろ」と言われたり、 ぐぐってみても「HTTPレスポンスヘッダ」がどうこうとか 「Content-Type」がどうとかわけのわからない言葉ばかり出てきて 途方にくれる、というのがよくあるパターンであるように思います。
もちろん、素のHTTP通信を直接使うといろいろ面倒なのですが、 現状のWebアプリケーションフレームワークは、 その面倒な作業の効率化はしてくれても、 面倒な部分を完全に隠蔽して抽象化してくれるという性質のものではないようです (最近 こちらでも議論がありました)。
Joel Spolskyが「 漏れのある抽象化の法則」と呼んだように、 たいていの抽象化には漏れがあるものですが、 とりわけWebアプリケーションの世界の抽象化は「だだ漏れ」に見えます。 各種フレームワークは確かに便利なのですが、 結局Webアプリゆえの制約に縛られている。 抽象化の層を重ねれば重ねるほど、宣伝のサンプルのような簡単なケースと、 いざはまった時の乖離は大きくなり、 結局下の方を知らないと対処できないということが多々あります。 それならやはり、 下の方から順々に知識を積み上げていくしかないのではないかと。
では、どれぐらい下から積み上げればよいのかといえば、 TCPによるソケット通信までは所与のものとして ※1 その上にWebサーバを作っていく、というあたりが適切だと思います。 だから「Webサーバを作ってみよう」なのです。
Webサーバを作るというと、 とてつもなく難しいことのように思えるかもしれませんが、 ただ動くだけでよいのであれば、あっけないほど簡単です。 各種フレームワークのややこしい設定や規約を覚えるよりも よっぽど楽なのではないかと思います。 かつて、アスキーから発売されていた「インターネットを256倍使うための本」では シェルスクリプトでWebサーバを実装していました。
現在も、ソースがこちらで公開されています。実質40行くらいです。
http://ascii.asciimw.jp/books/support/4-7561-1663-9/supplement/0001/shttpd
※2019/01/01追記:とっくに消えているのでWayback Machineのページはこちら。
こちらの説明によれば、 「筆者が偉いんではなく、shが偉いんで もなく、ズバリinetdが偉い。」 とのことですが、いくら偉いinetdの助けを借りたとはいえ ※2、 たったこれだけのソースでWebサーバらしきことは実現できてしまうわけです。 だったら一度くらい作ってみたほうが、 Webアプリケーションが結局のところどういうものなのか、 実感がつかめるというものでしょう。
上記のようなことは、私は過去何度かWeb上に書いてきました ( こことか こことか) ※3。
私自身、上記のシェルによるWebサーバの実装を見て、 Webの仕組みについて理解を深めた記憶があります。 ただ、いまどきシェルやinetdはよく知らない人が多いでしょうから、 Java等で同じようにWebサーバを実装する記事があれば 役に立つ人は多いのではないか、と私は思います。
なので、他力本願的に「誰か書いてくれませんかね…」とか言っていたのですが、 どうやら誰も書いてくれないようなので仕方がないので自分で書きます。
ところで、Webに限らず、インターネット関連のプログラムを作る時は、 RFCを隅から隅まで読み込んでから作る…… というのが本来なのかもしれませんが、 この記事では、ApacheやFirefoxといった既存の実装がどのように動いているかを 外部から観察しながら作る、という邪道な方法を取ります。 あくまで勉強として作るのであれば、それで十分だと思うからです。
あんまり細かいことは考えずに、投げやりに始めます。ほげほげ〜
お願い:
この文書にウソ、間違い、誤解を招く表現などを見つけられた方は、 ぜひ掲示板 の方にご連絡願います。 「確かにそれでもできるけど、その実装はアホだろ」とか、 「いくらなんでもそれは規格上おかしい」というご指摘も歓迎いたします。
私自身、仕事でWebアプリケーションを作ることはありますが、 アプリケーションプログラマであり、サーバを作るプロというわけではありません。 この記事は自分自身の勉強も兼ねています。
また、このページに関していただいたご意見・ご質問・ご感想等は、 公開することがありますのであらかじめご承知おきください。
反論があるようでしたら、オープンな場で議論すべきだと思いますし、 同じ疑問を持っている人が他にもいるかもしれないからです。