@remotion/lambda 4.0.178 → 4.0.179
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/functions/helpers/check-if-render-exists.js +1 -1
- package/dist/functions/helpers/get-cleanup-progress.d.ts +3 -1
- package/dist/functions/helpers/get-cleanup-progress.js +3 -1
- package/dist/functions/helpers/get-files-to-delete.d.ts +3 -1
- package/dist/functions/helpers/get-files-to-delete.js +35 -1
- package/dist/functions/helpers/get-lambdas-invoked-stats.d.ts +5 -0
- package/dist/functions/helpers/get-lambdas-invoked-stats.js +12 -0
- package/dist/shared/chunk-progress.d.ts +2 -1
- package/dist/shared/chunk-progress.js +2 -2
- package/dist/shared/serialize-props.d.ts +14 -0
- package/dist/shared/serialize-props.js +36 -0
- package/package.json +9 -9
- package/remotionlambda-arm64.zip +0 -0
- package/dist/functions/helpers/http-handler/custom-handler.d.ts +0 -42
- package/dist/functions/helpers/http-handler/custom-handler.js +0 -235
- package/dist/functions/helpers/http-handler/get-transformed-headers.d.ts +0 -5
- package/dist/functions/helpers/http-handler/get-transformed-headers.js +0 -14
- package/dist/functions/helpers/http-handler/set-connection-timeout.d.ts +0 -3
- package/dist/functions/helpers/http-handler/set-connection-timeout.js +0 -26
- package/dist/functions/helpers/http-handler/set-socket-keep-alive.d.ts +0 -7
- package/dist/functions/helpers/http-handler/set-socket-keep-alive.js +0 -12
- package/dist/functions/helpers/http-handler/set-socket-timeout.d.ts +0 -3
- package/dist/functions/helpers/http-handler/set-socket-timeout.js +0 -13
- package/dist/functions/helpers/http-handler/write-request-body.d.ts +0 -13
- package/dist/functions/helpers/http-handler/write-request-body.js +0 -70
|
@@ -5,7 +5,7 @@ const constants_1 = require("../../shared/constants");
|
|
|
5
5
|
const checkIfRenderExists = (contents, renderId, bucketName, region) => {
|
|
6
6
|
const initializedExists = Boolean(contents.find((c) => {
|
|
7
7
|
var _a;
|
|
8
|
-
return (_a = c.Key) === null || _a === void 0 ? void 0 : _a.startsWith((0, constants_1.
|
|
8
|
+
return (_a = c.Key) === null || _a === void 0 ? void 0 : _a.startsWith((0, constants_1.initalizedMetadataKey)(renderId));
|
|
9
9
|
}));
|
|
10
10
|
if (!initializedExists) {
|
|
11
11
|
// ! Error message is checked in progress handler and will be retried. Make sure to update
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import type { _Object } from '@aws-sdk/client-s3';
|
|
2
2
|
import type { CleanupInfo } from '../../shared/constants';
|
|
3
|
-
export declare const getCleanupProgress: ({ contents, output, chunkCount, renderId, }: {
|
|
3
|
+
export declare const getCleanupProgress: ({ contents, output, chunkCount, renderId, hasAudio, hasVideo, }: {
|
|
4
4
|
contents: _Object[];
|
|
5
5
|
output: string | null;
|
|
6
6
|
chunkCount: number;
|
|
7
7
|
renderId: string;
|
|
8
|
+
hasAudio: boolean;
|
|
9
|
+
hasVideo: boolean;
|
|
8
10
|
}) => null | CleanupInfo;
|
|
@@ -2,13 +2,15 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.getCleanupProgress = void 0;
|
|
4
4
|
const get_files_to_delete_1 = require("./get-files-to-delete");
|
|
5
|
-
const getCleanupProgress = ({ contents, output, chunkCount, renderId, }) => {
|
|
5
|
+
const getCleanupProgress = ({ contents, output, chunkCount, renderId, hasAudio, hasVideo, }) => {
|
|
6
6
|
if (output === null) {
|
|
7
7
|
return null;
|
|
8
8
|
}
|
|
9
9
|
const filesToDelete = (0, get_files_to_delete_1.getFilesToDelete)({
|
|
10
10
|
chunkCount,
|
|
11
11
|
renderId,
|
|
12
|
+
hasAudio,
|
|
13
|
+
hasVideo,
|
|
12
14
|
});
|
|
13
15
|
const filesStillThere = contents.filter((c) => {
|
|
14
16
|
return filesToDelete.find((f) => {
|
|
@@ -2,7 +2,9 @@ export type CleanupJob = {
|
|
|
2
2
|
name: string;
|
|
3
3
|
type: 'exact' | 'prefix';
|
|
4
4
|
};
|
|
5
|
-
export declare const getFilesToDelete: ({ chunkCount, renderId, }: {
|
|
5
|
+
export declare const getFilesToDelete: ({ chunkCount, renderId, hasVideo, hasAudio, }: {
|
|
6
6
|
chunkCount: number;
|
|
7
7
|
renderId: string;
|
|
8
|
+
hasVideo: boolean;
|
|
9
|
+
hasAudio: boolean;
|
|
8
10
|
}) => CleanupJob[];
|
|
@@ -2,17 +2,51 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.getFilesToDelete = void 0;
|
|
4
4
|
const constants_1 = require("../../shared/constants");
|
|
5
|
-
const getFilesToDelete = ({ chunkCount, renderId, }) => {
|
|
5
|
+
const getFilesToDelete = ({ chunkCount, renderId, hasVideo, hasAudio, }) => {
|
|
6
|
+
const videoChunks = hasVideo
|
|
7
|
+
? new Array(chunkCount).fill(true).map((_x, i) => (0, constants_1.chunkKeyForIndex)({
|
|
8
|
+
index: i,
|
|
9
|
+
renderId,
|
|
10
|
+
type: 'video',
|
|
11
|
+
}))
|
|
12
|
+
: [];
|
|
13
|
+
const audioChunks = hasAudio
|
|
14
|
+
? new Array(chunkCount).fill(true).map((_x, i) => (0, constants_1.chunkKeyForIndex)({
|
|
15
|
+
index: i,
|
|
16
|
+
renderId,
|
|
17
|
+
type: 'audio',
|
|
18
|
+
}))
|
|
19
|
+
: [];
|
|
6
20
|
const lambdaTimings = new Array(chunkCount)
|
|
7
21
|
.fill(true)
|
|
8
22
|
.map((_x, i) => (0, constants_1.lambdaTimingsPrefixForChunk)(renderId, i));
|
|
9
23
|
return [
|
|
24
|
+
{
|
|
25
|
+
name: (0, constants_1.lambdaChunkInitializedPrefix)(renderId),
|
|
26
|
+
type: 'prefix',
|
|
27
|
+
},
|
|
28
|
+
...videoChunks.map((i) => {
|
|
29
|
+
return {
|
|
30
|
+
name: i,
|
|
31
|
+
type: 'exact',
|
|
32
|
+
};
|
|
33
|
+
}),
|
|
34
|
+
...audioChunks.map((i) => {
|
|
35
|
+
return {
|
|
36
|
+
name: i,
|
|
37
|
+
type: 'exact',
|
|
38
|
+
};
|
|
39
|
+
}),
|
|
10
40
|
...lambdaTimings.map((i) => {
|
|
11
41
|
return {
|
|
12
42
|
name: i,
|
|
13
43
|
type: 'prefix',
|
|
14
44
|
};
|
|
15
45
|
}),
|
|
46
|
+
{
|
|
47
|
+
name: (0, constants_1.encodingProgressKey)(renderId),
|
|
48
|
+
type: 'exact',
|
|
49
|
+
},
|
|
16
50
|
];
|
|
17
51
|
};
|
|
18
52
|
exports.getFilesToDelete = getFilesToDelete;
|
|
@@ -1,2 +1,14 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getLambdasInvokedStats = void 0;
|
|
4
|
+
const constants_1 = require("../../shared/constants");
|
|
5
|
+
const parse_lambda_initialized_key_1 = require("../../shared/parse-lambda-initialized-key");
|
|
6
|
+
const getLambdasInvokedStats = ({ contents, renderId, }) => {
|
|
7
|
+
const lambdasInvoked = contents
|
|
8
|
+
.filter((c) => { var _a; return (_a = c.Key) === null || _a === void 0 ? void 0 : _a.startsWith((0, constants_1.lambdaChunkInitializedPrefix)(renderId)); })
|
|
9
|
+
.filter((c) => (0, parse_lambda_initialized_key_1.parseLambdaInitializedKey)(c.Key).attempt === 1);
|
|
10
|
+
return {
|
|
11
|
+
lambdasInvoked: lambdasInvoked.length,
|
|
12
|
+
};
|
|
13
|
+
};
|
|
14
|
+
exports.getLambdasInvokedStats = getLambdasInvokedStats;
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
export declare const writeLambdaInitializedFile: ({ bucketName, expectedBucketOwner, attempt, chunk, renderId, }: {
|
|
1
|
+
export declare const writeLambdaInitializedFile: ({ bucketName, expectedBucketOwner, attempt, chunk, renderId, framesRendered, }: {
|
|
2
2
|
bucketName: string;
|
|
3
3
|
expectedBucketOwner: string;
|
|
4
4
|
renderId: string;
|
|
5
5
|
chunk: number;
|
|
6
6
|
attempt: number;
|
|
7
|
+
framesRendered: number;
|
|
7
8
|
}) => Promise<void>;
|
|
8
9
|
export declare const getProgressOfChunk: (etag: string) => number;
|
|
@@ -2010,11 +2010,11 @@ const etags = [
|
|
|
2010
2010
|
'"c5b2cebf15b205503560c4e8e6d1ea78"',
|
|
2011
2011
|
'"5ec829debe54b19a5f78d9a65b900a39"',
|
|
2012
2012
|
];
|
|
2013
|
-
const writeLambdaInitializedFile = ({ bucketName, expectedBucketOwner, attempt, chunk, renderId, }) => {
|
|
2013
|
+
const writeLambdaInitializedFile = ({ bucketName, expectedBucketOwner, attempt, chunk, renderId, framesRendered, }) => {
|
|
2014
2014
|
return (0, io_1.lambdaWriteFile)({
|
|
2015
2015
|
privacy: 'private',
|
|
2016
2016
|
bucketName,
|
|
2017
|
-
body:
|
|
2017
|
+
body: String(framesRendered),
|
|
2018
2018
|
key: (0, constants_1.lambdaChunkInitializedKey)({
|
|
2019
2019
|
renderId,
|
|
2020
2020
|
chunk,
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
type SerializedJSONWithCustomFields = {
|
|
2
|
+
serializedString: string;
|
|
3
|
+
customDateUsed: boolean;
|
|
4
|
+
customFileUsed: boolean;
|
|
5
|
+
mapUsed: boolean;
|
|
6
|
+
setUsed: boolean;
|
|
7
|
+
};
|
|
8
|
+
export declare const FILE_TOKEN = "remotion-file:";
|
|
9
|
+
export declare const serializeJSONWithDate: ({ data, indent, staticBase, }: {
|
|
10
|
+
data: Record<string, unknown>;
|
|
11
|
+
indent: number | undefined;
|
|
12
|
+
staticBase: string | null;
|
|
13
|
+
}) => SerializedJSONWithCustomFields;
|
|
14
|
+
export {};
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// Must keep this file in sync with the one in packages/core/src/input-props-serialization.ts!
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
exports.serializeJSONWithDate = exports.FILE_TOKEN = void 0;
|
|
5
|
+
const DATE_TOKEN = 'remotion-date:';
|
|
6
|
+
exports.FILE_TOKEN = 'remotion-file:';
|
|
7
|
+
const serializeJSONWithDate = ({ data, indent, staticBase, }) => {
|
|
8
|
+
let customDateUsed = false;
|
|
9
|
+
let customFileUsed = false;
|
|
10
|
+
let mapUsed = false;
|
|
11
|
+
let setUsed = false;
|
|
12
|
+
const serializedString = JSON.stringify(data, function (key, value) {
|
|
13
|
+
const item = this[key];
|
|
14
|
+
if (item instanceof Date) {
|
|
15
|
+
customDateUsed = true;
|
|
16
|
+
return `${DATE_TOKEN}${item.toISOString()}`;
|
|
17
|
+
}
|
|
18
|
+
if (item instanceof Map) {
|
|
19
|
+
mapUsed = true;
|
|
20
|
+
return value;
|
|
21
|
+
}
|
|
22
|
+
if (item instanceof Set) {
|
|
23
|
+
setUsed = true;
|
|
24
|
+
return value;
|
|
25
|
+
}
|
|
26
|
+
if (typeof item === 'string' &&
|
|
27
|
+
staticBase !== null &&
|
|
28
|
+
item.startsWith(staticBase)) {
|
|
29
|
+
customFileUsed = true;
|
|
30
|
+
return `${exports.FILE_TOKEN}${item.replace(staticBase + '/', '')}`;
|
|
31
|
+
}
|
|
32
|
+
return value;
|
|
33
|
+
}, indent);
|
|
34
|
+
return { serializedString, customDateUsed, customFileUsed, mapUsed, setUsed };
|
|
35
|
+
};
|
|
36
|
+
exports.serializeJSONWithDate = serializeJSONWithDate;
|
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"url": "https://github.com/remotion-dev/remotion/tree/main/packages/lambda"
|
|
4
4
|
},
|
|
5
5
|
"name": "@remotion/lambda",
|
|
6
|
-
"version": "4.0.
|
|
6
|
+
"version": "4.0.179",
|
|
7
7
|
"description": "Render Remotion videos on AWS Lambda",
|
|
8
8
|
"main": "dist/index.js",
|
|
9
9
|
"sideEffects": false,
|
|
@@ -22,11 +22,11 @@
|
|
|
22
22
|
"@aws-sdk/s3-request-presigner": "3.583.0",
|
|
23
23
|
"mime-types": "2.1.34",
|
|
24
24
|
"zod": "3.22.3",
|
|
25
|
-
"@remotion/
|
|
26
|
-
"@remotion/
|
|
27
|
-
"@remotion/cli": "4.0.
|
|
28
|
-
"
|
|
29
|
-
"remotion": "4.0.
|
|
25
|
+
"@remotion/renderer": "4.0.179",
|
|
26
|
+
"@remotion/bundler": "4.0.179",
|
|
27
|
+
"@remotion/cli": "4.0.179",
|
|
28
|
+
"remotion": "4.0.179",
|
|
29
|
+
"@remotion/streaming": "4.0.179"
|
|
30
30
|
},
|
|
31
31
|
"devDependencies": {
|
|
32
32
|
"@types/mime-types": "2.1.1",
|
|
@@ -35,11 +35,11 @@
|
|
|
35
35
|
"pureimage": "0.4.13",
|
|
36
36
|
"vitest": "0.31.1",
|
|
37
37
|
"zip-lib": "^0.7.2",
|
|
38
|
-
"@remotion/bundler": "4.0.
|
|
39
|
-
"@remotion/compositor-linux-arm64-gnu": "4.0.
|
|
38
|
+
"@remotion/bundler": "4.0.179",
|
|
39
|
+
"@remotion/compositor-linux-arm64-gnu": "4.0.179"
|
|
40
40
|
},
|
|
41
41
|
"peerDependencies": {
|
|
42
|
-
"@remotion/bundler": "4.0.
|
|
42
|
+
"@remotion/bundler": "4.0.179"
|
|
43
43
|
},
|
|
44
44
|
"publishConfig": {
|
|
45
45
|
"access": "public"
|
package/remotionlambda-arm64.zip
CHANGED
|
Binary file
|
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
/// <reference types="node" />
|
|
2
|
-
/// <reference types="node" />
|
|
3
|
-
import type { HttpHandler, HttpRequest } from '@smithy/protocol-http';
|
|
4
|
-
import { HttpResponse } from '@smithy/protocol-http';
|
|
5
|
-
import type { HttpHandlerOptions, NodeHttpHandlerOptions, Provider } from '@smithy/types';
|
|
6
|
-
import { Agent as hAgent } from 'http';
|
|
7
|
-
import { Agent as hsAgent } from 'https';
|
|
8
|
-
/**
|
|
9
|
-
* Node.js system error codes that indicate timeout.
|
|
10
|
-
* @deprecated use NODEJS_TIMEOUT_ERROR_CODES from @smithy/service-error-classification/constants
|
|
11
|
-
*/
|
|
12
|
-
export declare const NODEJS_TIMEOUT_ERROR_CODES: string[];
|
|
13
|
-
export { NodeHttpHandlerOptions };
|
|
14
|
-
export declare const DEFAULT_REQUEST_TIMEOUT = 0;
|
|
15
|
-
export declare class NodeHttpHandler implements HttpHandler<NodeHttpHandlerOptions> {
|
|
16
|
-
private config?;
|
|
17
|
-
private configProvider;
|
|
18
|
-
private socketWarningTimestamp;
|
|
19
|
-
readonly metadata: {
|
|
20
|
-
handlerProtocol: string;
|
|
21
|
-
};
|
|
22
|
-
/**
|
|
23
|
-
* @returns the input if it is an HttpHandler of any class,
|
|
24
|
-
* or instantiates a new instance of this handler.
|
|
25
|
-
*/
|
|
26
|
-
static create(instanceOrOptions?: HttpHandler<any> | NodeHttpHandlerOptions | Provider<NodeHttpHandlerOptions | void>): NodeHttpHandler | HttpHandler<any>;
|
|
27
|
-
/**
|
|
28
|
-
* @internal
|
|
29
|
-
*
|
|
30
|
-
* @param agent - http(s) agent in use by the NodeHttpHandler instance.
|
|
31
|
-
* @returns timestamp of last emitted warning.
|
|
32
|
-
*/
|
|
33
|
-
static checkSocketUsage(agent: hAgent | hsAgent, socketWarningTimestamp: number): number;
|
|
34
|
-
constructor(options?: NodeHttpHandlerOptions | Provider<NodeHttpHandlerOptions | void>);
|
|
35
|
-
private resolveDefaultConfig;
|
|
36
|
-
destroy(): void;
|
|
37
|
-
handle(request: HttpRequest, { abortSignal }?: HttpHandlerOptions): Promise<{
|
|
38
|
-
response: HttpResponse;
|
|
39
|
-
}>;
|
|
40
|
-
updateHttpClientConfig(key: keyof NodeHttpHandlerOptions, value: NodeHttpHandlerOptions[typeof key]): void;
|
|
41
|
-
httpHandlerConfigs(): NodeHttpHandlerOptions;
|
|
42
|
-
}
|
|
@@ -1,235 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.NodeHttpHandler = exports.DEFAULT_REQUEST_TIMEOUT = exports.NODEJS_TIMEOUT_ERROR_CODES = void 0;
|
|
4
|
-
const protocol_http_1 = require("@smithy/protocol-http");
|
|
5
|
-
const querystring_builder_1 = require("@smithy/querystring-builder");
|
|
6
|
-
const http_1 = require("http");
|
|
7
|
-
const https_1 = require("https");
|
|
8
|
-
const get_transformed_headers_1 = require("./get-transformed-headers");
|
|
9
|
-
const set_connection_timeout_1 = require("./set-connection-timeout");
|
|
10
|
-
const set_socket_keep_alive_1 = require("./set-socket-keep-alive");
|
|
11
|
-
const set_socket_timeout_1 = require("./set-socket-timeout");
|
|
12
|
-
const write_request_body_1 = require("./write-request-body");
|
|
13
|
-
/**
|
|
14
|
-
* Node.js system error codes that indicate timeout.
|
|
15
|
-
* @deprecated use NODEJS_TIMEOUT_ERROR_CODES from @smithy/service-error-classification/constants
|
|
16
|
-
*/
|
|
17
|
-
exports.NODEJS_TIMEOUT_ERROR_CODES = ['ECONNRESET', 'EPIPE', 'ETIMEDOUT'];
|
|
18
|
-
exports.DEFAULT_REQUEST_TIMEOUT = 0;
|
|
19
|
-
class NodeHttpHandler {
|
|
20
|
-
/**
|
|
21
|
-
* @returns the input if it is an HttpHandler of any class,
|
|
22
|
-
* or instantiates a new instance of this handler.
|
|
23
|
-
*/
|
|
24
|
-
static create(instanceOrOptions) {
|
|
25
|
-
if (typeof (instanceOrOptions === null || instanceOrOptions === void 0 ? void 0 : instanceOrOptions.handle) === 'function') {
|
|
26
|
-
// is already an instance of HttpHandler.
|
|
27
|
-
return instanceOrOptions;
|
|
28
|
-
}
|
|
29
|
-
// input is ctor options or undefined.
|
|
30
|
-
return new NodeHttpHandler(instanceOrOptions);
|
|
31
|
-
}
|
|
32
|
-
/**
|
|
33
|
-
* @internal
|
|
34
|
-
*
|
|
35
|
-
* @param agent - http(s) agent in use by the NodeHttpHandler instance.
|
|
36
|
-
* @returns timestamp of last emitted warning.
|
|
37
|
-
*/
|
|
38
|
-
static checkSocketUsage(agent, socketWarningTimestamp) {
|
|
39
|
-
var _a, _b, _c, _d;
|
|
40
|
-
// note, maxSockets is per origin.
|
|
41
|
-
const { sockets, requests, maxSockets } = agent;
|
|
42
|
-
if (typeof maxSockets !== 'number' || maxSockets === Infinity) {
|
|
43
|
-
return socketWarningTimestamp;
|
|
44
|
-
}
|
|
45
|
-
const interval = 15000;
|
|
46
|
-
if (Date.now() - interval < socketWarningTimestamp) {
|
|
47
|
-
return socketWarningTimestamp;
|
|
48
|
-
}
|
|
49
|
-
if (sockets && requests) {
|
|
50
|
-
for (const origin in sockets) {
|
|
51
|
-
const socketsInUse = (_b = (_a = sockets[origin]) === null || _a === void 0 ? void 0 : _a.length) !== null && _b !== void 0 ? _b : 0;
|
|
52
|
-
const requestsEnqueued = (_d = (_c = requests[origin]) === null || _c === void 0 ? void 0 : _c.length) !== null && _d !== void 0 ? _d : 0;
|
|
53
|
-
/**
|
|
54
|
-
* Running at maximum socket usage can be intentional and normal.
|
|
55
|
-
* That is why this warning emits at a delay which can be seen
|
|
56
|
-
* at the call site's setTimeout wrapper. The warning will be cancelled
|
|
57
|
-
* if the request finishes in a reasonable amount of time regardless
|
|
58
|
-
* of socket saturation.
|
|
59
|
-
*
|
|
60
|
-
* Additionally, when the warning is emitted, there is an interval
|
|
61
|
-
* lockout.
|
|
62
|
-
*/
|
|
63
|
-
if (socketsInUse >= maxSockets && requestsEnqueued >= 2 * maxSockets) {
|
|
64
|
-
console.warn('@smithy/node-http-handler:WARN', `socket usage at capacity=${socketsInUse} and ${requestsEnqueued} additional requests are enqueued.`, 'See https://docs.aws.amazon.com/sdk-for-javascript/v3/developer-guide/node-configuring-maxsockets.html', 'or increase socketAcquisitionWarningTimeout=(millis) in the NodeHttpHandler config.');
|
|
65
|
-
return Date.now();
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
return socketWarningTimestamp;
|
|
70
|
-
}
|
|
71
|
-
constructor(options) {
|
|
72
|
-
this.socketWarningTimestamp = 0;
|
|
73
|
-
// Node http handler is hard-coded to http/1.1: https://github.com/nodejs/node/blob/ff5664b83b89c55e4ab5d5f60068fb457f1f5872/lib/_http_server.js#L286
|
|
74
|
-
this.metadata = { handlerProtocol: 'http/1.1' };
|
|
75
|
-
this.configProvider = new Promise((resolve, reject) => {
|
|
76
|
-
if (typeof options === 'function') {
|
|
77
|
-
options()
|
|
78
|
-
.then((_options) => {
|
|
79
|
-
resolve(this.resolveDefaultConfig(_options));
|
|
80
|
-
})
|
|
81
|
-
.catch(reject);
|
|
82
|
-
}
|
|
83
|
-
else {
|
|
84
|
-
resolve(this.resolveDefaultConfig(options));
|
|
85
|
-
}
|
|
86
|
-
});
|
|
87
|
-
}
|
|
88
|
-
resolveDefaultConfig(options) {
|
|
89
|
-
const { requestTimeout, connectionTimeout, socketTimeout, httpAgent, httpsAgent, } = options || {};
|
|
90
|
-
const keepAlive = true;
|
|
91
|
-
const maxSockets = 50;
|
|
92
|
-
return {
|
|
93
|
-
connectionTimeout,
|
|
94
|
-
requestTimeout: requestTimeout !== null && requestTimeout !== void 0 ? requestTimeout : socketTimeout,
|
|
95
|
-
httpAgent: (() => {
|
|
96
|
-
if (httpAgent instanceof http_1.Agent ||
|
|
97
|
-
typeof (httpAgent === null || httpAgent === void 0 ? void 0 : httpAgent.destroy) === 'function') {
|
|
98
|
-
return httpAgent;
|
|
99
|
-
}
|
|
100
|
-
return new http_1.Agent({ keepAlive, maxSockets, ...httpAgent });
|
|
101
|
-
})(),
|
|
102
|
-
httpsAgent: (() => {
|
|
103
|
-
if (httpsAgent instanceof https_1.Agent ||
|
|
104
|
-
typeof (httpsAgent === null || httpsAgent === void 0 ? void 0 : httpsAgent.destroy) === 'function') {
|
|
105
|
-
return httpsAgent;
|
|
106
|
-
}
|
|
107
|
-
return new https_1.Agent({ keepAlive, maxSockets, ...httpsAgent });
|
|
108
|
-
})(),
|
|
109
|
-
};
|
|
110
|
-
}
|
|
111
|
-
destroy() {
|
|
112
|
-
var _a, _b, _c, _d;
|
|
113
|
-
(_b = (_a = this.config) === null || _a === void 0 ? void 0 : _a.httpAgent) === null || _b === void 0 ? void 0 : _b.destroy();
|
|
114
|
-
(_d = (_c = this.config) === null || _c === void 0 ? void 0 : _c.httpsAgent) === null || _d === void 0 ? void 0 : _d.destroy();
|
|
115
|
-
}
|
|
116
|
-
async handle(request, { abortSignal } = {}) {
|
|
117
|
-
if (!this.config) {
|
|
118
|
-
this.config = await this.configProvider;
|
|
119
|
-
}
|
|
120
|
-
let socketCheckTimeoutId;
|
|
121
|
-
return new Promise((_resolve, _reject) => {
|
|
122
|
-
var _a, _b, _c, _d, _e;
|
|
123
|
-
let writeRequestBodyPromise;
|
|
124
|
-
const resolve = async (arg) => {
|
|
125
|
-
await writeRequestBodyPromise;
|
|
126
|
-
// if requests are still resolving, cancel the socket usage check.
|
|
127
|
-
clearTimeout(socketCheckTimeoutId);
|
|
128
|
-
_resolve(arg);
|
|
129
|
-
};
|
|
130
|
-
const reject = async (arg) => {
|
|
131
|
-
await writeRequestBodyPromise;
|
|
132
|
-
_reject(arg);
|
|
133
|
-
};
|
|
134
|
-
if (!this.config) {
|
|
135
|
-
throw new Error('Node HTTP request handler config is not resolved');
|
|
136
|
-
}
|
|
137
|
-
// if the request was already aborted, prevent doing extra work
|
|
138
|
-
if (abortSignal === null || abortSignal === void 0 ? void 0 : abortSignal.aborted) {
|
|
139
|
-
const abortError = new Error('Request aborted');
|
|
140
|
-
abortError.name = 'AbortError';
|
|
141
|
-
reject(abortError);
|
|
142
|
-
return;
|
|
143
|
-
}
|
|
144
|
-
// determine which http(s) client to use
|
|
145
|
-
const isSSL = request.protocol === 'https:';
|
|
146
|
-
const agent = isSSL ? this.config.httpsAgent : this.config.httpAgent;
|
|
147
|
-
// If the request is taking a long time, check socket usage and potentially warn.
|
|
148
|
-
// This warning will be cancelled if the request resolves.
|
|
149
|
-
socketCheckTimeoutId = setTimeout(() => {
|
|
150
|
-
this.socketWarningTimestamp = NodeHttpHandler.checkSocketUsage(agent, this.socketWarningTimestamp);
|
|
151
|
-
}, (_a = this.config.socketAcquisitionWarningTimeout) !== null && _a !== void 0 ? _a : ((_b = this.config.requestTimeout) !== null && _b !== void 0 ? _b : 2000) +
|
|
152
|
-
((_c = this.config.connectionTimeout) !== null && _c !== void 0 ? _c : 1000));
|
|
153
|
-
const queryString = (0, querystring_builder_1.buildQueryString)(request.query || {});
|
|
154
|
-
let auth;
|
|
155
|
-
if (request.username != null || request.password != null) {
|
|
156
|
-
const username = (_d = request.username) !== null && _d !== void 0 ? _d : '';
|
|
157
|
-
const password = (_e = request.password) !== null && _e !== void 0 ? _e : '';
|
|
158
|
-
auth = `${username}:${password}`;
|
|
159
|
-
}
|
|
160
|
-
let { path } = request;
|
|
161
|
-
if (queryString) {
|
|
162
|
-
path += `?${queryString}`;
|
|
163
|
-
}
|
|
164
|
-
if (request.fragment) {
|
|
165
|
-
path += `#${request.fragment}`;
|
|
166
|
-
}
|
|
167
|
-
const nodeHttpsOptions = {
|
|
168
|
-
headers: request.headers,
|
|
169
|
-
host: request.hostname,
|
|
170
|
-
method: request.method,
|
|
171
|
-
path,
|
|
172
|
-
port: request.port,
|
|
173
|
-
agent,
|
|
174
|
-
auth,
|
|
175
|
-
};
|
|
176
|
-
// create the http request
|
|
177
|
-
const requestFunc = isSSL ? https_1.request : http_1.request;
|
|
178
|
-
const req = requestFunc(nodeHttpsOptions, (res) => {
|
|
179
|
-
const httpResponse = new protocol_http_1.HttpResponse({
|
|
180
|
-
statusCode: res.statusCode || -1,
|
|
181
|
-
reason: res.statusMessage,
|
|
182
|
-
headers: (0, get_transformed_headers_1.getTransformedHeaders)(res.headers),
|
|
183
|
-
body: res,
|
|
184
|
-
});
|
|
185
|
-
resolve({ response: httpResponse });
|
|
186
|
-
});
|
|
187
|
-
req.on('error', (err) => {
|
|
188
|
-
if (exports.NODEJS_TIMEOUT_ERROR_CODES.includes(err.code)) {
|
|
189
|
-
reject(Object.assign(err, { name: 'TimeoutError' }));
|
|
190
|
-
}
|
|
191
|
-
else {
|
|
192
|
-
reject(err);
|
|
193
|
-
}
|
|
194
|
-
});
|
|
195
|
-
// wire-up any timeout logic
|
|
196
|
-
(0, set_connection_timeout_1.setConnectionTimeout)(req, reject, this.config.connectionTimeout);
|
|
197
|
-
(0, set_socket_timeout_1.setSocketTimeout)(req, reject, this.config.requestTimeout);
|
|
198
|
-
// wire-up abort logic
|
|
199
|
-
if (abortSignal) {
|
|
200
|
-
abortSignal.onabort = () => {
|
|
201
|
-
// ensure request is destroyed
|
|
202
|
-
req.abort();
|
|
203
|
-
const abortError = new Error('Request aborted');
|
|
204
|
-
abortError.name = 'AbortError';
|
|
205
|
-
reject(abortError);
|
|
206
|
-
};
|
|
207
|
-
}
|
|
208
|
-
// Workaround for bug report in Node.js https://github.com/nodejs/node/issues/47137
|
|
209
|
-
const httpAgent = nodeHttpsOptions.agent;
|
|
210
|
-
if (typeof httpAgent === 'object' && 'keepAlive' in httpAgent) {
|
|
211
|
-
(0, set_socket_keep_alive_1.setSocketKeepAlive)(req, {
|
|
212
|
-
// @ts-expect-error keepAlive is not public on httpAgent.
|
|
213
|
-
keepAlive: httpAgent.keepAlive,
|
|
214
|
-
// @ts-expect-error keepAliveMsecs is not public on httpAgent.
|
|
215
|
-
keepAliveMsecs: httpAgent.keepAliveMsecs,
|
|
216
|
-
});
|
|
217
|
-
}
|
|
218
|
-
writeRequestBodyPromise = (0, write_request_body_1.writeRequestBody)(req, request, this.config.requestTimeout).catch(_reject);
|
|
219
|
-
});
|
|
220
|
-
}
|
|
221
|
-
updateHttpClientConfig(key, value) {
|
|
222
|
-
this.config = undefined;
|
|
223
|
-
this.configProvider = this.configProvider.then((config) => {
|
|
224
|
-
return {
|
|
225
|
-
...config,
|
|
226
|
-
[key]: value,
|
|
227
|
-
};
|
|
228
|
-
});
|
|
229
|
-
}
|
|
230
|
-
httpHandlerConfigs() {
|
|
231
|
-
var _a;
|
|
232
|
-
return (_a = this.config) !== null && _a !== void 0 ? _a : {};
|
|
233
|
-
}
|
|
234
|
-
}
|
|
235
|
-
exports.NodeHttpHandler = NodeHttpHandler;
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.getTransformedHeaders = void 0;
|
|
4
|
-
const getTransformedHeaders = (headers) => {
|
|
5
|
-
const transformedHeaders = {};
|
|
6
|
-
for (const name of Object.keys(headers)) {
|
|
7
|
-
const headerValues = headers[name];
|
|
8
|
-
transformedHeaders[name] = Array.isArray(headerValues)
|
|
9
|
-
? headerValues.join(',')
|
|
10
|
-
: headerValues;
|
|
11
|
-
}
|
|
12
|
-
return transformedHeaders;
|
|
13
|
-
};
|
|
14
|
-
exports.getTransformedHeaders = getTransformedHeaders;
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.setConnectionTimeout = void 0;
|
|
4
|
-
const setConnectionTimeout = (request, reject, timeoutInMs = 0) => {
|
|
5
|
-
if (!timeoutInMs) {
|
|
6
|
-
return;
|
|
7
|
-
}
|
|
8
|
-
// Throw a connecting timeout error unless a connection is made within time.
|
|
9
|
-
const timeoutId = setTimeout(() => {
|
|
10
|
-
request.destroy();
|
|
11
|
-
reject(Object.assign(new Error(`Socket timed out without establishing a connection within ${timeoutInMs} ms`), {
|
|
12
|
-
name: 'TimeoutError',
|
|
13
|
-
}));
|
|
14
|
-
}, timeoutInMs);
|
|
15
|
-
request.on('socket', (socket) => {
|
|
16
|
-
if (socket.connecting) {
|
|
17
|
-
socket.on('connect', () => {
|
|
18
|
-
clearTimeout(timeoutId);
|
|
19
|
-
});
|
|
20
|
-
}
|
|
21
|
-
else {
|
|
22
|
-
clearTimeout(timeoutId);
|
|
23
|
-
}
|
|
24
|
-
});
|
|
25
|
-
};
|
|
26
|
-
exports.setConnectionTimeout = setConnectionTimeout;
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
/// <reference types="node" />
|
|
2
|
-
import type { ClientRequest } from 'http';
|
|
3
|
-
export interface SocketKeepAliveOptions {
|
|
4
|
-
keepAlive: boolean;
|
|
5
|
-
keepAliveMsecs?: number;
|
|
6
|
-
}
|
|
7
|
-
export declare const setSocketKeepAlive: (request: ClientRequest, { keepAlive, keepAliveMsecs }: SocketKeepAliveOptions) => void;
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.setSocketKeepAlive = void 0;
|
|
4
|
-
const setSocketKeepAlive = (request, { keepAlive, keepAliveMsecs }) => {
|
|
5
|
-
if (keepAlive !== true) {
|
|
6
|
-
return;
|
|
7
|
-
}
|
|
8
|
-
request.on('socket', (socket) => {
|
|
9
|
-
socket.setKeepAlive(keepAlive, keepAliveMsecs || 0);
|
|
10
|
-
});
|
|
11
|
-
};
|
|
12
|
-
exports.setSocketKeepAlive = setSocketKeepAlive;
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.setSocketTimeout = void 0;
|
|
4
|
-
const setSocketTimeout = (request, reject, timeoutInMs = 0) => {
|
|
5
|
-
request.setTimeout(timeoutInMs, () => {
|
|
6
|
-
// destroy the request
|
|
7
|
-
request.destroy();
|
|
8
|
-
reject(Object.assign(new Error(`Connection timed out after ${timeoutInMs} ms`), {
|
|
9
|
-
name: 'TimeoutError',
|
|
10
|
-
}));
|
|
11
|
-
});
|
|
12
|
-
};
|
|
13
|
-
exports.setSocketTimeout = setSocketTimeout;
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
/// <reference types="node" />
|
|
2
|
-
/// <reference types="node" />
|
|
3
|
-
import type { HttpRequest } from '@smithy/types';
|
|
4
|
-
import type { ClientRequest } from 'http';
|
|
5
|
-
import type { ClientHttp2Stream } from 'http2';
|
|
6
|
-
/**
|
|
7
|
-
* This resolves when writeBody has been called.
|
|
8
|
-
*
|
|
9
|
-
* @param httpRequest - opened Node.js request.
|
|
10
|
-
* @param request - container with the request body.
|
|
11
|
-
* @param maxContinueTimeoutMs - maximum time to wait for the continue event. Minimum of 1000ms.
|
|
12
|
-
*/
|
|
13
|
-
export declare function writeRequestBody(httpRequest: ClientRequest | ClientHttp2Stream, request: HttpRequest, maxContinueTimeoutMs?: number): Promise<void>;
|
|
@@ -1,70 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.writeRequestBody = void 0;
|
|
4
|
-
const stream_1 = require("stream");
|
|
5
|
-
const MIN_WAIT_TIME = 1000;
|
|
6
|
-
/**
|
|
7
|
-
* This resolves when writeBody has been called.
|
|
8
|
-
*
|
|
9
|
-
* @param httpRequest - opened Node.js request.
|
|
10
|
-
* @param request - container with the request body.
|
|
11
|
-
* @param maxContinueTimeoutMs - maximum time to wait for the continue event. Minimum of 1000ms.
|
|
12
|
-
*/
|
|
13
|
-
async function writeRequestBody(httpRequest, request, maxContinueTimeoutMs = MIN_WAIT_TIME) {
|
|
14
|
-
var _a;
|
|
15
|
-
const headers = (_a = request.headers) !== null && _a !== void 0 ? _a : {};
|
|
16
|
-
const expect = headers.Expect || headers.expect;
|
|
17
|
-
let timeoutId = -1;
|
|
18
|
-
let hasError = false;
|
|
19
|
-
if (expect === '100-continue') {
|
|
20
|
-
await Promise.race([
|
|
21
|
-
new Promise((resolve) => {
|
|
22
|
-
timeoutId = Number(setTimeout(resolve, Math.max(MIN_WAIT_TIME, maxContinueTimeoutMs)));
|
|
23
|
-
}),
|
|
24
|
-
new Promise((resolve) => {
|
|
25
|
-
httpRequest.on('continue', () => {
|
|
26
|
-
clearTimeout(timeoutId);
|
|
27
|
-
resolve();
|
|
28
|
-
});
|
|
29
|
-
httpRequest.on('error', () => {
|
|
30
|
-
hasError = true;
|
|
31
|
-
clearTimeout(timeoutId);
|
|
32
|
-
// this handler does not reject with the error
|
|
33
|
-
// because there is already an error listener
|
|
34
|
-
// on the request in node-http-handler
|
|
35
|
-
// and node-http2-handler.
|
|
36
|
-
resolve();
|
|
37
|
-
});
|
|
38
|
-
}),
|
|
39
|
-
]);
|
|
40
|
-
}
|
|
41
|
-
if (!hasError) {
|
|
42
|
-
writeBody(httpRequest, request.body);
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
exports.writeRequestBody = writeRequestBody;
|
|
46
|
-
function writeBody(httpRequest, body) {
|
|
47
|
-
if (body instanceof stream_1.Readable) {
|
|
48
|
-
// pipe automatically handles end
|
|
49
|
-
body.pipe(httpRequest);
|
|
50
|
-
return;
|
|
51
|
-
}
|
|
52
|
-
if (body) {
|
|
53
|
-
if (Buffer.isBuffer(body) || typeof body === 'string') {
|
|
54
|
-
httpRequest.end(body);
|
|
55
|
-
return;
|
|
56
|
-
}
|
|
57
|
-
const uint8 = body;
|
|
58
|
-
if (typeof uint8 === 'object' &&
|
|
59
|
-
uint8.buffer &&
|
|
60
|
-
typeof uint8.byteOffset === 'number' &&
|
|
61
|
-
typeof uint8.byteLength === 'number') {
|
|
62
|
-
// this avoids copying the array.
|
|
63
|
-
httpRequest.end(Buffer.from(uint8.buffer, uint8.byteOffset, uint8.byteLength));
|
|
64
|
-
return;
|
|
65
|
-
}
|
|
66
|
-
httpRequest.end(Buffer.from(body));
|
|
67
|
-
return;
|
|
68
|
-
}
|
|
69
|
-
httpRequest.end();
|
|
70
|
-
}
|