2016-08-03 13 views
0

Ich versuche folgende Fehlerbehandlung zu erreichen:Wenn der Zieldatenstrom Fehlerereignisse ausgibt, können wir den Quelldatenstrom irgendwie wiederverwenden?

  1. Sagen wir einen readable Strom haben.
  2. Wir leiten es in einen transform Strom.
  3. Irgendwie sendet der transform Strom eine error.
  4. Wir möchten den readable Stream (und alle seine Daten) wiederherstellen, und es erneut in einen anderen transform Stream pipen.

Schritt 4 erscheint schwierig zu sein: Ich unpipe Ereignis auf dem Zielstrom hören (transform Stream) und einen Verweis auf den Quellenstrom (readable Stream) abzurufen, aber zumindest einige Stücke seiner Daten wurden verloren.

Können wir dies tun, ohne einen benutzerdefinierten Transformations-Stream zu erstellen?

Ein reales Beispiel ist deflate Inhaltscodierung, where in some cases Sie zlib.createInflateRaw() statt zlib.createInflate() brauchen, aber wir können nicht entscheiden, welche die richtige Wahl bei der Antwort Körper Puffer vor der Suche sein würde.

+0

Unterstützen die meisten Seiten gzip in diesen Tagen sowieso nicht? Senden Sie einfach "Accept-Encoding: gzip" in Ihre Anfrage und Sie müssen sich keine Gedanken über Deflate-Probleme machen. – mscdex

+0

@mscdex Sie sind richtig, aber für eine http-Bibliothek können wir diese alten und verrückten Deflate-only-Server nicht ignorieren, endete ich dabei, scheint das Beste, was ich im Moment tun kann. https://github.com/bitinn/node-fetch/blob/master/index.js#L209-L222 – bitinn

Antwort

1

Sie müssen keinen Stream in der Mitte einfügen, nur um das erste Byte zu lesen. Zum Beispiel:

(function readChunk() { 
    var chunk = res.read(); 
    if (!chunk) 
    return res.once('readable', readChunk); 

    var inflate; 
    if ((chunk[0] & 0x0F) === 0x08) 
    inflate = zlib.createInflate(); 
    else 
    inflate = zlib.createInflateRaw(); 

    // Put chunk back into stream 
    res.unshift(chunk); 

    // Prepare the decompression 
    res.pipe(inflate); 

    output = new Response(inflate, response_options); 
    resolve(output); 
})(); 

Auch var body = res.pipe(new stream.PassThrough()); ist nicht erforderlich, können Sie einfach res verwenden, wo angemessen.