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

ali-oss

Package Overview
Dependencies
Maintainers
3
Versions
127
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

ali-oss

aliyun oss(open storage service) node client

  • 4.1.2
  • Source
  • npm
  • Socket score

Version published
Weekly downloads
56K
increased by38.41%
Maintainers
3
Weekly downloads
 
Created
Source

oss-nodejs-sdk

NPM version build status coverage David deps

aliyun OSS(open storage service) Node.js client.

Install

npm install ali-oss --save

License

MIT

OSS Usage

OSS, Open Storage Service. Equal to well known Amazon S3.

Summary

Data Regions

OSS current data regions.

namecountrycitydomaininner domains
oss-cn-hangzhouChinaHangZhouoss-cn-hangzhou.aliyuncs.comoss-cn-hangzhou-internal.aliyuncs.com
oss-cn-qingdaoChinaQingDaooss-cn-qingdao.aliyuncs.comoss-cn-qingdao-internal.aliyuncs.com
oss-cn-beijingChinaBeiJingoss-cn-beijing.aliyuncs.comoss-cn-beijing-internal.aliyuncs.com
oss-cn-hongkongChinaHongKongoss-cn-hongkong.aliyuncs.comoss-cn-hongkong-internal.aliyuncs.com
oss-cn-shenzhenChinaShenZhenoss-cn-shenzhen.aliyuncs.comoss-cn-shenzhen-internal.aliyuncs.com

Create Account

Go to OSS website, create a new account for new user.

After account created, you can create the OSS instance and get the accessKeyId and accessKeySecret.

Create A Bucket Instance

Each OSS instance required accessKeyId, accessKeySecret and bucket.

#oss(options)

Create a Bucket store instance.

options:

  • accessKeyId {String} access key you create on aliyun console website
  • accessKeySecret {String} access secret you create
  • [bucket] {String} the default bucket you want to access If you don't have any bucket, please use putBucket() create one first.
  • [endpoint] {String} oss region domain. It takes priority over region.
  • [region] {String} the bucket data region location, please see Data Regions, default is oss-cn-hangzhou Current available: oss-cn-hangzhou, oss-cn-qingdao, oss-cn-beijing, oss-cn-hongkong and oss-cn-shenzhen
  • [internal] {Boolean} access OSS with aliyun internal network or not, default is false If your servers are running on aliyun too, you can set true to save lot of money.
  • [timeout] {String|Number} instance level timeout for all operations, default is 60s

example:

var oss = require('ali-oss');

var store = oss({
  accessKeyId: 'your access key',
  accessKeySecret: 'your access secret',
  bucket: 'your bucket name',
  region: 'oss-cn-hangzhou'
});

Bucket Operations

.listBuckets*(query[, options])

List buckets in this account.

parameters:

  • [query] {Object} query parameters, default is null
    • [prefix] {String} search buckets using prefix key
    • [marker] {String} search start from marker, including marker key
    • [max-keys] {String|Number} max buckets, default is 100, limit to 1000
  • [options] {Object} optional parameters
    • [timeout] {Number} the operation timeout

Success will return buckets list on buckets properties.

  • buckets {Array} bucket meta info list Each BucketMeta will contains blow properties:
    • name {String} bucket name
    • region {String} bucket store data region, e.g.: oss-cn-hangzhou-a
    • creationDate {String} bucket create GMT date, e.g.: 2015-02-19T08:39:44.000Z
  • owner {Object} object owner, including id and displayName
  • isTruncated {Boolean} truncate or not
  • nextMarker {String} next marker string
  • res {Object} response info, including
    • status {Number} response status
    • headers {Object} response headers
    • size {Number} response size
    • rt {Number} request total use time (ms)

example:

  • List top 10 buckets
var result = yield store.listBuckets({
  "max-keys": 10
});
console.log(result);

.putBucket*(name, region[, options])

Create a new bucket.

parameters:

  • name {String} bucket name If bucket exists and not belong to current account, will throw BucketAlreadyExistsError. If bucket not exists, will create a new bucket and set it's ACL.
  • region {String} the bucket data region location, please see Data Regions, Current available: oss-cn-hangzhou, oss-cn-qingdao, oss-cn-beijing, oss-cn-hongkong and oss-cn-shenzhen If change exists bucket region, will throw BucketAlreadyExistsError. If region value invalid, will throw InvalidLocationConstraintError.
  • [options] {Object} optional parameters
    • [timeout] {Number} the operation timeout

Success will return the bucket name on bucket properties.

  • bucket {String} bucket name
  • res {Object} response info, including
    • status {Number} response status
    • headers {Object} response headers
    • size {Number} response size
    • rt {Number} request total use time (ms)

example:

  • Create a bucket name helloworld location on HongKong
yield store.putBucket('helloworld', 'oss-cn-hongkong');
// use it by default
store.useBucket('helloworld', 'oss-cn-hongkong');

.deleteBucket*(name, region[, options])

Delete an empty bucket.

parameters:

  • name {String} bucket name If bucket is not empty, will throw BucketNotEmptyError. If bucket is not exists, will throw NoSuchBucketError.
  • region {String} the bucket data region location, please see Data Regions, Current available: oss-cn-hangzhou, oss-cn-qingdao, oss-cn-beijing, oss-cn-hongkong and oss-cn-shenzhen
  • [options] {Object} optional parameters
    • [timeout] {Number} the operation timeout

Success will return:

  • res {Object} response info, including
    • status {Number} response status
    • headers {Object} response headers
    • size {Number} response size
    • rt {Number} request total use time (ms)

example:

  • Delete the exists 'helloworld' bucket on 'oss-cn-hongkong'
yield store.deleteBucket('helloworld', {
  region: 'oss-cn-hongkong'
});

.useBucket(name, region)

Use the bucket.

parameters:

  • name {String} bucket name
  • region {String} the bucket data region location, please see Data Regions, Current available: oss-cn-hangzhou, oss-cn-qingdao, oss-cn-beijing, oss-cn-hongkong and oss-cn-shenzhen

example:

  • Use helloworld as the default bucket
store.useBucket('helloworld', 'oss-cn-hongkong');

.putBucketACL*(name, region, acl[, options])

Update the bucket ACL.

