oss-client
Version:
Aliyun OSS(Object Storage Service) Node.js Client
330 lines • 24.5 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.OSSBaseClient = void 0;
const node_util_1 = require("node:util");
const node_assert_1 = __importDefault(require("node:assert"));
const node_crypto_1 = require("node:crypto");
const node_path_1 = require("node:path");
const stream_wormhole_1 = require("stream-wormhole");
const xml2js_1 = require("xml2js");
const utility_1 = require("utility");
const mime_1 = __importDefault(require("mime"));
const urllib_1 = require("urllib");
const ms_1 = __importDefault(require("ms"));
const index_js_1 = require("./util/index.js");
const index_js_2 = require("./error/index.js");
const debug = (0, node_util_1.debuglog)('oss-client:client');
class OSSBaseClient {
#httpClient = new urllib_1.HttpClient();
#userAgent;
options;
constructor(options) {
this.options = this.#initOptions(options);
this.#userAgent = this.#getUserAgent();
}
/** public methods */
/**
* get OSS signature
*/
signature(stringToSign) {
debug('authorization stringToSign: %s', stringToSign);
return (0, index_js_1.computeSignature)(this.options.accessKeySecret, stringToSign);
}
/** protected methods */
/**
* get author header
*
* "Authorization: OSS " + Access Key Id + ":" + Signature
*
* Signature = base64(hmac-sha1(Access Key Secret + "\n"
* + VERB + "\n"
* + CONTENT-MD5 + "\n"
* + CONTENT-TYPE + "\n"
* + DATE + "\n"
* + CanonicalizedOSSHeaders
* + CanonicalizedResource))
*/
authorization(method, resource, headers, subResource) {
const stringToSign = (0, index_js_1.buildCanonicalString)(method.toUpperCase(), resource, {
headers,
parameters: subResource,
});
debug('stringToSign: %o', stringToSign);
const auth = (0, index_js_1.authorization)(this.options.accessKeyId, this.options.accessKeySecret, stringToSign);
debug('authorization: %o', auth);
return auth;
}
/**
* encodeURIComponent name except '/'
*/
escape(name) {
return (0, utility_1.encodeURIComponent)(name).replaceAll('%2F', '/');
}
getRequestURL(params) {
let resourcePath = '/';
if (params.object) {
// Preserve '/' in result url
resourcePath += this.escape(params.object).replaceAll('+', '%2B');
}
const urlObject = new URL(this.getRequestEndpoint());
urlObject.pathname = resourcePath;
if (params.query) {
const query = params.query;
for (const key in query) {
const value = query[key];
urlObject.searchParams.set(key, `${value}`);
}
}
if (params.subResource) {
let subresAsQuery = {};
if (typeof params.subResource === 'string') {
subresAsQuery[params.subResource] = '';
}
else if (Array.isArray(params.subResource)) {
for (const k of params.subResource) {
subresAsQuery[k] = '';
}
}
else {
subresAsQuery = params.subResource;
}
for (const key in subresAsQuery) {
urlObject.searchParams.set(key, `${subresAsQuery[key]}`);
}
}
return urlObject.toString();
}
getResource(params) {
let resource = '/';
if (params.bucket)
resource += `${params.bucket}/`;
if (params.object)
resource += params.object;
return resource;
}
createHttpClientRequestParams(params) {
const headers = {
...params.headers,
// https://help.aliyun.com/zh/oss/developer-reference/include-signatures-in-the-authorization-header
// 此次操作的时间,Date必须为GMT格式,且不能为空。该值取自请求头的Date字段或者x-oss-date字段。当这两个字段同时存在时,以x-oss-date为准。
// e.g.: Sun, 22 Nov 2015 08:16:38 GMT
'x-oss-date': new Date().toUTCString(),
'user-agent': this.#userAgent,
};
if (this.options.isRequestPay) {
headers['x-oss-request-payer'] = 'requester';
}
if (!headers['content-type']) {
let contentType = null;
if (params.mime) {
if (params.mime.includes('/')) {
contentType = params.mime;
}
else {
contentType = mime_1.default.getType(params.mime);
}
}
else if (params.object) {
contentType = mime_1.default.getType((0, node_path_1.extname)(params.object));
}
if (contentType) {
headers['content-type'] = contentType;
}
}
if (params.content) {
if (!params.disabledMD5 && !headers['content-md5']) {
headers['content-md5'] = (0, node_crypto_1.createHash)('md5')
.update(Buffer.from(params.content))
.digest('base64');
}
if (!headers['content-length']) {
headers['content-length'] = `${params.content.length}`;
}
}
const authResource = this.getResource(params);
headers.authorization = this.authorization(params.method, authResource, headers, params.subResource);
const url = this.getRequestURL(params);
debug('request %s %s, with headers %j, !!stream: %s', params.method, url, headers, !!params.stream);
const timeout = params.timeout ?? this.options.timeout;
const options = {
method: params.method,
content: params.content,
stream: params.stream,
headers,
timeout,
writeStream: params.writeStream,
timing: true,
};
if (params.streaming) {
options.dataType = 'stream';
}
return { url, options };
}
/**
* request oss server
*/
// eslint-disable-next-line no-explicit-any
async request(params) {
const { url, options } = this.createHttpClientRequestParams(params);
const result = await this.#httpClient.request(url, options);
debug('response %s %s, got %s, headers: %j', params.method, url, result.status, result.headers);
if (!params.successStatuses?.includes(result.status)) {
const err = await this.#createClientException(result);
if (params.streaming && result.res) {
// consume the response stream
await (0, stream_wormhole_1.sendToWormhole)(result.res);
}
throw err;
}
let data = result.data;
if (params.xmlResponse) {
data = await this.#xml2json(result.data);
}
return {
data,
res: result.res,
};
}
/** private methods */
#initOptions(options) {
node_assert_1.default.ok(options.accessKeyId && options.accessKeySecret, 'require accessKeyId and accessKeySecret');
node_assert_1.default.ok(options.endpoint, 'require endpoint');
let timeout = 60_000;
if (options.timeout) {
if (typeof options.timeout === 'string') {
timeout = (0, ms_1.default)(options.timeout);
}
else {
timeout = options.timeout;
}
}
const initOptions = {
accessKeyId: options.accessKeyId.trim(),
accessKeySecret: options.accessKeySecret.trim(),
endpoint: options.endpoint,
region: options.region ?? 'oss-cn-hangzhou',
internal: options.internal ?? false,
isRequestPay: options.isRequestPay ?? false,
timeout,
};
return initOptions;
}
/**
* Get User-Agent for Node.js
* @example
* oss-client/2.0.0 Node.js/5.3.0 (darwin; arm64)
*/
#getUserAgent() {
// TODO: should read version from package.json
const sdk = 'oss-client/2.0.0';
const platform = `Node.js/${process.version.slice(1)} (${process.platform}; ${process.arch})`;
return `${sdk} ${platform}`;
}
// eslint-disable-next-line no-explicit-any
async #xml2json(xml) {
if (Buffer.isBuffer(xml)) {
xml = xml.toString();
}
debug('xml2json %o', xml);
return (await (0, xml2js_1.parseStringPromise)(xml, {
explicitRoot: false,
explicitArray: false,
}));
}
async #createClientException(result) {
let err;
let requestId = result.headers['x-oss-request-id'] ?? '';
let hostId = '';
const status = result.status;
if (!result.data || result.data.length === 0) {
// HEAD not exists resource
if (status === 404) {
err = new index_js_2.OSSClientError(status, 'NoSuchKey', 'Object not exists', requestId, hostId);
}
else if (status === 412) {
err = new index_js_2.OSSClientError(status, 'PreconditionFailed', 'Pre condition failed', requestId, hostId);
}
else {
err = new index_js_2.OSSClientError(status, 'Unknown', `Unknown error, status=${status}, raw error=${result}`, requestId, hostId);
}
}
else {
const xml = result.data.toString();
debug('request response error xml: %o', xml);
let info;
try {
info = await this.#xml2json(xml);
}
catch (e) {
const message = e instanceof Error ? e.message : String(e);
err = new index_js_2.OSSClientError(status, 'PreconditionFailed', `${message} (raw xml=${JSON.stringify(xml)})`, requestId, hostId);
return err;
}
let message = info?.Message ??
`Unknown request error, status=${result.status}, raw xml=${JSON.stringify(xml)}`;
if (info?.Condition) {
message += ` (condition=${info.Condition})`;
}
if (info?.RequestId) {
requestId = info.RequestId;
}
if (info?.HostId) {
hostId = info.HostId;
}
err = new index_js_2.OSSClientError(status, info?.Code ?? 'Unknown', message, requestId, hostId);
// https://help.aliyun.com/zh/oss/support/http-status-code-409#section-rmc-hvd-j38
if (info?.Code === 'PositionNotEqualToLength' &&
result.headers['x-oss-next-append-position']) {
err.nextAppendPosition = result.headers['x-oss-next-append-position'];
}
}
debug('generate error %o', err);
return err;
}
}
exports.OSSBaseClient = OSSBaseClient;
// /**
// * Object operations
// */
// merge(proto, require('./common/object'));
// merge(proto, require('./object'));
// merge(proto, require('./common/image'));
// /**
// * Bucket operations
// */
// merge(proto, require('./common/bucket'));
// merge(proto, require('./bucket'));
// // multipart upload
// merge(proto, require('./managed-upload'));
// /**
// * RTMP operations
// */
// merge(proto, require('./rtmp'));
// /**
// * common multipart-copy
// */
// merge(proto, require('./common/multipart-copy'));
// /**
// * Common module parallel
// */
// merge(proto, require('./common/parallel'));
// /**
// * Multipart operations
// */
// merge(proto, require('./common/multipart'));
// /**
// * ImageClient class
// */
// Client.ImageClient = require('./image')(Client);
// /**
// * Cluster Client class
// */
// Client.ClusterClient = require('./cluster')(Client);
// /**
// * STS Client class
// */
// Client.STS = require('./sts');
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiT1NTQmFzZUNsaWVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9PU1NCYXNlQ2xpZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7OztBQUFBLHlDQUFxQztBQUNyQyw4REFBaUM7QUFDakMsNkNBQXlDO0FBQ3pDLHlDQUFvQztBQUVwQyxxREFBaUQ7QUFDakQsbUNBQTRDO0FBQzVDLHFDQUF1RTtBQUN2RSxnREFBd0I7QUFDeEIsbUNBS2dCO0FBQ2hCLDRDQUFvQjtBQUNwQiw4Q0FJeUI7QUFNekIsK0NBQWtEO0FBRWxELE1BQU0sS0FBSyxHQUFHLElBQUEsb0JBQVEsRUFBQyxtQkFBbUIsQ0FBQyxDQUFDO0FBMkI1QyxNQUFzQixhQUFhO0lBQ3hCLFdBQVcsR0FBRyxJQUFJLG1CQUFVLEVBQUUsQ0FBQztJQUMvQixVQUFVLENBQVM7SUFDVCxPQUFPLENBQXVCO0lBRWpELFlBQVksT0FBaUM7UUFDM0MsSUFBSSxDQUFDLE9BQU8sR0FBRyxJQUFJLENBQUMsWUFBWSxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBQzFDLElBQUksQ0FBQyxVQUFVLEdBQUcsSUFBSSxDQUFDLGFBQWEsRUFBRSxDQUFDO0lBQ3pDLENBQUM7SUFFRCxxQkFBcUI7SUFFckI7O09BRUc7SUFDSCxTQUFTLENBQUMsWUFBb0I7UUFDNUIsS0FBSyxDQUFDLGdDQUFnQyxFQUFFLFlBQVksQ0FBQyxDQUFDO1FBQ3RELE9BQU8sSUFBQSwyQkFBZ0IsRUFBQyxJQUFJLENBQUMsT0FBTyxDQUFDLGVBQWUsRUFBRSxZQUFZLENBQUMsQ0FBQztJQUN0RSxDQUFDO0lBRUQsd0JBQXdCO0lBRXhCOzs7Ozs7Ozs7Ozs7T0FZRztJQUNPLGFBQWEsQ0FDckIsTUFBYyxFQUNkLFFBQWdCLEVBQ2hCLE9BQTRCLEVBQzVCLFdBQStCO1FBRS9CLE1BQU0sWUFBWSxHQUFHLElBQUEsK0JBQW9CLEVBQUMsTUFBTSxDQUFDLFdBQVcsRUFBRSxFQUFFLFFBQVEsRUFBRTtZQUN4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