UNPKG

oss-client

Version:

Aliyun OSS(Object Storage Service) Node.js Client

330 lines 24.5 kB
"use strict"; 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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