parameters:

  • name {String} bucket name
  • region {String} the bucket data region location, please see Data Regions, Current available: oss-cn-hangzhou, oss-cn-qingdao, oss-cn-beijing, oss-cn-hongkong and oss-cn-shenzhen
  • acl {String} access control list, current available: public-read-write, public-read and private
  • [options] {Object} optional parameters
    • [timeout] {Number} the operation timeout

Success will return:

  • res {Object} response info, including
    • status {Number} response status
    • headers {Object} response headers
    • size {Number} response size
    • rt {Number} request total use time (ms)

example:

  • Set bucket helloworld to public-read-write
yield store.putBucketACL('helloworld', 'oss-cn-hongkong', 'public-read-write');

.getBucketACL*(name, region[, options])

Get the bucket ACL.

parameters:

  • name {String} bucket name
  • region {String} the bucket data region location, please see Data Regions, Current available: oss-cn-hangzhou, oss-cn-qingdao, oss-cn-beijing, oss-cn-hongkong and oss-cn-shenzhen
  • [options] {Object} optional parameters
    • [timeout] {Number} the operation timeout

Success will return:

  • acl {String} acl settiongs string
  • res {Object} response info, including
    • status {Number} response status
    • headers {Object} response headers
    • size {Number} response size
    • rt {Number} request total use time (ms)

example:

  • Get bucket helloworld
var result = yield store.getBucketACL('helloworld', 'oss-cn-hongkong');
console.log(result.acl);

.putBucketLogging*(name, region, prefix[, options])

Update the bucket logging settings. Log file will create every one hour and name format: <prefix><bucket>-YYYY-mm-DD-HH-MM-SS-UniqueString.

parameters:

  • name {String} bucket name
  • region {String} the bucket data region location, please see Data Regions, Current available: oss-cn-hangzhou, oss-cn-qingdao, oss-cn-beijing, oss-cn-hongkong and oss-cn-shenzhen
  • [prefix] {String} prefix path name to store the log files
  • [options] {Object} optional parameters
    • [timeout] {Number} the operation timeout

Success will return:

  • res {Object} response info, including
    • status {Number} response status
    • headers {Object} response headers
    • size {Number} response size
    • rt {Number} request total use time (ms)

example:

  • Enable bucket helloworld logging and save with prefix logs/
yield store.putBucketLogging('helloworld', 'oss-cn-hongkong', 'logs/');

.getBucketLogging*(name, region[, options])

Get the bucket logging settings.

parameters:

  • name {String} bucket name
  • region {String} the bucket data region location, please see Data Regions, Current available: oss-cn-hangzhou, oss-cn-qingdao, oss-cn-beijing, oss-cn-hongkong and oss-cn-shenzhen
  • [options] {Object} optional parameters
    • [timeout] {Number} the operation timeout

Success will return:

  • enable {Boolean} enable logging or not
  • prefix {String} prefix path name to store the log files, maybe null
  • res {Object} response info, including
    • status {Number} response status
    • headers {Object} response headers
    • size {Number} response size
    • rt {Number} request total use time (ms)

example:

  • Get bucket helloworld logging settings
var result = yield store.getBucketLogging('helloworld', 'oss-cn-hongkong');
console.log(result.enable, result.prefix);

.deleteBucketLogging(name, region[, options])

Delete the bucket logging settings.

parameters:

  • name {String} bucket name
  • region {String} the bucket data region location, please see Data Regions, Current available: oss-cn-hangzhou, oss-cn-qingdao, oss-cn-beijing, oss-cn-hongkong and oss-cn-shenzhen
  • [options] {Object} optional parameters
    • [timeout] {Number} the operation timeout

Success will return:

  • res {Object} response info, including
    • status {Number} response status
    • headers {Object} response headers
    • size {Number} response size
    • rt {Number} request total use time (ms)

.putBucketWebsite*(name, region, config[, options])

Set the bucket as a static website.

parameters:

  • name {String} bucket name
  • region {String} the bucket data region location, please see Data Regions, Current available: oss-cn-hangzhou, oss-cn-qingdao, oss-cn-beijing, oss-cn-hongkong and oss-cn-shenzhen
  • config {Object} website config, contains blow properties:
    • index {String} default page, e.g.: index.html
    • [error] {String} error page, e.g.: 'error.html'
  • [options] {Object} optional parameters
    • [timeout] {Number} the operation timeout

Success will return:

  • res {Object} response info, including
    • status {Number} response status
    • headers {Object} response headers
    • size {Number} response size
    • rt {Number} request total use time (ms)

example:

yield store.putBucketWebsite('hello', 'oss-cn-hangzhou', {
  index: 'index.html'
});

.getBucketWebsite*(name, region[, options])

Get the bucket website config.

parameters:

  • name {String} bucket name
  • region {String} the bucket data region location, please see Data Regions, Current available: oss-cn-hangzhou, oss-cn-qingdao, oss-cn-beijing, oss-cn-hongkong and oss-cn-shenzhen
  • [options] {Object} optional parameters
    • [timeout] {Number} the operation timeout

Success will return:

  • index {String} index page
  • error {String} error page, maybe null
  • res {Object} response info, including
    • status {Number} response status
    • headers {Object} response headers
    • size {Number} response size
    • rt {Number} request total use time (ms)

.deleteBucketWebsite*(name, region[, options])

Delete the bucket website config.

parameters:

  • name {String} bucket name
  • region {String} the bucket data region location, please see Data Regions, Current available: oss-cn-hangzhou, oss-cn-qingdao, oss-cn-beijing, oss-cn-hongkong and oss-cn-shenzhen
  • [options] {Object} optional parameters
    • [timeout] {Number} the operation timeout

Success will return:

  • res {Object} response info, including
    • status {Number} response status
    • headers {Object} response headers
    • size {Number} response size
    • rt {Number} request total use time (ms)

.putBucketReferer*(name, region, allowEmpty, referers[, options])

Set the bucket request Referer white list.

parameters:

  • name {String} bucket name
  • region {String} the bucket data region location, please see Data Regions, Current available: oss-cn-hangzhou, oss-cn-qingdao, oss-cn-beijing, oss-cn-hongkong and oss-cn-shenzhen
  • allowEmpty {Boolean} allow empty request referer or not
  • referers {Array} Referer white list, e.g.:
    [
      'https://npm.taobao.org',
      'http://cnpmjs.org'
    ]
    
  • [options] {Object} optional parameters
    • [timeout] {Number} the operation timeout

