Question

J'ai écrit un client TCP brut pour les requêtes HTTP / HTTPS, mais j'ai des problèmes avec les réponses d'encodage en bloc. HTTP / 1.1 est une exigence donc je devrais le supporter.

Le TCP brut est une exigence commerciale que je dois respecter. Par conséquent, je ne peux pas passer à .NET HTTPWebRequest / HTTPWebResponse Cependant, s’il existe un moyen de convertir une demande / réponse HTTP RAW en HTTPWebRequest / HTTPWebResponse qui fonctionnerait.

Était-ce utile?

La solution

Le meilleur point de départ est la spécification http 1.1 , qui contient comment fonctionne la fragmentation. Plus précisément la section 3.6.1.

  

3.6.1 Codage de transfert en bloc

     

Le codage en bloc modifie la   corps d'un message afin de
  transférer comme une série de morceaux,   chacun avec son propre indicateur de taille,
  suivi d'un trailer FACULTATIF   contenant des champs d'en-tête d'entité. Ce   permet au contenu produit dynamiquement de   être transféré avec le
  informations nécessaires à la   destinataire pour vérifier qu'il a
  reçu le message complet.

   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)
     

Le champ de taille de morceau est une chaîne de   chiffres hexadécimaux indiquant la taille de
  le morceau. Le codage en bloc est   terminé par un morceau dont la taille est
  zéro, suivi de la bande-annonce, qui   se termine par une ligne vide.

     

La bande-annonce permet à l'expéditeur de   inclure un en-tête HTTP supplémentaire
  champs à la fin du message. le   Le champ d'en-tête de la bande-annonce peut être utilisé pour   indiquer quels champs d'en-tête sont   inclus dans une remorque (voir section   14.40).

En supposant que vous ayez déjà lu l'en-tête de la réponse et que vous pointez sur l'octet suivant du flux, votre pseudo-code se présente comme suit:

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.

Il s’agit d’ignorer la partie d’extension de bloc, mais comme elle est délimitée par un " ;; il devrait être facile de le séparer. Cela devrait être suffisant pour vous aider à démarrer. N'oubliez pas que la chaîne de taille de bloc n'a pas de début "0x".

Autres conseils

Pour la référence future aussi, j'ai trouvé ceci:

 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
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top