padlocal-client-ts
Version:
Padlocal ts client
131 lines • 6.48 kB
JavaScript
;
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.WeChatHttpProxy = void 0;
const RetryStrategy_1 = require("../utils/RetryStrategy");
const ByteUtils_1 = require("../utils/ByteUtils");
const http_1 = __importDefault(require("http"));
const erros_1 = require("./erros");
const padlocal_pb_1 = require("../proto/padlocal_pb");
const https = __importStar(require("https"));
const Log_1 = __importDefault(require("../utils/Log"));
const LOGPRE = "[HTTP]";
class WeChatHttpProxy {
constructor(traceId, request) {
this.retryStrategy = RetryStrategy_1.RetryStrategy.getStrategy(RetryStrategy_1.RetryStrategyRule.FAST, 5); // retry almost 1 min
this.traceId = traceId;
this.request = request;
}
send() {
return __awaiter(this, void 0, void 0, function* () {
try {
return yield this._sendImpl();
}
catch (e) {
if (!(e instanceof erros_1.IOError)) {
throw e;
}
if (!this.retryStrategy.canRetry()) {
const message = `[tid:${this.traceId}] Fail to send http request, [${this.request.getMethod()}]${this.request.getUrl()}, after max retry:${this.retryStrategy.retryCount}`;
throw new erros_1.IOError(e, message);
}
const delay = this.retryStrategy.nextRetryDelay();
Log_1.default.silly(LOGPRE, `[tid:${this.traceId}] http #${this.retryStrategy.retryCount} retry request, after delay: ${delay}ms, [${this.request.getMethod()}]${this.request.getUrl()}`);
return new Promise((resolve, reject) => {
setTimeout(() => __awaiter(this, void 0, void 0, function* () {
try {
const response = yield this.send();
resolve(response);
}
catch (e) {
reject(e);
}
}), delay);
});
}
});
}
_sendImpl() {
return __awaiter(this, void 0, void 0, function* () {
Log_1.default.silly(LOGPRE, `[tid:${this.traceId}] http send, [${this.request.getMethod()}]${this.request.getUrl()}`);
return new Promise((resolve, reject) => {
let responseDataBuffer = ByteUtils_1.newBytes();
const headers = {};
for (const [key, value] of this.request.getHeadersMap().getEntryList()) {
headers[key] = value;
}
const url = new URL(this.request.getUrl());
const protocol = url.protocol === "https:" ? https : http_1.default;
const req = protocol.request(this.request.getUrl(), {
method: this.request.getMethod(),
headers,
timeout: this.request.getTimeout(),
}, (res) => {
const wechatResponse = new padlocal_pb_1.WeChatHttpResponse();
if (res.statusCode !== undefined) {
wechatResponse.setStatuscode(res.statusCode);
}
for (const key of Object.keys(res.headers)) {
wechatResponse.getHeadersMap().set(key, res.headers[key] + "");
}
res.on("data", (chunk) => {
responseDataBuffer = ByteUtils_1.joinBytes(responseDataBuffer, chunk);
});
res.on("end", () => {
Log_1.default.silly(LOGPRE, `[tid:${this.traceId}] http receive, response: ${ByteUtils_1.bytesToHexString(responseDataBuffer, ByteUtils_1.MAX_LOG_BYTES_LEN)}`);
wechatResponse.setPayload(responseDataBuffer);
resolve(wechatResponse);
});
});
req.on("timeout", () => {
req.destroy(new erros_1.IOError("timeout"));
});
req.on("error", (e) => {
const errorCode = e.code;
// dns resolve failed
if (errorCode === "ENOTFOUND") {
e = new erros_1.IOError(e, "ENOTFOUND");
}
else if (errorCode === "ETIMEDOUT") {
e = new erros_1.IOError(e, "ETIMEDOUT");
}
reject(e);
});
this.request.getPayload() && req.write(this.request.getPayload());
req.end();
});
});
}
}
exports.WeChatHttpProxy = WeChatHttpProxy;
//# sourceMappingURL=WeChatHttpProxy.js.map