Success will return:

  • res {Object} response info, including
    • status {Number} response status
    • headers {Object} response headers
    • size {Number} response size
    • rt {Number} request total use time (ms)

example:

yield store.putBucketReferer('hello', 'oss-cn-hangzhou', false, [
  'https://npm.taobao.org',
  'http://cnpmjs.org'
]);

.getBucketReferer*(name, region[, options])

Get the bucket request Referer white list.

parameters:

  • name {String} bucket name
  • region {String} the bucket data region location, please see Data Regions, Current available: oss-cn-hangzhou, oss-cn-qingdao, oss-cn-beijing, oss-cn-hongkong and oss-cn-shenzhen
  • [options] {Object} optional parameters
    • [timeout] {Number} the operation timeout

Success will return:

  • allowEmpty {Boolean} allow empty request referer or not
  • referers {Array} Referer white list
  • res {Object} response info, including
    • status {Number} response status
    • headers {Object} response headers
    • size {Number} response size
    • rt {Number} request total use time (ms)

.deleteBucketReferer*(name, region[, options])

Delete the bucket request Referer white list.

parameters:

  • name {String} bucket name
  • region {String} the bucket data region location, please see Data Regions, Current available: oss-cn-hangzhou, oss-cn-qingdao, oss-cn-beijing, oss-cn-hongkong and oss-cn-shenzhen
  • [options] {Object} optional parameters
    • [timeout] {Number} the operation timeout

Success will return:

  • res {Object} response info, including
    • status {Number} response status
    • headers {Object} response headers
    • size {Number} response size
    • rt {Number} request total use time (ms)

.putBucketLifecycle*(name, region, rules[, options])

Set the bucket object lifecycle.

parameters:

  • name {String} bucket name
  • region {String} the bucket data region location, please see Data Regions, Current available: oss-cn-hangzhou, oss-cn-qingdao, oss-cn-beijing, oss-cn-hongkong and oss-cn-shenzhen
  • rules {Array} rule config list, each Rule will contains blow properties:
    • [id] {String} rule id, if not set, OSS will auto create it with random string.
    • prefix {String} store prefix
    • status {String} rule status, allow values: Enabled or Disabled
    • [days] {Number|String} expire after the days
    • [date] {String} expire date, e.g.: 2022-10-11T00:00:00.000Z date and days only set one.
  • [options] {Object} optional parameters
    • [timeout] {Number} the operation timeout

Success will return:

  • res {Object} response info, including
    • status {Number} response status
    • headers {Object} response headers
    • size {Number} response size
    • rt {Number} request total use time (ms)

example:

yield store.putBucketLifecycle('hello', 'oss-cn-hangzhou', [
  {
    id: 'delete after one day',
    prefix: 'logs/',
    status: 'Enabled',
    days: 1
  },
  {
    prefix: 'logs2/',
    status: 'Disabled',
    date: '2022-10-11T00:00:00.000Z'
  }
]);

.getBucketLifecycle*(name, region[, options])

Get the bucket object lifecycle.

parameters:

  • name {String} bucket name
  • region {String} the bucket data region location, please see Data Regions, Current available: oss-cn-hangzhou, oss-cn-qingdao, oss-cn-beijing, oss-cn-hongkong and oss-cn-shenzhen
  • [options] {Object} optional parameters
    • [timeout] {Number} the operation timeout

Success will return:

  • rules {Array} the lifecycle rule list
  • res {Object} response info, including
    • status {Number} response status
    • headers {Object} response headers
    • size {Number} response size
    • rt {Number} request total use time (ms)

.deleteBucketLifecycle*(name, region[, options])

Delete the bucket object lifecycle.

parameters:

  • name {String} bucket name
  • region {String} the bucket data region location, please see Data Regions, Current available: oss-cn-hangzhou, oss-cn-qingdao, oss-cn-beijing, oss-cn-hongkong and oss-cn-shenzhen
  • [options] {Object} optional parameters
    • [timeout] {Number} the operation timeout

Success will return:

  • res {Object} response info, including
    • status {Number} response status
    • headers {Object} response headers
    • size {Number} response size
    • rt {Number} request total use time (ms)

Object Operations

All operations function is generator, except signatureUrl.

generator function format: functionName*(...).

.put*(name, file[, options])

Add an object to the bucket.

parameters:

  • name {String} object name store on OSS
  • file {String|Buffer|ReadStream} object local path, content buffer or ReadStream content instance
  • [options] {Object} optional parameters
    • [timeout] {Number} the operation timeout
    • [mime] {String} custom mime
    • [meta] {Object} user meta, will send with x-oss-meta- prefix string e.g.: { uid: 123, pid: 110 }
    • [headers] {Object} extra headers, detail see RFC 2616
      • 'Cache-Control' cache control for download, e.g.: Cache-Control: public, no-cache
      • 'Content-Disposition' object name for download, e.g.: Content-Disposition: somename
      • 'Content-Encoding' object content encoding for download, e.g.: Content-Encoding: gzip
      • 'Expires' expires time (milliseconds) for download, e.g.: Expires: 3600000

Success will return the object information.

object:

  • name {String} object name
  • res {Object} response info, including
    • status {Number} response status
    • headers {Object} response headers
    • size {Number} response size
    • rt {Number} request total use time (ms)

example:

  • Add an object through local file path
var filepath = '/home/ossdemo/demo.txt';
var object = yield store.put('ossdemo/demo.txt', filepath);
console.log(object);

{
  name: 'ossdemo/demo.txt',
  res: {
    status: 200,
    headers: {
      date: 'Tue, 17 Feb 2015 13:28:17 GMT',
      'content-length': '0',
      connection: 'close',
      etag: '"BF7A03DA01440845BC5D487B369BC168"',
      server: 'AliyunOSS',
      'x-oss-request-id': '54E341F1707AA0275E829244'
    },
    size: 0,
    rt: 92
  }
}
  • Add an object through content buffer
var object = yield store.put('ossdemo/buffer', new Buffer('foo content'));
console.log(object);

{
  name: 'ossdemo/buffer',
  url: 'http://demo.oss-cn-hangzhou.aliyuncs.com/ossdemo/buffer',
  res: {
    status: 200,
    headers: {
      date: 'Tue, 17 Feb 2015 13:28:17 GMT',
      'content-length': '0',
      connection: 'close',
      etag: '"xxx"',
      server: 'AliyunOSS',
      'x-oss-request-id': '54E341F1707AA0275E829243'
    },
    size: 0,
    rt: 92
  }
}
  • Add an object through readstream
