Próbuję przesłać strumieniowo plik wysłany za pośrednictwem formularza bezpośrednio do zasobnika Amazon S3, używając aws-sdk lub knox. Obsługa formularzy odbywa się za pomocą formidable.Strumień przesyłania pliku do S3 na Node.js przy użyciu sformatowanego i (knox lub aws-sdk)
Moje pytanie brzmi: w jaki sposób prawidłowo używać potężnego przy pomocy aws-sdk (lub knox) przy użyciu każdej z najnowszych funkcji tej biblioteki do obsługi strumieni?
Zdaję sobie sprawę, że ten temat został już poproszony tutaj w różnych smakach, czyli:
- How to receive an uploaded file using node.js formidable library and save it to Amazon S3 using knox?
- node application stream file upload directly to amazon s3
- Accessing the raw file stream from a node-formidable file upload (i jego bardzo przydatna odpowiedź akceptowaną na overiding form.onPart ())
Sądzę jednak, że odpowiedzi są nieco nieaktualne i/lub wyłączone z tematu (np. Wsparcie CORS, którego nie chcę na razie używać r różne powody) i/lub, co najważniejsze, nie odwołują się do najnowszych funkcji z aws-sdk (patrz: https://github.com/aws/aws-sdk-js/issues/13#issuecomment-16085442) lub doxx (w szczególności putStream() lub jego readableStream.pipe (req) variant, both explained in the doc).
Po kilku godzinach zmagań, doszedłem do wniosku, że potrzebuję pomocy (zrzeczenie się: Jestem dość początkującym ze strumieniami).
formaHTML:
<form action="/uploadPicture" method="post" enctype="multipart/form-data">
<input name="picture" type="file" accept="image/*">
<input type="submit">
</form>
ekspresowe bodyParser middleware jest skonfigurowany w ten sposób:
app.use(express.bodyParser({defer: true}))
ofertę kupna Handler:
uploadPicture = (req, res, next) ->
form = new formidable.IncomingForm()
form.parse(req)
form.onPart = (part) ->
if not part.filename
# Let formidable handle all non-file parts (fields)
form.handlePart(part)
else
handlePart(part, form.bytesExpected)
handlePart = (part, fileSize) ->
# aws-sdk version
params =
Bucket: "mybucket"
Key: part.filename
ContentLength: fileSize
Body: part # passing stream object as body parameter
awsS3client.putObject(params, (err, data) ->
if err
console.log err
else
console.log data
)
Jednak ja otrzymuję następujący błąd:
{ [RequestTimeout: Your socket connection to the server was not read from or written to within the timeout period. Idle connections will be closed.]
message: 'Your socket connection to the server was not read from or written to within the timeout period. Idle connections will be closed.', code: 'RequestTimeout', name: 'RequestTimeout', statusCode: 400, retryable: false }
Wersja Knox z handlePart() funkcja dostosowane w ten sposób także nie zdało egzaminu:
handlePart = (part, fileSize) ->
headers =
"Content-Length": fileSize
"Content-Type": part.mime
knoxS3client.putStream(part, part.filename, headers, (err, res) ->
if err
console.log err
else
console.log res
)
ja również uzyskać duży obiekt o rozdzielczości 400 StatusCode gdzieś.
Region jest skonfigurowany do eu-west-1 w obu przypadkach.
Dodatkowe uwagi:
node 0.10.12
latest formidable from npm (1.0.14)
latest aws-sdk from npm (1.3.1)
latest knox from npm (0.8.3)
To właśnie uratowało mnie dużo czasu. Dzięki. –
W rzeczywistości tak nie jest. Możliwe jest potok/stream do s3! wystarczy znać rozmiar przesłanego pliku. Jeśli twój klient może to zapewnić, to możesz użyć rury do przesłania na s3 bez nieprzyjemnego zapisu na twardym dysku. Piszę serwer cli i pośredniczący, który zostanie przesłany do s3. Ponieważ kontroluję zarówno klienta, jak i serwer, mogę określić rozmiar pliku przed przesłaniem. Myślę, że mogą istnieć inne, skrajne przypadki, takie jak moje, których nie należy lekceważyć. Używam knox do streamowania do s3 za pomocą polecenia put. – CharlesTWall3
@ CharlesTWall3 To jest bardzo ważny komentarz, nie myślałem o tym w tym czasie - myślałem o rozwiązaniu tylko po stronie serwera. Jeśli dostaniesz odpowiedź, jeśli chcesz, aby coś działało, z przyjemnością zagłosuję na Twoje rozwiązanie. Możesz także edytować tę odpowiedź. Dzięki! – jbmusso