Edited at

Kotlin でオレオレフレームワークを作ってみる ~01 - HTTPのごく基本的な知識~


はじめに

今回は Ougi に組み込むウェブサーバーの実装に向けて、簡単に HTTP について説明をします(・∀・)。

※注意!

この一連の記事で紹介するコードは動作の概念を説明するものでありセキュリティーなどは意識していません(・∀・)。

実際に運用するシステムなどに使用しないでください(・∀・)。

(そのまま使うひともいないと思いますが)


一覧


ウェブサーバーについて

まずはウェブサーバーについて簡単に説明(・∀・)。


ウェブサーバーってなぁに?

ウェブサーバーとは、簡単に言うと

「ブラウザからURLにアクセスするとHTMLやら画像やらのファイルを返してくるサーバーソフトウェア」

です(・∀・)。

ウェブブラウザとウェブサーバーとは HTTP という決まりごとを守ってやり取りを行う必要があります(・∀・)。

詳細な説明は Wikipedia でも見てください(・∀・)。

と、何でもかんでも他の記事に丸投げしてしまっては拍子抜けするひとも出てきそうなので、ここでは最低限は知っておかないと行けなそうな基本を記述しておきます(・∀・)。


HTTP ざっくり解説

まずは HTTP というものについて簡単に説明します(・∀・)。

HTTP は、ブラウザが「何を」「どうして欲しい」と言うリクエストをウェブサーバーに送信し、ウェブサーバーは「結果」をレスポンスと言う形で送り返します(・∀・)。

これらのやり取りはテキストで行います(・∀・)。

なので、プログラムからはネットワークに文字列を送信したり受信したりする動作になります(・∀・)。

ブラウザは多くの場合 GETPOST のメソッドをウェブサーバーに送ります(・∀・)。

メソッドというのは「どうして欲しいか」に相当します(・∀・)。

(実際には他の種類のメソッドもあります)

GET は「ウェブサーバーよ、指定したファイルを送り返してくれまいか?」と言う感じ(・∀・)。

POST は「ウェブサーバーよ、これを受け取ってくれたまえ」ですね(・∀・)。

他にも HEAD とか PUT とか色々ありますが、まずは GET / POST だけ覚えておけばあまり不自由はしないと思います(・∀・)。

極論、HTTP は GET と POST を理解すればウェブの世界の9割を理解したと言っても過言ではありません(・∀・)w


GET / POST についてもう少し深掘り

そんな訳で GET と POST を深掘り解説(・∀・)。

ウェブサーバーから何かを GET したい場合、その何かを指定しないとウェブサーバーは何を送り返して良いのか分かりませんね(・∀・)。

そして、その「何かを指定」する為に URL は存在します(・∀・)。

ブラウザがウェブサーバーにアクセスしてホームページを表示するという場合を考えましょう(・∀・)。

まずは http://qiita.com/maosec にアクセスする事を考えます(・∀・)。

最初にある http というのは HTTP と言うプロトコル(送信と受信のルール)に従います!と言う宣言です(・∀・)。

今回扱っているテーマが HTTP なので、通信内容は GET とか POST とか、これから説明するルールで通信しますよーと言うのを ブラウザに教えます (・∀・)。

次の qiita.com というのはサーバーを指定します(・∀・)。

この場合は Qiita のウェブサーバーを名指ししているわけですね(・∀・)。

そして最後の maosec (・∀・)。

これは Qiita のウェブサーバーに maosec にあるものを指定しているわけです(・∀・)。

では、ブラウザが http://qiita.com/maosec にアクセスした場合はどんな HTTP 通信を行うのか(・∀・)?

実際にはたくさん情報を突っ込んで通信をするのですが、最低限必要な HTTP 通信は


GET /maosec HTTP/1.1


のようになります(・∀・)。

詳細を解説しましょう(・∀・)。

まずアクセスしているサーバーは Qiita のサーバー qiita.com を指定しているので GET に サーバーを指定する必要はありません (・∀・)。

http://qiita.com は「ハガキを出す時の住所」でも「お友達の電話番号」みたいなもので、もう 相手が Qiita( qiita.com ) であることは確定 していると考えます(・∀・)。

次の /maosec は /maosec にあるものを GET したい!と言う指示ですね(・∀・)。

この指示を行うために URL はこういう書き方をする決まりになっているのです(・∀・)。

最後の HTTP/1.1HTTP のバージョン を指定しています(・∀・)。

HTTP にもバージョンがあって、いま一般的に広く使われているのは HTTP/1.1 で、昔は 1.0 とか 0.9 とかもありました(・∀・)。

何故こんなものを指定するのか(・∀・)?

それは、ブラウザは HTTP/1.1 のつもりで通信しているからウェブサーバーさんはそのつもりで処理してほしいなー!と、お願いするために指定する決まりになっています(・∀・)。

このような文字列をウェブサーバーに送信すると、GET の場合は /maosec にあるデータを送り返してもらえるし、POST の場合は /maosec に対してデータを送信できます(・∀・)。

ブラウザやウェブサーバーが行っているのは、プログラムの内部で見てみるとこういう文字列を送ったり返したりしています(・∀・)。


やり取りする文字列は、基本的には ASCIIコード であることが望まれると思います(・∀・)。

Unicode とかの2バイト文字コードを使用すると、どうなるんだろ(・∀・)?

(試したことはないw)

日本語などを扱う場合は今どきは UTF-8 を使用するものだったりするでしょう(・∀・)。

また、:// の部分ですが、HTTP のプロトコルを考えた偉い人が、プロトコル指定(http)の部分と他の部分を確実に切り分けられるように複雑っぽい文字列にしたらしいです(・∀・)。