var filepath = '/home/ossdemo/demo.txt';
var object = yield store.put('ossdemo/readstream.txt', fs.createReadStream(filepath));
console.log(object);

{
  name: 'ossdemo/readstream.txt',
  url: 'http://demo.oss-cn-hangzhou.aliyuncs.com/ossdemo/readstream.txt',
  res: {
    status: 200,
    headers: {
      date: 'Tue, 17 Feb 2015 13:28:17 GMT',
      'content-length': '0',
      connection: 'close',
      etag: '"BF7A03DA01440845BC5D487B369BC168"',
      server: 'AliyunOSS',
      'x-oss-request-id': '54E341F1707AA0275E829242'
    },
    size: 0,
    rt: 92
  }
}

.putStream*(name, stream[, options])

Add a stream object to the bucket.

parameters:

  • name {String} object name store on OSS
  • stream {ReadStream} object ReadStream content instance
  • [options] {Object} optional parameters
    • [timeout] {Number} the operation timeout
    • [mime] {String} custom mime
    • [meta] {Object} user meta, will send with x-oss-meta- prefix string e.g.: { uid: 123, pid: 110 }
    • [headers] {Object} extra headers, detail see RFC 2616
      • 'Cache-Control' cache control for download, e.g.: Cache-Control: public, no-cache
      • 'Content-Disposition' object name for download, e.g.: Content-Disposition: somename
      • 'Content-Encoding' object content encoding for download, e.g.: Content-Encoding: gzip
      • 'Expires' expires time (milliseconds) for download, e.g.: Expires: 3600000

Success will return the object information.

object:

  • name {String} object name
  • res {Object} response info, including
    • status {Number} response status
    • headers {Object} response headers
    • size {Number} response size
    • rt {Number} request total use time (ms)

example:

  • Add an object through readstream
var filepath = '/home/ossdemo/demo.txt';
var object = yield store.put('ossdemo/readstream.txt', fs.createReadStream(filepath));
console.log(object);

{
  name: 'ossdemo/readstream.txt',
  url: 'http://demo.oss-cn-hangzhou.aliyuncs.com/ossdemo/readstream.txt',
  res: {
    status: 200,
    headers: {
      date: 'Tue, 17 Feb 2015 13:28:17 GMT',
      'content-length': '0',
      connection: 'close',
      etag: '"BF7A03DA01440845BC5D487B369BC168"',
      server: 'AliyunOSS',
      'x-oss-request-id': '54E341F1707AA0275E829242'
    },
    size: 0,
    rt: 92
  }
}

.head*(name[, options])

Head an object and get the meta info.

parameters:

  • name {String} object name store on OSS
  • [options] {Object} optional parameters
    • [timeout] {Number} the operation timeout
    • [headers] {Object} extra headers, detail see RFC 2616
      • 'If-Modified-Since' object modified after this time will return 200 and object meta, otherwise return 304 not modified
      • 'If-Unmodified-Since' object modified before this time will return 200 and object meta, otherwise throw PreconditionFailedError
      • 'If-Match' object etag equal this will return 200 and object meta, otherwise throw PreconditionFailedError
      • 'If-None-Match' object etag not equal this will return 200 and object meta, otherwise return 304 not modified

Success will return the object's meta information.

object:

  • status {Number} response status, maybe 200 or 304
  • meta {Object} object user meta, if not set on put(), will return null. If return status 304, meta will be null too
  • res {Object} response info, including
    • status {Number} response status
    • headers {Object} response headers
    • size {Number} response size
    • rt {Number} request total use time (ms)

example:

  • Head an exists object and get user meta
yield this.store.put('ossdemo/head-meta', new Buffer('foo'), {
  meta: {
    uid: 1,
    path: 'foo/demo.txt'
  }
});
var object = this.store.head('ossdemo/head-meta');
console.log(object);

{
  status: 200,
  meta: {
    uid: '1',
    path: 'foo/demo.txt'
  },
  res: { ... }
}
  • Head a not exists object
var object = this.store.head('ossdemo/head-meta');
// will throw NoSuchKeyError

.get*(name, file[, options])

Get an object from the bucket.

parameters:

  • name {String} object name store on OSS
  • [file] {String|WriteStream} file path or WriteStream instance to store the content If file is null or ignore this parameter, function will return info contains content property.
  • [options] {Object} optional parameters
    • [timeout] {Number} the operation timeout
    • [headers] {Object} extra headers, detail see RFC 2616
      • 'Range' get specifying range bytes content, e.g.: Range: bytes=0-9
      • 'If-Modified-Since' object modified after this time will return 200 and object meta, otherwise return 304 not modified
      • 'If-Unmodified-Since' object modified before this time will return 200 and object meta, otherwise throw PreconditionFailedError
      • 'If-Match' object etag equal this will return 200 and object meta, otherwise throw PreconditionFailedError
      • 'If-None-Match' object etag not equal this will return 200 and object meta, otherwise return 304 not modified

Success will return the info contains response.

object:

  • [content] {Buffer} file content buffer if file parameter is null or ignore
  • res {Object} response info, including
    • status {Number} response status
    • headers {Object} response headers
    • size {Number} response size
    • rt {Number} request total use time (ms)

If object not exists, will throw NoSuchKeyError.

example:

  • Get an exists object and store it to the local file
var filepath = '/home/ossdemo/demo.txt';
yield store.get('ossdemo/demo.txt', filepath);

_ Store object to a writestream

yield store.get('ossdemo/demo.txt', somestream);
  • Get an object content buffer
var result = yield store.get('ossdemo/demo.txt');
console.log(Buffer.isBuffer(result.content));
  • Get a not exists object
var filepath = '/home/ossdemo/demo.txt';
yield store.get('ossdemo/not-exists-demo.txt', filepath);
// will throw NoSuchKeyError

.getStream*(name[, options])

Get an object read stream.

