Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

ali-oss

Package Overview
Dependencies
Maintainers
2
Versions
127
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

ali-oss - npm Package Compare versions

Comparing version 1.1.0 to 2.0.0

lib/bucket.js

17

History.md
2.0.0 / 2015-02-28
==================
* fix get not exists object TypeError
* transfer to ali-sdk/ali-oss
* feat(object): support streaming put
* refactor object operations with successStatuses and xmpResponse
* finish bucket operations
* ensure tmp dir exists
* add appveyor.yml
* add bucket operations
* support deleteMulti
* support copy and updateMeta
* support get object
* support delete object
* totally refactor according to ali-sdk
1.1.0 / 2015-01-30

@@ -3,0 +20,0 @@ ==================

4

index.js

@@ -1,3 +0,1 @@

module.exports = require('generator-supported')
? require('./lib/client')
: require('./build/client');
module.exports = require('./lib/client');

@@ -1,5 +0,10 @@

/*!
/**!
* ali-oss - lib/client.js
* Copyright(c) 2014 dead_horse <dead_horse@qq.com>
*
* Copyright(c) ali-sdk and other contributors.
* MIT Licensed
*
* Authors:
* dead_horse <dead_horse@qq.com>
* fengmk2 <m@fengmk2.com> (http://fengmk2.com)
*/

@@ -13,15 +18,16 @@

