Ich glaube, dass, wenn Sie tun POST mögen Sie verwenden müssen Content-Type: multipart/form-data;boundary=myboundary
Kopfzeile. Und dann, im Körper, write()
so etwas wie dies für jeden String Feld (Zeilenumbrüche sollten \r\n
sein):
--myboundary
Content-Disposition: form-data; name="field_name"
field_value
und dann für die Datei selbst, write()
so etwas wie dies auf den Körper:
--myboundary
Content-Disposition: form-data; name="file"; filename="urlencoded_filename.jpg"
Content-Type: image/jpeg
Content-Transfer-Encoding: binary
binary_file_data
Die binary_file_data
ist, wo Sie verwenden pipe()
:
var fileStream = fs.createReadStream("path/to/my/file.jpg");
fileStream.pipe(requestToGoogle, {end: false});
fileStream.on('end, function() {
req.end("--myboundary--\r\n\r\n");
});
Die {end: false}
012 verhindertdie Anforderung automatisch schließen, da Sie nach dem Senden der Datei eine weitere Begrenzung schreiben müssen. Beachten Sie die zusätzlichen --
am Ende der Grenze.
Die große Sache ist, dass Google eine Header (sehr wahrscheinlich) benötigt. Wenn dies der Fall ist, können Sie keinen POST von Ihrem Benutzer an einen POST an Google streamen, da Sie nicht sicher wissen, was das ist, bis Sie die gesamte Datei erhalten haben.
Der Wert Header sollte eine einzige Zahl für den gesamten Körper sein. Der einfachste Weg ist, den ganzen Körper Buffer.byteLength(body)
anzurufen, aber das wird schnell hässlich, wenn Sie große Dateien haben, und es wird auch das Streaming beendet.Eine Alternative wäre es zu berechnen, wie so:
var body_before_file = "..."; // string fields + boundary and metadata for the file
var body_after_file = "--myboundary--\r\n\r\n";
var fs = require('fs');
fs.stat(local_path_to_file, function(err, file_info) {
var content_length = Buffer.byteLength(body_before_file) +
file_info.size +
Buffer.byteLength(body_after_file);
// create request to google, write content-length and other headers
// write() the body_before_file part,
// and then pipe the file and end the request like we did above
Aber, die noch Ihre Fähigkeit tötet vom Benutzer zu streamen Google, hat die Datei auf der lokalen Festplatte heruntergeladen werden, um zu bestimmen es Länge ist.
Alternative Option
... nun, danach durch alle gehen, PUT könnte Ihr Freund hier sein. Gemäß https://developers.google.com/storage/docs/reference-methods#putobject können Sie einen transfer-encoding: chunked
Header verwenden, so dass Sie die Dateilänge nicht finden müssen. Und ich glaube, dass der gesamte Körper der Anfrage nur die Datei ist, also können Sie pipe()
verwenden und die Anfrage einfach beenden, wenn sie fertig ist. Wenn Sie https://github.com/felixge/node-formidable verwenden Uploads zu handhaben, dann können Sie etwas tun:
incomingForm.onPart = function(part) {
if (part.filename) {
var req = ... // create a PUT request to google and set the headers
part.pipe(req);
} else {
// let formidable handle all non-file parts
incomingForm.handlePart(part);
}
}
Leider Google erfordert es eine POST-Anforderung, um zu tun, was ich versuche zu tun. Allerdings, große Antwort, und ich werde sicherlich die von Ihnen gemachten Vorschläge umsetzen. – jwegner
Übrigens, node.js gibt Ihnen die Möglichkeit, [Stop-Pipe vom Schließen der Verbindung] (http://nodejs.org/api/stream.html#stream_stream_pipe_destination_options) – jwegner
Guter Punkt, habe ich vergessen. Ich werde die Antwort bearbeiten, falls jemand anders darauf stößt. –