Реализация Chunked Encoding в .NET (или хотя бы псевдокод) - PullRequest
3 голосов
/ 25 ноября 2008

Я написал необработанный TCP-клиент для запросов HTTP / HTTPS, однако у меня возникли проблемы с ответами кодированной части. HTTP / 1.1 является требованием, поэтому я должен его поддерживать.

Необработанный TCP - это бизнес-требование, которое мне нужно соблюдать, поэтому я не могу переключиться на .NET HTTPWebRequest / HTTPWebResponse Однако, если есть способ преобразовать запрос / ответ RAW HTTP в HTTPWebRequest / HTTPWebResponse это бы сработало.

Ответы [ 2 ]

5 голосов
/ 25 ноября 2008

Лучше всего начать с спецификации 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)

Поле размера куска представляет собой строку шестнадцатеричные цифры, обозначающие размер
кусок Кодирование по частям заканчивается любым куском, размер которого
ноль, а затем трейлер, который заканчивается пустой строкой.

Трейлер позволяет отправителю включить дополнительный заголовок 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.

Это игнорирует часть расширения чанка, но так как она ограничена ";" должно быть легко разделить это. Этого должно быть достаточно, чтобы вы начали. Помните, что строка размера не имеет начальный "0x".

1 голос
/ 29 ноября 2008

Для дальнейшего использования также я нашел это:

 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
...