86 lines
3.7 KiB
JavaScript
86 lines
3.7 KiB
JavaScript
"use strict";
|
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
};
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
exports.error = exports.sendRequest = void 0;
|
|
const file_request_1 = __importDefault(require("./file-request"));
|
|
const destination_request_1 = __importDefault(require("./destination-request"));
|
|
const messages_1 = require("../messages");
|
|
const logger_1 = __importDefault(require("../utils/logger"));
|
|
const http_header_parser_1 = require("./http-header-parser");
|
|
// An empty line that indicates the end of the header section
|
|
// https://tools.ietf.org/html/rfc7230#section-3
|
|
const HTTP_BODY_SEPARATOR = '\r\n\r\n';
|
|
// Used to calculate the recommended maximum header size
|
|
// See getRecommendedMaxHeaderSize() below
|
|
const HEADER_SIZE_MULTIPLIER = 2;
|
|
const HEADER_SIZE_CALCULATION_PRECISION = 2;
|
|
// Calculates the HTTP header size in bytes that a customer should specify via the
|
|
// --max-http-header-size Node option so that the proxy can process the site
|
|
// https://nodejs.org/api/cli.html#cli_max_http_header_size_size
|
|
// Example:
|
|
// (8211 * 2).toPrecision(2) -> 16 * 10^3 -> 16000
|
|
function getRecommendedMaxHeaderSize(currentHeaderSize) {
|
|
return Number((currentHeaderSize * HEADER_SIZE_MULTIPLIER).toPrecision(HEADER_SIZE_CALCULATION_PRECISION));
|
|
}
|
|
function sendRequest(ctx) {
|
|
return new Promise(resolve => {
|
|
const req = ctx.isFileProtocol ? new file_request_1.default(ctx.reqOpts.url) : new destination_request_1.default(ctx.reqOpts, ctx.serverInfo.cacheRequests);
|
|
ctx.goToNextStage = false;
|
|
req.on('response', (res) => {
|
|
if (ctx.isWebSocketConnectionReset) {
|
|
res.destroy();
|
|
resolve();
|
|
return;
|
|
}
|
|
ctx.destRes = res;
|
|
ctx.goToNextStage = true;
|
|
ctx.buildContentInfo();
|
|
ctx.calculateIsDestResReadableEnded();
|
|
ctx.createCacheEntry(res);
|
|
resolve();
|
|
});
|
|
req.on('error', err => {
|
|
// NOTE: Sometimes the underlying socket emits an error event. But if we have a response body,
|
|
// we can still process such requests. (B234324)
|
|
if (!ctx.isDestResReadableEnded) {
|
|
const rawHeadersStr = err.rawPacket ? err.rawPacket.asciiSlice().split(HTTP_BODY_SEPARATOR)[0].split('\n').splice(1).join('\n') : '';
|
|
const headerSize = rawHeadersStr.length;
|
|
error(ctx, (0, messages_1.getText)(messages_1.MESSAGE.destConnectionTerminated, {
|
|
url: ctx.dest.url,
|
|
message: messages_1.MESSAGE.nodeError[err.code] || err.toString(),
|
|
headerSize: headerSize,
|
|
recommendedMaxHeaderSize: getRecommendedMaxHeaderSize(headerSize).toString(),
|
|
invalidChars: (0, http_header_parser_1.getFormattedInvalidCharacters)(rawHeadersStr),
|
|
}));
|
|
}
|
|
resolve();
|
|
});
|
|
req.on('fatalError', err => {
|
|
if (ctx.isFileProtocol)
|
|
logger_1.default.destination.onFileReadError(ctx, err);
|
|
error(ctx, err);
|
|
resolve();
|
|
});
|
|
req.on('socketHangUp', () => {
|
|
ctx.req.socket.end();
|
|
resolve();
|
|
});
|
|
if (req instanceof file_request_1.default) {
|
|
logger_1.default.destination.onFileRead(ctx);
|
|
req.init();
|
|
}
|
|
});
|
|
}
|
|
exports.sendRequest = sendRequest;
|
|
function error(ctx, err) {
|
|
if (ctx.isPage && !ctx.isIframe)
|
|
ctx.session.handlePageError(ctx, err);
|
|
else if (ctx.isAjax)
|
|
ctx.req.destroy();
|
|
else
|
|
ctx.closeWithError(500, err.toString());
|
|
}
|
|
exports.error = error;
|