使用 NodeJS 从 IBM Bluemix 对象存储下载文件

Download File from IBM Bluemix Object Storage using NodeJS

我在使用 NodeJS 脚本从 IBM Bluemix 对象存储下载文件时遇到问题,问题是从存储下载文件需要很长时间,100K 文件大约需要 21 秒,大约 8 秒等待第一个块,然后休息读取所有块

我正在使用该服务来存储图像并使用 NodeJS 脚本从存储中读取这些图像,并且图像是通过 HTML img 标签下载的,所以我到底做错了什么?

nodeJS代码:

app.get("/ostore/image/:filename", function(request, response) {
    response.set('Content-Type', 'image/jpg');
    response.set('cache-control', 'max-age=604800');
    response.set('Last-Modified', 'Sat, 05 Dec 2015 03:17:48 GMT');
    var credentials = app.appEnv.services['Object-Storage'][0].credentials
    var pkgcloud = require("pkgcloud");
    var client = pkgcloud.storage.createClient({
        provider: 'openstack',
        username: credentials.userId,
        password: credentials.password,
        authUrl: credentials.auth_url,
        tenantId: credentials.projectId,
        region: credentials.region,
        version: "2"
    });
    client.download({
        container: app.storageContainer,
        remote: request.params.filename,
        stream: response
    }, function() {
        response.end('done');
    });
});

尝试这样的事情:

routes.js

var vcap_os = require(__dirname + '/../utils/vcap')('Object-Storage'),
    os = require(__dirname + '/../modules/object-storage');

module.exports = function(app) {
    var router = app.loopback.Router();

    // proxy for object storage service
    router.get('/api/Products/image/:container/:file', function(req, res) {
        os(vcap_os.credentials).download(req.params.container, req.params.file, function(download) {
            download.pipe(res);
        });
    });

    app.use(router);
}

modules/object-storage.js

var pkgcloud = require('pkgcloud');

module.exports = function(creds) {
    var config = {
        provider: 'openstack',
        useServiceCatalog: true,
        useInternal: false,
        keystoneAuthVersion: 'v3',
        authUrl: creds.auth_url,
        tenantId: creds.projectId,
        domainId: creds.domainId,
        username: creds.username,
        password: creds.password,
        region: creds.region
    };

    return {
        download: function(container, file, cbk) {
            var client = pkgcloud.storage.createClient(config);
            client.auth(function (error) {
                if(error) {
                    console.error("Authorization error for storage client (pkgcloud): ", error);
                }
                else {
                    var request = client.download({
                        container: container,
                        remote: file
                    });

                    cbk(request);
                }
            });
        }
    };
};

使用 joe 的回答,经过少量修改,该服务现在运行良好,我不得不更改库 pkgcloud,因为它导致了 bluemix 的身份验证问题,我切换到包装程序包 pkgcloud-bluemix-objectstorage ,我的代码现在看起来像这样:

app.get('/ostore/image/:filename', (request, response) => {
    const credentials = app.appEnv.services['Object-Storage'][0].credentials;
    const config = {};
    config.provider = 'openstack';
    config.authUrl = 'https://identity.open.softlayer.com/';
    config.region = credentials.region;
    config.useServiceCatalog = true;
    config.useInternal = true;
    config.tenantId = credentials.projectId;
    config.userId = credentials.userId;
    config.username = credentials.username;
    config.password = credentials.password;
    config.auth = {
        forceUri: 'https://identity.open.softlayer.com/v3/auth/tokens',
        interfaceName: 'public',
        identity: {
            methods: [
                'password'
            ],
            password: {
                user: {
                    id: credentials.userId,
                    password: credentials.password
                }
            }
        },
        scope: {
            project: {
                id: credentials.projectId
            }
        }
    };

    const client = pkgcloud.storage.createClient(config);
    client.auth(error => {
        if (error) {
            console.error('Authorization error for storage client (pkgcloud): ', error);
        } else {
            const download = client.download({
                container: app.storageContainer,
                remote: request.params.filename
            });
            download.on('response', res => {
                delete res.headers['content-type'];
                delete res.headers['last-modified'];
                res.headers['Last-Modified'] = 'Sat, 05 Dec 2015 03:17:48 GMT';
                res.headers['Cache-Control'] = 'public, max-age=2592000';
                res.headers['Expires'] = new Date(Date.now() + 2592000000).toUTCString();
                res.headers['Content-Type'] = 'image/jpg';
            }).pipe(response);
        }
    });
});