Skip to content

Commit c93b4df

Browse files
committed
refactor BucketManager, FormUploader, ResumeUploader
COMPLETED: - Add promise style; - Add Retrier for Endpoints or Regions retrying; - Improve all test cases in rs.js, form_up.js, resume_up.js; - Fix multiple bugs. An important is v1 resume upload will not callback if resume from the last part;
1 parent f60fecd commit c93b4df

34 files changed

+5393
-3661
lines changed

index.d.ts

Lines changed: 71 additions & 40 deletions
Large diffs are not rendered by default.

index.js

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,7 @@ module.exports = {
1818
Region: require('./qiniu/httpc/region').Region,
1919
StaticRegionsProvider: require('./qiniu/httpc/regionsProvider').StaticRegionsProvider,
2020
CachedRegionsProvider: require('./qiniu/httpc/regionsProvider').CachedRegionsProvider,
21-
QueryRegionsProvider: require('./qiniu/httpc/regionsProvider').QueryRegionsProvider,
22-
ChainedRegionsProvider: require('./qiniu/httpc/regionsProvider').ChainedRegionsProvider
21+
QueryRegionsProvider: require('./qiniu/httpc/regionsProvider').QueryRegionsProvider
2322
},
2423
rpc: require('./qiniu/rpc.js'),
2524
util: require('./qiniu/util.js'),

qiniu/auth/digest.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
var conf = require('../conf');
1+
const conf = require('../conf');
22

33
exports.Mac = Mac;
44

qiniu/conf.js

Lines changed: 173 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,18 @@
11
const os = require('os');
22
const pkg = require('../package.json');
3+
const { Endpoint } = require('./httpc/endpoint');
4+
const { Region } = require('./httpc/region');
5+
const { StaticEndpointsProvider } = require('./httpc/endpointsProvider');
6+
const crypto = require('crypto');
7+
const {
8+
CachedRegionsProvider,
9+
QueryRegionsProvider
10+
} = require('./httpc/regionsProvider');
311

412
exports.ACCESS_KEY = '<PLEASE APPLY YOUR ACCESS KEY>';
513
exports.SECRET_KEY = '<DONT SEND YOUR SECRET KEY TO ANYONE>';
614

