# 3.1 Webでの作業方法 普段ホームページを閲覧する際、ブラウザを開くと思います。アドレスを入力してエンターキーを押すと、あなたが見たいコンテンツが表示されます。この見た目には簡単なユーザの行動には一体何が隠されているのでしょうか? 普通のネットワーク上の操作に対して、システムは実はこのように行なっています:ブラウザそのものはクライアントです。URLを入力する際まずブラウザはDNSサーバにアクセスします。DNSを通してドメインと対応するIPを取得し、IPアドレスからIPに対応したサーバを探しだした後、TCPコネクションの設立を要求します。ブラウザがHTTP Request(リクエスト)パケットを送信し終わると、サーバはリクエストパケットを受け取ってリクエストパケットを処理しはじめます。サーバは自分のサービスをコールし、HTTP Response(レスポンス)パケットを返します。クライアントがサーバからのレスポンスを受け取ると、このレスポンスパケットのbodyを読み出します。すべての内容を受け取ると、このサーバとのTCP接続を切断します。 ![](images/3.1.web2.png?raw=true) 図3.1 ユーザがWebサーバにアクセスする過程 WebサーバはHTTPサーバとも呼ばれます。HTTPプロトコルを通じてクライアントと通信を行います。このクライアントは普通はWebブラウザを指します(実はモバイルクライアントでも内部ではブラウザによって実現されています。) Webサーバの動作原理は簡単に説明できます: - クライアントがTCP/IPプロトコルによってサーバまでTCP接続を設立します。 - クライアントはサーバに対してHTTPプロトコルのリクエストパケットを送信し、サーバのリソースドキュメントを要求します。 - サーバはクライアントに対してHTTPプロトコルの応答パケットを送信し、もし要求されたリソースに動的な言語によるコンテンツが含まれている場合、サーバが動的言語のインタープリターエンジンに"動的な内容"の処理をコールさせます。処理によって得られたデータをクライアントに返します。 - クライアントとサーバが切断されます。クライアントはHTMLドキュメントを解釈し、クライアントの画面上に図形として結果を表示します。 簡単なHTTPタスクはこのように実現されます。見た目にはとても複雑ですが、原理はとても簡単です。気をつけなければならないのは、クライアントとサーバの間の通信は常に接続されているわけではありません。サーバが応答を送信した後クライアントと接続が切断され、次のリクエストを待ち受けます。 ## URLとDNS解決 ホームページの閲覧は常にURLの訪問で行われます。ではURLとは一体どういうものなのでしょうか? URL(Uniform Resource Locator)は"統一資源位置指定子"の英語の短縮です。ネットワーク上のリソースを表現しています。基本的なシンタックスは以下のとおりです。 scheme://host[:port#]/path/.../[?query-string][#anchor] scheme 低レイヤーで使用されるプロトコルを指定します。(例えば:http, https, ftp) host HTTPサーバのIPアドレスまたはドメイン port# HTTPサーバのデフォルトのポート番号は80です。この場合ポート番号は省略することができます。もし別のポートを使用する場合は指定しなければなりません。例えば http://www.cnblogs.com:8080/ path リソースまでのパス query-string httpサーバへ送るデータ anchor アンカー DNS(Domain Name System)は"ドメインシステム"の英文の省略です。これは組織の木構造の計算機とネットワークサービスの命名システムです。これはTCP/IPネットワークで使用されます。ホスト名またはドメインを実際のIPアドレスに変換する作業を行う役目を担っています。DNSはこのような翻訳家です。この基本的な動作原理は下の図に示しているとおりです。 ![](images/3.1.dns_hierachy.png?raw=true) 図3.2 DNSの動作原理 より詳細なDNS解決のプロセスは下のようなものです。このプロセスは我々がDNSの作業モードを理解するのに助けとなります。 1. ブラウザでwww.qq.comドメインを入力します。オペレーティングシステムはまず自分のローカルのhostsファイルにこのアドレスがないか検査します。もしあれば、このIPアドレスの設定が適用されます。ドメイン解決終了。 2. もしhostsにこのドメインの設定がなければ、ローカルのDNSリゾルバのバッファを探します。もしあれば、これを返します。ドメイン解決終了。 3. もしhostsとローカルのDNSリゾルバのバッファのどちらにも目的のドメインがなかった場合、まずTCP/IPのオプションで設定されているプライマリDNSサーバを探します。ここではこれをローカルDNSサーバと呼びましょう。このサーバが要求を受けた時、もし要求したドメイン名がローカルで設定されたリソースの中に含まれている場合、解決の結果をクライアントに返します。ドメイン解決終了。これは権威ある解決です。 4. もし要求したドメイン名がローカルDNSサーバのゾーンでは解決できなかったものの、このサーバがこのURLをバッファリングしていた場合このIPアドレスが適用されます。ドメイン名解決終了。これは権威ある解決ではありません。 5. もしローカルDNSサーバがそのゾーンファイルとバッファリングのどちらも有効でなかった場合、ローカルDNSサーバの設定に従って(リピータが設定されているか)検査を行います。もし転送モードが使用されていなければローカルDNSはリクエストを"ルートDNSサーバ"に送ります。"ルートDNSサーバ"はリクエストを受け取った後このドメイン名(.com)が誰によって権限を受け管理されているか判断し、このトップレベルドメインの権威サーバのIPを返します。ローカルDNSサーバがIP情報を受け取った後、.comドメインを担当するこのサーバと接続を行います。.comドメインを担当するサーバがリクエストを受け取った後、もし自分で名前解決できなければ、.comドメインを管理するもう一つ下のレイヤーのDNSサーバのアドレス(qq.com)をローカルDNSサーバに送ります。ローカルDNSサーバがこのアドレスを受け取った後、qq.comドメインのサーバを探し出し、www.qq.comのホストが見つかるまで上の動作を繰り返します。 6. もし転送モードを使用していれば、このDNSサーバはリクエストをひとつ上のレイヤーのDNSサーバに転送します。このサーバが名前解決を行い、名前が解決できなかった場合は、ルートDNSを探すか、もう一つ上のレイヤーのにリクエストを転送します。またはルートが提示されます。最後に結果をローカルDNSサーバに返し、このDNSサーバはクライアントに返します。 ![](images/3.1.dns_inquery.png?raw=true) 図3.3 DNS解決の全体のプロセス > いわゆる`再帰検索プロセス`は"検索者"の交代を意味します。また、`反復する検索プロセス`では"検索者"は不変です。 > > 例をあげて説明しましょう。あなたは一緒に法律の授業を受けている女の子の電話番号を知りたいとします。あなたはこっそり彼女の写真も撮っています。寝室にもどって、正義感の強いアニキたちにそのことを伝えます。このアニキたちは異議を唱えることもなく、胸を叩いてあなたにこう言います。「急ぐ必要はない。私があなたに替わって調べてあげましょう」(この時一時再帰検索が完了しています。すなわち、検索者の役割が変更されました。)。その後彼は写真を携え学部の4年生の先輩のところに聞きにいきます。「この女の子はxx学部なんですけど・・・」その後このアニキは矢継ぎ早にxx学部のオフィス主任の助手を務めているクラスメートに聞きます。このクラスメートはxx学部のyyゼミであると言います。またこの正義感の強いアニキたちはxx学部のyyゼミのゼミ長のところにいき、この女の子の電話番号をゲットします。(ここまでで何回かの連続検索が完了しました。すなわち、検索者の役は変わっていませんが、聞きに行く対象を反復して取り替えています。)最後に彼は番号をあなたの手に渡すことで全体の検索が完了します。 上のステップを通して、IPアドレスを最後に取得します。つまりブラウザが最後にリクエストを送る時はIPにもとづいて、サーバと情報のやりとりをするのです。 ## HTTPプロトコル詳細 HTTPプロトコルはWeb作業の核心です。そのためWebの作業方法をくまなく理解するためには、HTTPがいったいどのような作業を行なっているのか深く理解する必要があります。 HTTPはWebサーバにブラウザ(クライアント)とInternetを通してデータをやり取りさせるプロトコルです。これはTCPプロトコルの上で成立しますので、一般的にはTCPの80番ポートが採用されます。これはリクエストとレスポンスのプロトコルです--クライアントはリクエストを送信しサーバがこのリクエストに対してレスポンスを行います。HTTPでは、クライアントは常に接続を行いHTTPリクエストを送信することでタスクをこなします。サーバは主導的にクライアントと接続することはできません。また、クライアントに対してコールバック接続を送信することもできません。クライアントとサーバは事前に接続を中断することができます。例えば、ブラウザでファイルをダウンロードする際、"停止"ボタンをクリックすることでファイルのダウンロードを中断し、サーバとのHTTP接続を閉じることができます。 HTTPプロトコルはステートレスです。同じクライアントの前のリクエストと今回のリクエストの間にはなんの対応関係もありません。HTTPサーバからすれば、この2つのリクエストが同じクライアントから発せられたものかすらも知りません。この問題を解決するため、WebプログラムではCookie機構を導入することで、接続の持続可能状態を維持しています。 >HTTPプロトコルはTCPプロトコルの上で確立しますので、TCPアタックはHTTPの通信に同じように影響を与えます。例えばよく見かける攻撃として:SYN Floodは現在最も流行したDoS(サービス不能攻撃)とDdoS(分散型サービス不能攻撃)などがあります。これはTCPプロトコルの欠陥を利用して大量に偽造されたTCP接続要求を送信するのです。これにより攻撃された側はリソースが枯渇(CPUの高負荷やメモリ不足)する攻撃です。 ### HTTPリクエストパケット(ブラウザ情報) まずRequestパケットの構造を見てみることにしましょう。Requestパケットは3つの部分にわけられます。第一部分はRequest line(リクエスト行)。第二部分はRequest header(リクエストヘッダ)、第三部分はbody(ボディ)と呼ばれます。headerとbodyの間には空行があり、リクエストパケットの例は以下のようなものです。 GET /domains/example/ HTTP/1.1 //リクエスト行:リクエスト方法 リクエストRUI HTTPプロトコル/プロトコルバージョン Host:www.iana.org //サーバのホスト名 User-Agent:Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.4 (KHTML, like Gecko) Chrome/22.0.1229.94 Safari/537.4 //ブラウザ情報 Accept:text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 //クライアントが受け取れるmime Accept-Encoding:gzip,deflate,sdch //ストリーム圧縮をサポートするか否か Accept-Charset:UTF-8,*;q=0.5 //クライアントの文字コードセット //空行、リクエストヘッダとボディを分けるために使われます。 //ボディ、リソースへのリクエストのオプション、例えばPOSTが渡すオプション HTTPプロトコルはサーバに対して交互にリクエストを送る方法が定義されています。基本は四種類。GET,POST,PUT,DELETEです。ひとつのURLアドレスはひとつのネットワーク上のリソースを描写しています。またHTTPの中のGET, POST, PUT, DELETEはこのリソースの検索、修正、増加、削除の4つの操作に対応しています。よく見かけるのはGETとPOSTです。GETは一般的にリソースの情報を取得/検索するために用いられ、POSTはリソース情報を更新するために用いられます。 fiddlerパケットキャプチャを通して下のようなリクエスト情報を見ることができます。 ![](images/3.1.http.png?raw=true) 図3.4 fiddlerがキャプチャしたGET情報 ![](images/3.1.httpPOST.png?raw=true) 図3.5 fiddlerがキャプチャしたPOST情報 GETとPOSTの区別を見てみましょう。 1. GETリクエストのボディが空であることがわかります。POSTリクエストにはボディがあります。 2. GETが入力するデータはURLの後に置かれます。?によってURLと渡すデータを分割します。オプションの間は&で繋ぎます。例えばEditPosts.aspx?name=test1&id=12345。POSTメソッドは入力するデータをHTTPパケットのBodyの中に置きます。 3. GETが入力するデータの大きさには制限があります。(ブラウザのURLに対する長に制限があるためです。)またPOSTメソッドで入力するデータには制限がありません。 4. GETメソッドで入力されたデータはセキュリティの問題を引き起こします。例えばログイン画面があったとして、GETメソッドでデータを入力した場合、ユーザ名とパスワードはURL上にあらわれてしまうことになります。もしページがバッファリングされていたり他の人によっがこのマシンにアクセスすることができれば、ヒストリログからこのユーザのアカウントとパスワードを取得することができてしまいます。 ### HTTPレスポンスパケット(サーバ情報) HTTPのresponseパケットを見てみることにしましょう。構造は以下のとおりです: HTTP/1.1 200 OK //ステータス行 Server: nginx/1.0.8 //サーバが使用するWEBソフトウェアの名称及びバージョン Date:Date: Tue, 30 Oct 2012 04:14:25 GMT //送信時刻 Content-Type: text/html //サーバが送信するデータの型 Transfer-Encoding: chunked //送信するHTTPパケットが分解されることを表しています。 Connection: keep-alive //コネクション状態の保持 Content-Length: 90 //ボディの内容の長さ //空行 ヘッダとボディを分けるために使われます。 ホームページの改良では、HTTPのリクエスト回数を減らすことがあります。つまり、なるべく多くのcssとjsリソースを同じところに集めるのです。目的は出来る限りホームページの静的リソースのリクエスト回数を減少させる事にあります。ホームページの表示速度を上げると同時にサーバのバッファリングを減らす事ができます。 ## links * [目次]() * 前へ: [Webの基礎](<03.0.md>) * 次へ: [GOでWebサーバを建てる](<03.2.md>)