parameters:

  • name {String} object name store on OSS
  • [options] {Object} optional parameters
    • [timeout] {Number} the operation timeout
    • [headers] {Object} extra headers
      • 'If-Modified-Since' object modified after this time will return 200 and object meta, otherwise return 304 not modified
      • 'If-Unmodified-Since' object modified before this time will return 200 and object meta, otherwise throw PreconditionFailedError
      • 'If-Match' object etag equal this will return 200 and object meta, otherwise throw PreconditionFailedError
      • 'If-None-Match' object etag not equal this will return 200 and object meta, otherwise return 304 not modified

Success will return the stream instance and response info.

object:

  • stream {ReadStream} readable stream instance if response status is not 200, stream will be null.
  • res {Object} response info, including
    • status {Number} response status
    • headers {Object} response headers
    • size {Number} response size
    • rt {Number} request total use time (ms)

If object not exists, will throw NoSuchKeyError.

example:

  • Get an exists object stream
var result = yield store.getStream('ossdemo/demo.txt');
result.stream.pipe(fs.createWriteStream('some file.txt'));

.delete*(name[, options])

Delete an object from the bucket.

parameters:

  • name {String} object name store on OSS
  • [options] {Object} optional parameters
    • [timeout] {Number} the operation timeout

Success will return the info contains response.

object:

  • res {Object} response info, including
    • status {Number} response status
    • headers {Object} response headers
    • size {Number} response size
    • rt {Number} request total use time (ms)

If delete object not exists, will also delete success.

example:

  • Delete an exists object
yield store.delete('ossdemo/someobject');
  • Delete a not exists object
yield store.delete('ossdemo/some-not-exists-object');

.copy*(name, sourceName[, options])

Copy an object from sourceName to name.

parameters:

  • name {String} object name store on OSS
  • sourceName {String} source object name If sourceName start with /, meaning it's a full name contains the bucket name. e.g.: /otherbucket/logo.png meaning copy otherbucket logn.png object to current bucket.
  • [options] {Object} optional parameters
    • [timeout] {Number} the operation timeout
    • [meta] {Object} user meta, will send with x-oss-meta- prefix string e.g.: { uid: 123, pid: 110 } If the meta set, will override the source object meta.
    • [headers] {Object} extra headers
      • 'If-Match' do copy if source object etag equal this, otherwise throw PreconditionFailedError
      • 'If-None-Match' do copy if source object etag not equal this, otherwise throw PreconditionFailedError
      • 'If-Modified-Since' do copy if source object modified after this time, otherwise throw PreconditionFailedError
      • 'If-Unmodified-Since' do copy if source object modified before this time, otherwise throw PreconditionFailedError

Success will return the copy result in data property.

object:

  • data {Object} copy result
    • lastModified {String} object last modified GMT string
    • etag {String} object etag contains ", e.g.: "5B3C1A2E053D763E1B002CC607C5A0FE"
  • res {Object} response info, including
    • status {Number} response status
    • headers {Object} response headers
    • size {Number} response size
    • rt {Number} request total use time (ms)

If source object not exists, will throw NoSuchKeyError.

example:

  • Copy same bucket object
var result = yield store.copy('newName', 'oldName');
  • Copy other bucket object
var result = yield store.copy('logo.png', '/other-bucket/logo.png');

.putMeta*(name, meta[, options])

Set an exists object meta.

parameters:

  • name {String} object name store on OSS
  • meta {Object} user meta, will send with x-oss-meta- prefix string e.g.: { uid: 123, pid: 110 } If meta: null, will clean up the exists meta
  • [options] {Object} optional parameters
    • [timeout] {Number} the operation timeout

Success will return the copy result in data property.

  • data {Object} copy result
    • lastModified {String} object last modified GMT date, e.g.: 2015-02-19T08:39:44.000Z
    • etag {String} object etag contains ", e.g.: "5B3C1A2E053D763E1B002CC607C5A0FE"
  • res {Object} response info, including
    • status {Number} response status
    • headers {Object} response headers
    • size {Number} response size
    • rt {Number} request total use time (ms)

If object not exists, will throw NoSuchKeyError.

example:

  • Update exists object meta
var result = yield store.putMeta('ossdemo.txt', {
  uid: 1, pid: 'p123'
});
console.log(result);
  • Clean up object meta
yield store.putMeta('ossdemo.txt', null);

.deleteMulti*(names[, options])

Delete multi objects in one request.

parameters:

  • names {Array} object names, max 1000 objects in once.
  • [options] {Object} optional parameters
    • [quiet] {Boolean} quiet mode or verbose mode, default is false, verbose mode quiet mode: if all objects delete succes, return emtpy response. otherwise return delete error object results. verbose mode: return all object delete results.
    • [timeout] {Number} the operation timeout

Success will return delete success objects in deleted property.

  • [deleted] {Array} deleted object names list
  • res {Object} response info, including
    • status {Number} response status
    • headers {Object} response headers
    • size {Number} response size
    • rt {Number} request total use time (ms)

example:

  • Delete multi objects in quiet mode
var result = yield store.deleteMulti(['obj1', 'obj2', 'obj3'], {
  quiet: true
});
  • Delete multi objects in verbose mode
var result = yield store.deleteMulti(['obj1', 'obj2', 'obj3']);

.list*(query[, options])

List objects in the bucket.

parameters:

  • [query] {Object} query parameters, default is null
    • [prefix] {String} search object using prefix key
    • [marker] {String} search start from marker, including marker key
    • [delimiter] {String} delimiter search scope e.g. / only search current dir, not including subdir
    • [max-keys] {String|Number} max objects, default is 100, limit to 1000
  • [options] {Object} optional parameters
    • [timeout] {Number} the operation timeout

Success will return objects list on objects properties.

  • objects {Array} object meta info list Each ObjectMeta will contains blow properties:
    • name {String} object name on oss
    • lastModified {String} object last modified GMT date, e.g.: 2015-02-19T08:39:44.000Z
    • etag {String} object etag contains ", e.g.: "5B3C1A2E053D763E1B002CC607C5A0FE"
    • type {String} object type, e.g.: Normal
    • size {Number} object size, e.g.: 344606
    • storageClass {String} storage class type, e.g.: Standard
    • owner {Object} object owner, including id and displayName
  • prefixes {Array} prefix list
  • isTruncated {Boolean} truncate or not
  • nextMarker {String} next marker string
  • res {Object} response info, including
    • status {Number} response status
    • headers {Object} response headers
    • size {Number} response size
    • rt {Number} request total use time (ms)

example:

  • List top 10 objects