7-
var defaultUserAgent = function () {
15+
const defaultUserAgent = function () {
816
return 'QiniuNodejs/' + pkg.version + ' (' + os.type() + '; ' + os.platform() +
917
'; ' + os.arch() + '; )';
1018
};
@@ -50,68 +58,180 @@ Object.defineProperty(exports, 'UC_HOST', {
5058
exports.RPC_HTTP_AGENT = null;
5159
exports.RPC_HTTPS_AGENT = null;
5260

53-
exports.Config = function Config (options) {
61+
/**
62+
* @class
63+
* @constructor
64+
* @param {Object} [options]
65+
* @param {boolean} [options.useHttpsDomain]
66+
* @param {boolean} [options.useCdnDomain]
67+
* @param {EndpointsProvider} [options.ucEndpointsProvider]
68+
* @param {EndpointsProvider} [options.queryRegionsEndpointsProvider]
69+
* @param {RegionsProvider} [options.regionsProvider]
70+
* @param {Zone} [options.zone]
71+
* @param {number} [options.zoneExpire]
72+
*/
73+
function Config (options) {
5474
options = options || {};
5575
// use http or https protocol
5676
this.useHttpsDomain = !!(options.useHttpsDomain || false);
57-
// use cdn accerlated domains, this is not work with auto query region
77+
// use cdn accelerated domains, this is not work with auto query region
5878
this.useCdnDomain = !!(options.useCdnDomain && true);
79+
// custom uc endpoints
80+
this.ucEndpointsProvider = options.ucEndpointsProvider || null;
81+
// custom query region endpoints
82+
this.queryRegionsEndpointsProvider = options.queryRegionsEndpointsProvider || null;
83+
// custom regions
84+
this.regionsProvider = options.regionsProvider || null;
85+
86+
// deprecated
5987
// zone of the bucket
60-
// z0 huadong, z1 huabei, z2 huanan, na0 beimei
6188
this.zone = options.zone || null;
6289
this.zoneExpire = options.zoneExpire || -1;
63-
// only available with upload for now
64-
this.regionsProvider = options.regionsProvider || null;
90+
}
91+
92+
/**
93+
* @returns {EndpointsProvider}
94+
*/
95+
Config.prototype.getUcEndpointsProvider = function () {
96+
if (this.ucEndpointsProvider) {
97+
return this.ucEndpointsProvider;
98+
}
99+
100+
return new Endpoint(
101+
UC_HOST,
102+
{
103+
defaultScheme: this.useHttpsDomain ? 'https' : 'http'
104+
}
105+
);
65106
};
66107

67-
exports.Zone = function (
68-
srcUpHosts,
69-
cdnUpHosts,
70-
ioHost,
71-
rsHost,
72-
rsfHost,
73-
apiHost
74-
) {
75-
this.srcUpHosts = srcUpHosts || [];
76-
this.cdnUpHosts = cdnUpHosts || [];
77-
this.ioHost = ioHost || '';
78-
this.rsHost = rsHost;
79-
this.rsfHost = rsfHost;
80-
this.apiHost = apiHost;
81-
82-
// set specific hosts if possible
83-
const dotIndex = this.ioHost.indexOf('.');
84-
if (dotIndex !== -1) {
85-
const ioTag = this.ioHost.substring(0, dotIndex);
86-
const zoneSepIndex = ioTag.indexOf('-');
87-
if (zoneSepIndex !== -1) {
88-
const zoneTag = ioTag.substring(zoneSepIndex + 1);
89-
switch (zoneTag) {
90-
case 'z1':
91-
!this.rsHost && (this.rsHost = 'rs-z1.qbox.me');
92-
!this.rsfHost && (this.rsfHost = 'rsf-z1.qbox.me');
93-
!this.apiHost && (this.apiHost = 'api-z1.qiniuapi.com');
94-
break;
95-
case 'z2':
96-
!this.rsHost && (this.rsHost = 'rs-z2.qbox.me');
97-
!this.rsfHost && (this.rsfHost = 'rsf-z2.qbox.me');
98-
!this.apiHost && (this.apiHost = 'api-z2.qiniuapi.com');
99-
break;
100-
case 'na0':
101-
!this.rsHost && (this.rsHost = 'rs-na0.qbox.me');
102-
!this.rsfHost && (this.rsfHost = 'rsf-na0.qbox.me');
103-
!this.apiHost && (this.apiHost = 'api-na0.qiniuapi.com');
104-
break;
105-
case 'as0':
106-
!this.rsHost && (this.rsHost = 'rs-as0.qbox.me');
107-
!this.rsfHost && (this.rsfHost = 'rsf-as0.qbox.me');
108-
!this.apiHost && (this.apiHost = 'api-as0.qiniuapi.com');
109-
break;
108+
/**
109+
* @private
110+
* @returns {EndpointsProvider}
111+
*/
112+
Config.prototype._getQueryRegionEndpointsProvider = function () {
113+
if (this.queryRegionsEndpointsProvider) {
114+
return this.queryRegionsEndpointsProvider;
115+
}
116+
117+
if (this.ucEndpointsProvider) {
118+
return this.ucEndpointsProvider;
119+
}
120+
121+
const queryRegionsHosts = [QUERY_REGION_HOST].concat(QUERY_REGION_BACKUP_HOSTS);
122+
return new StaticEndpointsProvider(queryRegionsHosts.map(h =>
123+
new Endpoint(
124+
h,
125+
{
126+
defaultScheme: this.useHttpsDomain ? 'https' : 'http'
110127
}
111-
}
128+
)
129+
));
130+
};
131+
132+
/**
133+
* @param {Object} [options]
134+
* @param {string} [options.bucketName]
135+
* @param {string} [options.accessKey]
136+
* @returns {Promise<RegionsProvider>}
137+
*/
138+
Config.prototype.getRegionsProvider = function (options) {
139+
// returns custom regions provider, if it's configured
140+
if (this.regionsProvider) {
141+
return Promise.resolve(this.regionsProvider);
142+
}
143+
144+
// backward compatibility with custom zone configuration
145+
const zoneProvider = this._getRegionsProviderFromZone();
146+
if (zoneProvider) {
147+
return Promise.resolve(zoneProvider);
148+
}
149+
150+
// get default regions provider
151+
const {
152+
bucketName,
153+
accessKey
154+
} = options || {};
155+
if (!bucketName || !accessKey) {
156+
return Promise.reject(
157+
new Error('bucketName and accessKey is required for query regions')
158+
);
159+
}
160+
return this._getDefaultRegionsProvider({
161+
bucketName,
162+
accessKey
163+
});
164+
};
165+
166+
/**
167+
* @private
168+
* @returns {RegionsProvider | undefined}
169+
*/
170+
Config.prototype._getRegionsProviderFromZone = function () {
171+
let zoneTTL;
172+
let shouldUseZone;
173+
if (this.zoneExpire > 0) {
174+
zoneTTL = this.zoneExpire - Math.trunc(Date.now() / 1000);
175+
shouldUseZone = this.zone && zoneTTL > 0;
176+
} else {
177+
zoneTTL = -1;
178+
shouldUseZone = Boolean(this.zone);
179+
}
180+
if (!shouldUseZone) {
181+
return;
112182
}
183+
return Region.fromZone(this.zone, {
184+
ttl: zoneTTL,
185+
isPreferCdnHost: this.useCdnDomain,
186+
preferredScheme: this.useHttpsDomain ? 'https' : 'http'
187+
});
188+
};
189+
190+
/**
191+
* @private
192+
* @param {Object} options
193+
* @param {string} options.bucketName
194+
* @param {string} options.accessKey
195+
* @returns {Promise<RegionsProvider>}
196+
*/
197+
Config.prototype._getDefaultRegionsProvider = function (options) {
198+
const {
199+
bucketName,
200+
accessKey
201+
} = options;
113202

114-
!this.rsHost && (this.rsHost = 'rs.qiniu.com');
115-
!this.rsfHost && (this.rsfHost = 'rsf.qiniu.com');
116-
!this.apiHost && (this.apiHost = 'api.qiniuapi.com');
203+
const queryRegionsEndpointsProvider = this._getQueryRegionEndpointsProvider();
204+
return queryRegionsEndpointsProvider
205+
.getEndpoints()
206+
.then(endpoints => {
207+
const endpointsMd5 = endpoints
208+
.map(e => e.host)
209+
.sort()
210+
.reduce(
211+
(hash, host) => hash.update(host),
212+
crypto.createHash('md5')
213+
)
214+
.digest('hex');
215+
const cacheKey = [
216+
endpointsMd5,
217+
accessKey,
218+
bucketName
219+
].join(':');
220+
return new CachedRegionsProvider({
221+
cacheKey,
222+
baseRegionsProvider: new QueryRegionsProvider({
223+
accessKey: accessKey,
224+
bucketName: bucketName,
225+
endpointsProvider: queryRegionsEndpointsProvider,
226+
preferredScheme: this.useHttpsDomain ? 'https' : 'http'
227+
})
228+
});
229+
});
117230
};
231+
232+
exports.Config = Config;
233+
/**
234+
* backward compatibility
235+
* @deprecated use qiniu/httpc/region.js instead
236+
*/
237+
exports.Zone = require('./zone').Zone;

0 commit comments

Comments
 (0)