web-dev-qa-db-ja.com

HTTPリクエストにnetcat(nc)とcurlを使用することの違いは何ですか?

Curlを使用して特定のURLを要求し、200 OK応答を取得しています。

curl -v www.youtypeitwepostit.com
* About to connect() to www.youtypeitwepostit.com port 80 (#0)
*   Trying 54.197.246.21...
* Connected to www.youtypeitwepostit.com (54.197.246.21) port 80 (#0)
> GET / HTTP/1.1
> User-Agent: curl/7.29.0
> Host: www.youtypeitwepostit.com
> Accept: */*
>
< HTTP/1.1 200 OK
...

ヘッダーをファイルに保存する場合:

GET / HTTP/1.1
User-Agent: curl/7.29.0
Host: www.youtypeitwepostit.com
Accept: */*

ncコマンド(netcat)を実行してみます:

nc www.youtypeitwepostit.com 80 < file
HTTP/1.1 505 HTTP Version Not Supported
Connection: close
Server: Cowboy
Date: Wed, 02 Nov 2016 04:08:34 GMT
Content-Length: 0

別の返事をもらっています。違いは何ですか?また、ncを使用して200 OKを取得するにはどうすればよいですか?

リクエストヘッダーでさまざまなバージョンのHTTPを試し、誤ったCRLFを回避するために手動でリクエストを入力し、オプションのヘッダーを除外してみました。結果は似ています。

4
heytar

関連するRFC、 ハイパーテキスト転送プロトコル(HTTP/1.1):メッセージ構文とルーティング には、質問に対する回答が含まれています。つまり、HTTP要求の各行はCR/LFで終わる必要があります。


HTTPの文法 Message Format は、各ヘッダー行が改行文字(0x0d)とその後に続く改行文字(0x0a)で終わることを指定します。

 HTTP-message   = start-line
                  *( header-field CRLF )
                  CRLF
                  [ message-body ]

これは Request Line の説明でより明確に表現されています:

リクエストラインはメソッドトークンで始まり、シングルスペース(SP)、リクエストターゲット、別のシングルスペース(SP)、プロトコルバージョンが続き、CRLFで終わります。

 request-line   = method SP request-target SP HTTP-version CRLF

curlはHTTPリクエスト用に特別に開発されているため、HTTPリクエストを行うときにすでに適切な行末を使用しています。ただし、netcatはより汎用的なプログラムです。 Unixユーティリティとして、これはデフォルトで改行に改行文字を使用するため、ユーザーは行が正しく終了していることを確認する必要があります。

unix2dosユーティリティを使用して、リクエストヘッダーを含むファイルを改行/改行で終了するように変換できます。

HTTPリクエストを手動で入力し、ncの最新バージョンがある場合は、その-Cオプションを使用して、行末にCRLFを使用する必要があります。

nc -C www.youtypeitwepostit.com 80

ところで、最も一般的なインターネットプロトコル(SMTPなど)はCR/LFの行末を使用することに注意してください。


一部のWebサーバー(Apacheなど)はより寛容であり、改行文字のみで終了する要求行を受け入れます。 Message Parsing Robustness セクションで説明されているように、HTTP仕様ではこれが可能です。

Start-lineおよびheaderフィールドの行ターミネータはシーケンスCRLFですが、受信者は単一のLFを行ターミネータとして認識し、先行するCRを無視してもかまいません。

2