LoginSignup
1
0

More than 5 years have passed since last update.

HTTPによるコンテンツ取得

Posted at

概要

curl の引数にURLを与えて実行すると指定したコンテンツを取得してコンソールに表示できますが、そこでどういう処理が行われているかを説明します。

URLのパース

URL文字列は例えば http://example.com/some/data といったものです。まずはこの文字列を解析します。このような処理をパース(parse)とかデシリアライズ(deserialize)と言いますが、例に出したURLを

  • http
  • example.com
  • /some/data

という3つの要素に分解し、それぞれを scheme, host, path と呼びます1

名前解決

次にURLから取り出した host の部分に対応するIPアドレスを取得するために getaddrinfo 関数を呼び出します。getaddrinfo 関数では、必要ならDNSサーバに host 文字列を送信してIPアドレスを取得します。

TCP接続

対象ホストにTCP接続します。TCP接続にはIPアドレスとポート番号が必要になります。接続先のIPアドレスはhostの名前解決をすることで取得しました。URL中でポート番号が明示的に指定されていない場合、schemeに依存したデフォルトのポート番号を使用します。httpの場合は80です。

HTTPリクエストの送信

TCP接続が確立されたら、URLのschemaパートに基づく方法でコンテンツを取得します。今回はhttpだったので、RFC7239で規定されたHTTPのお作法でコンテンツを取得します。パスとしてURLから取り出したpathを使って、HTTPリクエスト

GET /some/data HTTP/1.1
Host: example.com

をTCPソケットに書き込みます2。すると、対象ホストから応答(HTTPレスポンス)が返ってきます。

HTTPレスポンスのパース

HTTPレスポンスはMIME3で規定されたフォーマットになっているので、それを解析して本文(body)を取り出し、標準出力に書き込みます。これにより、取得したコンテンツがコンソールに表示されます。

まとめ

HTTPによるコンテンツ取得の処理を説明しました。

WebブラウザでアドレスバーにURLを入力してページを表示する際に行われている処理も、レスポンスをパースした後の処理がもうちょっと複雑になるだけで同様の処理が行われています。処理内容を把握しておくことで、コンテンツが取得できない場合の切り分けの参考になると思い説明してみました。

dig example.com +shortで名前解決したり、telnet example.com 80 でTCP接続してHTTPリクエストを送信してみるとより理解が深まるかもしれません。


  1. URLのフォーマットはRFC3986で規定されています 

  2. 説明の簡略化のため必須でないヘッダは省略しました。 

  3. RFC2045 

1
0
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
0