var result = yield store.list();
console.log(result.objects);
  • List fun/ dir including subdirs objects
var result = yield store.list({
  perfix: 'fun/'
});
console.log(result.objects);
  • List fun/ dir objects, not including subdirs
var result = yield store.list({
  perfix: 'fun/',
  delimiter: '/'
});
console.log(result.objects);

.signatureUrl(name)

Create a signature url for directly download.

parameters:

  • name {String} object name store on OSS
  • [options] {Object} optional parameters
    • [expires] {Number} after expires seconds, the url will become invalid, default is 1800
    • [timeout] {Number} the operation timeout

Success will return signature url.

example:

  • Get an object signature url for download
var url = store.signatureUrl('ossdemo.txt');
console.log(url);

Create A Image Service Instance

Each Image Service instance required accessKeyId, accessKeySecret, bucket and imageHost.

oss.ImageClient(options)

Create a Image service instance.

options:

  • imageHost {String} your image service domain that binding to a OSS bucket
  • accessKeyId {String} access key you create on aliyun console website
  • accessKeySecret {String} access secret you create
  • bucket {String} the default bucket you want to access If you don't have any bucket, please use putBucket() create one first.
  • [region] {String} the bucket data region location, please see Data Regions, default is oss-cn-hangzhou Current available: oss-cn-hangzhou, oss-cn-qingdao, oss-cn-beijing, oss-cn-hongkong and oss-cn-shenzhen
  • [internal] {Boolean} access OSS with aliyun internal network or not, default is false If your servers are running on aliyun too, you can set true to save lot of money.
  • [timeout] {String|Number} instance level timeout for all operations, default is 60s

example:

var oss = require('ali-oss');

var imgClient = oss.ImageClient({
  accessKeyId: 'your access key',
  accessKeySecret: 'your access secret',
  bucket: 'my_image_bucket'
  imageHost: 'thumbnail.myimageservice.com'
});

Image Operations

All operations function is generator, except imgClient.signatureUrl.

generator function format: functionName*(...).

imgClient.get*(name, file[, options])

Get an image from the image channel.

parameters:

  • name {String} image object name with operation style store on OSS
  • [file] {String|WriteStream} file path or WriteStream instance to store the image If file is null or ignore this parameter, function will return info contains content property.
  • [options] {Object} optional parameters
    • [timeout] {Number} the operation timeout
    • [headers] {Object} extra headers, detail see RFC 2616
      • 'If-Modified-Since' object modified after this time will return 200 and object meta, otherwise return 304 not modified
      • 'If-Unmodified-Since' object modified before this time will return 200 and object meta, otherwise throw PreconditionFailedError
      • 'If-Match' object etag equal this will return 200 and object meta, otherwise throw PreconditionFailedError
      • 'If-None-Match' object etag not equal this will return 200 and object meta, otherwise return 304 not modified

Success will return the info contains response.

object:

  • [content] {Buffer} file content buffer if file parameter is null or ignore
  • res {Object} response info, including
    • status {Number} response status
    • headers {Object} response headers
    • size {Number} response size
    • rt {Number} request total use time (ms)

If object not exists, will throw NoSuchKeyError.

example:

  • Get an exists image with a style and store it to the local file
var imagepath = '/home/ossdemo/demo.jpg';
yield imgClient.get('ossdemo/demo.jpg@200w_200h', filepath);

_ Store image to a writestream

yield imgClient.get('ossdemo/demo.jpg@200w_200h', somestream);
  • Get an image content buffer
var result = yield imgClient.get('ossdemo/demo.jpg@200w_200h');
console.log(Buffer.isBuffer(result.content));
  • Get a not exists object or a not image object
var imagepath = '/home/ossdemo/demo.jpg';
yield imgClient.get('ossdemo/not-exists-demo.jpg@200w_200h', filepath);
// will throw NoSuchKeyError

imgClient.getStream*(name[, options])

Get an image read stream.

parameters:

  • name {String} image object name with operation style store on OSS
  • [options] {Object} optional parameters
    • [timeout] {Number} the operation timeout
    • [headers] {Object} extra headers
      • 'If-Modified-Since' object modified after this time will return 200 and object meta, otherwise return 304 not modified
      • 'If-Unmodified-Since' object modified before this time will return 200 and object meta, otherwise throw PreconditionFailedError
      • 'If-Match' object etag equal this will return 200 and object meta, otherwise throw PreconditionFailedError
      • 'If-None-Match' object etag not equal this will return 200 and object meta, otherwise return 304 not modified

Success will return the stream instance and response info.

object:

  • stream {ReadStream} readable stream instance if response status is not 200, stream will be null.
  • res {Object} response info, including
    • status {Number} response status
    • headers {Object} response headers
    • size {Number} response size
    • rt {Number} request total use time (ms)

If object not exists, will throw NoSuchKeyError.

example:

  • Get an exists image object stream
var result = yield imgClient.getStream('ossdemo/demo.jpg@200w_200h');
result.stream.pipe(fs.createWriteStream('some demo.jpg'));

imgClient.getExif*(name[, options])

Get a image exif info by image object name from the image channel.

parameters:

  • name {String} image object name
  • [options] {Object} optional parameters
    • [timeout] {Number} the operation timeout

Success will return the info contains response.

object:

  • res {Object} response info, including
    • status {Number} response status
    • headers {Object} response headers
    • size {Number} response size
    • rt {Number} request total use time (ms)
  • data {Object} image exif object

If object don't have exif, will throw 400 BadRequest.

example:

var result = yield imgClient.getExif('demo.jpg');
// resut:
// {
//   res: {
//     status: 200,
//     statusCode: 200,
//     headers: {
//       server: "Tengine",
//       content - type: "application/json",
//       content - length: "148",
//       connection: "keep-alive",
//       date: "Tue, 31 Mar 2015 11:06:32 GMT",
//       "last-modified": "Mon, 30 Mar 2015 10:46:35 GMT"
//     },
//     size: 148,
//     aborted: false,
//     rt: 461,
//     keepAliveSocket: false
//   },
//   data: {
//     FileSize: 343683,
//     ImageHeight: 1200,
//     ImageWidth: 1600,
//     Orientation: 1
//   }
// }

imgClient.getInfo*(name[, options])

Get a image info and exif info by image object name from the image channel.

