2013-05-17 3 views
1

Я пытаюсь выяснить, как загрузить данные в ведро Amazon S3 через RESTful API, который я пишу в Node.js/Restify. Я думаю, что у меня есть основные понятия, которые все работают, но когда я иду, чтобы подключиться к телу моего запроса POST, вот когда все идет не так. Когда я настраивал свою функцию обратного вызова, чтобы просто передать строку в S3, она работает просто отлично, и файл создается в соответствующем S3 ведро:Загрузка данных на S3 через POST с использованием AWS SDK для Node.js/Restify

function postPoint(req, res, next) { 

    var point = [ 
    { "x": "0.12" }, 
    { "y": "0.32" } 
    ]; 

    var params = { Bucket: 'myBucket', Key: 'myKey', Body: JSON.stringify(point) }; 

    s3.client.putObject(params, function (perr, pres) { 
    if (perr) { 
     console.log("Error uploading data: ", perr); 
    } else { 
     console.log("Successfully uploaded data to myBucket/myKey"); 
    } 
    }); 

    res.send(200); 
    return next(); 
} 

server.post('/point', postPoint); 

Очевидно, что мне нужно, чтобы в конечном итоге поток/трубопровод мой запрос от тело запроса. Я предполагал, все, что мне нужно было бы сделать, чтобы просто переключить тело из Params в поток запроса:

function postPoint(req, res, next) { 

    var params = { Bucket: 'myBucket', Key: 'myKey', Body: req }; 

    s3.client.putObject(params, function (perr, pres) { 
    if (perr) { 
     console.log("Error uploading data: ", perr); 
    } else { 
     console.log("Successfully uploaded data to myBucket/myKey"); 
    } 
    }); 

    res.send(200); 
    return next(); 
} 

Но в конечном итоге вызывает следующее сообщение журнала, который будет отображаться: «Ошибка при загрузке данных: [TypeError : путь должен быть строкой] ", что дает мне очень мало указания на то, что мне нужно сделать, чтобы исправить ошибку. В конечном счете, я хочу иметь возможность передавать результат, поскольку отправляемые данные могут быть довольно большими (я не уверен, что предыдущие примеры заставляют тело храниться в памяти), поэтому я подумал, что что-то вроде этого может работать :

function postPoint(req, res, next) { 

    var params = { Bucket: 'myBucket', Key: 'myKey', Body: req }; 

    req.pipe(s3.client.putObject(params)); 

    res.send(200); 
    return next(); 
} 

Так как я сделал что-то подобное в функции GET, который работает просто отлично :(s3.client.getObject(params).createReadStream().pipe(res);). Но это тоже не сработало.

Я нахожусь в убытке на этом этапе, поэтому любое руководство будет принята с благодарностью!

ответ

1

Итак, я наконец нашел ответ после публикации на форумах разработчиков AWS. Оказывается, заголовок Content-Length отсутствовал в моих запросах S3. [email protected] подвел итог очень хорошо:

In order to upload any object to S3, you need to provide a Content-Length. Typically, the SDK can infer the contents from Buffer and String data (or any object with a .length property), and we have special detections for file streams to get file length. Unfortunately, there's no way the SDK can figure out the length of an arbitrary stream, so if you pass something like an HTTP stream, you will need to manually provide the content length yourself.

Предложенное решением было просто передать длину содержимого из заголовков http.IncomingMessage объекта:

var params = { 
    Bucket: 'bucket', Key: 'key', Body: req, 
    ContentLength: parseInt(req.headers['content-length'], 10) 
}; 
s3.putObject(params, ...); 

Если кому-то интересно читать всю нить , вы можете получить к нему доступ here.

Смежные вопросы