【初心者にやさしい】HTTP通信解剖~HTTP通信の動きってどうなってるの？~

# 本記事の目的
　本記事では、WebブラウザからWebサーバーにアクセスするときに使うHTTP通信について、実際にはどのように動いているのかというところを解剖していきます。

# HTTPとは
　__HTTP__ とは「__Hyper Text Transfer Protocol__」の略であり、HTMLを始めとするWeb通信に必要な情報をやり取りするためのルールを定めた規約です。
　インターネットを使用しているときに、「404 Not Found」や「500 Internal Server Error」などの状況に出くわしたことがある方も多いと思います。これらは全てWebサーバーからのレスポンスであり、HTTPによって、 __クライアントからのリクエストとサーバーからのレスポンスの方式が定められています。__

# HTTP解剖① 「リクエスト」と「レスポンス」の書式
　HTTP通信では、クライアントとサーバー間のリクエストおよびレスポンスの方式を定めています。この「リクエスト」と「レスポンス」を行うときに、それぞれ __決まった書式で必要な情報を送る決まり__ になっています。

## リクエストの書式
　リクエストには、「__リクエストライン__」、「__リクエストヘッダー__」、「__ボディー__」の３つの要素が含まれています。

### リクエストライン
　リクエストラインには、「__要求方法__」と「__要求先のURL__」の情報が入っています。
　実際にブラウザの「__開発者ツール__」を利用して中身を見てみましょう。今回は、ブラウザとして __Firefox__ を利用し、「__www.google.com__」にアクセスした場合を例にして解剖していきます。
　まず開発者ツールを開くと、下のようなツールが出てきます。
![FireFox 開発者ツール.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2375287/5a78398a-3e5f-5d6a-b37a-ba4dbc35ba8f.jpeg)
　ここで、今回アクセスした「www.google.com」のところを見てみると、「__ヘッダー__」というタブでリクエストに関する情報を見ることができます。
![HTTPリクエストライン.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2375287/a0525222-9313-06a1-c765-8028d5fa52cf.png)
　ここに表示されている「__GET__」がリクエストラインで言うところの「__要求方法__」であり、「__https:://www.google.com__」が「__要求先URL__」です。

#### ※HTTPメソッドについて
　上で示した「__GET__」は「__要求方法__」であると説明しました。このように、HTTP通信では、Webサーバーに対し、どのような種類の要求をするのかによって、「GET」や「POST」などの決められた要求方法を用います。これらを「__HTTPメソッド__」と呼びます。以下に代表的なHTTPメソッドを示します。
![HTTPメソッド一覧.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2375287/0d931ae4-886a-744e-9d34-f316a8ea0bcb.png)

### リクエストヘッダー
　リクエストの情報２つ目は「__リクエストヘッダー__」です。同じく開発者ツールで「__要求ヘッダー__」というところを見てみると、ヘッダーとして持っている情報を見ることができます。
![HTTP通信　ヘッダー.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2375287/fac03d64-a086-2911-8425-e864ca5836ce.png)
　これらのヘッダー情報はリクエストの際の追加情報となります。掻い摘んで説明すると、「__Hostヘッダー__」は要求先のホスト名です。「__User-Agent__」は対象のブラウザを判別するための情報です。「__Cookieヘッダー__」は以前に送られてきたものと同じCookie情報が載っています。Cookieにはログインしたユーザーと結びつける情報が格納されていることがあるので、注意が必要です。

### ボディ
　ボディには、HTMLのForm要素に入力された値など、リクエストの際に一緒に送信するデータの情報が入っています。

## レスポンスの書式
　レスポンスにも同じく決まった情報があります。「__ステータスライン__」、「__ヘッダー__」、「__ボディ__」です。

### ステータスライン
　ステータスラインには、リクエストに対して結果がどの様なものだったかを返すための情報が入っています。先ほどの開発者ツールをもう一度見てみると、「__200 OK__」という文言があるのが分かります。これは、 __正常にリクエストが処理され、レスポンスが返されたことを示します。__
![HTTPリクエストライン.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2375287/f6d88f01-43c4-6271-faae-39b46ef7bea8.png)

#### ※HTTPステータスコードについて
　上の「__200 OK__」の様なコードを「__HTTPステータスコード__」と言います。HTTP通信では様々なステータスコードを用いてレスポンスを返しています。以下をご参照ください。
![HTTPステータスコード一覧.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2375287/0cb43af8-9cff-53f6-96a2-bba465f68b29.png)

