2013-05-17 2 views
1

Node.js/Restify에 작성한 RESTful API를 통해 Amazon S3 버킷에 데이터를 업로드하는 방법을 알아 내려고합니다. 기본 개념이 모두 작동한다고 생각하지만 POST 요청의 본문에 연결하면 상황이 잘못 될 수 있습니다. 나는 단순히 S3에 문자열을 전달하는 내 콜백 함수를 설정하면, 그것은 잘 작동하고 파일이 적절한 S3 버킷에 생성됩니다 : 분명히Node.js/Restify 용 AWS SDK를 사용하여 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(); 
} 

그러나 다음과 같은 로그 메시지가 표시되는 원인이 끝납니다 : "오류 업로드 데이터 : [형식 오류 : 경로는 문자열이어야합니다] "오류를 수정하기 위해 수행해야 할 작업이 거의 없다는 것을 알려줍니다. 궁극적으로, 나는 데이터가 전송 될 수 있기 때문에 결과를 파이프 할 수 있기를 원한다. (이전 예제가 몸체를 메모리에 저장하는 원인인지는 확실치 않다.) 그래서 나는 이것과 비슷한 것이 효과가있을 것이라고 생각했다. :

내가) :( s3.client.getObject(params).createReadStream().pipe(res); 잘 작동하는 GET 함수에서 비슷한 짓을했는지 때문에
function postPoint(req, res, next) { 

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

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

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

. 하지만 그것도 효과가 없었습니다.

나는이 시점에서 약간의 손실이 있으므로 어떤 지침을 주시면 매우 감사하겠습니다!

답변

1

그래서 결국 AWS 개발자 포럼에 게시 한 후 답변을 발견했습니다. 내 S3 요청에서 Content-Length 헤더가 누락되었습니다. [email protected]은 매우 잘 요약 :

제안 된 솔루션은 단순히 http.IncomingMessage 개체의 헤더에서 콘텐츠 길이를 통과했다

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.

: 사람이 전체 스레드를 읽고 관심

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

경우 , here에 액세스 할 수 있습니다.

관련 문제