var debug = require('debug')('ali-oss:client');
var debug = require('debug')('ali-oss');
var crypto = require('crypto');
var fs = require('fs');
var path = require('path');
var querystring = require('querystring');
var copy = require('copy-to');
var is = require('is-type-of');
var read = require('co-read');
var mime = require('mime');
var urllib = require('urllib');
var xml = require('xml2js');
var ms = require('ms');
var utility = require('utility');
var ms = require('humanize-ms');
var AgentKeepalive = require('agentkeepalive');
var merge = require('merge-descriptors');
var agent = new AgentKeepalive();
/**

@@ -31,27 +37,5 @@ * Expose `Client`

var exports = module.exports = Client;
module.exports = Client;
exports.create = create;
var DEFAULT_OPTIONS = {
host: 'oss.aliyuncs.com',
timeout: '10s',
};
/**
* aliyun OSS client
* @param {Object} options
* - {String} accessKeyId
* - {String} accessKeySecret
* - {String} [host]
* - {Number} [timeout]
*/
function Client(options) {
if (!options
|| !options.accessKeyId
|| !options.accessKeySecret
|| !options.bucket) {
throw new Error('require accessKeyId, accessKeySecret and bucket');
}
if (!(this instanceof Client)) {

@@ -61,7 +45,19 @@ return new Client(options);

copy(options).and(DEFAULT_OPTIONS).to(this);
if (!options
|| !options.accessKeyId
|| !options.accessKeySecret) {
throw new Error('require accessKeyId, accessKeySecret');
}
if (is.string(this.timeout)) {
this.timeout = ms(this.timeout);
}
var DEFAULT_OPTIONS = {
region: 'oss-cn-hangzhou',
internal: false,
timeout: '60s',
bucket: null,
};
this.options = {};
copy(options).and(DEFAULT_OPTIONS).to(this.options);
this.setRegion(this.options.region);
this.options.timeout = ms(this.options.timeout);
}

@@ -75,20 +71,17 @@

proto.signatureUrl = function (name) {
var resourceName = '/' + this.bucket + '/' + name;
var expires = utility.timestamp() + 1800;
var params = [
'GET',
'', // md5
'', // Content-Type
expires, // Expires
resourceName,
];
/**
* Object operations
*/
merge(proto, require('./object'));
/**
* Bucket operations
*/
merge(proto, require('./bucket'));
debug('authorization with params: %j', params);
var signature = crypto.createHmac('sha1', this.accessKeySecret);
signature = signature.update(params.join('\n')).digest('base64');
var url = this._objectUrl(name);
return url + '?OSSAccessKeyId=' + encodeURIComponent(this.accessKeyId) +
'&Expires=' + expires + '&Signature=' + encodeURIComponent(signature);
proto.setRegion = function (region) {
if (!this.options.host || region !== this.options.region) {
this.options.region = region;
this.options.host = this._getRegionHost(region);
}
return this;
};

@@ -118,6 +111,6 @@

proto.authorization = function (method, resource, headers) {
var auth = 'OSS ' + this.accessKeyId + ':';
var auth = 'OSS ' + this.options.accessKeyId + ':';
var params = [
method.toUpperCase(),
headers['Content-Md5'],
headers['Content-Md5'] || '',
headers['Content-Type'],

@@ -132,3 +125,3 @@ headers.Date || new Date().toString()

ossHeaders[lkey] = ossHeaders[lkey] || [];
ossHeaders[lkey].push(headers[key].trim());
ossHeaders[lkey].push(String(headers[key]).trim());
}

@@ -144,16 +137,13 @@ }

//TODO: support sub resource
// TODO: support sub resource
params.push(resource);
debug('authorization with params: %j', params);
var stringToSign = params.join('\n');
debug('authorization stringToSign: %s', stringToSign);
var signature = crypto.createHmac('sha1', this.accessKeySecret);
signature = signature.update(params.join('\n')).digest('base64');
var signature = crypto.createHmac('sha1', this.options.accessKeySecret);
signature = signature.update(stringToSign).digest('base64');
return auth + signature;
};
proto._objectUrl = function (name) {
return 'http://' + this.host + '/' + this.bucket + '/' + name;
};
/**

@@ -164,4 +154,7 @@ * request oss server

* - {String} method
* - {Object} headers
* - {Number} timeout
* - {String} [resource]
* - {String} [region]
* - {Object} [headers]
* - {Object} [query]
* - {Number} [timeout]
* - {Buffer} [content]

@@ -175,15 +168,22 @@ * - {Stream} [writeStream]

proto.request = function* (params) {
var url = this._objectUrl(params.name);
var host = this.options.host;
if (params.region) {
host = this._getRegionHost(params.region);
}
var headers = {
Date: new Date().toGMTString(),
Host: this.host
Host: host
};
if (params.content) {
if (params.content || params.stream) {
headers['Content-Type'] = mime.lookup(params.mime || path.extname(params.name));
headers['Content-Md5'] = crypto
.createHash('md5')
.update(params.content)
.digest('base64');
headers['Content-Length'] = params.content.length;
if (params.content) {
headers['Content-Md5'] = crypto
.createHash('md5')
.update(params.content)
.digest('base64');
if (!headers['Content-Length']) {
headers['Content-Length'] = params.content.length;
}
}
}

@@ -193,151 +193,50 @@

var resource = '/' + this.bucket + '/' + params.name;
headers.authorization = this.authorization(params.method, resource, headers);
var resource = params.resource;
if (!resource) {
if (!this.options.bucket) {
throw new Error('Please create a bucket first');
}
resource = '/' + this.options.bucket + '/' + params.name;
}
debug('request %s %s, with headers %j', params.method, url, headers);
return yield urllib.requestThunk(url, {
var authResource = params.authResource || resource;
headers.authorization = this.authorization(params.method, authResource, headers);
var url = 'http://' + host + resource;
if (params.query) {
url += '?' + querystring.stringify(params.query);
}
debug('request %s %s, with headers %j, !!stream: %s', params.method, url, headers, params.stream);
var timeout = params.timeout || this.options.timeout;
var reqParams = {
agent: agent,
method: params.method,
content: params.content,
stream: params.stream,
headers: headers,
timeout: params.timeout,
timeout: timeout,
writeStream: params.writeStream
});
};
/**
* upload a file to oss
* @param {Mix} file filepath, fileContent, stream
* @param {String} name
* @param {Object} [options]
* - {Number} timeout
* - {Object} headers
* - {String} mime
* @param {Function} callback
*
* @api public
*/
proto.upload = function* (file, name, options) {
options = options || {};
var timeout = options.timeout || this.timeout;
var content = yield* getContent(file);
debug('start update %s with content length %d', name, content.length);
var res = yield* this.request({
name: name,
content: content,
headers: options.headers,
timeout: timeout,
mime: options.mime,
method: 'PUT'
});
debug('upload %s response %s, with data: %s', name, res.status, res.data);
if (res.status === 200) {
return null;
};
var result = yield urllib.requestThunk(url, reqParams);
debug('response %s %s, got %s, headers: %j', params.method, url, result.status, result.headers);
if (params.successStatuses && params.successStatuses.indexOf(result.status) === -1) {
throw yield* this.requestError(result);
}
throw yield* requestError(res);
if (params.xmlResponse) {
result.data = yield this.parseXML(result.data);
}
return result;
};
proto.put = proto.upload;
/**
* get an object from oss
* support return a buffer, write into file and write into Stream
*
* ```
* get('test.png', stream);
*
* get('test.png', './test.png');
*
* var content = get('test.png');
*```
*
*
* @param {String} name
* @param {Mix} [path]
* if give a string file path, will write into this file
* if give a writeStream, will write into this stream
* if empty, will return a buffer
* @param {String} Options
* - {Number} timeout
* - {Objects} headers
* ignore if writeStream exist
* @api public
*/
proto.download = function* (name, path, options) {
var writeStream = null;
var needDestroy = false;
if (is.writableStream(path)) {
writeStream = path;
} else if (is.string(path)) {
writeStream = fs.createWriteStream(path);
needDestroy = true;
proto._getRegionHost = function (region) {
if (this.options.internal) {
return region + '-internal.aliyuncs.com';
} else {
options = path;
return region + '.aliyuncs.com';
}
options = options || {};
var timeout = options.timeout || this.timeout;
debug('get file %s', name);
var res;
try {
res = yield* this.request({
name: name,
headers: options.headers,
timeout: timeout,
method: 'GET',
writeStream: writeStream
});
} catch (err) {
throw err;
} finally {
needDestroy && writeStream.destroy();
}
debug('get response %s, headers %j', res.status, res.headers);
if (res.status === 200) {
return res.data;
}
throw yield* requestError(res);
};
proto.get = proto.download;
/**
* remove an object from oss
* @param {String} name
* @param {Object} options
* - {Number} timeout
*/
proto.remove = function* (name, options) {
options = options || {};
var timeout = options.timeout || this.timeout;
var res = yield* this.request({
name: name,
method: 'DELETE',
timeout: timeout
});
if (res.status === 204) {
return;
}
throw yield* requestError(res);
};
proto.delete = proto.remove;
/**
* get content from string(file path), buffer(file content), stream(file stream)
* @param {Mix} file
* @return {Buffer}
* thunkify xml.parseString
* @param {String|Buffer} str
*

@@ -347,32 +246,17 @@ * @api private

function* getContent(file) {
if (is.buffer(file)) {
return file;
}
proto.parseXML = function (str) {
return function (done) {
if (Buffer.isBuffer(str)) {
str = str.toString();
}
xml.parseString(str, {
explicitRoot: false,
explicitArray: false
}, done);
};
};
var created = false;
if (is.string(file)) {
file = fs.createReadStream(file);
created = true;
}
if (!is.readableStream(file)) {
throw new TypeError('upload file type error');
}
var bufs = [];
var buf;
while (buf = yield read(file)) {
bufs.push(buf);
}
if (created) {
file.destroy();
}
return Buffer.concat(bufs);
}
/**
* generater a request error with request response
* @param {Object} res
* @param {Object} result
*

@@ -382,57 +266,52 @@ * @api private

function* requestError(res) {
if (res.status === 404) {
var err = new Error('resource not found');
err.status = 404;
return err;
}
proto.requestError = function* (result) {
var err;
if (!result.data || !result.data.length) {
// HEAD not exists resource
if (result.status === 404) {
err = new Error('Object not exists');
err.name = 'NoSuchKeyError';
err.status = 404;
err.code = 'NoSuchKey';
} else if (result.status === 412) {
err = new Error('Pre condition failed');
err.name = 'PreconditionFailedError';
err.status = 412;
err.code = 'PreconditionFailed';
} else {
err = new Error('Unknow error, status: ' + result.status);
err.name = 'UnknowError';
err.status = result.status;
}
err.requestId = result.headers['x-oss-request-id'];
err.host = '';
} else {
var message = String(result.data);
debug('request response error data: %s', message);
var message = String(res.data);
debug('request response error data: %s', message);
var info;
try {
info = yield this.parseXML(message) || {};
} catch (err) {
debug(message);
err.message += '\nraw xml: ' + message;
err.status = result.status;
err.requestId = result.headers['x-oss-request-id'];
return err;
}
var info;
try {
info = yield parseXml(message);
} catch (err) {
err.message += '\nraw xml: ' + message;
err.status = res.status;
return err;
var message = info.Message || ('unknow request error, status: ' + result.status);
if (info.Condition) {
message += ' (condition: ' + info.Condition + ')';
}
var err = new Error(message);
err.name = info.Code ? info.Code + 'Error' : 'UnknowError';
err.status = result.status;
err.code = info.Code;
err.requestId = info.RequestId;
err.hostId = info.HostId;
}
info = info && info.Error
? info.Error
: {};
var err = new Error(info.Message || 'request error');
err.status = res.status;
err.code = info.Code;
err.requestId = info.RequestId;
err.host = info.HostId;
debug('generate error %j', err);
return err;
}
/**
* thunkify xml.parseString
* @param {String} str
*
* @api private
*/
function parseXml(str) {
return function (done) {
xml.parseString(str, done);
};
}
/**
* create a new oss client
*
* @api public
*/
function create(options) {
return new Client(options);
}
};
{
"name": "ali-oss",
"version": "1.1.0",
"version": "2.0.0",
"description": "aliyun oss(open storage service) node client",
"main": "index.js",
"files": [
"index.js",
"lib/"
],
"scripts": {
"test": "make test",
"prepublish": "make clean build"
"test": "mocha --harmony --check-leaks -R spec -t 30000 -r co-mocha test/*.test.js",
"test-cov": "node --harmony node_modules/.bin/istanbul cover node_modules/.bin/_mocha -- --check-leaks -t 30000 -r co-mocha test/*.test.js",
"test-travis": "node --harmony node_modules/.bin/istanbul cover node_modules/.bin/_mocha --report lcovonly -- --check-leaks -t 30000 -r co-mocha test/*.test.js",
"jshint": "jshint .",
"autod": "autod -w --prefix '~'",
"cnpm": "npm install --registry=https://registry.npm.taobao.org",
"contributors": "contributors -f plain -o AUTHORS"
},
"repository": {
"type": "git",
"url": "git://github.com/alibaba/ali-oss.git"
"url": "git://github.com/ali-sdk/ali-oss.git"
},

@@ -23,9 +32,9 @@ "keywords": [

"bugs": {
"url": "https://github.com/alibaba/ali-oss/issues"
"url": "https://github.com/ali-sdk/ali-oss/issues"
},
"homepage": "https://github.com/alibaba/ali-oss",
"homepage": "https://github.com/ali-sdk/ali-oss",
"devDependencies": {
"co": "3",
"ali.regenerator": "*",
"autod": "1",
"autod": "*",
"co": "*",
"co-fs": "~1.2.0",
"co-mocha": "*",

@@ -37,13 +46,15 @@ "istanbul-harmony": "*",

"dependencies": {
"co-read": "~0.1.1",
"agentkeepalive": "~1.2.0",
"copy-to": "~2.0.1",
"debug": "~2.1.1",
"generator-supported": "~0.0.1",
"destroy": "~1.0.3",
"end-or-error": "~1.0.0",
"humanize-ms": "~1.0.1",
"is-type-of": "~0.3.1",
"mime": "~1.2.11",
"ms": "~0.7.0",
"urllib": "~2.2.2",
"utility": "~1.2.1",
"xml2js": "~0.4.4"
"merge-descriptors": "~0.0.2",
"mime": "~1.3.4",
"urllib": "~2.3.0",
"utility": "~1.3.0",
"xml2js": "~0.4.5"
}
}
ali-oss
=======
[![NPM version][npm-image]][npm-url]
[![build status][travis-image]][travis-url]
[![David deps][david-image]][david-url]
[![iojs version][iojs-image]][iojs-url]
[![node version][node-image]][node-url]

@@ -11,14 +13,16 @@ [![Gittip][gittip-image]][gittip-url]

[npm-url]: https://npmjs.org/package/ali-oss
[travis-image]: https://img.shields.io/travis/alibaba/ali-oss.svg?style=flat-square
[travis-url]: https://travis-ci.org/alibaba/ali-oss
[david-image]: https://img.shields.io/david/alibaba/ali-oss.svg?style=flat-square
[david-url]: https://david-dm.org/alibaba/ali-oss
[node-image]: https://img.shields.io/badge/node.js-%3E=_0.11-red.svg?style=flat-square
[travis-image]: https://img.shields.io/travis/ali-sdk/ali-oss.svg?style=flat-square
[travis-url]: https://travis-ci.org/ali-sdk/ali-oss
[david-image]: https://img.shields.io/david/ali-sdk/ali-oss.svg?style=flat-square
[david-url]: https://david-dm.org/ali-sdk/ali-oss
[node-image]: https://img.shields.io/badge/node.js-%3E=_0.11-green.svg?style=flat-square
[node-url]: http://nodejs.org/download/
[iojs-image]: https://img.shields.io/badge/io.js-%3E=_1.0-green.svg?style=flat-square
[iojs-url]: http://iojs.org/
[gittip-image]: https://img.shields.io/gittip/dead-horse.svg?style=flat-square
[gittip-url]: https://www.gittip.com/dead-horse/
aliyun OSS(open storage service) node client. generator friendly.
aliyun OSS(open storage service) node client.
a node.js wrapper for [OSS restful api](http://docs.aliyun.com/#/oss/api-reference/abstract)
Sub module of [ali-sdk](https://github.com/ali-sdk/ali-sdk).

@@ -33,97 +37,43 @@ ## Install

### Init
@see [OSS Usage on ali-sdk](https://github.com/ali-sdk/ali-sdk/blob/master/docs/oss.md)
init a oss client, need `accessKeyId`, `accessKeySecret` and `bucket`
## TODO
```js
var OSS = require('ali-oss');
- Bucket
- Base
- [x] listBuckets*
- [x] putBucket*
- [x] deleteBucket*
- ACL
- [x] putBucketACL*
- [x] getBucketACL*
- Logging
- [x] putBucketLogging*
- [x] getBucketLogging*
- [x] deleteBucketLogging*
- Website
- [x] putBucketWebsite*
- [x] getBucketWebsite*
- [x] deleteBucketWebsite*
- Referer
- [x] putBucketReferer*
- [x] getBucketReferer*
- [x] deleteBucketReferer*
- Lifecycle
- [x] putBucketLifecycle*
- [x] getBucketLifecycle*
- [x] deleteBucketLifecycle*
- Object
- [x] put*
- [x] putMeta*
- [x] get*
- [x] head*
- [x] copy*
- [x] delete*
- [x] deleteMulti*
- [ ] post*
- [x] list*
var client = OSS.create({
accessKeyId: 'id',
accessKeySecret: 'xxx',
bucket: 'test'
});
```
options:
- accessKeyId
- accessKeySecret
- [host]: default to `oss.aliyuncs.com:8080`
- [timeout]: default to '10s'
### Methods
#### upload, put
```js
yield* client.upload(file, name, options);
```
options:
- **file**: can be filepath, fileContent, stream
- **name**: object name in oss
- **options**:
- timeout: request timeout
- headers: custom headers, checkout the doc
- mime: file mime type, will send to `mime.lookup`
#### download, get
```js
yield* client.get(name, path, options);
```
options:
- **name**: object name in oss
- **path**: can be filepath and stream
- **options**:
- timeout
- headers
#### remove, delete
```js
yield* client.remove(name, options);
```
options:
- **name**: object name in oss
- **options**:
- timeout
#### signatureUrl
```js
var downloadUrl = client.signatureUrl(name);
// http://oss.aliyuncs.com/oss-api.pdf?OSSAccessKeyId=xxxx&Expires=1141889120&Signature=vjbyPxybdZaNmGa%2ByT272YEAiv4%3D
```
options:
- **name**: object name in oss
## backward compatibility
if you do not use node v0.11+ or do not use `node --harmony`.
this module will use [regenerator](https://github.com/facebook/regenerator) to convert to es5 style.
so you only need to use co wrap the generator function into callback style:
```js
var co = require('co');
var OSS = require('ali-oss');
var client = OSS.create({});
client.update = co(client.update);
client.get = co(client.get);
client.remove = co(client.remove);
```
then you use these APIs as common async callback APIs. checkout the [callback_example.js](callback_example.js).
## License
MIT
[MIT](LICENSE)

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc