2013-05-17 66 views
1

我試圖弄清楚如何通過我在Node.js/Restify中編寫的RESTful API將數據上傳到Amazon S3存儲桶。我想我已經掌握了所有工作的基本概念,但是當我連接到POST請求的主體時,就是在事情出錯的時候。當我建立了我的回調函數來簡單地傳遞一個字符串到S3,它工作得很好,並在適當的S3桶被創建的文件:使用適用於Node.js/Restify的AWS開發工具包通過POST將數據上傳到S3

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(); 
} 

但是,最終造成顯示以下日誌消息:「錯誤上傳數據:[類型錯誤:path必須是一個字符串]「,這讓我很少指出我需要做什麼來修復錯誤。最終,我希望能夠管理結果,因爲發送的數據可能相當大(我不確定前面的例子是否導致身體被存儲在內存中),所以我認爲這樣的事情可能會起作用:

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開發者論壇上發佈後終於找到了答案。事實證明,我的S3請求中缺少Content-Length標題。 [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

相關問題