@nocobase/plugin-workflow-mailer 2.4.0-alpha.1 → 2.4.0-alpha.10
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/externalVersion.js +6 -6
- package/dist/node_modules/joi/dist/joi-browser.min.js +1 -1
- package/dist/node_modules/joi/lib/index.js +1 -1
- package/dist/node_modules/joi/lib/messages.js +35 -6
- package/dist/node_modules/joi/lib/types/keys.js +18 -1
- package/dist/node_modules/joi/lib/types/link.js +18 -2
- package/dist/node_modules/joi/lib/types/string.js +2 -2
- package/dist/node_modules/joi/package.json +1 -1
- package/dist/node_modules/nodemailer/dist/cjs/addressparser/index.d.ts +59 -0
- package/dist/node_modules/nodemailer/dist/cjs/addressparser/index.js +790 -0
- package/dist/node_modules/nodemailer/dist/cjs/base64/index.d.ts +36 -0
- package/dist/node_modules/nodemailer/dist/cjs/base64/index.js +119 -0
- package/dist/node_modules/nodemailer/dist/cjs/dkim/index.d.ts +52 -0
- package/dist/node_modules/nodemailer/dist/cjs/dkim/index.js +228 -0
- package/dist/node_modules/nodemailer/dist/cjs/dkim/message-parser.d.ts +48 -0
- package/dist/node_modules/nodemailer/dist/cjs/dkim/message-parser.js +180 -0
- package/dist/node_modules/nodemailer/dist/cjs/dkim/relaxed-body.d.ts +36 -0
- package/dist/node_modules/nodemailer/dist/cjs/dkim/relaxed-body.js +148 -0
- package/dist/node_modules/nodemailer/dist/cjs/dkim/sign.d.ts +52 -0
- package/dist/node_modules/nodemailer/dist/cjs/dkim/sign.js +165 -0
- package/dist/node_modules/nodemailer/dist/cjs/errors.d.ts +96 -0
- package/dist/node_modules/nodemailer/dist/cjs/errors.js +70 -0
- package/dist/node_modules/nodemailer/dist/cjs/fetch/cookies.d.ts +107 -0
- package/dist/node_modules/nodemailer/dist/cjs/fetch/cookies.js +282 -0
- package/dist/node_modules/nodemailer/dist/cjs/fetch/index.d.ts +65 -0
- package/dist/node_modules/nodemailer/dist/cjs/fetch/index.js +384 -0
- package/dist/node_modules/nodemailer/dist/cjs/json-transport/index.d.ts +64 -0
- package/dist/node_modules/nodemailer/dist/cjs/json-transport/index.js +99 -0
- package/dist/node_modules/nodemailer/dist/cjs/mail-composer/index.d.ts +174 -0
- package/dist/node_modules/nodemailer/dist/cjs/mail-composer/index.js +613 -0
- package/dist/node_modules/nodemailer/dist/cjs/mailer/index.d.ts +237 -0
- package/dist/node_modules/nodemailer/dist/cjs/mailer/index.js +415 -0
- package/dist/node_modules/nodemailer/dist/cjs/mailer/mail-message.d.ts +97 -0
- package/dist/node_modules/nodemailer/dist/cjs/mailer/mail-message.js +342 -0
- package/dist/node_modules/nodemailer/dist/cjs/mime-funcs/index.d.ts +161 -0
- package/dist/node_modules/nodemailer/dist/cjs/mime-funcs/index.js +787 -0
- package/dist/node_modules/nodemailer/dist/cjs/mime-funcs/mime-types.d.ts +2 -0
- package/dist/node_modules/nodemailer/dist/cjs/mime-funcs/mime-types.js +2103 -0
- package/dist/node_modules/nodemailer/dist/cjs/mime-node/index.d.ts +333 -0
- package/dist/node_modules/nodemailer/dist/cjs/mime-node/index.js +1493 -0
- package/dist/node_modules/nodemailer/dist/cjs/mime-node/last-newline.d.ts +5 -0
- package/dist/node_modules/nodemailer/dist/cjs/mime-node/last-newline.js +32 -0
- package/dist/node_modules/nodemailer/dist/cjs/mime-node/le-unix.d.ts +9 -0
- package/dist/node_modules/nodemailer/dist/cjs/mime-node/le-unix.js +40 -0
- package/dist/node_modules/nodemailer/dist/cjs/mime-node/le-windows.d.ts +10 -0
- package/dist/node_modules/nodemailer/dist/cjs/mime-node/le-windows.js +47 -0
- package/dist/node_modules/nodemailer/dist/cjs/nodemailer.d.ts +124 -0
- package/dist/node_modules/nodemailer/dist/cjs/nodemailer.js +1 -0
- package/dist/node_modules/nodemailer/dist/cjs/package-info.d.ts +3 -0
- package/dist/node_modules/nodemailer/dist/cjs/package-info.js +7 -0
- package/dist/node_modules/nodemailer/dist/cjs/package.json +3 -0
- package/dist/node_modules/nodemailer/dist/cjs/punycode/index.d.ts +73 -0
- package/dist/node_modules/nodemailer/{lib → dist/cjs}/punycode/index.js +63 -112
- package/dist/node_modules/nodemailer/dist/cjs/qp/index.d.ts +32 -0
- package/dist/node_modules/nodemailer/dist/cjs/qp/index.js +207 -0
- package/dist/node_modules/nodemailer/dist/cjs/sendmail-transport/index.d.ts +69 -0
- package/dist/node_modules/nodemailer/dist/cjs/sendmail-transport/index.js +210 -0
- package/dist/node_modules/nodemailer/dist/cjs/ses-transport/index.d.ts +112 -0
- package/dist/node_modules/nodemailer/dist/cjs/ses-transport/index.js +252 -0
- package/dist/node_modules/nodemailer/dist/cjs/shared/index.d.ts +260 -0
- package/dist/node_modules/nodemailer/dist/cjs/shared/index.js +680 -0
- package/dist/node_modules/nodemailer/dist/cjs/shared/objects.d.ts +23 -0
- package/dist/node_modules/nodemailer/dist/cjs/shared/objects.js +43 -0
- package/dist/node_modules/nodemailer/dist/cjs/shared/url.d.ts +21 -0
- package/dist/node_modules/nodemailer/dist/cjs/shared/url.js +255 -0
- package/dist/node_modules/nodemailer/dist/cjs/smtp-connection/data-stream.d.ts +15 -0
- package/dist/node_modules/nodemailer/dist/cjs/smtp-connection/data-stream.js +108 -0
- package/dist/node_modules/nodemailer/dist/cjs/smtp-connection/http-proxy-client.d.ts +47 -0
- package/dist/node_modules/nodemailer/dist/cjs/smtp-connection/http-proxy-client.js +189 -0
- package/dist/node_modules/nodemailer/dist/cjs/smtp-connection/index.d.ts +416 -0
- package/dist/node_modules/nodemailer/dist/cjs/smtp-connection/index.js +1837 -0
- package/dist/node_modules/nodemailer/dist/cjs/smtp-pool/index.d.ts +133 -0
- package/dist/node_modules/nodemailer/dist/cjs/smtp-pool/index.js +569 -0
- package/dist/node_modules/nodemailer/dist/cjs/smtp-pool/pool-resource.d.ts +62 -0
- package/dist/node_modules/nodemailer/dist/cjs/smtp-pool/pool-resource.js +257 -0
- package/dist/node_modules/nodemailer/dist/cjs/smtp-transport/index.d.ts +156 -0
- package/dist/node_modules/nodemailer/dist/cjs/smtp-transport/index.js +371 -0
- package/dist/node_modules/nodemailer/dist/cjs/stream-transport/index.d.ts +65 -0
- package/dist/node_modules/nodemailer/dist/cjs/stream-transport/index.js +146 -0
- package/dist/node_modules/nodemailer/dist/cjs/well-known/index.d.ts +35 -0
- package/dist/node_modules/nodemailer/dist/cjs/well-known/index.js +41 -0
- package/dist/node_modules/nodemailer/dist/cjs/well-known/services.d.ts +2 -0
- package/dist/node_modules/nodemailer/dist/cjs/well-known/services.js +674 -0
- package/dist/node_modules/nodemailer/dist/cjs/xoauth2/index.d.ts +201 -0
- package/dist/node_modules/nodemailer/dist/cjs/xoauth2/index.js +426 -0
- package/dist/node_modules/nodemailer/dist/esm/addressparser/index.d.ts +59 -0
- package/dist/node_modules/nodemailer/dist/esm/addressparser/index.js +786 -0
- package/dist/node_modules/nodemailer/dist/esm/base64/index.d.ts +36 -0
- package/dist/node_modules/nodemailer/{lib → dist/esm}/base64/index.js +39 -68
- package/dist/node_modules/nodemailer/dist/esm/dkim/index.d.ts +52 -0
- package/dist/node_modules/nodemailer/{lib → dist/esm}/dkim/index.js +62 -92
- package/dist/node_modules/nodemailer/dist/esm/dkim/message-parser.d.ts +48 -0
- package/dist/node_modules/nodemailer/dist/esm/dkim/message-parser.js +176 -0
- package/dist/node_modules/nodemailer/dist/esm/dkim/relaxed-body.d.ts +36 -0
- package/dist/node_modules/nodemailer/dist/esm/dkim/relaxed-body.js +141 -0
- package/dist/node_modules/nodemailer/dist/esm/dkim/sign.d.ts +52 -0
- package/dist/node_modules/nodemailer/dist/esm/dkim/sign.js +125 -0
- package/dist/node_modules/nodemailer/dist/esm/errors.d.ts +96 -0
- package/dist/node_modules/nodemailer/dist/esm/errors.js +67 -0
- package/dist/node_modules/nodemailer/dist/esm/fetch/cookies.d.ts +107 -0
- package/dist/node_modules/nodemailer/dist/esm/fetch/cookies.js +242 -0
- package/dist/node_modules/nodemailer/dist/esm/fetch/index.d.ts +65 -0
- package/dist/node_modules/nodemailer/dist/esm/fetch/index.js +344 -0
- package/dist/node_modules/nodemailer/dist/esm/json-transport/index.d.ts +64 -0
- package/dist/node_modules/nodemailer/dist/esm/json-transport/index.js +62 -0
- package/dist/node_modules/nodemailer/dist/esm/mail-composer/index.d.ts +174 -0
- package/dist/node_modules/nodemailer/{lib → dist/esm}/mail-composer/index.js +283 -275
- package/dist/node_modules/nodemailer/dist/esm/mailer/index.d.ts +237 -0
- package/dist/node_modules/nodemailer/{lib → dist/esm}/mailer/index.js +151 -205
- package/dist/node_modules/nodemailer/dist/esm/mailer/mail-message.d.ts +97 -0
- package/dist/node_modules/nodemailer/{lib → dist/esm}/mailer/mail-message.js +111 -125
- package/dist/node_modules/nodemailer/dist/esm/mime-funcs/index.d.ts +161 -0
- package/dist/node_modules/nodemailer/dist/esm/mime-funcs/index.js +738 -0
- package/dist/node_modules/nodemailer/dist/esm/mime-funcs/mime-types.d.ts +2 -0
- package/dist/node_modules/nodemailer/{lib → dist/esm}/mime-funcs/mime-types.js +43 -49
- package/dist/node_modules/nodemailer/dist/esm/mime-node/index.d.ts +333 -0
- package/dist/node_modules/nodemailer/{lib → dist/esm}/mime-node/index.js +576 -437
- package/dist/node_modules/nodemailer/dist/esm/mime-node/last-newline.d.ts +5 -0
- package/dist/node_modules/nodemailer/{lib → dist/esm}/mime-node/last-newline.js +4 -10
- package/dist/node_modules/nodemailer/dist/esm/mime-node/le-unix.d.ts +9 -0
- package/dist/node_modules/nodemailer/{lib → dist/esm}/mime-node/le-unix.js +7 -15
- package/dist/node_modules/nodemailer/dist/esm/mime-node/le-windows.d.ts +10 -0
- package/dist/node_modules/nodemailer/{lib → dist/esm}/mime-node/le-windows.js +6 -16
- package/dist/node_modules/nodemailer/dist/esm/nodemailer.d.ts +124 -0
- package/dist/node_modules/nodemailer/dist/esm/nodemailer.js +166 -0
- package/dist/node_modules/nodemailer/dist/esm/package-info.d.ts +3 -0
- package/dist/node_modules/nodemailer/dist/esm/package-info.js +4 -0
- package/dist/node_modules/nodemailer/dist/esm/package.json +3 -0
- package/dist/node_modules/nodemailer/dist/esm/punycode/index.d.ts +73 -0
- package/dist/node_modules/nodemailer/dist/esm/punycode/index.js +405 -0
- package/dist/node_modules/nodemailer/dist/esm/qp/index.d.ts +32 -0
- package/dist/node_modules/nodemailer/{lib → dist/esm}/qp/index.js +59 -77
- package/dist/node_modules/nodemailer/dist/esm/sendmail-transport/index.d.ts +69 -0
- package/dist/node_modules/nodemailer/dist/esm/sendmail-transport/index.js +170 -0
- package/dist/node_modules/nodemailer/dist/esm/ses-transport/index.d.ts +112 -0
- package/dist/node_modules/nodemailer/dist/esm/ses-transport/index.js +212 -0
- package/dist/node_modules/nodemailer/dist/esm/shared/index.d.ts +260 -0
- package/dist/node_modules/nodemailer/dist/esm/shared/index.js +631 -0
- package/dist/node_modules/nodemailer/dist/esm/shared/objects.d.ts +23 -0
- package/dist/node_modules/nodemailer/dist/esm/shared/objects.js +38 -0
- package/dist/node_modules/nodemailer/dist/esm/shared/url.d.ts +21 -0
- package/dist/node_modules/nodemailer/dist/esm/shared/url.js +214 -0
- package/dist/node_modules/nodemailer/dist/esm/smtp-connection/data-stream.d.ts +15 -0
- package/dist/node_modules/nodemailer/dist/esm/smtp-connection/data-stream.js +103 -0
- package/dist/node_modules/nodemailer/dist/esm/smtp-connection/http-proxy-client.d.ts +47 -0
- package/dist/node_modules/nodemailer/dist/esm/smtp-connection/http-proxy-client.js +149 -0
- package/dist/node_modules/nodemailer/dist/esm/smtp-connection/index.d.ts +416 -0
- package/dist/node_modules/nodemailer/dist/esm/smtp-connection/index.js +1797 -0
- package/dist/node_modules/nodemailer/dist/esm/smtp-pool/index.d.ts +133 -0
- package/dist/node_modules/nodemailer/{lib → dist/esm}/smtp-pool/index.js +195 -314
- package/dist/node_modules/nodemailer/dist/esm/smtp-pool/pool-resource.d.ts +62 -0
- package/dist/node_modules/nodemailer/{lib → dist/esm}/smtp-pool/pool-resource.js +70 -107
- package/dist/node_modules/nodemailer/dist/esm/smtp-transport/index.d.ts +156 -0
- package/dist/node_modules/nodemailer/dist/esm/smtp-transport/index.js +331 -0
- package/dist/node_modules/nodemailer/dist/esm/stream-transport/index.d.ts +65 -0
- package/dist/node_modules/nodemailer/dist/esm/stream-transport/index.js +106 -0
- package/dist/node_modules/nodemailer/dist/esm/well-known/index.d.ts +35 -0
- package/dist/node_modules/nodemailer/{lib → dist/esm}/well-known/index.js +12 -23
- package/dist/node_modules/nodemailer/dist/esm/well-known/services.d.ts +2 -0
- package/dist/node_modules/nodemailer/dist/esm/well-known/services.js +671 -0
- package/dist/node_modules/nodemailer/dist/esm/xoauth2/index.d.ts +201 -0
- package/dist/node_modules/nodemailer/dist/esm/xoauth2/index.js +386 -0
- package/dist/node_modules/nodemailer/dist/well-known/services.json +640 -0
- package/dist/node_modules/nodemailer/package.json +1 -1
- package/package.json +4 -4
- package/dist/node_modules/nodemailer/.gitattributes +0 -6
- package/dist/node_modules/nodemailer/.ncurc.js +0 -7
- package/dist/node_modules/nodemailer/.prettierrc.js +0 -8
- package/dist/node_modules/nodemailer/lib/addressparser/index.js +0 -313
- package/dist/node_modules/nodemailer/lib/dkim/message-parser.js +0 -155
- package/dist/node_modules/nodemailer/lib/dkim/relaxed-body.js +0 -154
- package/dist/node_modules/nodemailer/lib/dkim/sign.js +0 -117
- package/dist/node_modules/nodemailer/lib/fetch/cookies.js +0 -281
- package/dist/node_modules/nodemailer/lib/fetch/index.js +0 -274
- package/dist/node_modules/nodemailer/lib/json-transport/index.js +0 -82
- package/dist/node_modules/nodemailer/lib/mime-funcs/index.js +0 -625
- package/dist/node_modules/nodemailer/lib/nodemailer.js +0 -1
- package/dist/node_modules/nodemailer/lib/sendmail-transport/index.js +0 -210
- package/dist/node_modules/nodemailer/lib/ses-transport/index.js +0 -349
- package/dist/node_modules/nodemailer/lib/shared/index.js +0 -688
- package/dist/node_modules/nodemailer/lib/smtp-connection/data-stream.js +0 -108
- package/dist/node_modules/nodemailer/lib/smtp-connection/http-proxy-client.js +0 -143
- package/dist/node_modules/nodemailer/lib/smtp-connection/index.js +0 -1825
- package/dist/node_modules/nodemailer/lib/smtp-transport/index.js +0 -416
- package/dist/node_modules/nodemailer/lib/stream-transport/index.js +0 -135
- package/dist/node_modules/nodemailer/lib/well-known/services.json +0 -343
- package/dist/node_modules/nodemailer/lib/xoauth2/index.js +0 -376
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Parsed URL in the shape of the legacy `url.parse()` result
|
|
3
|
+
*/
|
|
4
|
+
export interface ParsedUrl {
|
|
5
|
+
protocol: string | null;
|
|
6
|
+
host: string | null;
|
|
7
|
+
hostname: string | null;
|
|
8
|
+
port: string | null;
|
|
9
|
+
pathname: string | null;
|
|
10
|
+
search: string | null;
|
|
11
|
+
path: string | null;
|
|
12
|
+
href: string;
|
|
13
|
+
auth: string | null;
|
|
14
|
+
/** Decoded user name, null when the URL carries no credentials */
|
|
15
|
+
username: string | null;
|
|
16
|
+
/** Decoded password, null when the URL carries none */
|
|
17
|
+
password: string | null;
|
|
18
|
+
query: string | null | Record<string, string | string[]>;
|
|
19
|
+
}
|
|
20
|
+
export declare const parse: (input?: string | null, parseQueryString?: boolean) => ParsedUrl;
|
|
21
|
+
export declare const resolve: (from: string, to: string) => string;
|
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
// URL parsing wrapper around the WHATWG `URL` class. It only falls back to the
|
|
2
|
+
// legacy, deprecation-warning-emitting `url.parse()` / `url.resolve()` for input
|
|
3
|
+
// the WHATWG parser rejects.
|
|
4
|
+
//
|
|
5
|
+
// The WHATWG `URL` exposes a different shape than the legacy parser, so results
|
|
6
|
+
// are normalized back into the legacy field names the rest of the codebase reads
|
|
7
|
+
// (`protocol`, `hostname`, `port`, `pathname`, `path`, `search`, `auth`, `query`,
|
|
8
|
+
// `href`). This keeps every existing call site unchanged.
|
|
9
|
+
//
|
|
10
|
+
// Known, accepted divergences from the legacy parser:
|
|
11
|
+
// - non-special schemes (smtp:/smtps:/direct:) are not host-lowercased by
|
|
12
|
+
// WHATWG; cosmetic only, SMTP/DNS hosts are case-insensitive. (IDNA mapping
|
|
13
|
+
// and IPv6 brackets are normalized back by normalizeHostname below.)
|
|
14
|
+
// - a literal unescaped ':' inside a password is percent-encoded by WHATWG;
|
|
15
|
+
// such passwords should be percent-encoded by the caller anyway.
|
|
16
|
+
import net from 'node:net';
|
|
17
|
+
import urllib from 'node:url';
|
|
18
|
+
import * as punycode from '../punycode/index.js';
|
|
19
|
+
// Matches a "scheme:" not followed by "//" (and with something after it), used
|
|
20
|
+
// to re-insert the authority separator the legacy parser did not require.
|
|
21
|
+
const SLASHLESS_AUTHORITY = /^([a-zA-Z][a-zA-Z0-9+.-]*:)(?!\/\/)([\s\S]+)$/;
|
|
22
|
+
// Leading and trailing C0 controls and spaces, which the WHATWG parser strips before it
|
|
23
|
+
// looks at the input. Stripped up front so that the slash-less form is recognized in a
|
|
24
|
+
// value read from a file with a trailing newline as well.
|
|
25
|
+
const SURROUNDING_WHITESPACE = /^[\x00-\x20]+|[\x00-\x20]+$/g;
|
|
26
|
+
// Leading characters legacy url.parse() skips before it reads the scheme
|
|
27
|
+
const LEGACY_TRIM = /^[\x00-\x20\u00a0\ufeff]+/;
|
|
28
|
+
// The authority of a "scheme://authority/..." or a scheme-relative "//authority/..."
|
|
29
|
+
// string: the scheme, if any (anything the legacy parser takes for one, it is less strict
|
|
30
|
+
// than WHATWG about the first character), and what the legacy parser has to report as the
|
|
31
|
+
// host once the userinfo is removed, see legacyParse. The legacy parser treats a backslash
|
|
32
|
+
// as a slash.
|
|
33
|
+
const AUTHORITY = /^([a-zA-Z0-9+.-]+:)?[\\/]{2}([^\\/?#]*)/;
|
|
34
|
+
// The WHATWG forbidden domain code points, except '%' which an opaque host may carry: the
|
|
35
|
+
// C0 control characters, space, DEL and the URL delimiters. CONTROL_CHARS is the C0 and DEL
|
|
36
|
+
// subset, checked on its own in legacyParse where the host string still carries the port
|
|
37
|
+
// and IPv6 brackets.
|
|
38
|
+
const FORBIDDEN_HOST_CHARS = /[\x00-\x20#/:<>?@[\\\]^|\x7f]/;
|
|
39
|
+
const CONTROL_CHARS = /[\x00-\x1f\x7f]/;
|
|
40
|
+
// The error the WHATWG parser throws, for a host that only fails the checks in this module
|
|
41
|
+
function invalidUrl(input) {
|
|
42
|
+
const err = new TypeError('Invalid URL');
|
|
43
|
+
err.code = 'ERR_INVALID_URL';
|
|
44
|
+
err.input = input;
|
|
45
|
+
return err;
|
|
46
|
+
}
|
|
47
|
+
// Legacy url.parse() for input the WHATWG parser refused. The legacy parser does not
|
|
48
|
+
// reject a host it can not represent: a NUL byte, a percent-encoded byte, a space or a
|
|
49
|
+
// '<' inside the host ends the host early and the rest becomes the path, so
|
|
50
|
+
// 'localhost%00.example.com' silently turns into a request to 'localhost'. When the
|
|
51
|
+
// input has an authority that the legacy parser reads as the host (always for
|
|
52
|
+
// "scheme://", for "//host" only when slashesDenoteHost is set, as url.resolve() does
|
|
53
|
+
// for its target), the legacy result is accepted only if that host is the whole written
|
|
54
|
+
// authority, lowercased and IDNA mapped the way the legacy parser does it, and carries
|
|
55
|
+
// no control character. A legacy result with a host (an empty one included, 'http:///x'
|
|
56
|
+
// is a request to localhost) that no such authority accounts for is refused as well.
|
|
57
|
+
// Otherwise the WHATWG error is reported. Relative input has no authority to check and
|
|
58
|
+
// keeps the legacy behavior.
|
|
59
|
+
function legacyParse(input, parseQueryString, whatwgError, slashesDenoteHost) {
|
|
60
|
+
const parsed = urllib.parse(input, parseQueryString, slashesDenoteHost);
|
|
61
|
+
const authority = AUTHORITY.exec(input.replace(LEGACY_TRIM, ''));
|
|
62
|
+
if (authority && (authority[1] || parsed.hostname !== null)) {
|
|
63
|
+
const written = authority[2].slice(authority[2].lastIndexOf('@') + 1);
|
|
64
|
+
if (!written || CONTROL_CHARS.test(written) || (parsed.host || '').toLowerCase() !== punycode.toASCII(written.toLowerCase())) {
|
|
65
|
+
throw whatwgError;
|
|
66
|
+
}
|
|
67
|
+
// the legacy parser takes any bracketed value for an IPv6 literal
|
|
68
|
+
if (written.charAt(0) === '[' && !net.isIPv6(written.slice(1, written.indexOf(']')))) {
|
|
69
|
+
throw whatwgError;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
else if (parsed.hostname !== null) {
|
|
73
|
+
throw whatwgError;
|
|
74
|
+
}
|
|
75
|
+
// the legacy parser only offers the joined form, split it on the first colon
|
|
76
|
+
const legacyAuth = parsed.auth === null || parsed.auth === undefined ? null : parsed.auth.split(':');
|
|
77
|
+
const result = parsed;
|
|
78
|
+
result.username = legacyAuth ? legacyAuth.shift() : null;
|
|
79
|
+
result.password = legacyAuth && legacyAuth.length ? legacyAuth.join(':') : null;
|
|
80
|
+
return result;
|
|
81
|
+
}
|
|
82
|
+
// decodeURIComponent that never throws. Legacy url.parse() decodes the auth
|
|
83
|
+
// component but tolerates malformed percent sequences, so mirror that.
|
|
84
|
+
function safeDecode(str) {
|
|
85
|
+
try {
|
|
86
|
+
return decodeURIComponent(str);
|
|
87
|
+
}
|
|
88
|
+
catch (_err) {
|
|
89
|
+
return str;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
// Derives the legacy-shaped bare hostname from a WHATWG URL. WHATWG keeps IPv6
|
|
93
|
+
// literals bracketed ('[::1]') and, for non-special schemes (smtp:/smtps:/socks:),
|
|
94
|
+
// percent-encodes a non-ASCII host instead of IDNA-mapping it. Both forms are
|
|
95
|
+
// un-resolvable when handed to net/dns/http.request, which is what every call
|
|
96
|
+
// site does, so map them back to what legacy url.parse() returned: the bare
|
|
97
|
+
// address and the IDNA mapped (lowercased, punycode) form. Idempotent on plain
|
|
98
|
+
// ASCII and already-punycode hosts, so special-scheme hosts (already IDNA-mapped
|
|
99
|
+
// by WHATWG) pass through.
|
|
100
|
+
function normalizeHostname(raw, href) {
|
|
101
|
+
const hostname = raw || '';
|
|
102
|
+
if (!hostname) {
|
|
103
|
+
// Host-less URL (e.g. 'direct:'): legacy returned '' here, not null;
|
|
104
|
+
// consumers do `hostname.length` / `'.' + hostname`, so keep it a string.
|
|
105
|
+
return '';
|
|
106
|
+
}
|
|
107
|
+
if (hostname.charAt(0) === '[' && hostname.charAt(hostname.length - 1) === ']') {
|
|
108
|
+
return hostname.slice(1, -1);
|
|
109
|
+
}
|
|
110
|
+
const decoded = safeDecode(hostname);
|
|
111
|
+
// domainToASCII applies the WHATWG host rules (IDNA mapping included) and returns an
|
|
112
|
+
// empty string for a host it refuses, the forbidden characters among them
|
|
113
|
+
const mapped = FORBIDDEN_HOST_CHARS.test(decoded) ? '' : urllib.domainToASCII(decoded);
|
|
114
|
+
if (!mapped) {
|
|
115
|
+
throw invalidUrl(href);
|
|
116
|
+
}
|
|
117
|
+
return mapped;
|
|
118
|
+
}
|
|
119
|
+
export const parse = (input, parseQueryString) => {
|
|
120
|
+
input = (input || '').replace(SURROUNDING_WHITESPACE, '');
|
|
121
|
+
// Legacy url.parse() parses a "user:pass@host:port" authority that follows
|
|
122
|
+
// the scheme even without the "//" separator, for schemes outside its
|
|
123
|
+
// built-in slashed-protocol list (smtp:/smtps:/socks:/...). The WHATWG
|
|
124
|
+
// parser instead treats a scheme not followed by "//" as an opaque path.
|
|
125
|
+
// Re-insert the "//" so slash-less connection/proxy URLs keep resolving to
|
|
126
|
+
// an authority, as they did before. This assumes a slash-authority scheme,
|
|
127
|
+
// which every consumer here uses (http/https/smtp/smtps/socks/direct); an
|
|
128
|
+
// opaque scheme like mailto:/data:/tel: would be mis-split, but none reach
|
|
129
|
+
// this module.
|
|
130
|
+
const slashless = SLASHLESS_AUTHORITY.exec(input);
|
|
131
|
+
const normalized = slashless ? slashless[1] + '//' + slashless[2] : input;
|
|
132
|
+
let u;
|
|
133
|
+
try {
|
|
134
|
+
u = new URL(normalized);
|
|
135
|
+
}
|
|
136
|
+
catch (err) {
|
|
137
|
+
// WHATWG rejects some input the legacy parser tolerated (empty/relative
|
|
138
|
+
// strings, scheme-relative '//host/path', out-of-range ports, ...). Fall
|
|
139
|
+
// back to the legacy parser so behavior, including the downstream errors
|
|
140
|
+
// callers rely on, is preserved. This is the only path that can still
|
|
141
|
+
// emit a deprecation warning; it fires for anything WHATWG cannot
|
|
142
|
+
// represent, including legitimate relative URLs, not just malformed input.
|
|
143
|
+
return legacyParse(normalized, parseQueryString, err);
|
|
144
|
+
}
|
|
145
|
+
const hostname = normalizeHostname(u.hostname, u.href);
|
|
146
|
+
const port = u.port || null;
|
|
147
|
+
const pathname = u.pathname || null;
|
|
148
|
+
const search = u.search || null;
|
|
149
|
+
// Legacy `.auth` is the decoded "user[:pass]" string; WHATWG keeps the
|
|
150
|
+
// username/password percent-encoded, so decode to stay byte-compatible with
|
|
151
|
+
// existing consumers (parseConnectionUrl, Basic/Proxy-Authorization headers).
|
|
152
|
+
let auth = null;
|
|
153
|
+
let username = null;
|
|
154
|
+
let password = null;
|
|
155
|
+
if (u.username || u.password) {
|
|
156
|
+
// Gate on password too: legacy url.parse('smtps://:pass@host').auth was
|
|
157
|
+
// ':pass'. Dropping it would silently connect unauthenticated.
|
|
158
|
+
username = safeDecode(u.username);
|
|
159
|
+
password = u.password ? safeDecode(u.password) : null;
|
|
160
|
+
// the joined form is ambiguous once the user name contains a colon, so
|
|
161
|
+
// consumers that need the parts read username and password instead
|
|
162
|
+
auth = username + (password !== null ? ':' + password : '');
|
|
163
|
+
}
|
|
164
|
+
let query;
|
|
165
|
+
if (parseQueryString) {
|
|
166
|
+
// Mirror querystring.parse(): null-prototype object, repeated keys become an array.
|
|
167
|
+
const parsed = Object.create(null);
|
|
168
|
+
u.searchParams.forEach((value, key) => {
|
|
169
|
+
if (Object.prototype.hasOwnProperty.call(parsed, key)) {
|
|
170
|
+
const existing = parsed[key];
|
|
171
|
+
if (Array.isArray(existing)) {
|
|
172
|
+
existing.push(value);
|
|
173
|
+
}
|
|
174
|
+
else {
|
|
175
|
+
parsed[key] = [existing, value];
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
else {
|
|
179
|
+
parsed[key] = value;
|
|
180
|
+
}
|
|
181
|
+
});
|
|
182
|
+
query = parsed;
|
|
183
|
+
}
|
|
184
|
+
else {
|
|
185
|
+
query = search ? search.slice(1) : null;
|
|
186
|
+
}
|
|
187
|
+
return {
|
|
188
|
+
protocol: u.protocol || null,
|
|
189
|
+
host: u.host || null,
|
|
190
|
+
hostname,
|
|
191
|
+
port,
|
|
192
|
+
pathname,
|
|
193
|
+
search,
|
|
194
|
+
path: (pathname || '') + (search || '') || null,
|
|
195
|
+
href: u.href,
|
|
196
|
+
auth,
|
|
197
|
+
username,
|
|
198
|
+
password,
|
|
199
|
+
query
|
|
200
|
+
};
|
|
201
|
+
};
|
|
202
|
+
export const resolve = (from, to) => {
|
|
203
|
+
try {
|
|
204
|
+
return new URL(to, from).href;
|
|
205
|
+
}
|
|
206
|
+
catch (err) {
|
|
207
|
+
// Malformed target, fall back to the legacy resolver, but only when the legacy
|
|
208
|
+
// parser reads the same host out of both inputs that was written. The target
|
|
209
|
+
// decides the host when it is absolute or scheme-relative, the base otherwise
|
|
210
|
+
legacyParse(from, false, err, true);
|
|
211
|
+
legacyParse(to, false, err, true);
|
|
212
|
+
return urllib.resolve(from, to);
|
|
213
|
+
}
|
|
214
|
+
};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { Transform, type TransformOptions } from 'node:stream';
|
|
2
|
+
/**
|
|
3
|
+
* Escapes dots in the beginning of lines. Ends the stream with <CR><LF>.<CR><LF>
|
|
4
|
+
* Also makes sure that only <CR><LF> sequences are used for linebreaks, bare CR and bare LF
|
|
5
|
+
* are both turned into <CR><LF>
|
|
6
|
+
*
|
|
7
|
+
* @param options Stream options
|
|
8
|
+
*/
|
|
9
|
+
export default class DataStream extends Transform {
|
|
10
|
+
options: TransformOptions;
|
|
11
|
+
inByteCount: number;
|
|
12
|
+
outByteCount: number;
|
|
13
|
+
lastByte: number | false;
|
|
14
|
+
constructor(options?: TransformOptions);
|
|
15
|
+
}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import { Transform } from 'node:stream';
|
|
2
|
+
// bytes inserted into the output, shared as they are only ever copied by Buffer.concat
|
|
3
|
+
const INSERT_LF = Buffer.from('\n');
|
|
4
|
+
const INSERT_LF_DOT = Buffer.from('\n.');
|
|
5
|
+
const INSERT_CR = Buffer.from('\r');
|
|
6
|
+
const INSERT_DOT = Buffer.from('.');
|
|
7
|
+
/**
|
|
8
|
+
* Escapes dots in the beginning of lines. Ends the stream with <CR><LF>.<CR><LF>
|
|
9
|
+
* Also makes sure that only <CR><LF> sequences are used for linebreaks, bare CR and bare LF
|
|
10
|
+
* are both turned into <CR><LF>
|
|
11
|
+
*
|
|
12
|
+
* @param options Stream options
|
|
13
|
+
*/
|
|
14
|
+
export default class DataStream extends Transform {
|
|
15
|
+
constructor(options) {
|
|
16
|
+
super(options);
|
|
17
|
+
this.options = options || {};
|
|
18
|
+
this.inByteCount = 0;
|
|
19
|
+
this.outByteCount = 0;
|
|
20
|
+
this.lastByte = false;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Escapes dots
|
|
24
|
+
* @internal
|
|
25
|
+
*/
|
|
26
|
+
_transform(chunk, encoding, done) {
|
|
27
|
+
const chunks = [];
|
|
28
|
+
let chunklen = 0;
|
|
29
|
+
let i, len, lastPos = 0;
|
|
30
|
+
let buf;
|
|
31
|
+
if (!chunk || !chunk.length) {
|
|
32
|
+
return done();
|
|
33
|
+
}
|
|
34
|
+
if (typeof chunk === 'string') {
|
|
35
|
+
chunk = Buffer.from(chunk);
|
|
36
|
+
}
|
|
37
|
+
this.inByteCount += chunk.length;
|
|
38
|
+
for (i = 0, len = chunk.length; i < len; i++) {
|
|
39
|
+
const byte = chunk[i];
|
|
40
|
+
const prev = i ? chunk[i - 1] : this.lastByte;
|
|
41
|
+
let insert = false;
|
|
42
|
+
if (prev === 0x0d && byte !== 0x0a) {
|
|
43
|
+
// a bare CR becomes CRLF. A receiver that treats a lone CR as a line end would
|
|
44
|
+
// otherwise see "\r.\r" as the end of the data (SMTP smuggling), so a dot
|
|
45
|
+
// following it is stuffed like at the start of any other line
|
|
46
|
+
insert = byte === 0x2e ? INSERT_LF_DOT : INSERT_LF;
|
|
47
|
+
}
|
|
48
|
+
else if (byte === 0x0a && prev !== 0x0d) {
|
|
49
|
+
// a bare LF becomes CRLF
|
|
50
|
+
insert = INSERT_CR;
|
|
51
|
+
}
|
|
52
|
+
else if (byte === 0x2e && (prev === 0x0a || prev === false)) {
|
|
53
|
+
// a dot at the start of a line
|
|
54
|
+
insert = INSERT_DOT;
|
|
55
|
+
}
|
|
56
|
+
if (insert) {
|
|
57
|
+
if (i > lastPos) {
|
|
58
|
+
buf = chunk.slice(lastPos, i);
|
|
59
|
+
chunks.push(buf);
|
|
60
|
+
chunklen += buf.length;
|
|
61
|
+
}
|
|
62
|
+
chunks.push(insert);
|
|
63
|
+
chunklen += insert.length;
|
|
64
|
+
lastPos = i;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
if (chunks.length) {
|
|
68
|
+
// add last piece
|
|
69
|
+
if (lastPos < chunk.length) {
|
|
70
|
+
buf = chunk.slice(lastPos);
|
|
71
|
+
chunks.push(buf);
|
|
72
|
+
chunklen += buf.length;
|
|
73
|
+
}
|
|
74
|
+
this.outByteCount += chunklen;
|
|
75
|
+
this.push(Buffer.concat(chunks, chunklen));
|
|
76
|
+
}
|
|
77
|
+
else {
|
|
78
|
+
this.outByteCount += chunk.length;
|
|
79
|
+
this.push(chunk);
|
|
80
|
+
}
|
|
81
|
+
this.lastByte = chunk[chunk.length - 1];
|
|
82
|
+
done();
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Finalizes the stream with a dot on a single line
|
|
86
|
+
* @internal
|
|
87
|
+
*/
|
|
88
|
+
_flush(done) {
|
|
89
|
+
let buf;
|
|
90
|
+
if (this.lastByte === 0x0a) {
|
|
91
|
+
buf = Buffer.from('.\r\n');
|
|
92
|
+
}
|
|
93
|
+
else if (this.lastByte === 0x0d) {
|
|
94
|
+
buf = Buffer.from('\n.\r\n');
|
|
95
|
+
}
|
|
96
|
+
else {
|
|
97
|
+
buf = Buffer.from('\r\n.\r\n');
|
|
98
|
+
}
|
|
99
|
+
this.outByteCount += buf.length;
|
|
100
|
+
this.push(buf);
|
|
101
|
+
done();
|
|
102
|
+
}
|
|
103
|
+
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Minimal HTTP/S proxy client
|
|
3
|
+
*/
|
|
4
|
+
import net from 'node:net';
|
|
5
|
+
import type { Callback } from '../errors.js';
|
|
6
|
+
/**
|
|
7
|
+
* TLS options for connecting to an HTTPS proxy
|
|
8
|
+
*/
|
|
9
|
+
export interface HttpProxyClientOptions {
|
|
10
|
+
/** Set to false to accept a proxy certificate that fails validation (e.g. self-signed) */
|
|
11
|
+
rejectUnauthorized?: boolean | undefined;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Receives the proxied socket once the CONNECT handshake has succeeded, or the error that prevented it
|
|
15
|
+
*/
|
|
16
|
+
export type HttpProxyClientCallback = Callback<net.Socket>;
|
|
17
|
+
/**
|
|
18
|
+
* Establishes proxied connection to destinationPort
|
|
19
|
+
*
|
|
20
|
+
* httpProxyClient("http://localhost:3128/", 80, "google.com", function(err, socket){
|
|
21
|
+
* socket.write("GET / HTTP/1.0\r\n\r\n");
|
|
22
|
+
* });
|
|
23
|
+
*
|
|
24
|
+
* @param proxyUrl proxy configuration, e.g. "http://proxy.host:3128/"
|
|
25
|
+
* @param destinationPort Port to open in destination host
|
|
26
|
+
* @param destinationHost Destination hostname
|
|
27
|
+
* @param callback Callback to run with the socket object once connection is established
|
|
28
|
+
*/
|
|
29
|
+
declare function httpProxyClient(proxyUrl: string, destinationPort: number | string, destinationHost: string, callback: HttpProxyClientCallback): void;
|
|
30
|
+
/**
|
|
31
|
+
* Establishes proxied connection to destinationPort through an HTTPS proxy
|
|
32
|
+
*
|
|
33
|
+
* @param proxyUrl proxy configuration, e.g. "https://proxy.host:3128/"
|
|
34
|
+
* @param destinationPort Port to open in destination host
|
|
35
|
+
* @param destinationHost Destination hostname
|
|
36
|
+
* @param tlsOptions TLS options for the proxy connection (e.g. { rejectUnauthorized: false })
|
|
37
|
+
* @param callback Callback to run with the socket object once connection is established
|
|
38
|
+
*/
|
|
39
|
+
declare function httpProxyClient(proxyUrl: string, destinationPort: number | string, destinationHost: string, tlsOptions: HttpProxyClientOptions | undefined, callback: HttpProxyClientCallback): void;
|
|
40
|
+
/**
|
|
41
|
+
* Socket timeout in milliseconds while the CONNECT handshake is in progress, defaults to 30 seconds.
|
|
42
|
+
* Settable on the function itself, the same way the CommonJS module exposed it.
|
|
43
|
+
*/
|
|
44
|
+
declare namespace httpProxyClient {
|
|
45
|
+
let timeout: number | undefined;
|
|
46
|
+
}
|
|
47
|
+
export default httpProxyClient;
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Minimal HTTP/S proxy client
|
|
3
|
+
*/
|
|
4
|
+
import net from 'node:net';
|
|
5
|
+
import tls from 'node:tls';
|
|
6
|
+
import * as urllib from '../shared/url.js';
|
|
7
|
+
import * as errors from '../errors.js';
|
|
8
|
+
// Cap the CONNECT response we buffer before the header terminator, so a proxy that
|
|
9
|
+
// never sends \r\n\r\n cannot grow memory unboundedly before the socket times out.
|
|
10
|
+
const MAX_RESPONSE_HEADER_BYTES = 64 * 1024;
|
|
11
|
+
function httpProxyClient(proxyUrl, destinationPort, destinationHost, tlsOptions, callback) {
|
|
12
|
+
if (typeof tlsOptions === 'function') {
|
|
13
|
+
callback = tlsOptions;
|
|
14
|
+
tlsOptions = {};
|
|
15
|
+
}
|
|
16
|
+
tlsOptions = tlsOptions || {};
|
|
17
|
+
// the error paths hand over the error alone
|
|
18
|
+
const done = callback;
|
|
19
|
+
// Reject CRLF in the destination before it reaches the CONNECT request line
|
|
20
|
+
// and Host header. A tainted host/port could otherwise inject additional
|
|
21
|
+
// request headers into the proxy connection (HTTP request splitting).
|
|
22
|
+
destinationPort = Number(destinationPort) || 0;
|
|
23
|
+
if (!destinationPort || /[\r\n]/.test(destinationHost)) {
|
|
24
|
+
const err = new Error('Invalid proxy destination');
|
|
25
|
+
err.code = errors.EPROXY;
|
|
26
|
+
setImmediate(() => done(err));
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
const proxy = urllib.parse(proxyUrl);
|
|
30
|
+
const connectOptions = {
|
|
31
|
+
host: proxy.hostname,
|
|
32
|
+
port: Number(proxy.port) ? Number(proxy.port) : proxy.protocol === 'https:' ? 443 : 80
|
|
33
|
+
};
|
|
34
|
+
let connect;
|
|
35
|
+
if (proxy.protocol === 'https:') {
|
|
36
|
+
// Validate the proxy's TLS certificate by default. A caller that uses a
|
|
37
|
+
// self-signed proxy (e.g. integration tests) opts out explicitly with
|
|
38
|
+
// tls.rejectUnauthorized === false.
|
|
39
|
+
connectOptions.rejectUnauthorized = tlsOptions.rejectUnauthorized !== false;
|
|
40
|
+
connect = tls.connect.bind(tls);
|
|
41
|
+
}
|
|
42
|
+
else {
|
|
43
|
+
connect = net.connect.bind(net);
|
|
44
|
+
}
|
|
45
|
+
let socket;
|
|
46
|
+
// Error harness for initial connection. Once connection is established, the responsibility
|
|
47
|
+
// to handle errors is passed to whoever uses this socket
|
|
48
|
+
let finished = false;
|
|
49
|
+
const tempSocketErr = (err) => {
|
|
50
|
+
if (finished) {
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
finished = true;
|
|
54
|
+
try {
|
|
55
|
+
socket.destroy();
|
|
56
|
+
}
|
|
57
|
+
catch (_E) {
|
|
58
|
+
// ignore
|
|
59
|
+
}
|
|
60
|
+
done(err);
|
|
61
|
+
};
|
|
62
|
+
const timeoutErr = () => {
|
|
63
|
+
const err = new Error('Proxy socket timed out');
|
|
64
|
+
err.code = 'ETIMEDOUT';
|
|
65
|
+
tempSocketErr(err);
|
|
66
|
+
};
|
|
67
|
+
socket = connect(connectOptions, () => {
|
|
68
|
+
if (finished) {
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
const reqHeaders = {
|
|
72
|
+
Host: destinationHost + ':' + destinationPort,
|
|
73
|
+
Connection: 'close'
|
|
74
|
+
};
|
|
75
|
+
if (proxy.auth) {
|
|
76
|
+
reqHeaders['Proxy-Authorization'] = 'Basic ' + Buffer.from(proxy.auth).toString('base64');
|
|
77
|
+
}
|
|
78
|
+
socket.write(
|
|
79
|
+
// HTTP method
|
|
80
|
+
'CONNECT ' +
|
|
81
|
+
destinationHost +
|
|
82
|
+
':' +
|
|
83
|
+
destinationPort +
|
|
84
|
+
' HTTP/1.1\r\n' +
|
|
85
|
+
// HTTP request headers
|
|
86
|
+
Object.keys(reqHeaders)
|
|
87
|
+
.map(key => key + ': ' + reqHeaders[key])
|
|
88
|
+
.join('\r\n') +
|
|
89
|
+
// End request
|
|
90
|
+
'\r\n\r\n');
|
|
91
|
+
// The response is collected as chunks and only the bytes that just arrived, together
|
|
92
|
+
// with the three before them, are searched for the end of the headers. Appending to a
|
|
93
|
+
// string and searching all of it again re-read the whole response on every chunk.
|
|
94
|
+
const chunks = [];
|
|
95
|
+
let received = 0;
|
|
96
|
+
let tail = '';
|
|
97
|
+
const onSocketData = (chunk) => {
|
|
98
|
+
let match;
|
|
99
|
+
if (finished) {
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
const window = tail + chunk.toString('binary');
|
|
103
|
+
const windowEnd = window.indexOf('\r\n\r\n');
|
|
104
|
+
chunks.push(chunk);
|
|
105
|
+
received += chunk.length;
|
|
106
|
+
tail = window.slice(-3);
|
|
107
|
+
if (windowEnd >= 0) {
|
|
108
|
+
socket.removeListener('data', onSocketData);
|
|
109
|
+
const headerEnd = received - window.length + windowEnd;
|
|
110
|
+
const response = Buffer.concat(chunks, received).toString('binary');
|
|
111
|
+
const headers = response.substr(0, headerEnd);
|
|
112
|
+
const remainder = response.substr(headerEnd + 4);
|
|
113
|
+
if (remainder) {
|
|
114
|
+
socket.unshift(Buffer.from(remainder, 'binary'));
|
|
115
|
+
}
|
|
116
|
+
// proxy connection is now established
|
|
117
|
+
finished = true;
|
|
118
|
+
// check response code
|
|
119
|
+
match = headers.match(/^HTTP\/\d+\.\d+ (\d+)/i);
|
|
120
|
+
if (!match || (match[1] || '').charAt(0) !== '2') {
|
|
121
|
+
try {
|
|
122
|
+
socket.destroy();
|
|
123
|
+
}
|
|
124
|
+
catch (_E) {
|
|
125
|
+
// ignore
|
|
126
|
+
}
|
|
127
|
+
const err = new Error('Invalid response from proxy' + ((match && ': ' + match[1]) || ''));
|
|
128
|
+
err.code = errors.EPROXY;
|
|
129
|
+
return done(err);
|
|
130
|
+
}
|
|
131
|
+
socket.removeListener('error', tempSocketErr);
|
|
132
|
+
socket.removeListener('timeout', timeoutErr);
|
|
133
|
+
socket.setTimeout(0);
|
|
134
|
+
return done(null, socket);
|
|
135
|
+
}
|
|
136
|
+
if (received > MAX_RESPONSE_HEADER_BYTES) {
|
|
137
|
+
socket.removeListener('data', onSocketData);
|
|
138
|
+
const err = new Error('Proxy response headers too large');
|
|
139
|
+
err.code = errors.EPROXY;
|
|
140
|
+
return tempSocketErr(err);
|
|
141
|
+
}
|
|
142
|
+
};
|
|
143
|
+
socket.on('data', onSocketData);
|
|
144
|
+
});
|
|
145
|
+
socket.setTimeout(httpProxyClient.timeout || 30 * 1000);
|
|
146
|
+
socket.on('timeout', timeoutErr);
|
|
147
|
+
socket.once('error', tempSocketErr);
|
|
148
|
+
}
|
|
149
|
+
export default httpProxyClient;
|