HTTPサーバがデータに応答して考える
3183 ワード
HTTPサーバがデータに応答して考える
ソース
最近はネットのプログラミングに関する情報を勉強していますが、突発的に自分でhttp postを作ってデータを要求して会社のデータを要求します。
発見する
この応答データを注意深く観察した後、2つの点があることが分かりました。1.このpost応答ヘッダには
http要求の長さ
ネットワーク要求は、一般的にコンテンツの終了を示す2つの方法があります。このようにデータを受け取る段階は、盲目的に待つ必要はありません。は最初からコンテンツの長さを示していますが、httpは一般的にこのような方式を用いて、headerに を識別します。は、コンテンツの前後に開始と終了の表示を追加し、ファイルを転送する場合、そのデータの前後に
第一の方法は、データを伝送する前にその内容の長さを知っていますが、第二の方法は、データを伝送する前にコンテンツの長さを知らないときに採用されます。例えば、
具体的な方法 ヘッドに を追加します。の各ブロックは16進数の長さ値を含み、この値は1ラインを独占し、長さはその後ろの も含まない。の最後のブロックは だけです。
重点
したがって、
参照
ブロック分けコード(Transfer-Enccoding:chunked)
HTTPプロトコルにおけるContent-Lengthの詳細な解読。
multiipad/form-data要求とファイルアップロードの詳細
MultiiPad/form-data POSTファイルアップロード詳細
ソース
最近はネットのプログラミングに関する情報を勉強していますが、突発的に自分でhttp postを作ってデータを要求して会社のデータを要求します。
try {
Socket socket = new Socket();
socket.connect(new InetSocketAddress("...", 80)); // host,
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
writer.write("POST / HTTP/1.1\r
");
writer.write("Host: ...\r
"); //
writer.write("User-Agent: Socket\r
");
writer.write("Accept: application/json\r
");
writer.write("Connection: close\r
");
writer.write("Content-Type: application/x-www-form-urlencoded\r
");
String body = "action=adv_index";
byte[] bytes = body.getBytes();
writer.write("Content-Length: " + bytes.length);
writer.write("\r
");
writer.write("\r
");
writer.write(body);
writer.flush();
BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
String line;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
writer.close();
reader.close();
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
以下は取得した応答データです。HTTP/1.1 200 OK
Server: nginx
Date: Sat, 27 Apr 2019 06:32:53 GMT
Content-Type: application/json; charset=utf-8
Transfer-Encoding: chunked
Connection: close
X-Powered-By: PHP/5.5.38
Access-Control-Allow-Origin: *
70c
//...
0
最初はおかしいと思いましたが、なぜentity bodyの前後に文字列を追加しましたか?また他のインターフェースを要請しました。前の文字列が変わります。後ろの文字列は永遠に0です。発見する
この応答データを注意深く観察した後、2つの点があることが分かりました。1.このpost応答ヘッダには
Content-Length
がありません。2.この文字列はentity body
の16進数長です。そこでいくつかの資料を検索しながらhttpプロトコルの内容を振り返ってみると、Transfer-Encoding
というheaderが働いていることが分かりました。http要求の長さ
ネットワーク要求は、一般的にコンテンツの終了を示す2つの方法があります。このようにデータを受け取る段階は、盲目的に待つ必要はありません。
Content-Length
を使用して------
の文字列表示の開始と終了を追加します。第一の方法は、データを伝送する前にその内容の長さを知っていますが、第二の方法は、データを伝送する前にコンテンツの長さを知らないときに採用されます。例えば、
post
を使ってファイルをアップロードする場合、Content-Type
に設定されたmultipart/form-data
は、boundary
の開始、パラメータ分割、終了を示すためにentity body
属性を追加する。Transfer-Encoding
はまた別の方法を採用しています。最初は内容の長さが分かりませんでした。もちろんContent-Length
は使えません。この時、私達はもう一つの方法でコンテンツの境界を知る必要があります。Transfer-Encoding
は一つのブロック分け方法を提供しています。コンテンツ全体の長さは分かりませんが、毎回送信されるコンテンツの長さは分かります。コンテンツ送信前に長さを追加します。具体的な方法
Transfer-Encoding: chunked
CRLF(/r/n)
を含まず、後のブロック内容のCRLF
0
であると同時にブロックがありますが、ブロックにはコンテンツがありません。CRLF
重点
したがって、
Transfer-Encoding
とContent-Type
は共存しない。参照
ブロック分けコード(Transfer-Enccoding:chunked)
HTTPプロトコルにおけるContent-Lengthの詳細な解読。
multiipad/form-data要求とファイルアップロードの詳細
MultiiPad/form-data POSTファイルアップロード詳細