parameters:

  • name {String} image object name
  • [options] {Object} optional parameters
    • [timeout] {Number} the operation timeout

Success will return the info contains response.

object:

  • res {Object} response info, including
    • status {Number} response status
    • headers {Object} response headers
    • size {Number} response size
    • rt {Number} request total use time (ms)
  • data {Object} image exif object

example:

var result = yield imgClient.getInfo('demo.jpg');
// resut:
// {
//   res: {
//     status: 200,
//     statusCode: 200,
//     headers: {
//       server: "Tengine",
//       content - type: "application/json",
//       content - length: "148",
//       connection: "keep-alive",
//       date: "Tue, 31 Mar 2015 11:06:32 GMT",
//       "last-modified": "Mon, 30 Mar 2015 10:46:35 GMT"
//     },
//     size: 148,
//     aborted: false,
//     rt: 461,
//     keepAliveSocket: false
//   },
//   data: {
//     FileSize: 343683,
//     Format: "jpg",
//     ImageHeight: 1200,
//     ImageWidth: 1600,
//     Orientation: 1
//   }
// }

imgClient.putStyle*(name, style[, options])

// TODO

imgClient.getStyle*(name[, options])

Get a style by name from the image channel.

parameters:

  • name {String} image style name
  • [options] {Object} optional parameters
    • [timeout] {Number} the operation timeout

Success will return the info contains response.

object:

  • res {Object} response info, including
    • status {Number} response status
    • headers {Object} response headers
    • size {Number} response size
    • rt {Number} request total use time (ms)
  • data {Object} styles object
    • Name {String} style name
    • Content {String} style content
    • CreateTime {String} style create time
    • LastModifyTime {String} style last modify time

example:

var result = yield imgClient.getStyle('400');
// resut:
// {
//   res: {
//     status: 200,
//     statusCode: 200,
//     headers: {
//       server: "Tengine",
//       content - type: "application/xml",
//       content - length: "234",
//       connection: "keep-alive",
//       date: "Tue, 31 Mar 2015 10:58:20 GMT"
//     },
//     size: 234,
//     aborted: false,
//     rt: 398,
//     keepAliveSocket: false
//   },
//   data: {
//     Name: "400",
//     Content: "400w_90Q_1x.jpg",
//     CreateTime: "Thu, 19 Mar 2015 08:34:21 GMT",
//     LastModifyTime: "Thu, 19 Mar 2015 08:34:21 GMT"
//   }
// }

imgClient.listStyle*([options])

Get all styles from the image channel.

parameters:

  • [options] {Object} optional parameters
    • [timeout] {Number} the operation timeout

Success will return the info contains response.

object:

  • res {Object} response info, including
    • status {Number} response status
    • headers {Object} response headers
    • size {Number} response size
    • rt {Number} request total use time (ms)
  • data {Array} styles array, a style object:
    • Name {String} style name
    • Content {String} style content
    • CreateTime {String} style create time
    • LastModifyTime {String} style last modify time

example:

var result = yield imgClient.listStyle();
// resut:
// {
//   res: {
//     status: 200,
//     statusCode: 200,
//     headers: {
//       server: "Tengine",
//       content - type: "application/xml",
//       content - length: "913",
//       connection: "keep-alive",
//       date: "Tue, 31 Mar 2015 10:47:32 GMT"
//     },
//     size: 913,
//     aborted: false,
//     rt: 1911,
//     keepAliveSocket: false
//   },
//   data: [{
//     Name: "200-200",
//     Content: "0e_200w_200h_0c_0i_0o_90Q_1x.jpg",
//     CreateTime: "Thu, 19 Mar 2015 08:28:08 GMT",
//     LastModifyTime: "Thu, 19 Mar 2015 08:28:08 GMT"
//   }, {
//     Name: "800",
//     Content: "800w_90Q_1x.jpg",
//     CreateTime: "Thu, 19 Mar 2015 08:29:15 GMT",
//     LastModifyTime: "Thu, 19 Mar 2015 08:29:15 GMT"
//   }, {
//     Name: "400",
//     Content: "400w_90Q_1x.jpg",
//     CreateTime: "Thu, 19 Mar 2015 08:34:21 GMT",
//     LastModifyTime: "Thu, 19 Mar 2015 08:34:21 GMT"
//   }, {
//     Name: "600",
//     Content: "600w_90Q_1x.jpg",
//     CreateTime: "Thu, 19 Mar 2015 08:35:02 GMT",
//     LastModifyTime: "Thu, 19 Mar 2015 08:35:02 GMT"
//   }]
// }

imgClient.deleteStyle*(name[, options])

// TODO

imgClient.signatureUrl(name)

Create a signature url for directly download.

parameters:

  • name {String} image object name with operation style store on OSS
  • [options] {Object} optional parameters
    • [expires] {Number} after expires seconds, the url will become invalid, default is 1800
    • [timeout] {Number} the operation timeout

Success will return full signature url.

example:

