.NETでのチャンクエンコーディング実装(または少なくとも擬似コード)
-
11-07-2019 - |
質問
HTTP / HTTPSリクエスト用に生のTCPクライアントを作成しましたが、チャンクエンコードレスポンスに問題があります。 HTTP / 1.1は要件であるため、サポートする必要があります。
生のTCPは維持する必要があるビジネス要件であるため、.NET HTTPWebRequest / HTTPWebResponseに切り替えることはできませんただし、RAW HTTP要求/応答をHTTPWebRequest /に変換する方法がある場合動作するHTTPWebResponse。
解決
開始するのに最適な場所は、 http 1.1仕様です。チャンクの仕組みを調べてください。具体的にはセクション3.6.1。
3.6.1チャンク転送コーディング
チャンクエンコーディングは、
一連のチャンクとして転送し、 それぞれに独自のサイズインジケータがあります。
オプションのトレーラーが続きます エンティティヘッダーフィールドを含む。この 動的に生成されたコンテンツを許可します
に必要な情報 受信者が持っていることを確認する
完全なメッセージを受け取りました。Chunked-Body = *chunk last-chunk trailer CRLF chunk = chunk-size [ chunk-extension ] CRLF chunk-data CRLF chunk-size = 1*HEX last-chunk = 1*("0") [ chunk-extension ] CRLF chunk-extension= *( ";" chunk-ext-name [ "=" chunk-ext-val ] ) chunk-ext-name = token chunk-ext-val = token | quoted-string chunk-data = chunk-size(OCTET) trailer = *(entity-header CRLF)
チャンクサイズフィールドは、
のサイズを示す16進数 チャンク。チャンクエンコーディングは サイズが
のチャンクで終了 ゼロ、その後に続くトレーラー、 空行で終了します。トレーラーは、送信者が 追加のHTTPヘッダーを含める
メッセージの最後のフィールド。の トレーラーヘッダーフィールドを使用して、 どのヘッダーフィールドが トレーラーに含まれる(セクションを参照 14.40)。
すでにレスポンスからヘッダーを読み取っており、ストリームの次のバイトを指していると仮定すると、擬似コードは次のようになります。
done = false;
uint8 bytes[];
while (!done)
{
chunksizeString = readuntilCRLF(); // read in the chunksize as a string
chunksizeString.strip(); // strip off the CRLF
chunksize = chunksizeString.convertHexString2Int(); // convert the hex string to an integer.
bytes.append(readXBytes(chunksize)); // read in the x bytes and append them to your buffer.
readCRLF(); // read the trailing CRLF and throw it away.
if (chunksize == 0)
done = true; //
}
// now read the trailer if any
// trailer is optional, so it may be just the empty string
trailer = readuntilCRLF()
trailer = trailer.strip()
if (trailer != "")
readCRLF(); // read out the last CRLF and we are done.
これはチャンク拡張部分を無視していますが、「;」で区切られているため、簡単に分割できるはずです。これで開始できます。チャンクサイズの文字列には先頭に「」が付いていないことに注意してください。
他のヒント
将来の参考のために、これも見つけました:
length := 0
read chunk-size, chunk-extension (if any) and CRLF
while (chunk-size > 0) {
read chunk-data and CRLF
append chunk-data to entity-body
length := length + chunk-size
read chunk-size and CRLF
}
read entity-header
while (entity-header not empty) {
append entity-header to existing header fields
read entity-header
}
Content-Length := length
Remove "chunked" from Transfer-Encoding