Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
64 changes: 35 additions & 29 deletions examples/form_upload_simple.js
Original file line number Diff line number Diff line change
@@ -1,37 +1,43 @@
const qiniu = require('../index.js');
const proc = require('process');
const os = require('os');

var bucket = proc.env.QINIU_TEST_BUCKET;
var accessKey = proc.env.QINIU_ACCESS_KEY;
var secretKey = proc.env.QINIU_SECRET_KEY;
var mac = new qiniu.auth.digest.Mac(accessKey, secretKey);
var options = {
const qiniu = require('qiniu');

const bucket = process.env.QINIU_TEST_BUCKET;
const accessKey = process.env.QINIU_ACCESS_KEY;
const secretKey = process.env.QINIU_SECRET_KEY;
const mac = new qiniu.auth.digest.Mac(accessKey, secretKey);
const options = {
scope: bucket
};
var putPolicy = new qiniu.rs.PutPolicy(options);
const putPolicy = new qiniu.rs.PutPolicy(options);

var uploadToken = putPolicy.uploadToken(mac);
var config = new qiniu.conf.Config();
var localFile = '/Users/jemy/Downloads/download.csv';
const uploadToken = putPolicy.uploadToken(mac);
const config = new qiniu.conf.Config();
const localFile = os.homedir() + '/Downloads/83eda6926b94bb14.css';
// config.zone = qiniu.zone.Zone_z0;
var formUploader = new qiniu.form_up.FormUploader(config);
var putExtra = new qiniu.form_up.PutExtra();
const formUploader = new qiniu.form_up.FormUploader(config);
const putExtra = new qiniu.form_up.PutExtra();
// file
putExtra.fname = 'test01.csv';
putExtra.crc32 = 3497766758;
putExtra.metadata = {
'x-qn-meta-name': 'qiniu'
};
formUploader.putFile(uploadToken, null, localFile, putExtra, function (respErr,
respBody, respInfo) {
if (respErr) {
throw respErr;
}
// putExtra.fname = 'frontend-static-resource/widgets/_next/static/css/83eda6926b94bb14.css';
// putExtra.metadata = {
// 'x-qn-meta-name': 'qiniu'
// };
formUploader.putFile(
uploadToken,
'frontend-static-resource/widgets/_next/static/css/83eda6926b94bb14.css',
localFile,
putExtra,
function (respErr,
respBody, respInfo) {
if (respErr) {
throw respErr;
}

if (respInfo.statusCode == 200) {
console.log(respBody);
} else {
console.log(respInfo.statusCode);
console.log(respBody);
if (respInfo.statusCode === 200) {
console.log(respBody);
} else {
console.log(respInfo.statusCode);
console.log(respBody);
}
}
});
);
151 changes: 150 additions & 1 deletion index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,10 @@
* @date 2017-06-27
* @author xialeistudio<xialeistudio@gmail.com>
*/
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";

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

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

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 {
type Headers = Record<string, string> & {
'User-Agent'?: string;
Expand All @@ -428,6 +575,8 @@ export declare namespace rpc {
mac: auth.digest.Mac;
}

const qnHttpClient: httpc.HttpClient;

/**
*
* @param requestUrl 请求地址
Expand Down
5 changes: 5 additions & 0 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,11 @@ module.exports = {
rs: require('./qiniu/storage/rs.js'),
fop: require('./qiniu/fop.js'),
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'),
util: require('./qiniu/util.js'),
zone: require('./qiniu/zone.js'),
Expand Down
21 changes: 19 additions & 2 deletions qiniu/conf.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,30 @@ exports.FormMimeJson = 'application/json';
exports.FormMimeRaw = 'application/octet-stream';
exports.RS_HOST = 'rs.qiniu.com';
exports.RPC_TIMEOUT = 600000; // 600s
exports.UC_HOST = 'uc.qbox.me';
let UC_BACKUP_HOSTS = [
'kodo-config.qiniuapi.com',
'api.qiniu.com'
];
Object.defineProperty(exports, 'UC_BACKUP_HOSTS', {
get: () => UC_BACKUP_HOSTS,
set: v => {
UC_BACKUP_HOSTS = v;
}
});
let UC_HOST = 'uc.qbox.me';
Object.defineProperty(exports, 'UC_HOST', {
get: () => UC_HOST,
set: v => {
UC_HOST = v;
UC_BACKUP_HOSTS = [];
}
});

// proxy
exports.RPC_HTTP_AGENT = null;
exports.RPC_HTTPS_AGENT = null;

exports.Config = function Config(options) {
exports.Config = function Config (options) {
options = options || {};
// use http or https protocol
this.useHttpsDomain = !!(options.useHttpsDomain || false);
Expand Down
Loading