var url = imgClient.signatureUrl('
');
// http://thumbnail.myimageservice.com/demo.jpg@200w_200h?OSSAccessKeyId=uZxyLARzYZtGwHKY&Expires=1427803849&Signature=JSPRe06%2FjQpQSj5zlx2ld1V%2B35I%3D

Cluster Mode

Cluster mode now only support object operations.

var Cluster = require('ali-oss').ClusterClient;

var client = Cluster({
  cluster: [{
    host: 'host1',
    accessKeyId: 'id1',
    accessKeySecret: 'secret1'
  }, {
    host: 'host2',
    accessKeyId: 'id2',
    accessKeySecret: 'secret2'
  }],
  schedule: 'masterSlave', //default is `roundRobin`
});

// listen error event to logging error
client.on('error', function(err) {
  console.error(err.stack);
});

// client init ready
client.ready(function() {
  console.log('cluster client init ready, go ahead!');
});

Get Methods

Will choose an alive client by schedule(masterSlave or roundRobin).

  • client.get()
  • client.head()
  • client.getStream()
  • client.list()
  • client.signatureUrl()
  • client.chooseAvailable() - choose an available client by schedule.

Put Methods

Will put to all clients.

  • client.put()
  • client.putStream()
  • client.delete()
  • client.deleteMulti()
  • client.copy()
  • client.putMeta()

Browser Usage

You can use most of the functionalities of ali-oss in browser with some exceptions:

  • put object with streaming: no chunked encoding, we use multipart upload instead
  • get object to local file: we cannot manipulate file system in browser, we provide signed object url for downloading needs
  • bucket operations(listBuckets, putBucketLogging, etc) will fail: OSS server currently do not support CORS requests for bucket operations (will probably be fixed later)

Compatibility

  • IE >= 10 & Edge
  • Major versions of Chrome/Firefox/Safari
  • Major versions of Android/iOS/WP

Setup

Bucket setup

As browser-side javascript involves CORS operations. You need to setup your bucket CORS rules to allow CORS operations:

  • include your domain in allowed origins
  • include your HTTP methods in allowed methods
  • include 'x-oss-date' and 'Authorization' in allowed headers
  • expose 'ETag' in expose headers
STS setup

As we don't want to expose the accessKeyId/accessKeySecret in the browser, a common practice is to use STS to grant temporary access.

Basic usage

Include the sdk lib in the <script> tag and wrap your application logic in upload.js:

<script type="javascript" src="https://gosspublic.alicdn.com/aliyun-oss-sdk.min.js"></script>
<script type="javascript" src="upload.js"></script>

In upload.js we have:

var applyToken = function* () {
  var url = appServer;
  var result = yield OSS.urllib.requestThunk(url, {
    method: 'GET'
  });
  return JSON.parse(result.data);
};

var progress = function* (p) {
  var bar = document.getElementById('progress-bar');
  bar.style.width = Math.floor(p * 100) + '%';
  bar.innerHTML = Math.floor(p * 100) + '%';
};

var withStore = function (func) {
  return function () {
    OSS.co(function* () {
      var creds = yield applyToken();
      var store = new OSS({
        region: region,
        accessKeyId: creds.AccessKeyId,
        accessKeySecret: creds.AccessKeySecret,
        stsToken: creds.Security,
        bucket: bucket
      });

      var result = yield func(store);

      console.log(result);
    }).then(function () {
      // pass
    }).catch(function (err) {
      console.log(err);
    });
  };
};

var uploadFile = function* (store) {
  var file = document.getElementById('file').files[0];
  var key = document.getElementById('object-key-file').value.trim() || 'object';
  console.log(file.name + ' => ' + key);

  var result = yield store.multipartUpload(key, file, {progress: progress});
  yield listFiles(store);

  return result;
};

window.onload = function () {
  document.getElementById('file-button').onclick = withStore(uploadFile);
};

The full sample can be found here.

How to build

To build your own lib for browser usage, we need browserify. To be accepted by most browsers we need babel:

npm install -g browserify
npm install --save-dev babelify
npm install babel-preset-es2015 --save-dev
echo '{ "presets": ["es2015"] }' > .babelrc
browserify browser.js -t babelify -s OSS > aliyun-oss-sdk.js

Optionally, you may want to minimumize the script size:

npm install -g uglify-js
uglifyjs aliyun-oss-sdk.js -c > aliyun-oss-sdk.min.js

Known Errors

Each error return by OSS server will contains these properties:

  • name {String} error name
  • message {String} error message
  • requestId {String} uuid for this request, if you meet some unhandled problem, you can send this request id to OSS engineer to find out what's happend.
  • hostId {String} OSS cluster name for this request
namestatusmessagemessage in Chinese
AccessDeniedError403Access Denied拒绝访问
BucketAlreadyExistsError409Bucket already existsBucket 已经存在
BucketNotEmptyError409Bucket is not emptyBucket 不为空
EntityTooLargeError400Entity too large实体过大
EntityTooSmallError400Entity too small实体过小
FileGroupTooLargeError400File group too large文件组过大
InvalidLinkNameError400Link name can't be the same as the object nameObject Link 与指向的 Object 同名
LinkPartNotExistError400Can't link to not exists objectObject Link 中指向的 Object 不存在
ObjectLinkTooLargeError400Too many links to this objectObject Link 中 Object 个数过多
FieldItemTooLongError400Post form fields items too largePost 请求中表单域过大
FilePartInterityError400File part has changed文件 Part 已改变
FilePartNotExistError400File part not exists文件 Part 不存在
FilePartStaleError400File part stale文件 Part 过时
IncorrectNumberOfFilesInPOSTRequestError400Post request contains invalid number of filesPost 请求中文件个数非法
InvalidArgumentError400Invalid format argument参数格式错误
InvalidAccessKeyIdError400Access key id not existsAccess Key ID 不存在
InvalidBucketNameError400Invalid bucket name无效的 Bucket 名字
InvalidDigestError400Invalid digest无效的摘要
InvalidEncryptionAlgorithmError400Invalid encryption algorithm指定的熵编码加密算法错误
InvalidObjectNameError400Invalid object name无效的 Object 名字
InvalidPartError400Invalid part无效的 Part
InvalidPartOrderError400Invalid part order无效的 part 顺序
InvalidPolicyDocumentError400Invalid policy document无效的 Policy 文档
InvalidTargetBucketForLoggingError400Invalid bucket on logging operationLogging 操作中有无效的目标 bucket
InternalError500OSS server internal errorOSS 内部发生错误
MalformedXMLError400Malformed XML formatXML 格式非法
MalformedPOSTRequestError400Invalid post body formatPost 请求的 body 格式非法
MaxPOSTPreDataLengthExceededError400Post extra data too largePost 请求上传文件内容之外的 body 过大
MethodNotAllowedError405Not allowed method不支持的方法
MissingArgumentError411Missing argument缺少参数
MissingContentLengthError411Missing Content-Length header缺少内容长度
NoSuchBucketError404Bucket not existsBucket 不存在
NoSuchKeyError404Object not exists文件不存在
NoSuchUploadError404Multipart upload id not existsMultipart Upload ID 不存在
NotImplementedError501Not implemented无法处理的方法
PreconditionFailedError412Pre condition failed预处理错误
RequestTimeTooSkewedError403Request time exceeds 15 minutes to server time发起请求的时间和服务器时间超出 15 分钟
RequestTimeoutError400Request timeout请求超时
RequestIsNotMultiPartContentError400Invalid post content-typePost 请求 content-type 非法
SignatureDoesNotMatchError403Invalid signature签名错误
TooManyBucketsError400Too many buckets on this user用户的 Bucket 数目超过限制

Keywords

FAQs

Package last updated on 27 Jan 2016

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts

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