如何通过流星铁路由器从S3提供文件 [英] How do I serve a file from S3 through Meteor Iron Router

查看:55
本文介绍了如何通过流星铁路由器从S3提供文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的问题与这非常相似一个,其中描述了如何使用Iron Router提供本地文件.我需要做同样的事情,但不是从磁盘同步读取文件,而是需要从S3获取文件,这是一个异步调用.

My question is very similar to this one which describes how to serve a local file using Iron Router. I need to do the same, but instead of reading the file synchronously from disk, I need to get the file from S3 which is an asynchronous call.

问题似乎是在异步s3.getObject完成之前返回了action方法,给了我以下错误.

The problem appears to be the fact that the action method has returned before the asynchronous s3.getObject completes giving me the following error.

Error: Can't render headers after they are sent to the client.

我假设Iron Router在意识到我尚未处理我的action方法中的响应时,正在为我生成响应,但是我很困惑如何告诉它等待我的异步调用完成.

I'm assuming that Iron Router is generating the response for me when it realizes that I haven't handled the response in my action method, but I'm stumped about how to tell it to wait for my asynchronous call to finish.

这是我的代码.

Router.map(function () {
    this.route('resumeDownload', {
        where: 'server',
        path: '/resume/:_id',
        action: function () {
            var response = this.response;

            var candidate = Candidates.findOne(this.params._id);
            if (!candidate || !candidate.resumeS3Key) {
                // this works fine because the method hasn't returned yet.
                response.writeHead(404);
                return response.end();
            }

            var s3 = new AWS.S3();
            s3.getObject({Bucket: 'myBucket', Key: candidate.resumeS3Key}, function (err, data) {
                if (err) {
                    // this will cause the error to be displayed
                    response.writeHead(500);
                    return response.end();
                }
                // this will also cause the error to be displayed
                response.writeHead(200, {'Content-Type': data.ContentType});
                response.end(data.Body);
            });
        }
    });
});

推荐答案

我自己解决了这个问题.我需要在action方法中使用future.

I was able to solve this one myself. I needed to use a future in my action method.

这是工作代码.

Router.map(function () {
    this.route('resumeDownload', {
        where: 'server',
        path: '/resume/:_id',
        action: function () {
            var response = this.response,
                candidate = Candidates.findOne(this.params._id);

            if (!candidate || !candidate.resumeS3Key) {
                response.writeHead(404);
                return response.end();
            }

            var Future = Npm.require('fibers/future'),
                s3 = new AWS.S3(),
                futureGetObject = Future.wrap(s3.getObject.bind(s3)),
                data = futureGetObject({Bucket: 'myBucket', Key: candidate.resumeS3Key}).wait();

            response.writeHead(200, {'Content-Type': data.ContentType});
            response.end(data.Body);
        }
    });
});

这篇关于如何通过流星铁路由器从S3提供文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