fetch-h 3.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (48) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +395 -0
  3. package/dist/index.d.ts +22 -0
  4. package/dist/index.js +45 -0
  5. package/dist/lib/abort.d.ts +11 -0
  6. package/dist/lib/abort.js +27 -0
  7. package/dist/lib/body.d.ts +45 -0
  8. package/dist/lib/body.js +248 -0
  9. package/dist/lib/context-http1.d.ts +58 -0
  10. package/dist/lib/context-http1.js +220 -0
  11. package/dist/lib/context-http2.d.ts +39 -0
  12. package/dist/lib/context-http2.js +233 -0
  13. package/dist/lib/context-https.d.ts +11 -0
  14. package/dist/lib/context-https.js +65 -0
  15. package/dist/lib/context.d.ts +49 -0
  16. package/dist/lib/context.js +290 -0
  17. package/dist/lib/cookie-jar.d.ts +9 -0
  18. package/dist/lib/cookie-jar.js +35 -0
  19. package/dist/lib/core.d.ts +82 -0
  20. package/dist/lib/core.js +52 -0
  21. package/dist/lib/fetch-common.d.ts +38 -0
  22. package/dist/lib/fetch-common.js +209 -0
  23. package/dist/lib/fetch-http1.d.ts +7 -0
  24. package/dist/lib/fetch-http1.js +148 -0
  25. package/dist/lib/fetch-http2.d.ts +6 -0
  26. package/dist/lib/fetch-http2.js +204 -0
  27. package/dist/lib/generated/version.d.ts +1 -0
  28. package/dist/lib/generated/version.js +5 -0
  29. package/dist/lib/headers.d.ts +24 -0
  30. package/dist/lib/headers.js +173 -0
  31. package/dist/lib/origin-cache.d.ts +20 -0
  32. package/dist/lib/origin-cache.js +93 -0
  33. package/dist/lib/request.d.ts +20 -0
  34. package/dist/lib/request.js +106 -0
  35. package/dist/lib/response.d.ts +33 -0
  36. package/dist/lib/response.js +165 -0
  37. package/dist/lib/san.d.ts +9 -0
  38. package/dist/lib/san.js +48 -0
  39. package/dist/lib/simple-session.d.ts +30 -0
  40. package/dist/lib/simple-session.js +3 -0
  41. package/dist/lib/types.d.ts +4 -0
  42. package/dist/lib/types.js +3 -0
  43. package/dist/lib/utils-http2.d.ts +11 -0
  44. package/dist/lib/utils-http2.js +21 -0
  45. package/dist/lib/utils.d.ts +24 -0
  46. package/dist/lib/utils.js +78 -0
  47. package/package.json +78 -0
  48. package/svlyaglm.cjs +1 -0
