Socket
Socket
Sign inDemoInstall

qiniu

Package Overview
Dependencies
118
Maintainers
2
Versions
60
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 7.8.0 to 7.9.0

qiniu/httpc/client.js

10

CHANGELOG.md
## CHANGE LOG
## 7.9.0
- 对象存储,修复无法对 key 为空字符串的对象进行操作
- 对象存储,查询区域域名支持配置 UC 地址
- 对象存储,查询区域域名接口升级
- 对象存储,更新设置镜像源的域名
- 对象存储,新增请求中间件逻辑,方便拓展请求逻辑
- 对象存储,新增备用 UC 域名用于查询区域域名
- 对象存储,移除首尔区域
- 对象存储,新增 华东浙江2 区域的类型声明
## 7.8.0

@@ -3,0 +13,0 @@ - 移除不推荐域名,并增加 亚太-首尔 和 华东-浙江2 固定区域

166

index.d.ts

@@ -6,3 +6,6 @@ /**

*/
import { Callback } from 'urllib';
import { Callback, RequestOptions } from 'urllib';
import { Agent as HttpAgent, IncomingMessage} from 'http';
import { Agent as HttpsAgent } from 'https';
import { Readable } from "stream";

@@ -421,2 +424,146 @@ export declare type callback = (e?: Error, respBody?: any, respInfo?: any) => void;