http 以外にも記号とか使ったプロトコル名が後から生まれるかも知れない!とか、そういう風に考えたのかも知れませんね(・∀・)。

ちなみに、今となっては :// なんていう変な文字列にしてしまった事をすっごく後悔しているとかどっかで聞いた記憶があるけど、情報ソース的な記事が見当たらなかった(・∀・)w



HTTP の リスエスト と レスポンス について

リスエスト と レスポンス、よく出てくる用語なので 必ず 覚えるようにしましょう(・∀・)。

覚えると言っても辞書的に単語を覚えるのではなく、考え方を理解しましょうね( ´∀`)bグッ!

まず リクエスト は、ブラウザからウェブサーバーに GET とか POST とかを送ることを言います(・∀・)。

そして レスポンス は、ウェブサーバーからブラウザに返された GET とか POST とかの結果です(・∀・)。

そして、リクエストにもレスポンスにも 決まったルール があります(・∀・)。

コンピュータは命令に従ったことしか出来ませんので、何でもかんでもルールで指示してあげないと何も出来ないのです(・∀・)。

面倒くさいですね(;´Д`)。


リクエスト のしかた

まずは リクエスト のしかたです(・∀・)。

「HTTP Request を送る」などを言いますね(・∀・)。

ザックリいうと、レスポンスは以下の構造の 文字列 になります(・∀・)。

リクエストヘッダ

メッセージボディ

と言う構造をしてます(・∀・)。

これだけじゃ何を言っているのか分からないと思うので、もちろんちゃんと解説します(・∀・)。

まずリクエストヘッダは リクエストラインヘッダフィールド に分けられます(・∀・)。

さらに、リクエストラインは リクエストメソッドリクエストURIHTTPバージョン に分けられます(・∀・)。

難しい言葉がいっぱい出てきますが、要は先ほど書いた GET /maosec HTTP/1.1 とかにいろいろな情報をくっつけた 文字列 です(・∀・)。

例えば以下のような文字列ですね(・∀・)。

GET /maosec HTTP/1.1 (<- ここがリクエストライン)

Host: <接続元であるブラウザのあるIPアドレスとかホスト名>
User-Agent: <ブラウザの種類とかバージョンとかいろいろな情報>
... (<- 通常は他にも何かいっぱいある)

送ったりしたいデータ(POST の場合はあるけど GET の時は通常は何もない)

みたいな感じになります(・∀・)。

新しく出てきた


Host: <接続元であるブラウザのあるIPアドレスとかホスト名>

User-Agent: <ブラウザの種類とかバージョンとかいろいろな情報>


は、よく単に ヘッダ と呼ばれるものですね(・∀・)。

<ヘッダ>:<コロン> <半角スペース><ヘッダの内容> のように指定します(・∀・)。

改行は '\r\n' と決まっていて、空の改行が見つかるまでは リクエストヘッダ で、それ以降が POST で送りたいデータというのが基本です(・∀・)。

この構造のデータをサーバーに送ればレスポンスが返ってくるというのが HTTP の基本的な仕組みです(・∀・)。


レスポンスの構造

さて、ブラウザからウェブサーバーにリクエストする方法とその内容を駆け足で説明しました(・∀・)。

次はウェブサーバーからブラウザに返却する レスポンス について説明します(・∀・)。

といっても、リクエストの構造と大きくは変わりません(・∀・)。

レスポンスヘッダ

レスポンスボディ

と言う構造をしてます(・∀・)。

リクエストヘッダにそっくりですね(・∀・)w

更にレスポンスヘッダは ステータスラインヘッダフィールド に分けられます(・∀・)。

ステータスラインは プロトコルステータスコードステータス に分けられます(・∀・)。

HTTP/1.1 200 OK

Date: <レスポンスの時刻が入る>
Content-Type: text/html
... (<- 通常は他にも何かいっぱいある)

サーバーからブラウザに返却されるデータ(テキストだけではなく画像などのバイナリの場合もある)

だいたいリクエストと同じような感じですね(・∀・)。

HTTP/1.1 は、リクエストに対してウェブサーバーは HTTP/1.1 で「処理しましたよ!」という意味です(・∀・)。

200 はステータスコードで、この 200 場合は「正常終了」を意味します(・∀・)。

OK はステータスコードの意味で、この場合は「OK」ですね(・∀・)。

ステータスコードもかなりの種類があるのですが、ひとまず以下を覚えておけばどうにかなります(・∀・)。


  • 200 正常終了

  • 301 リダイレクト


    • レスポンスヘッダの中に Location: <リダイレクト先のURL> というヘッダがあり、これを受け取るとブラウザはリダイレクト処理を行う



  • 403 アクセス権限がない

  • 404 アクセス先のファイルが見つからない

  • 500 サーバーエラー

ひとまずはこれくらいでしょうか(・∀・)。

必要になったら調べればすぐに出てきますが、上記くらいは覚えておくと良いでしょう(・∀・)。

また、リクエストと同様で改行は '\r\n' と決まっています(・∀・)。


決まっているったら決まっているんです(・∀・)。


空っぽの改行を見つけたら、それ以降は返却されるデータの本体です(・∀・)。

HTML ファイルの GET をリクエストしたのなら、正常終了である 200 を確認した後に レスポンスボディ を読み込めば、それが要求した HTML ファイルになっています(・∀・)。

JPEG をリクエストしたのなら JPEG のバイナリデータが入っています(・∀・)。

HTTP の基本的な構造はこの様になっています(・∀・)。

簡単と思うか、複雑と思うか、それはアナタ次第です(・∀・)w


次回

次回はごく簡単なウェブサーバーっぽいものを実装していく予定です(・∀・)。