.NET中的分块编码实现(或至少伪代码)

时间:2008-11-25 18:59:18

标签: .net http encoding tcp chunked-encoding

我为HTTP / HTTPS请求编写了一个原始TCP客户端,但是我遇到了分块编码响应的问题。 HTTP / 1.1是必需的,因此我应该支持它。

原始TCP是我需要保留的业务需求,因此我无法切换到.NET HTTPWebRequest / HTTPWebResponse 但是如果有办法将RAW HTTP请求/响应转换为HTTPWebRequest / HTTPWebResponse,它工作。

2 个答案:

答案 0 :(得分:5)

最好的起点是http 1.1 specification,它列出了分块的工作原理。特别是第3.6.1节。

  

3.6.1分块传输编码

     

分块编码修改了   消息的正文为了   将其转换为一系列块,   每个都有自己的尺寸指示器,
  随后是一个可选预告片   包含entity-header字段。这个   允许动态生成的内容   随着转移   的必要信息   收件人验证是否有   收到了完整的信息。

   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)
     

chunk-size字段是一个字符串   十六进制数字表示
的大小   块。分块编码是   以任何大小为的块结束   零,其次是预告片   以空行终止。

     

预告片允许发件人   包括额外的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.

这忽略了块扩展部分,但由于它以“;”分隔。它应该很容易分开。这应该足以让你入门。请记住,chunksize字符串具有前导“0x”。

答案 1 :(得分:1)

为了将来的参考,我发现了这个:

 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