Pregunta

Escribí un cliente TCP sin procesar para solicitudes HTTP / HTTPS, sin embargo, tengo problemas con las respuestas de codificación fragmentadas. HTTP / 1.1 es un requisito, por lo tanto, debería admitirlo.

Raw TCP es un requisito comercial que debo mantener, por lo tanto, no puedo cambiar a .NET HTTPWebRequest / HTTPWebResponse Sin embargo, si hay una manera de convertir una solicitud / respuesta HTTP RAW en HTTPWebRequest / HTTPWebResponse que funcionaría.

¿Fue útil?

Solución

El mejor lugar para comenzar es la especificación http 1.1 , que establece a ver cómo funciona el fragmentado. Específicamente la sección 3.6.1.

  

3.6.1 Codificación de transferencia fragmentada

     

La codificación fragmentada modifica el   cuerpo de un mensaje para
  transfiérelo como una serie de trozos,   cada uno con su propio indicador de tamaño,
  seguido de un trailer OPCIONAL   que contiene campos de encabezado de entidad. Esta   permite contenido producido dinámicamente para   ser transferido junto con el
  información necesaria para el   destinatario para verificar que tiene
  recibió el mensaje completo.

   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)
     

El campo de tamaño de fragmento es una cadena de   dígitos hexadecimales que indican el tamaño de
  el trozo La codificación fragmentada es   terminado por cualquier fragmento cuyo tamaño es
  cero, seguido por el trailer, que   termina con una línea vacía.

     

El avance le permite al remitente   incluir encabezado HTTP adicional
  campos al final del mensaje. los   El campo de encabezado de tráiler se puede usar para   indicar qué campos de encabezado son   incluido en un trailer (ver sección   14.40).

Suponiendo que ya ha leído el encabezado de la respuesta y está apuntando al siguiente byte en la secuencia, su pseudocódigo se vería así:

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.

Esto ignora la porción de extensión de fragmento, pero dado que está delimitada con un " ;; " debería ser fácil dividirlo. Esto debería ser suficiente para comenzar. Tenga en cuenta que la cadena de tamaño de fragmento no tiene un " 0x " ;.

Otros consejos

Para la referencia futura también encontré esto:

 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
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top