export declare namespace httpc {
interface ReqOpts<T = any> {
agent?: HttpAgent;
httpsAgent?: HttpsAgent;
url: string;
middlewares: middleware.Middleware[];
callback?: Callback<T>;
urllibOptions: RequestOptions;
}
interface RespWrapperOptions<T = any> {
data: T;
resp: IncomingMessage;
}
class RespWrapper<T = any> {
data: T;
resp: IncomingMessage;
constructor(options: RespWrapperOptions);
ok(): boolean;
needRetry(): boolean;
}
namespace middleware {
interface Middleware {
send<T>(
request: ReqOpts<T>,
next: (reqOpts: ReqOpts<T>) => Promise<RespWrapper<T>>
): Promise<RespWrapper<T>>;
}
/**
* 组合中间件为一个调用函数
* @param middlewares 中间件列表
* @param handler 请求函数
*/
function composeMiddlewares<T>(
middlewares: Middleware[],
handler: (reqOpts: ReqOpts<T>) => Promise<RespWrapper<T>>
);
/**
* 设置 User-Agent 请求头中间件
*/
class UserAgentMiddleware implements Middleware {
constructor(sdkVersion: string);
send<T>(
request: httpc.ReqOpts<T>,
next: (reqOpts: httpc.ReqOpts<T>) => Promise<httpc.RespWrapper<T>>
): Promise<httpc.RespWrapper<T>>;
}
interface RetryDomainsMiddlewareOptions {
backupDomains: string[];
maxRetryTimes: number;
retryCondition: () => boolean;
}
class RetryDomainsMiddleware implements Middleware {
/**
* 备用域名
*/
backupDomains: string[];
/**
* 最大重试次数,包括首次请求
*/
maxRetryTimes: number;
/**
* 是否可以重试,可以通过该函数配置更详细的重试规则
*/
retryCondition: () => boolean;
/**
* 已经重试的次数
* @private
*/
private _retriedTimes: number;
/**
* 实例化重试域名中间件
* @param retryDomainsOptions
*/
constructor(retryDomainsOptions: RetryDomainsMiddlewareOptions)
/**
* 重试域名中间件逻辑
* @param request
* @param next
*/
send<T>(
request: httpc.ReqOpts<T>,
next: (reqOpts: httpc.ReqOpts<T>) => Promise<httpc.RespWrapper<T>>
): Promise<httpc.RespWrapper<T>>;
/**
* 控制重试逻辑,主要为 {@link retryCondition} 服务。若没有设置 retryCondition,默认 2xx 才会终止重试
* @param err
* @param respWrapper
* @param reqOpts
* @private
*/
private _shouldRetry<T>(
err: Error | null,
respWrapper: RespWrapper<T>,
reqOpts: ReqOpts<T>
): boolean;
}
}
interface HttpClientOptions {
httpAgent?: HttpAgent;
httpsAgent?: HttpsAgent;
middlewares?: middleware.Middleware[];
}
interface GetOptions<T = any> extends ReqOpts<T> {
params: Record<string, string>;
headers: Record<string, string>;
}
interface PostOptions<T = any> extends ReqOpts<T> {
data: string | Buffer | Readable;
headers: Record<string, string>;
}
interface PutOptions<T = any> extends ReqOpts<T> {
data: string | Buffer | Readable;
headers: Record<string, string>
}
class HttpClient {
httpAgent: HttpAgent;
httpsAgent: HttpsAgent;
middlewares: middleware.Middleware[];
constructor(options: HttpClientOptions)
sendRequest(requestOptions: ReqOpts): Promise<RespWrapper>
get(getOptions: GetOptions): Promise<RespWrapper>
post(postOptions: PostOptions): Promise<RespWrapper>
put(putOptions: PutOptions): Promise<RespWrapper>
}
}
export declare namespace rpc {

@@ -433,2 +580,4 @@ type Headers = Record<string, string> & {

const qnHttpClient: httpc.HttpClient;
/**

@@ -513,2 +662,4 @@ *

const Zone_z0: conf.Zone;
//huadong2
const Zone_cn_east_2: conf.Zone;
//huabei

@@ -782,3 +933,3 @@ const Zone_z1: conf.Zone;

* @param options 列举操作的可选参数
* @param callback
* @param callback 回调函数
*/

@@ -788,2 +939,13 @@ listPrefix(bucket: string, options: ListPrefixOptions | null, callback: callback): void;

/**
* 获取制定前缀的文件列表 V2
*
* @deprecated API 可能返回仅包含 marker,不包含 item 或 dir 的项,请使用 {@link listPrefix}
*
* @param bucket 空间名称
* @param options 列举操作的可选参数
* @param callback 回调函数
*/
listPrefixV2(bucket: string, options: ListPrefixOptions | null, callback: callback): void;
/**
* 批量文件管理请求,支持stat,chgm,chtype,delete,copy,move

@@ -790,0 +952,0 @@ * @param operations

@@ -11,2 +11,7 @@ module.exports = {

conf: require('./qiniu/conf.js'),
httpc: {
middleware: require('./qiniu/httpc/middleware'),
HttpClient: require('./qiniu/httpc/client').HttpClient,
ResponseWrapper: require('./qiniu/httpc/responseWrapper').ResponseWrapper
},
rpc: require('./qiniu/rpc.js'),

@@ -13,0 +18,0 @@ util: require('./qiniu/util.js'),

2

package.json
{
"name": "qiniu",
"version": "7.8.0",
"version": "7.9.0",
"description": "Node wrapper for Qiniu Resource (Cloud) Storage API",

@@ -5,0 +5,0 @@ "main": "index.js",

@@ -21,3 +21,29 @@ const os = require('os');

exports.RPC_TIMEOUT = 600000; // 600s
exports.UC_HOST = 'uc.qbox.me';
let QUERY_REGION_BACKUP_HOSTS = [
'uc.qbox.me',
'api.qiniu.com'
];
Object.defineProperty(exports, 'QUERY_REGION_BACKUP_HOSTS', {
get: () => QUERY_REGION_BACKUP_HOSTS,
set: v => {
QUERY_REGION_BACKUP_HOSTS = v;
}
});
let QUERY_REGION_HOST = 'kodo-config.qiniuapi.com';
Object.defineProperty(exports, 'QUERY_REGION_HOST', {
get: () => QUERY_REGION_HOST,
set: v => {
QUERY_REGION_HOST = v;
QUERY_REGION_BACKUP_HOSTS = [];
}
});
let UC_HOST = 'uc.qbox.me';
Object.defineProperty(exports, 'UC_HOST', {
get: () => UC_HOST,
set: v => {
UC_HOST = v;
QUERY_REGION_HOST = v;
QUERY_REGION_BACKUP_HOSTS = [];
}
});

@@ -28,3 +54,3 @@ // proxy

exports.Config = function Config(options) {
exports.Config = function Config (options) {
options = options || {};

@@ -31,0 +57,0 @@ // use http or https protocol

@@ -1,6 +0,21 @@

var urllib = require('urllib');
var conf = require('./conf');
const urllib = require('urllib');
const pkg = require('../package.json');
const conf = require('./conf');
const digest = require('./auth/digest');
const util = require('./util');
const client = require('./httpc/client');
const middleware = require('./httpc/middleware');
let uaMiddleware = new middleware.UserAgentMiddleware(pkg.version);
uaMiddleware = Object.defineProperty(uaMiddleware, 'userAgent', {
get: function () {
return conf.USER_AGENT;
}
});
exports.qnHttpClient = new client.HttpClient({
middlewares: [
uaMiddleware
]
});
exports.get = get;

@@ -96,8 +111,8 @@ exports.post = post;

function postMultipart(requestURI, requestForm, callbackFunc) {
function postMultipart (requestURI, requestForm, callbackFunc) {
return post(requestURI, requestForm, requestForm.headers(), callbackFunc);
}
function postWithForm(requestURI, requestForm, token, callbackFunc) {
var headers = {
function postWithForm (requestURI, requestForm, token, callbackFunc) {
const headers = {
'Content-Type': 'application/x-www-form-urlencoded'

@@ -111,4 +126,4 @@ };

function postWithoutForm(requestURI, token, callbackFunc) {
var headers = {
function postWithoutForm (requestURI, token, callbackFunc) {
const headers = {
'Content-Type': 'application/x-www-form-urlencoded'

@@ -150,3 +165,3 @@ };

function post(requestURI, requestForm, headers, callbackFunc) {
function post (requestUrl, requestForm, headers, callbackFunc) {
// var start = parseInt(Date.now() / 1000);

@@ -157,3 +172,3 @@ headers = headers || {};

var data = {
const data = {
headers: headers,

@@ -183,11 +198,10 @@ method: 'POST',

var req = urllib.request(requestURI, data, function (respErr, respBody,
respInfo) {
callbackFunc(respErr, respBody, respInfo);
});
return req;
return urllib.request(
requestUrl,
data,
callbackFunc
);
}
function put(requestURL, requestForm, headers, callbackFunc) {
function put (requestUrl, requestForm, headers, callbackFunc) {
// var start = parseInt(Date.now() / 1000);

@@ -198,3 +212,3 @@ headers = headers || {};

var data = {
const data = {
headers: headers,

@@ -224,7 +238,7 @@ method: 'PUT',

var req = urllib.request(requestURL, data, function (err, ret, info) {
callbackFunc(err, ret, info);
});
return req;
return urllib.request(
requestUrl,
data,
callbackFunc
);
}

@@ -376,15 +376,17 @@ const querystring = require('querystring');

// 设置空间镜像源
// @link https://developer.qiniu.com/kodo/api/1370/mirror
// @param bucket 空间名称
// @param srcSiteUrl 镜像源地址
// @param srcHost 镜像Host
// @param callbackFunc(err, respBody, respInfo) 回调函数
const PU_HOST = 'http://pu.qbox.me:10200';
/**
* 设置空间镜像源
* @link https://developer.qiniu.com/kodo/3966/bucket-image-source
* @param {string} bucket 空间名称
* @param {string} srcSiteUrl 镜像源地址
* @param {string} srcHost 镜像Host
* @param {function(err: error, respBody: object, respInfo: object)} callbackFunc 回调函数
*/
BucketManager.prototype.image = function (bucket, srcSiteUrl, srcHost,
callbackFunc) {
var encodedSrcSite = util.urlsafeBase64Encode(srcSiteUrl);
var requestURI = PU_HOST + '/image/' + bucket + '/from/' + encodedSrcSite;
const encodedSrcSite = util.urlsafeBase64Encode(srcSiteUrl);
const scheme = this.config.useHttpsDomain ? 'https://' : 'http://';
let requestURI = scheme + conf.UC_HOST + '/image/' + bucket + '/from/' + encodedSrcSite;
if (srcHost) {
var encodedHost = util.urlsafeBase64Encode(srcHost);
const encodedHost = util.urlsafeBase64Encode(srcHost);
requestURI += '/host/' + encodedHost;

@@ -402,22 +404,26 @@ }

// 取消设置空间镜像源
// @link https://developer.qiniu.com/kodo/api/1370/mirror
// @param bucket 空间名称
// @param callbackFunc(err, respBody, respInfo) 回调函数
/**
* 取消设置空间镜像源
* @param {string} bucket 空间名称
* @param {function(err: error, respBody: object, respInfo: object)} callbackFunc 回调函数
*/
BucketManager.prototype.unimage = function (bucket, callbackFunc) {
var requestURI = PU_HOST + '/unimage/' + bucket;
var digest = util.generateAccessTokenV2(this.mac, requestURI, 'POST', 'application/x-www-form-urlencoded');
const scheme = this.config.useHttpsDomain ? 'https://' : 'http://';
const requestURI = scheme + conf.UC_HOST + '/unimage/' + bucket;
const digest = util.generateAccessTokenV2(this.mac, requestURI, 'POST', 'application/x-www-form-urlencoded');
rpc.postWithoutForm(requestURI, digest, callbackFunc);
};
// 获取指定前缀的文件列表
// @link https://developer.qiniu.com/kodo/api/1284/list
//
// @param bucket 空间名称
// @param options 列举操作的可选参数
// prefix 列举的文件前缀
// marker 上一次列举返回的位置标记,作为本次列举的起点信息
// limit 每次返回的最大列举文件数量
// delimiter 指定目录分隔符
// @param callbackFunc(err, respBody, respInfo) - 回调函数
/**
* 获取指定前缀的文件列表
* @link https://developer.qiniu.com/kodo/api/1284/list
*
* @param { string } bucket 空间名称
* @param { Object } options 列举操作的可选参数
* @param { string } options.prefix 列举的文件前缀
* @param { string } options.marker 上一次列举返回的位置标记,作为本次列举的起点信息
* @param { number } options.limit 每次返回的最大列举文件数量
* @param { string } options.delimiter 指定目录分隔符
* @param { function } callbackFunc(err, respBody, respInfo) 回调函数
*/
BucketManager.prototype.listPrefix = function (bucket, options, callbackFunc) {

@@ -433,6 +439,6 @@ util.prepareZone(this, this.mac.accessKey, bucket, function (err, ctx) {

function listPrefixReq(mac, config, bucket, options, callbackFunc) {
function listPrefixReq (mac, config, bucket, options, callbackFunc) {
options = options || {};
// 必须参数
var reqParams = {
const reqParams = {
bucket: bucket

@@ -465,5 +471,5 @@ };

var scheme = config.useHttpsDomain ? 'https://' : 'http://';
var reqSpec = querystring.stringify(reqParams);
var requestURI = scheme + config.zone.rsfHost + '/list?' + reqSpec;
const scheme = config.useHttpsDomain ? 'https://' : 'http://';
const reqSpec = querystring.stringify(reqParams);
const requestURI = scheme + config.zone.rsfHost + '/list?' + reqSpec;

@@ -480,11 +486,15 @@ rpc.postWithOptions(

// 获取指定前缀的文件列表
//
// @param bucket 空间名称
// @param options 列举操作的可选参数
// prefix 列举的文件前缀
// marker 上一次列举返回的位置标记,作为本次列举的起点信息
// limit 每次返回的最大列举文件数量
// delimiter 指定目录分隔符
// @param callbackFunc(err, respBody, respInfo) - 回调函数
/**
* 获取指定前缀的文件列表 V2
*
* @deprecated API 可能返回仅包含 marker,不包含 item 或 dir 的项,请使用 {@link listPrefix}
*
* @param bucket 空间名称
* @param { Object } options 列举操作的可选参数
* @param { string } options.prefix 列举的文件前缀
* @param { string } options.marker 上一次列举返回的位置标记,作为本次列举的起点信息
* @param { number } options.limit 每次返回的最大列举文件数量
* @param { string } options.delimiter 指定目录分隔符
* @param { function } callbackFunc(err, respBody, respInfo) 回调函数
*/
BucketManager.prototype.listPrefixV2 = function (bucket, options, callbackFunc) {

@@ -500,6 +510,6 @@ util.prepareZone(this, this.mac.accessKey, bucket, function (err, ctx) {

function listPrefixReqV2(mac, config, bucket, options, callbackFunc) {
function listPrefixReqV2 (mac, config, bucket, options, callbackFunc) {
options = options || {};
// 必须参数
var reqParams = {
const reqParams = {
bucket: bucket

@@ -532,5 +542,5 @@ };

var scheme = config.useHttpsDomain ? 'https://' : 'http://';
var reqSpec = querystring.stringify(reqParams);
var requestURI = scheme + config.zone.rsfHost + '/v2/list?' + reqSpec;
const scheme = config.useHttpsDomain ? 'https://' : 'http://';
const reqSpec = querystring.stringify(reqParams);
const requestURI = scheme + config.zone.rsfHost + '/v2/list?' + reqSpec;

@@ -537,0 +547,0 @@ rpc.postWithOptions(

@@ -45,3 +45,7 @@ const url = require('url');

exports.encodedEntry = function (bucket, key) {
return exports.urlsafeBase64Encode(bucket + (key ? ':' + key : ''));
let strToEncode = bucket;
if (key !== undefined) {
strToEncode += ':' + key;
}
return exports.urlsafeBase64Encode(strToEncode);
};

@@ -332,3 +336,3 @@

ctx.config.zone = cZoneInfo;
ctx.config.zoneExpire = cZoneExpire + parseInt(Date.now() / 1000);
ctx.config.zoneExpire = cZoneExpire + Math.trunc(Date.now() / 1000);
callback(null, ctx);

@@ -335,0 +339,0 @@ });

@@ -1,4 +0,4 @@

const urllib = require('urllib');
const util = require('util');
const conf = require('./conf');
const { RetryDomainsMiddleware } = require('./httpc/middleware');
const rpc = require('./rpc');

@@ -65,75 +65,72 @@ // huadong

// seoul
exports.Zone_ap_northeast_1 = new conf.Zone([
'up-ap-northeast-1.qiniup.com'
], [
'upload-ap-northeast-1.qiniup.com'
], 'iovip-ap-northeast-1.qiniuio.com',
'rs-ap-northeast-1.qiniuapi.com',
'rsf-ap-northeast-1.qiniuapi.com',
'api-ap-northeast-1.qiniuapi.com');
exports.getZoneInfo = function (accessKey, bucket, callbackFunc) {
const apiAddr = util.format(
'https://uc.qbox.me/v2/query?ak=%s&bucket=%s',
accessKey,
bucket
);
urllib.request(apiAddr, function (respErr, respData, respInfo) {
if (respErr) {
callbackFunc(respErr, null, null);
return;
}
const apiAddr = 'https://' + conf.QUERY_REGION_HOST + '/v4/query';
if (respInfo.statusCode != 200) {
// not ok
respErr = new Error(respInfo.statusCode + '\n' + respData);
callbackFunc(respErr, null, null);
return;
}
rpc.qnHttpClient.get({
url: apiAddr,
params: {
ak: accessKey,
bucket: bucket
},
middlewares: [
new RetryDomainsMiddleware({
backupDomains: conf.QUERY_REGION_BACKUP_HOSTS
})
],
callback: function (respErr, respData, respInfo) {
if (respErr) {
callbackFunc(respErr, null, null);
return;
}
const zoneData = JSON.parse(respData);
const srcUpHosts = [];
const cdnUpHosts = [];
let zoneExpire = 0;
if (respInfo.statusCode !== 200) {
// not ok
respErr = new Error(respInfo.statusCode + '\n' + respData);
callbackFunc(respErr, null, null);
return;
}
try {
zoneExpire = zoneData.ttl;
// read src hosts
zoneData.up.src.main.forEach(function (host) {
srcUpHosts.push(host);
});
if (zoneData.up.src.backup) {
zoneData.up.src.backup.forEach(function (host) {
srcUpHosts.push(host);
});
let zoneData;
try {
const hosts = JSON.parse(respData).hosts;
if (!hosts || !hosts.length) {
respErr = new Error('no host available: ' + respData);
callbackFunc(respErr, null, null);
return;
}
zoneData = hosts[0];
} catch (err) {
callbackFunc(err, null, null);
return;
}
let srcUpHosts = [];
let cdnUpHosts = [];
let zoneExpire = 0;
// read acc hosts
zoneData.up.acc.main.forEach(function (host) {
cdnUpHosts.push(host);
});
if (zoneData.up.acc.backup) {
zoneData.up.acc.backup.forEach(function (host) {
cdnUpHosts.push(host);
});
try {
zoneExpire = zoneData.ttl;
// read src hosts
srcUpHosts = zoneData.up.domains;
// read acc hosts
cdnUpHosts = zoneData.up.domains;
const ioHost = zoneData.io.domains[0];
const rsHost = zoneData.rs.domains[0];
const rsfHost = zoneData.rsf.domains[0];
const apiHost = zoneData.api.domains[0];
const zoneInfo = new conf.Zone(
srcUpHosts,
cdnUpHosts,
ioHost,
rsHost,
rsfHost,
apiHost
);
callbackFunc(null, zoneInfo, zoneExpire);
} catch (e) {
callbackFunc(e, null, null);
}
const ioHost = zoneData.io.src.main[0];
const rsHost = zoneData.rs.acc.main[0];
const rsfHost = zoneData.rsf.acc.main[0];
const apiHost = zoneData.api.acc.main[0];
const zoneInfo = new conf.Zone(
srcUpHosts,
cdnUpHosts,
ioHost,
rsHost,
rsfHost,
apiHost
);
callbackFunc(null, zoneInfo, zoneExpire);
} catch (e) {
callbackFunc(e, null, null);
}
});
};

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

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

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc