-
Notifications
You must be signed in to change notification settings - Fork 8
/
web-outgoing.ts
145 lines (131 loc) 路 4.42 KB
/
web-outgoing.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
import { rewriteCookieProperty } from "../_utils";
import {
ProxyOutgoingMiddleware,
defineProxyOutgoingMiddleware,
} from "./_utils";
const redirectRegex = /^201|30([1278])$/;
/**
* If is a HTTP 1.0 request, remove chunk headers
*/
const removeChunked = defineProxyOutgoingMiddleware((req, res, proxyRes) => {
if (req.httpVersion === "1.0") {
delete proxyRes.headers["transfer-encoding"];
}
});
/**
* If is a HTTP 1.0 request, set the correct connection header
* or if connection header not present, then use `keep-alive`
*/
const setConnection = defineProxyOutgoingMiddleware((req, res, proxyRes) => {
if (req.httpVersion === "1.0") {
proxyRes.headers.connection = req.headers.connection || "close";
} else if (req.httpVersion !== "2.0" && !proxyRes.headers.connection) {
proxyRes.headers.connection = req.headers.connection || "keep-alive";
}
});
const setRedirectHostRewrite = defineProxyOutgoingMiddleware(
(req, res, proxyRes, options) => {
if (
(options.hostRewrite || options.autoRewrite || options.protocolRewrite) &&
proxyRes.headers.location &&
redirectRegex.test(String(proxyRes.statusCode))
) {
const target = new URL(options.target);
const u = new URL(proxyRes.headers.location);
// Make sure the redirected host matches the target host before rewriting
if (target.host !== u.host) {
return;
}
if (options.hostRewrite) {
u.host = options.hostRewrite;
} else if (options.autoRewrite) {
u.host = req.headers.host;
}
if (options.protocolRewrite) {
u.protocol = options.protocolRewrite;
}
proxyRes.headers.location = u.toString();
}
},
);
/**
* Copy headers from proxyResponse to response
* set each header in response object.
*
* @param {ClientRequest} Req Request object
* @param {IncomingMessage} Res Response object
* @param {proxyResponse} Res Response object from the proxy request
* @param {Object} Options options.cookieDomainRewrite: Config to rewrite cookie domain
*
* @api private
*/
const writeHeaders = defineProxyOutgoingMiddleware(
(req, res, proxyRes, options) => {
let rewriteCookieDomainConfig = options.cookieDomainRewrite;
let rewriteCookiePathConfig = options.cookiePathRewrite;
const preserveHeaderKeyCase = options.preserveHeaderKeyCase;
let rawHeaderKeyMap;
const setHeader = function (key, header) {
if (header === undefined) {
return;
}
if (rewriteCookieDomainConfig && key.toLowerCase() === "set-cookie") {
header = rewriteCookieProperty(
header,
rewriteCookieDomainConfig,
"domain",
);
}
if (rewriteCookiePathConfig && key.toLowerCase() === "set-cookie") {
header = rewriteCookieProperty(header, rewriteCookiePathConfig, "path");
}
res.setHeader(String(key).trim(), header);
};
if (typeof rewriteCookieDomainConfig === "string") {
// also test for ''
rewriteCookieDomainConfig = { "*": rewriteCookieDomainConfig };
}
if (typeof rewriteCookiePathConfig === "string") {
// also test for ''
rewriteCookiePathConfig = { "*": rewriteCookiePathConfig };
}
// message.rawHeaders is added in: v0.11.6
// https://nodejs.org/api/http.html#http_message_rawheaders
if (preserveHeaderKeyCase && proxyRes.rawHeaders !== undefined) {
rawHeaderKeyMap = {};
for (let i = 0; i < proxyRes.rawHeaders.length; i += 2) {
const key = proxyRes.rawHeaders[i];
rawHeaderKeyMap[key.toLowerCase()] = key;
}
}
for (let key of Object.keys(proxyRes.headers)) {
const header = proxyRes.headers[key];
if (preserveHeaderKeyCase && rawHeaderKeyMap) {
key = rawHeaderKeyMap[key] || key;
}
setHeader(key, header);
}
},
);
/**
* Set the statusCode from the proxyResponse
*/
const writeStatusCode = defineProxyOutgoingMiddleware((req, res, proxyRes) => {
// From Node.js docs: response.writeHead(statusCode[, statusMessage][, headers])
if (proxyRes.statusMessage) {
// @ts-expect-error
res.statusCode = proxyRes.statusCode;
// @ts-expect-error
res.statusMessage = proxyRes.statusMessage;
} else {
// @ts-expect-error
res.statusCode = proxyRes.statusCode;
}
});
export const webOutgoingMiddleware: readonly ProxyOutgoingMiddleware[] = [
removeChunked,
setConnection,
setRedirectHostRewrite,
writeHeaders,
writeStatusCode,
] as const;