### レスポンスヘッダー
　以下を見てください。
![HTTP 応答ヘッダー.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2375287/8c42446e-278a-bc10-131c-23b823e16ec1.png)
　これは開発者ツールで「__応答ヘッダー__」という項目を開いた時の状態です。ここに表示されている項目は、レスポンスの時の追加情報となります。掻い摘んで説明すると、「__Content-Typeヘッダー__」は、レスポンスとして返すコンテンツの種類を示しています。この場合は、「text/html」となっているので、htmlを返していることが分かります。「__Dateヘッダー__」は、レスポンスの日付を示します。「__Set-Cookieヘッダー__」は、ブラウザに返すCookieの情報が入っています。これを用いて、次回のリクエストを行うことでユーザーを追跡することが可能になります。

### ボディ
　以下を見てください。
![HTTP 応答ボディー.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2375287/e9562806-8b7d-15d1-61bf-862ea3df593d.png)
　レスポンスで返す実際のコンテンツ情報は、「__ボディ__」として返します。開発者ツールで、「__応答__」というところを見てみると、レスポンスとして返されたHTMLのテキストなどが記載されていることが分かります。

# HTTP解剖② HTTPからHTTPSへのリダイレクト
　今では、セキュリティの観点から、「HTTP通信」ではなく、「__HTTPS通信__」で通信を行うことが当たり前になっています。Webサーバーによっては、「__http://~__」でアクセスしようとすると、自動的に「__https://~__」にリダイレクトされるものもあります。
　では、このHTTPS通信とは、どの様な仕組みで行われているのでしょうか。

## HTTPプロトコル　と　SSLプロトコルの組み合わせ
　まず、HTTPS通信と言っても、HTTPとSSLという２つのルールを組み合わせてできたルールに則って行う通信となっています。「__SSL__」は「__Secure Socket Layer__」の略であり、通信を暗号化して送るためのプロトコルになります。つまり、HTTPS通信とは、 __クライアントからサーバーへの通信を暗号化して行うことができる方法__ ということになります。
![HTTPS暗号化通信.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2375287/33737c2f-9e6d-9fbf-6dd6-802c7e27e2ce.png)
　通信を暗号化することにより、盗聴や改ざんのリスクを減らすことができます。更に、SSLプロトコルを使用するときは、「__SSLサーバー証明書__」という証明書が必要なため、他人によるなりすましのリスクも減らすことができます。
　これにはWebサーバーが __認証局（CA：Certification Authority）__ と呼ばれる第三者の機関からSSLサーバ証明書を発行してもらう必要があります。
　このSSLサーバー証明書には、サーバー所有者の情報や暗号化通信に必要な鍵、発行者の署名データなどが含まれます。
　各ブラウザごとにそのサイトがHTTPS通信で安全に通信が行えるサイトなのかどうかを確認することができます。Forefoxの場合は、URLの左側に鍵マークがあるので、そこを押すことでサーバー証明書の内容なども確認できます。
![HTTPS通信　SSL証明書.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2375287/a84a939b-8177-8e8c-c2b9-f81b918591c0.png)
　「__詳細を表示__」から証明書を確認できます。 __中には身元の不確かな機関から発行された証明書を利用しているサイトも存在する可能性もあるので、証明書の内容をしっかりと確認する必要があります。__
![HTTPS通信　安全.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2375287/efcb6448-ba17-b8ed-616e-ed0ece47c317.png)
　「SSL」に関する詳しい解説は以下のサイトが参考になります。
　　
　　[SSL/TLS総合解説サイト](https://www.sslcerts.jp/)
　
　また、SSLでの暗号化通信に用いられる「公開鍵暗号方式」や「共通鍵暗号方式」については、以下のサイトが参考になります。
　
　　[SSL（HTTPS）の仕組みを図解で分かりやすく説明](https://medium-company.com/ssl-%E4%BB%95%E7%B5%84%E3%81%BF/)

# まとめ
　HTTP通信の仕組みを理解してからは、Webアプリケーションの実装中にエラーが起きた際など、どこに問題点があるのかを順を追って検証することができる様になり、効率が上がってきています。エンジニアの駆け出しとして必須の知識だと改めて感じました。

# 参考
- [SSL/TLS総合解説サイト](https://www.sslcerts.jp/)
- [SSL（HTTPS）の仕組みを図解で分かりやすく説明](https://medium-company.com/ssl-%E4%BB%95%E7%B5%84%E3%81%BF/)
- [Amazon Web Services 基礎からのネットワーク＆サーバー構築　改訂3版](https://www.amazon.co.jp/Amazon-Web-Services-%E5%9F%BA%E7%A4%8E%E3%81%8B%E3%82%89%E3%81%AE%E3%83%8D%E3%83%83%E3%83%88%E3%83%AF%E3%83%BC%E3%82%AF%EF%BC%86%E3%82%B5%E3%83%BC%E3%83%90%E3%83%BC%E6%A7%8B%E7%AF%89-%E6%94%B9%E8%A8%823%E7%89%88-%E5%A4%A7%E6%BE%A4-ebook/dp/B084QQ7TCF)