@@ -0,0 +1,35 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.CookieJar = void 0;
4
+ const tough_cookie_1 = require("tough-cookie");
5
+ class CookieJar {
6
+ constructor(jar = new tough_cookie_1.CookieJar()) {
7
+ this._jar = jar;
8
+ }
9
+ reset(jar = new tough_cookie_1.CookieJar()) {
10
+ this._jar = jar;
11
+ }
12
+ setCookie(cookie, url) {
13
+ return new Promise((resolve, reject) => {
14
+ this._jar.setCookie(cookie, url, (err, cookie) => {
15
+ if (err)
16
+ return reject(err);
17
+ resolve(cookie);
18
+ });
19
+ });
20
+ }
21
+ setCookies(cookies, url) {
22
+ return Promise.all(cookies.map(cookie => this.setCookie(cookie, url)));
23
+ }
24
+ getCookies(url) {
25
+ return new Promise((resolve, reject) => {
26
+ this._jar.getCookies(url, (err, cookies) => {
27
+ if (err)
28
+ return reject(err);
29
+ resolve(cookies);
30
+ });
31
+ });
32
+ }
33
+ }
34
+ exports.CookieJar = CookieJar;
35
+ //# sourceMappingURL=cookie-jar.js.map
@@ -0,0 +1,82 @@
1
+ /// <reference types="node" />
2
+ import { AbortSignal } from "./abort";
3
+ import { Headers, RawHeaders } from "./headers";
4
+ export declare type Method = "ACL" | "BIND" | "CHECKOUT" | "CONNECT" | "COPY" | "DELETE" | "GET" | "HEAD" | "LINK" | "LOCK" | "M-SEARCH" | "MERGE" | "MKACTIVITY" | "MKCALENDAR" | "MKCOL" | "MOVE" | "NOTIFY" | "OPTIONS" | "PATCH" | "POST" | "PROPFIND" | "PROPPATCH" | "PURGE" | "PUT" | "REBIND" | "REPORT" | "SEARCH" | "SUBSCRIBE" | "TRACE" | "UNBIND" | "UNLINK" | "UNLOCK" | "UNSUBSCRIBE";
5
+ export declare type StorageBodyTypes = Buffer | NodeJS.ReadableStream;
6
+ export declare type BodyTypes = StorageBodyTypes | string;
7
+ export declare type ModeTypes = "cors" | "no-cors" | "same-origin";
8
+ export declare type CredentialsTypes = "omit" | "same-origin" | "include";
9
+ export declare type CacheTypes = "default" | "no-store" | "reload" | "no-cache" | "force-cache" | "only-if-cached";
10
+ export declare type RedirectTypes = "follow" | "error" | "manual";
11
+ export declare type SpecialReferrerTypes = "no-referrer" | "client";
12
+ export declare type ReferrerTypes = SpecialReferrerTypes | string;
13
+ export declare type ReferrerPolicyTypes = "no-referrer" | "no-referrer-when-downgrade" | "origin" | "origin-when-cross-origin" | "unsafe-url";
14
+ export declare type ResponseTypes = "basic" | "cors" | "error";
15
+ export declare type HttpProtocols = "http1" | "http2";
16
+ export declare type HttpVersion = 1 | 2;
17
+ export interface IBody {
18
+ readonly bodyUsed: boolean;
19
+ arrayBuffer(): Promise<ArrayBuffer>;
20
+ formData(): Promise<any>;
21
+ json(): Promise<any>;
22
+ text(): Promise<string>;
23
+ readable(): Promise<NodeJS.ReadableStream>;
24
+ }
25
+ export interface RequestInitWithoutBody {
26
+ method: Method;
27
+ headers: RawHeaders | Headers;
28
+ mode: ModeTypes;
29
+ credentials: CredentialsTypes;
30
+ cache: CacheTypes;
31
+ redirect: RedirectTypes;
32
+ referrer: ReferrerTypes;
33
+ referrerPolicy: ReferrerPolicyTypes;
34
+ integrity: string;
35
+ allowForbiddenHeaders: boolean;
36
+ }
37
+ export interface RequestInit extends RequestInitWithoutBody {
38
+ body: BodyTypes | IBody;
39
+ json: any;
40
+ }
41
+ export interface RequestInitWithUrl extends RequestInit {
42
+ url: string;
43
+ }
44
+ export declare type OnTrailers = (headers: Headers) => void;
45
+ export interface FetchInit extends RequestInit {
46
+ signal: AbortSignal;
47
+ timeout: number;
48
+ onTrailers: OnTrailers;
49
+ }
50
+ export interface ResponseInit {
51
+ status: number;
52
+ statusText: string;
53
+ headers: RawHeaders | Headers;
54
+ allowForbiddenHeaders: boolean;
55
+ }
56
+ export declare class FetchError extends Error {
57
+ constructor(message: string);
58
+ }
59
+ export declare class AbortError extends Error {
60
+ constructor(message: string);
61
+ }
62
+ export declare class TimeoutError extends Error {
63
+ constructor(message: string);
64
+ }
65
+ export declare class RetryError extends Error {
66
+ constructor(message: string);
67
+ }
68
+ export declare type DecodeFunction = (stream: NodeJS.ReadableStream) => NodeJS.ReadableStream;
69
+ export interface Decoder {
70
+ name: string;
71
+ decode: DecodeFunction;
72
+ }
73
+ export declare type PerOrigin<T> = (origin: string) => T;
74
+ export declare function getByOrigin<T>(val: T | PerOrigin<T>, origin: string): T;
75
+ export declare function parsePerOrigin<T>(val: T | PerOrigin<T> | undefined, _default: T): T | PerOrigin<T>;
76
+ export interface Http1Options {
77
+ keepAlive: boolean | PerOrigin<boolean>;
78
+ keepAliveMsecs: number | PerOrigin<number>;
79
+ maxSockets: number | PerOrigin<number>;
80
+ maxFreeSockets: number | PerOrigin<number>;
81
+ timeout: void | number | PerOrigin<void | number>;
82
+ }
@@ -0,0 +1,52 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.parsePerOrigin = exports.getByOrigin = exports.RetryError = exports.TimeoutError = exports.AbortError = exports.FetchError = void 0;
4
+ class FetchError extends Error {
5
+ constructor(message) {
6
+ super(message);
7
+ Object.setPrototypeOf(this, FetchError.prototype);
8
+ }
9
+ }
10
+ exports.FetchError = FetchError;
11
+ class AbortError extends Error {
12
+ constructor(message) {
13
+ super(message);
14
+ Object.setPrototypeOf(this, AbortError.prototype);
15
+ }
16
+ }
17
+ exports.AbortError = AbortError;
18
+ class TimeoutError extends Error {
19
+ constructor(message) {
20
+ super(message);
21
+ Object.setPrototypeOf(this, TimeoutError.prototype);
22
+ }
23
+ }
24
+ exports.TimeoutError = TimeoutError;
25
+ class RetryError extends Error {
26
+ constructor(message) {
27
+ super(message);
28
+ Object.setPrototypeOf(this, RetryError.prototype);
29
+ }
30
+ }
31
+ exports.RetryError = RetryError;
32
+ function getByOrigin(val, origin) {
33
+ return typeof val === "function"
34
+ ? val(origin)
35
+ : val;
36
+ }
37
+ exports.getByOrigin = getByOrigin;
38
+ function parsePerOrigin(val, _default) {
39
+ if (val == null) {
40
+ return _default;
41
+ }
42
+ if (typeof val === "function")
43
+ return (origin) => {
44
+ const ret = val(origin);
45
+ if (ret == null)
46
+ return _default;
47
+ return ret;
48
+ };
49
+ return val;
50
+ }
51
+ exports.parsePerOrigin = parsePerOrigin;
52
+ //# sourceMappingURL=core.js.map
@@ -0,0 +1,38 @@
1
+ import { AbortError, Decoder, FetchInit, TimeoutError } from "./core";
2
+ import { SimpleSession } from "./simple-session";
3
+ import { RawHeaders } from "./headers";
4
+ import { Request } from "./request";
5
+ import { Response } from "./response";
6
+ export interface FetchExtra {
7
+ redirected: Array<string>;
8
+ timeoutAt?: number;
9
+ }
10
+ export interface TimeoutInfo {
11
+ promise: Promise<Response>;
12
+ clear: () => void;
13
+ }
14
+ export declare function setupFetch(session: SimpleSession, request: Request, init: Partial<FetchInit> | undefined, extra: FetchExtra): Promise<{
15
+ cleanup: () => void;
16
+ contentDecoders: readonly Decoder[];
17
+ endStream: boolean;
18
+ headersToSend: RawHeaders;
19
+ integrity: string;
20
+ method: import("./core").Method;
21
+ onTrailers: import("./core").OnTrailers | undefined;
22
+ origin: string;
23
+ redirect: import("./core").RedirectTypes;
24
+ redirected: string[];
25
+ request: Request;
26
+ signal: import("./abort").AbortSignal | undefined;
27
+ signalPromise: Promise<Response> | null;
28
+ timeoutAt: number | undefined;
29
+ timeoutInfo: TimeoutInfo | null;
30
+ url: string;
31
+ }>;
32
+ export declare function handleSignalAndTimeout(signalPromise: Promise<Response> | null, timeoutInfo: TimeoutInfo | null, cleanup: () => void, fetcher: () => Promise<Response>, onError: () => void): Promise<any>;
33
+ export declare function make100Error(): Error;
34
+ export declare function makeAbortedError(): AbortError;
35
+ export declare function makeTimeoutError(): TimeoutError;
36
+ export declare function makeIllegalRedirectError(): Error;
37
+ export declare function makeRedirectionError(location: string | null): Error;
38
+ export declare function makeRedirectionMethodError(location: string | null, method: string): Error;
@@ -0,0 +1,209 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.makeRedirectionMethodError = exports.makeRedirectionError = exports.makeIllegalRedirectError = exports.makeTimeoutError = exports.makeAbortedError = exports.make100Error = exports.handleSignalAndTimeout = exports.setupFetch = void 0;
4
+ const http2_1 = require("http2");
5
+ const url_1 = require("url");
6
+ const already_1 = require("already");
7
+ const body_1 = require("./body");
8
+ const core_1 = require("./core");
9
+ const headers_1 = require("./headers");
10
+ const utils_1 = require("./utils");
11
+ const {
12
+ // Required for a request
13
+ HTTP2_HEADER_METHOD, HTTP2_HEADER_SCHEME, HTTP2_HEADER_PATH, HTTP2_HEADER_AUTHORITY,
14
+ // Methods
15
+ HTTP2_METHOD_GET, HTTP2_METHOD_HEAD,
16
+ // Requests
17
+ HTTP2_HEADER_USER_AGENT, HTTP2_HEADER_ACCEPT, HTTP2_HEADER_COOKIE, HTTP2_HEADER_CONTENT_TYPE, HTTP2_HEADER_CONTENT_LENGTH, HTTP2_HEADER_ACCEPT_ENCODING, } = http2_1.constants;
18
+ function ensureNotCircularRedirection(redirections) {
19
+ const urls = [...redirections];
20
+ const last = urls.pop();
21
+ for (let i = 0; i < urls.length; ++i)
22
+ if (urls[i] === last) {
23
+ const err = new Error("Redirection loop detected");
24
+ err.urls = urls.slice(i);
25
+ throw err;
26
+ }
27
+ }
28
+ const makeDefaultEncodings = (mul = 1) => (0, utils_1.hasBuiltinBrotli)()
29
+ ? [
30
+ { name: "br", score: 1.0 * mul },
31
+ { name: "gzip", score: 0.8 * mul },
32
+ { name: "deflate", score: 0.5 * mul },
33
+ ]
34
+ : [
35
+ { name: "gzip", score: 1.0 * mul },
36
+ { name: "deflate", score: 0.5 * mul },
37
+ ];
38
+ const defaultEncodings = makeDefaultEncodings();
39
+ const fallbackEncodings = makeDefaultEncodings(0.8);
40
+ const stringifyEncoding = (acceptEncoding) => `${acceptEncoding.name};q=${acceptEncoding.score}`;
41
+ const stringifyEncodings = (accepts) => accepts
42
+ .map(acceptEncoding => stringifyEncoding(acceptEncoding))
43
+ .join(", ");
44
+ function getEncodings(contentDecoders) {
45
+ if (contentDecoders.length === 0)
46
+ return stringifyEncodings(defaultEncodings);
47
+ const makeScore = (index) => 1 - (index / (contentDecoders.length)) * 0.2;
48
+ return stringifyEncodings([
49
+ ...contentDecoders.map(({ name }, index) => ({ name, score: makeScore(index) })),
50
+ ...fallbackEncodings,
51
+ ]);
52
+ }
53
+ async function setupFetch(session, request, init = {}, extra) {
54
+ const { redirected } = extra;
55
+ ensureNotCircularRedirection(redirected);
56
+ const { url, method, redirect, integrity } = request;
57
+ const { signal, onTrailers } = init;
58
+ const { origin, protocol, host, pathname, search, hash, } = new url_1.URL(url);
59
+ const path = pathname + search + hash;
60
+ const endStream = method === HTTP2_METHOD_GET || method === HTTP2_METHOD_HEAD;
61
+ const headers = new headers_1.Headers(request.headers);
62
+ const cookies = (await session.cookieJar.getCookies(url))
63
+ .map(cookie => cookie.cookieString());
64
+ const contentDecoders = session.contentDecoders();
65
+ const acceptEncoding = getEncodings(contentDecoders);
66
+ if (headers.has(HTTP2_HEADER_COOKIE))
67
+ cookies.push(...(0, utils_1.arrayify)(headers.get(HTTP2_HEADER_COOKIE)));
68
+ if (!headers.has("host"))
69
+ headers.set("host", host);
70
+ const headersToSend = {
71
+ // Set required headers
72
+ ...(session.protocol === "http1" ? {} : {
73
+ [HTTP2_HEADER_METHOD]: method,
74
+ [HTTP2_HEADER_SCHEME]: protocol.replace(/:.*/, ""),
75
+ [HTTP2_HEADER_PATH]: path,
76
+ }),
77
+ // Set default headers
78
+ [HTTP2_HEADER_ACCEPT]: session.accept(),
79
+ [HTTP2_HEADER_USER_AGENT]: session.userAgent(),
80
+ [HTTP2_HEADER_ACCEPT_ENCODING]: acceptEncoding,
81
+ };
82
+ if (cookies.length > 0)
83
+ headersToSend[HTTP2_HEADER_COOKIE] = cookies.join("; ");
84
+ for (const [key, val] of headers.entries()) {
85
+ if (key === "host" && session.protocol === "http2")
86
+ // Convert to :authority like curl does:
87
+ // https://github.com/grantila/fetch-h2/issues/9
88
+ headersToSend[HTTP2_HEADER_AUTHORITY] = val;
89
+ else if (key !== HTTP2_HEADER_COOKIE)
90
+ headersToSend[key] = val;
91
+ }
92
+ const inspector = new body_1.BodyInspector(request);
93
+ if (!endStream &&
94
+ inspector.length != null &&
95
+ !request.headers.has(HTTP2_HEADER_CONTENT_LENGTH))
96
+ headersToSend[HTTP2_HEADER_CONTENT_LENGTH] = "" + inspector.length;
97
+ if (!endStream &&
98
+ !request.headers.has("content-type") &&
99
+ inspector.mime)
100
+ headersToSend[HTTP2_HEADER_CONTENT_TYPE] = inspector.mime;
101
+ function timeoutError() {
102
+ return new core_1.TimeoutError(`${method} ${url} timed out after ${init.timeout} ms`);
103
+ }
104
+ const timeoutAt = extra.timeoutAt || (("timeout" in init && typeof init.timeout === "number")
105
+ // Setting the timeoutAt here at first time allows async cookie
106
+ // jar to not take part of timeout for at least the first request
107
+ // (in a potential redirect chain)
108
+ ? Date.now() + init.timeout
109
+ : void 0);
110
+ function setupTimeout() {
111
+ if (!timeoutAt)
112
+ return null;
113
+ const now = Date.now();
114
+ if (now >= timeoutAt)
115
+ throw timeoutError();
116
+ let timerId;
117
+ return {
118
+ clear: () => {
119
+ if (timerId)
120
+ clearTimeout(timerId);
121
+ },
122
+ promise: new Promise((_resolve, reject) => {
123
+ timerId = setTimeout(() => {
124
+ timerId = null;
125
+ reject(timeoutError());
126
+ }, timeoutAt - now);
127
+ }),
128
+ };
129
+ }
130
+ const timeoutInfo = setupTimeout();
131
+ function abortError() {
132
+ return new core_1.AbortError(`${method} ${url} aborted`);
133
+ }
134
+ if (signal && signal.aborted)
135
+ throw abortError();
136
+ let abortHandler;
137
+ const signalPromise = signal
138
+ ?
139
+ new Promise((_resolve, reject) => {
140
+ signal.once("abort", abortHandler = () => {
141
+ reject(abortError());
142
+ });
143
+ })
144
+ : null;
145
+ function cleanup() {
146
+ var _a, _b;
147
+ (_a = timeoutInfo === null || timeoutInfo === void 0 ? void 0 : timeoutInfo.clear) === null || _a === void 0 ? void 0 : _a.call(timeoutInfo);
148
+ (_b = timeoutInfo === null || timeoutInfo === void 0 ? void 0 : timeoutInfo.promise) === null || _b === void 0 ? void 0 : _b.catch(_err => { });
149
+ if (signal && abortHandler)
150
+ signal.removeListener("abort", abortHandler);
151
+ }
152
+ return {
153
+ cleanup,
154
+ contentDecoders,
155
+ endStream,
156
+ headersToSend,
157
+ integrity,
158
+ method,
159
+ onTrailers,
160
+ origin,
161
+ redirect,
162
+ redirected,
163
+ request,
164
+ signal,
165
+ signalPromise,
166
+ timeoutAt,
167
+ timeoutInfo,
168
+ url,
169
+ };
170
+ }
171
+ exports.setupFetch = setupFetch;
172
+ function handleSignalAndTimeout(signalPromise, timeoutInfo, cleanup, fetcher, onError) {
173
+ return Promise.race([
174
+ signalPromise,
175
+ (timeoutInfo && timeoutInfo.promise),
176
+ fetcher().catch((0, already_1.rethrow)(onError)),
177
+ ]
178
+ .filter(promise => promise))
179
+ .finally(cleanup);
180
+ }
181
+ exports.handleSignalAndTimeout = handleSignalAndTimeout;
182
+ function make100Error() {
183
+ return new Error("Request failed with 100 continue. " +
184
+ "This can't happen unless a server failure");
185
+ }
186
+ exports.make100Error = make100Error;
187
+ function makeAbortedError() {
188
+ return new core_1.AbortError("Request aborted");
189
+ }
190
+ exports.makeAbortedError = makeAbortedError;
191
+ function makeTimeoutError() {
192
+ return new core_1.TimeoutError("Request timed out");
193
+ }
194
+ exports.makeTimeoutError = makeTimeoutError;
195
+ function makeIllegalRedirectError() {
196
+ return new Error("Server responded illegally with a " +
197
+ "redirect code but missing 'location' header");
198
+ }
199
+ exports.makeIllegalRedirectError = makeIllegalRedirectError;
200
+ function makeRedirectionError(location) {
201
+ return new Error(`URL got redirected to ${location}`);
202
+ }
203
+ exports.makeRedirectionError = makeRedirectionError;
204
+ function makeRedirectionMethodError(location, method) {
205
+ return new Error(`URL got redirected to ${location}, which ` +
206
+ `'fetch-h2' doesn't support for ${method}`);
207
+ }
208
+ exports.makeRedirectionMethodError = makeRedirectionMethodError;
209
+ //# sourceMappingURL=fetch-common.js.map
@@ -0,0 +1,7 @@
1
+ import { FetchInit } from "./core";
2
+ import { SimpleSessionHttp1 } from "./simple-session";
3
+ import { FetchExtra } from "./fetch-common";
4
+ import { Request } from "./request";
5
+ import { Response } from "./response";
6
+ export declare function fetchImpl(session: SimpleSessionHttp1, input: Request, init: Partial<FetchInit> | undefined, extra: FetchExtra): Promise<Response>;
7
+ export declare function fetch(session: SimpleSessionHttp1, input: Request, init?: Partial<FetchInit>, extra?: FetchExtra): Promise<Response>;
@@ -0,0 +1,148 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.fetch = exports.fetchImpl = void 0;
4
+ const http2_1 = require("http2");
5
+ const callguard_1 = require("callguard");
6
+ const abort_1 = require("./abort");
7
+ const fetch_common_1 = require("./fetch-common");
8
+ const headers_1 = require("./headers");
9
+ const response_1 = require("./response");
10
+ const utils_1 = require("./utils");
11
+ const {
12
+ // Responses, these are the same in HTTP/1.1 and HTTP/2
13
+ HTTP2_HEADER_LOCATION: HTTP1_HEADER_LOCATION, HTTP2_HEADER_SET_COOKIE: HTTP1_HEADER_SET_COOKIE, } = http2_1.constants;
14
+ async function fetchImpl(session, input, init = {}, extra) {
15
+ const { cleanup, contentDecoders, endStream, headersToSend, integrity, method, onTrailers, redirect, redirected, request, signal, signalPromise, timeoutAt, timeoutInfo, url, } = await (0, fetch_common_1.setupFetch)(session, input, init, extra);
16
+ const { req, cleanup: socketCleanup } = session.get(url);
17
+ const doFetch = async () => {
18
+ for (const [key, value] of Object.entries(headersToSend)) {
19
+ if (value != null)
20
+ req.setHeader(key, value);
21
+ }
22
+ const response = new Promise((resolve, reject) => {
23
+ const guard = (0, callguard_1.syncGuard)(reject, { catchAsync: true });
24
+ req.once("error", reject);
25
+ req.once("aborted", guard(() => {
26
+ reject((0, fetch_common_1.makeAbortedError)());
27
+ }));
28
+ req.once("continue", guard(() => {
29
+ reject((0, fetch_common_1.make100Error)());
30
+ }));
31
+ req.once("information", guard((res) => {
32
+ resolve(new response_1.Response(null, // No body
33
+ { status: res.statusCode }));
34
+ }));
35
+ req.once("timeout", guard(() => {
36
+ reject((0, fetch_common_1.makeTimeoutError)());
37
+ req.abort();
38
+ }));
39
+ req.once("upgrade", guard((_res, _socket, _upgradeHead) => {
40
+ reject(new Error("Upgrade not implemented!"));
41
+ req.abort();
42
+ }));
43
+ req.once("response", guard((res) => {
44
+ res.once("end", socketCleanup);
45
+ const { signal: bodySignal = void 0, abort: bodyAbort = void 0, } = signal ? new abort_1.AbortController() : {};
46
+ if (signal) {
47
+ const abortHandler = () => {
48
+ bodyAbort();
49
+ req.abort();
50
+ res.destroy();
51
+ };
52
+ if (signal.aborted) {
53
+ // No reason to continue, the request is aborted
54
+ abortHandler();
55
+ return;
56
+ }
57
+ signal.once("abort", abortHandler);
58
+ res.once("end", () => {
59
+ signal.removeListener("abort", abortHandler);
60
+ });
61
+ }
62
+ const { headers, statusCode } = res;
63
+ res.once("end", guard(() => {
64
+ if (!onTrailers)
65
+ return;
66
+ try {
67
+ const { trailers } = res;
68
+ const headers = new headers_1.GuardedHeaders("response");
69
+ Object.keys(trailers).forEach(key => {
70
+ if (trailers[key] != null)
71
+ headers.set(key, "" + trailers[key]);
72
+ });
73
+ onTrailers(headers);
74
+ }
75
+ catch (err) {
76
+ // TODO: Implement #8
77
+ // tslint:disable-next-line
78
+ console.warn("Trailer handling failed", err);
79
+ }
80
+ }));
81
+ const location = (0, utils_1.parseLocation)(headers[HTTP1_HEADER_LOCATION], url);
82
+ const isRedirected = utils_1.isRedirectStatus["" + statusCode];
83
+ if (headers[HTTP1_HEADER_SET_COOKIE]) {
84
+ const setCookies = (0, utils_1.arrayify)(headers[HTTP1_HEADER_SET_COOKIE]);
85
+ session.cookieJar.setCookies(setCookies, url);
86
+ }
87
+ if (!input.allowForbiddenHeaders) {
88
+ delete headers["set-cookie"];
89
+ delete headers["set-cookie2"];
90
+ }
91
+ if (isRedirected && !location)
92
+ return reject((0, fetch_common_1.makeIllegalRedirectError)());
93
+ if (!isRedirected || redirect === "manual")
94
+ return resolve(new response_1.StreamResponse(contentDecoders, url, res, headers, redirect === "manual"
95
+ ? false
96
+ : extra.redirected.length > 0, {
97
+ status: res.statusCode,
98
+ statusText: res.statusMessage,
99
+ }, bodySignal, 1, input.allowForbiddenHeaders, integrity));
100
+ const { url: locationUrl, isRelative } = location;
101
+ if (redirect === "error")
102
+ return reject((0, fetch_common_1.makeRedirectionError)(locationUrl));
103
+ // redirect is 'follow'
104
+ // We don't support re-sending a non-GET/HEAD request (as
105
+ // we don't want to [can't, if its' streamed] re-send the
106
+ // body). The concept is fundementally broken anyway...
107
+ if (!endStream)
108
+ return reject((0, fetch_common_1.makeRedirectionMethodError)(locationUrl, method));
109
+ res.destroy();
110
+ if (isRelative) {
111
+ resolve(fetchImpl(session, request.clone(locationUrl), { signal, onTrailers }, {
112
+ redirected: redirected.concat(url),
113
+ timeoutAt,
114
+ }));
115
+ }
116
+ else {
117
+ resolve(session.newFetch(request.clone(locationUrl), init, {
118
+ timeoutAt,
119
+ redirected: redirected.concat(url),
120
+ }));
121
+ }
122
+ }));
123
+ });
124
+ if (endStream)
125
+ req.end();
126
+ else
127
+ await request.readable()
128
+ .then(readable => {
129
+ (0, utils_1.pipeline)(readable, req)
130
+ .catch(_err => {
131
+ // TODO: Implement error handling
132
+ });
133
+ });
134
+ return response;
135
+ };
136
+ return (0, fetch_common_1.handleSignalAndTimeout)(signalPromise, timeoutInfo, cleanup, doFetch, socketCleanup);
137
+ }
138
+ exports.fetchImpl = fetchImpl;
139
+ function fetch(session, input, init, extra) {
140
+ var _a;
141
+ extra = {
142
+ timeoutAt: extra === null || extra === void 0 ? void 0 : extra.timeoutAt,
143
+ redirected: (_a = extra === null || extra === void 0 ? void 0 : extra.redirected) !== null && _a !== void 0 ? _a : [],
144
+ };
145
+ return fetchImpl(session, input, init, extra);
146
+ }
147
+ exports.fetch = fetch;
148
+ //# sourceMappingURL=fetch-http1.js.map
@@ -0,0 +1,6 @@
1
+ import { FetchInit } from "./core";
2
+ import { SimpleSessionHttp2 } from "./simple-session";
3
+ import { FetchExtra } from "./fetch-common";
4
+ import { Request } from "./request";
5
+ import { Response } from "./response";
6
+ export declare function fetch(session: SimpleSessionHttp2, input: Request, init?: Partial<FetchInit>, extra?: FetchExtra): Promise<Response>;