LoginSignup
1
3

More than 5 years have passed since last update.

HTTP通信の中身

Posted at

HTTP通信を何気なーく使っている皆さん。
HTTPHypertext Transfer Protocol (HTTP/1.1)ってどのようなプロトコルかご存知でしょうか。

そんな疑問を少しでも解消すべく、軽く説明しようかなと思います。
なんとなくわかったつもりになって記事を書いているので間違っている箇所があればご指摘をお願い致します。

概要

とは言っても、RFCのように規約内容ををダラダラ書いても意味がわからないと思うので、実践を踏まえて全体の流れを見ていきたいと思います。

通信の流れ

HTTP通信はあるサーバ(オリジンサーバ)とクライアント(ユーザエージェント)間で行われる通信を規約化されたものです。

image.png

HTTPの規約があることで、クライアントとサーバ間でのテキストのやり取りが可能になります。
これを大前提に、一度通信内容を見てみましょう。

通信の中身を見てみよう

Windowsの方はWSLでUbuntuなど入れて試してみましょう。
https://qiita.com/Brutus/items/f26af71d3cc6f50d1640

オリジンサーバの設定

まずはサーバ側のセッティングを行います。
なんでもいいのですが、今回はnpmhttp-serverを使います。

Linux Ubuntu

$ sudo apt install -y nodejs npm

MacOS

$ brew install node

共通

$ sudo npm install -g http-server
$ mkdir test_program
$ cd test_program
$ vim index.html

# index.htmlを編集

$ http-server ./
Starting up http-server, serving ./
Available on:
  http://127.0.0.1:8080
Hit CTRL-C to stop the server
index.html
<!DOCTYPE html>
<html lang="ja">
<head>
    <title>Document</title>
</head>
<body>
</body>
</html>

これでHTTPサーバの起動は完了です。(超簡単)

通信の内容を見よう!

さて、HTTP通信の内容を見てみよう。

サーバを起動しつつ、別のターミナルでcurlというコマンドを叩いてみると通信の内容が全て見られます。

$ curl -v "http://127.0.0.1:8080"

通信内容

* Rebuilt URL to: http://127.0.0.1:8080/
*   Trying 127.0.0.1...
* TCP_NODELAY set
* Connected to 127.0.0.1 (127.0.0.1) port 8080 (#0)
> GET / HTTP/1.1
> Host: 127.0.0.1:8080
> User-Agent: curl/7.54.0
> Accept: */*
>
< HTTP/1.1 200 OK
< server: ecstatic-3.3.1
< cache-control: max-age=3600
< last-modified: Sat, 27 Apr 2019 14:08:58 GMT
< etag: W/"3068562-99-2019-04-27T14:08:58.104Z"
< content-length: 99
< content-type: text/html; charset=UTF-8
< Date: Sat, 27 Apr 2019 14:10:45 GMT
< Connection: keep-alive
<
<!DOCTYPE html>
<html lang="ja">
<head>
    <title>Document</title>
</head>
<body>
</body>
</html>
* Connection #0 to host 127.0.0.1 left intact

各所解説

コネクション

* Rebuilt URL to: http://127.0.0.1:8080/
*   Trying 127.0.0.1...
* TCP_NODELAY set
* Connected to 127.0.0.1 (127.0.0.1) port 8080 (#0)

こちらはcurlが行っているTCP/IPプロトコルによるコネクションの確率を意味しています。
こちらはTCP/IPプロトコルの話なので、割愛します。

リクエスト(要求)

> GET / HTTP/1.1
> Host: 127.0.0.1:8080
> User-Agent: curl/7.54.0
> Accept: */*
>

ここから本題です。

この通信内容はクライアントからサーバへのリクエスト内容を示しています。

HTTP通信は、文字列を規則的に送信することで解釈を行っています。
したがって、規則的に送信をしなかった場合はサーバ側でHTTP通信とみなされなくなり、エラーを排出(あるいは解釈不能による予期せぬ挙動)します。

GET / HTTP/1.1
メソッド名 URI 規格/メジャーバージョン.マイナーバージョン

メソッド名のあと、スペースが一つ入り、その後にURL...
など、スペースの場所もすべて該当します。

では、ここからはサクッと見てまいりましょう。

解説
GET / HTTP/1.1 GET というメソット名で、リクエストしたURLは / 規格は HTTP/1.1
Host 接続先が 127.0.0.1:8080 ということを意味しています
User-Agent 今回はcurlを使用しましたので、ユーザエージェントはcurlとなっています
Accept 例えばテキストのみであれば text/plain 画像であれば image/jpegとなります
最後の空白 これがないとリクエストが終了したことがわかりません。最後はなにもない行を投げます。

レスポンス(返答)

< HTTP/1.1 200 OK
< server: ecstatic-3.3.1
< cache-control: max-age=3600
< last-modified: Sat, 27 Apr 2019 14:08:58 GMT
< etag: W/"3068562-99-2019-04-27T14:08:58.104Z"
< content-length: 99
< content-type: text/html; charset=UTF-8
< Date: Sat, 27 Apr 2019 14:10:45 GMT
< Connection: keep-alive
<
解説
HTTP/1.1 200 OK プロトコル了解しましたという意味です。 ステータスコードは正常である200番でメッセージの最後にOKがあります。
server サーバの名前です
cache-control キャッシュの情報をリクエスト、レスポンスの双方で共有するために記述しています
last-modified 最後にキャッシュがリセットされた時刻です
etag バリアントのエンティティタグ
content-length コンテンツのデータ量です
content-type htmlファイルであったり、文字コードを指定しています
Date レスポンス時の時刻です
Connection ホップバイホップヘッダ

コンテンツデータ

<!DOCTYPE html>
<html lang="ja">
<head>
    <title>Document</title>
</head>
<body>
</body>
</html>

先程記述したデータが帰ってきて、通信終了です。

最後に

いかがでしたでしょうか。
普段使用しているWebブラウザからのリクエストやレスポンスはこのようなテキストのやり取りで行われているんですね。
それを応用して様々な通信を行っていたりします(Websocketなどなど)

興味があればRFCを読めば完全に理解できると思いますので、是非そちらをご観覧ください。
https://triple-underscore.github.io/RFC2616-ja.htm

ではでは。

1
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
3