Frage

Ich habe Probleme beim Lesen einer „chunked“-Antwort, wenn ich einen StreamReader verwende, um den von GetResponseStream() einer HttpWebResponse zurückgegebenen Stream zu lesen:

// response is an HttpWebResponse
StreamReader reader = new StreamReader(response.GetResponseStream());
string output = reader.ReadToEnd(); // throws exception...

Wenn das reader.ReadToEnd() Methode aufgerufen wird, erhalte ich die folgende System.IO.IOException: Es können keine Daten von der Transportverbindung gelesen werden:Die Verbindung wurde geschlossen.

Der obige Code funktioniert einwandfrei, wenn der Server eine „nicht-chunked“-Antwort zurückgibt.

Die einzige Möglichkeit, es zum Laufen zu bringen, besteht darin, HTTP/1.0 für die erste Anfrage zu verwenden (anstelle von HTTP/1.1, der Standardeinstellung), aber das scheint eine lahme Lösung zu sein.

Irgendwelche Ideen?


@Futter

Deine Lösung funktioniert ziemlich gut.Beim letzten Read() wird immer noch die gleiche IOExeception ausgelöst.Nach der Überprüfung des Inhalts des StringBuilder sieht es jedoch so aus, als ob alle Daten empfangen wurden.Vielleicht muss ich also einfach Read() in einen Try-Catch einbinden und den „Fehler“ schlucken.

War es hilfreich?

Lösung

Ich habe es noch nicht mit einer „chunked“-Antwort versucht, aber würde so etwas funktionieren?

StringBuilder sb = new StringBuilder();
Byte[] buf = new byte[8192];
Stream resStream = response.GetResponseStream();
string tmpString = null;
int count = 0;
do
{
     count = resStream.Read(buf, 0, buf.Length);
     if(count != 0)
     {
          tmpString = Encoding.ASCII.GetString(buf, 0, count);
          sb.Append(tmpString);
     }
}while (count > 0);

Andere Tipps

Ich arbeite an einem ähnlichen Problem.Die .net-HttpWebRequest- und HttpWebRequest-Funktionen verarbeiten Cookies und Weiterleitungen automatisch, jedoch nicht automatisch den Chunk-Inhalt im Antworttext.

Dies liegt möglicherweise daran, dass fragmentierter Inhalt mehr als nur einfache Daten enthalten kann (d. h.:Chunk-Namen, nachgestellte Header).

Den Stream einfach zu lesen und die EOF-Ausnahme zu ignorieren, wird nicht funktionieren, da der Stream mehr als den gewünschten Inhalt enthält.Der Stream enthält Chunks und jeder Chunk beginnt mit der Angabe seiner Größe.Wenn der Stream einfach von Anfang bis Ende gelesen wird, enthalten die endgültigen Daten die Chunk-Metadaten (und wenn es sich um gzip-Inhalte handelt, besteht die CRC-Prüfung beim Dekomprimieren keinen Erfolg).

Um das Problem zu lösen, ist es notwendig, den Stream manuell zu analysieren, die Blockgröße von jedem Block zu entfernen (sowie die CR-LF-Trennzeichen), den letzten Block zu erkennen und nur die Blockdaten beizubehalten.Es gibt wahrscheinlich irgendwo da draußen eine Bibliothek, die das macht, ich habe sie noch nicht gefunden.

Nützliche Ressourcen:

http://en.wikipedia.org/wiki/Chunked_transfer_encoding http://tools.ietf.org/html/rfc2616#section-3.6.1

Craig, ohne den Stream zu sehen, den du gerade liest, ist das Debuggen etwas schwierig, aber VIELLEICHT könntest du die Einstellung der Zählvariablen wie folgt ändern:

count = resStream.Read(buf, 0, buf.Length-1);

Es ist zwar ein kleiner Trick, aber wenn der letzte Lesevorgang Sie umbringt und keine Daten zurückgibt, wird das Problem theoretisch dadurch vermieden.Ich frage mich immer noch, warum der Stream das macht.

Ich hatte das gleiche Problem (und so bin ich hier gelandet :-).Letztendlich habe ich es auf die Tatsache zurückgeführt, dass der Chunk-Stream nicht gültig war – der letzte Chunk mit der Länge Null fehlte.Ich habe mir den folgenden Code ausgedacht, der sowohl gültige als auch ungültige Chunked-Streams verarbeitet.

using (StreamReader sr = new StreamReader(response.GetResponseStream(), Encoding.UTF8))
{
    StringBuilder sb = new StringBuilder();

    try
    {
        while (!sr.EndOfStream)
        {
            sb.Append((char)sr.Read());
        }
    }
    catch (System.IO.IOException)
    { }

    string content = sb.ToString();
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top