Skip to content

Commit 2ded367

Browse files
authored
Merge pull request #412 from qiniu/feat/middleware-and-backup-domains
add middleware and backup domains for query region
2 parents ba9cb83 + 889b1f1 commit 2ded367

14 files changed

+972
-149
lines changed

examples/form_upload_simple.js

+35-29
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,43 @@
1-
const qiniu = require('../index.js');
2-
const proc = require('process');
1+
const os = require('os');
32

4-
var bucket = proc.env.QINIU_TEST_BUCKET;
5-
var accessKey = proc.env.QINIU_ACCESS_KEY;
6-
var secretKey = proc.env.QINIU_SECRET_KEY;
7-
var mac = new qiniu.auth.digest.Mac(accessKey, secretKey);
8-
var options = {
3+
const qiniu = require('qiniu');
4+
5+
const bucket = process.env.QINIU_TEST_BUCKET;
6+
const accessKey = process.env.QINIU_ACCESS_KEY;
7+
const secretKey = process.env.QINIU_SECRET_KEY;
8+
const mac = new qiniu.auth.digest.Mac(accessKey, secretKey);
9+
const options = {
910
scope: bucket
1011
};
11-
var putPolicy = new qiniu.rs.PutPolicy(options);
12+
const putPolicy = new qiniu.rs.PutPolicy(options);
1213

13-
var uploadToken = putPolicy.uploadToken(mac);
14-
var config = new qiniu.conf.Config();
15-
var localFile = '/Users/jemy/Downloads/download.csv';
14+
const uploadToken = putPolicy.uploadToken(mac);
15+
const config = new qiniu.conf.Config();
16+
const localFile = os.homedir() + '/Downloads/83eda6926b94bb14.css';
1617
// config.zone = qiniu.zone.Zone_z0;
17-
var formUploader = new qiniu.form_up.FormUploader(config);
18-
var putExtra = new qiniu.form_up.PutExtra();
18+
const formUploader = new qiniu.form_up.FormUploader(config);
19+
const putExtra = new qiniu.form_up.PutExtra();
1920
// file
20-
putExtra.fname = 'test01.csv';
21-
putExtra.crc32 = 3497766758;
22-
putExtra.metadata = {
23-
'x-qn-meta-name': 'qiniu'
24-
};
25-
formUploader.putFile(uploadToken, null, localFile, putExtra, function (respErr,
26-
respBody, respInfo) {
27-
if (respErr) {
28-
throw respErr;
29-
}
21+
// putExtra.fname = 'frontend-static-resource/widgets/_next/static/css/83eda6926b94bb14.css';
22+
// putExtra.metadata = {
23+
// 'x-qn-meta-name': 'qiniu'
24+
// };
25+
formUploader.putFile(
26+
uploadToken,
27+
'frontend-static-resource/widgets/_next/static/css/83eda6926b94bb14.css',
28+
localFile,
29+
putExtra,
30+
function (respErr,
31+
respBody, respInfo) {
32+
if (respErr) {
33+
throw respErr;
34+
}
3035

31-
if (respInfo.statusCode == 200) {
32-
console.log(respBody);
33-
} else {
34-
console.log(respInfo.statusCode);
35-
console.log(respBody);
36+
if (respInfo.statusCode === 200) {
37+
console.log(respBody);
38+
} else {
39+
console.log(respInfo.statusCode);
40+
console.log(respBody);
41+
}
3642
}
37-
});
43+
);

index.d.ts

+150-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,10 @@
33
* @date 2017-06-27
44
* @author xialeistudio<[email protected]>
55
*/
6-
import { Callback } from 'urllib';
6+
import { Callback, RequestOptions } from 'urllib';
7+
import { Agent as HttpAgent, IncomingMessage} from 'http';
8+
import { Agent as HttpsAgent } from 'https';
9+
import { Readable } from "stream";
710

811
export declare type callback = (e?: Error, respBody?: any, respInfo?: any) => void;
912

@@ -417,6 +420,150 @@ export declare namespace util {
417420
function isQiniuCallback(mac: auth.digest.Mac, requestURI: string, reqBody: string | null, callbackAuth: string): boolean;
418421
}
419422

423+
export declare namespace httpc {
424+
interface ReqOpts<T = any> {
425+
agent?: HttpAgent;
426+
httpsAgent?: HttpsAgent;
427+
url: string;
428+
middlewares: middleware.Middleware[];
429+
callback?: Callback<T>;
430+
urllibOptions: RequestOptions;
431+
}
432+
433+
interface RespWrapperOptions<T = any> {
434+
data: T;
435+
resp: IncomingMessage;
436+
}
437+
438+
class RespWrapper<T = any> {
439+
data: T;
440+
resp: IncomingMessage;
441+
constructor(options: RespWrapperOptions);
442+
ok(): boolean;
443+
needRetry(): boolean;
444+
}
445+
446+
namespace middleware {
447+
interface Middleware {
448+
send<T>(
449+
request: ReqOpts<T>,
450+
next: (reqOpts: ReqOpts<T>) => Promise<RespWrapper<T>>
451+
): Promise<RespWrapper<T>>;
452+
}
453+
454+
/**
455+
* 组合中间件为一个调用函数
456+
* @param middlewares 中间件列表
457+
* @param handler 请求函数
458+
*/
459+
function composeMiddlewares<T>(
460+
middlewares: Middleware[],
461+
handler: (reqOpts: ReqOpts<T>) => Promise<RespWrapper<T>>
462+
);
463+
464+
/**
465+
* 设置 User-Agent 请求头中间件
466+
*/
467+
class UserAgentMiddleware implements Middleware {
468+
constructor(sdkVersion: string);
469+
send<T>(
470+
request: httpc.ReqOpts<T>,
471+
next: (reqOpts: httpc.ReqOpts<T>) => Promise<httpc.RespWrapper<T>>
472+
): Promise<httpc.RespWrapper<T>>;
473+
}
474+
475+
interface RetryDomainsMiddlewareOptions {
476+
backupDomains: string[];
477+
maxRetryTimes: number;
478+
retryCondition: () => boolean;
479+
}
480+
481+
class RetryDomainsMiddleware implements Middleware {
482+
/**
483+
* 备用域名
484+
*/
485+
backupDomains: string[];
486+
487+
/**
488+
* 最大重试次数,包括首次请求
489+
*/
490+
maxRetryTimes: number;
491+
492+
/**
493+
* 是否可以重试,可以通过该函数配置更详细的重试规则
494+
*/
495+
retryCondition: () => boolean;
496+
497+
/**
498+
* 已经重试的次数
499+
* @private
500+
*/
501+
private _retriedTimes: number;
502+
503+
/**
504+
* 实例化重试域名中间件
505+
* @param retryDomainsOptions
506+
*/
507+
constructor(retryDomainsOptions: RetryDomainsMiddlewareOptions)
508+
509+
/**
510+
* 重试域名中间件逻辑
511+
* @param request
512+
* @param next
513+
*/
514+
send<T>(
515+
request: httpc.ReqOpts<T>,
516+
next: (reqOpts: httpc.ReqOpts<T>) => Promise<httpc.RespWrapper<T>>
517+
): Promise<httpc.RespWrapper<T>>;
518+
519+
/**
520+
* 控制重试逻辑,主要为 {@link retryCondition} 服务。若没有设置 retryCondition,默认 2xx 才会终止重试
521+
* @param err
522+
* @param respWrapper
523+
* @param reqOpts
524+
* @private
525+
*/
526+
private _shouldRetry<T>(
527+
err: Error | null,
528+
respWrapper: RespWrapper<T>,
529+
reqOpts: ReqOpts<T>
530+
): boolean;
531+
}
532+
}
533+
534+
interface HttpClientOptions {
535+
httpAgent?: HttpAgent;
536+
httpsAgent?: HttpsAgent;
537+
middlewares?: middleware.Middleware[];
538+
}
539+
540+
interface GetOptions<T = any> extends ReqOpts<T> {
541+
params: Record<string, string>;
542+
headers: Record<string, string>;
543+
}
544+
545+
interface PostOptions<T = any> extends ReqOpts<T> {
546+
data: string | Buffer | Readable;
547+
headers: Record<string, string>;
548+
}
549+
550+
interface PutOptions<T = any> extends ReqOpts<T> {
551+
data: string | Buffer | Readable;
552+
headers: Record<string, string>
553+
}
554+
555+
class HttpClient {
556+
httpAgent: HttpAgent;
557+
httpsAgent: HttpsAgent;
558+
middlewares: middleware.Middleware[];
559+
constructor(options: HttpClientOptions)
560+
sendRequest(requestOptions: ReqOpts): Promise<RespWrapper>
561+
get(getOptions: GetOptions): Promise<RespWrapper>
562+
post(postOptions: PostOptions): Promise<RespWrapper>
563+
put(putOptions: PutOptions): Promise<RespWrapper>
564+
}
565+
}
566+
420567
export declare namespace rpc {
421568
type Headers = Record<string, string> & {
422569
'User-Agent'?: string;
@@ -428,6 +575,8 @@ export declare namespace rpc {
428575
mac: auth.digest.Mac;
429576
}
430577

578+
const qnHttpClient: httpc.HttpClient;
579+
431580
/**
432581
*
433582
* @param requestUrl 请求地址

index.js

+5
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,11 @@ module.exports = {
88
rs: require('./qiniu/storage/rs.js'),
99
fop: require('./qiniu/fop.js'),
1010
conf: require('./qiniu/conf.js'),
11+
httpc: {
12+
middleware: require('./qiniu/httpc/middleware'),
13+
HttpClient: require('./qiniu/httpc/client').HttpClient,
14+
ResponseWrapper: require('./qiniu/httpc/responseWrapper').ResponseWrapper
15+
},
1116
rpc: require('./qiniu/rpc.js'),
1217
util: require('./qiniu/util.js'),
1318
zone: require('./qiniu/zone.js'),

qiniu/conf.js

+19-2
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,30 @@ exports.FormMimeJson = 'application/json';
1818
exports.FormMimeRaw = 'application/octet-stream';
1919
exports.RS_HOST = 'rs.qiniu.com';
2020
exports.RPC_TIMEOUT = 600000; // 600s
21-
exports.UC_HOST = 'uc.qbox.me';
21+
let UC_BACKUP_HOSTS = [
22+
'kodo-config.qiniuapi.com',
23+
'api.qiniu.com'
24+
];
25+
Object.defineProperty(exports, 'UC_BACKUP_HOSTS', {
26+
get: () => UC_BACKUP_HOSTS,
27+
set: v => {
28+
UC_BACKUP_HOSTS = v;
29+
}
30+
});
31+
let UC_HOST = 'uc.qbox.me';
32+
Object.defineProperty(exports, 'UC_HOST', {
33+
get: () => UC_HOST,
34+
set: v => {
35+
UC_HOST = v;
36+
UC_BACKUP_HOSTS = [];
37+
}
38+
});
2239

2340
// proxy
2441
exports.RPC_HTTP_AGENT = null;
2542
exports.RPC_HTTPS_AGENT = null;
2643

27-
exports.Config = function Config(options) {
44+
exports.Config = function Config (options) {
2845
options = options || {};
2946
// use http or https protocol
3047
this.useHttpsDomain = !!(options.useHttpsDomain || false);

0 commit comments

Comments
 (0)