@edgeone/opennextjs-pages 0.0.3 → 0.0.5
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.
|
@@ -16,21 +16,44 @@ process.env.USE_REGIONAL_BLOBS = '{{useRegionalBlobs}}'
|
|
|
16
16
|
async function handleResponse(res, response, passHeaders = {}) {
|
|
17
17
|
const startTime = Date.now();
|
|
18
18
|
|
|
19
|
+
// 没有响应 - 404 拦截
|
|
19
20
|
if (!response) {
|
|
20
|
-
|
|
21
|
+
const requestId = passHeaders['functions-request-id'] || '';
|
|
22
|
+
res.writeHead(404, {
|
|
23
|
+
'Functions-Request-Id': requestId,
|
|
24
|
+
'eo-pages-inner-scf-status': '404',
|
|
25
|
+
'eo-pages-inner-status-intercept': 'true'
|
|
26
|
+
});
|
|
21
27
|
res.end(JSON.stringify({
|
|
22
28
|
error: "Not Found",
|
|
23
29
|
message: "The requested path does not exist"
|
|
24
30
|
}));
|
|
25
31
|
const endTime = Date.now();
|
|
26
|
-
console.log(`
|
|
32
|
+
console.log(`Pages response status: 404`);
|
|
27
33
|
return;
|
|
28
34
|
}
|
|
29
35
|
|
|
30
36
|
try {
|
|
31
37
|
if (response instanceof Response) {
|
|
38
|
+
const requestId = passHeaders['functions-request-id'] || '';
|
|
39
|
+
const responseStatus = response.status;
|
|
40
|
+
|
|
32
41
|
const headers = Object.fromEntries(response.headers);
|
|
33
42
|
Object.assign(headers, passHeaders);
|
|
43
|
+
|
|
44
|
+
// 添加状态码区分的 headers
|
|
45
|
+
headers['Functions-Request-Id'] = requestId;
|
|
46
|
+
|
|
47
|
+
// 如果 Response 中已经设置了,使用它的值;否则使用 responseStatus
|
|
48
|
+
if (!headers['eo-pages-inner-scf-status']) {
|
|
49
|
+
headers['eo-pages-inner-scf-status'] = String(responseStatus);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// 如果 Response 中已经设置了,使用它的值;否则默认为 false
|
|
53
|
+
if (!headers['eo-pages-inner-status-intercept']) {
|
|
54
|
+
headers['eo-pages-inner-status-intercept'] = 'false';
|
|
55
|
+
}
|
|
56
|
+
|
|
34
57
|
if (response.headers.get('eop-client-geo')) {
|
|
35
58
|
// 删除 eop-client-geo 头部
|
|
36
59
|
response.headers.delete('eop-client-geo');
|
|
@@ -91,22 +114,30 @@ async function handleResponse(res, response, passHeaders = {}) {
|
|
|
91
114
|
}
|
|
92
115
|
} else {
|
|
93
116
|
// 非 Response 对象,直接返回 JSON
|
|
117
|
+
const requestId = passHeaders['functions-request-id'] || '';
|
|
94
118
|
res.writeHead(200, {
|
|
95
|
-
'Content-Type': 'application/json'
|
|
119
|
+
'Content-Type': 'application/json',
|
|
120
|
+
'Functions-Request-Id': requestId,
|
|
121
|
+
'eo-pages-inner-scf-status': '200',
|
|
122
|
+
'eo-pages-inner-status-intercept': 'false'
|
|
96
123
|
});
|
|
97
124
|
res.end(JSON.stringify(response));
|
|
98
125
|
}
|
|
99
126
|
} catch (error) {
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
res.writeHead(
|
|
127
|
+
// 用户函数内部错误 内部502 - 拦截
|
|
128
|
+
const requestId = passHeaders['functions-request-id'] || '';
|
|
129
|
+
res.writeHead(502, {
|
|
130
|
+
'Functions-Request-Id': requestId,
|
|
131
|
+
'eo-pages-inner-scf-status': '502',
|
|
132
|
+
'eo-pages-inner-status-intercept': 'true'
|
|
133
|
+
});
|
|
103
134
|
res.end(JSON.stringify({
|
|
104
135
|
error: "Internal Server Error",
|
|
105
136
|
message: error.message
|
|
106
137
|
}));
|
|
107
138
|
} finally {
|
|
108
139
|
const endTime = Date.now();
|
|
109
|
-
console.log(`
|
|
140
|
+
console.log(`Pages response status: ${response?.status || 'unknown'}`);
|
|
110
141
|
}
|
|
111
142
|
}
|
|
112
143
|
|
|
@@ -169,11 +200,14 @@ const server = createServer(async (req, res) => {
|
|
|
169
200
|
const requestStartTime = Date.now();
|
|
170
201
|
|
|
171
202
|
// 构造 handler 需要的 req 对象(可根据需要扩展)
|
|
203
|
+
// 用 eo-pages-host 替换 host
|
|
204
|
+
const originalHost = req.headers['eo-pages-host'] || req.headers['host'];
|
|
172
205
|
const handlerReq = {
|
|
173
206
|
...req,
|
|
174
207
|
headers: {
|
|
175
208
|
...req.headers,
|
|
176
209
|
'accept-encoding': 'identity',
|
|
210
|
+
'host': originalHost,
|
|
177
211
|
},
|
|
178
212
|
method: req.method,
|
|
179
213
|
url: req.url,
|
|
@@ -191,20 +225,45 @@ const server = createServer(async (req, res) => {
|
|
|
191
225
|
|
|
192
226
|
const response = await eoHandler(handlerReq, {});
|
|
193
227
|
|
|
194
|
-
response.headers.set('functions-request-id', req.headers['x-scf-request-id'] || '');
|
|
228
|
+
// response.headers.set('functions-request-id', req.headers['x-scf-request-id'] || '');
|
|
195
229
|
|
|
196
230
|
const requestEndTime = Date.now();
|
|
197
231
|
const url = new URL(req.url, `http://${req.headers.host}`);
|
|
198
|
-
|
|
199
|
-
|
|
232
|
+
let pathname = url.pathname;
|
|
233
|
+
|
|
234
|
+
if (pathname !== '/' && pathname.endsWith('/')) {
|
|
235
|
+
pathname = pathname.slice(0, -1);
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
let fullPath = '';
|
|
239
|
+
if (req.headers.host === 'localhost:9000') {
|
|
240
|
+
fullPath = pathname;
|
|
241
|
+
} else {
|
|
242
|
+
const host = req.headers['eo-pages-host'];
|
|
243
|
+
const xForwardedProto = req.headers['x-forwarded-proto'];
|
|
244
|
+
|
|
245
|
+
fullPath = (xForwardedProto || 'https') + '://' + host + req.url;
|
|
246
|
+
|
|
247
|
+
if (fullPath.endsWith('?')) {
|
|
248
|
+
fullPath = fullPath.slice(0, -1);
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
console.log(`Pages request path: ${fullPath}`);
|
|
253
|
+
|
|
200
254
|
await handleResponse(res, response, {
|
|
201
255
|
'functions-request-id': req.headers['x-scf-request-id'] || ''
|
|
202
256
|
});
|
|
203
257
|
return;
|
|
204
258
|
} catch (error) {
|
|
205
|
-
console.
|
|
206
|
-
|
|
259
|
+
console.log(`Pages response status: 502`);
|
|
260
|
+
// 用户函数内部错误 内部502 - 拦截
|
|
261
|
+
const requestId = req.headers['x-scf-request-id'] || '';
|
|
262
|
+
res.statusCode = 502;
|
|
207
263
|
res.setHeader('Content-Type', 'text/html; charset=utf-8');
|
|
264
|
+
res.setHeader('Functions-Request-Id', requestId);
|
|
265
|
+
res.setHeader('eo-pages-inner-scf-status', '502');
|
|
266
|
+
res.setHeader('eo-pages-inner-status-intercept', 'true');
|
|
208
267
|
res.end('<html><body><h1>Error</h1><p>'+error.message+'</p></body></html>');
|
|
209
268
|
}
|
|
210
269
|
});
|
|
@@ -11,29 +11,51 @@ import { getTracer } from './.edgeone/dist/run/handlers/tracer.cjs';
|
|
|
11
11
|
async function handleResponse(res, response, passHeaders = {}) {
|
|
12
12
|
const startTime = Date.now();
|
|
13
13
|
|
|
14
|
+
// 没有响应 - 404 拦截
|
|
14
15
|
if (!response) {
|
|
15
|
-
|
|
16
|
+
const requestId = passHeaders['functions-request-id'] || '';
|
|
17
|
+
res.writeHead(404, {
|
|
18
|
+
'Functions-Request-Id': requestId,
|
|
19
|
+
'eo-pages-inner-scf-status': '404',
|
|
20
|
+
'eo-pages-inner-status-intercept': 'true'
|
|
21
|
+
});
|
|
16
22
|
res.end(JSON.stringify({
|
|
17
23
|
error: "Not Found",
|
|
18
24
|
message: "The requested path does not exist"
|
|
19
25
|
}));
|
|
20
26
|
const endTime = Date.now();
|
|
21
|
-
console.log(`
|
|
27
|
+
console.log(`Pages response status: 404`);
|
|
22
28
|
return;
|
|
23
29
|
}
|
|
24
30
|
|
|
25
31
|
try {
|
|
26
32
|
if (response instanceof Response) {
|
|
33
|
+
const requestId = passHeaders['functions-request-id'] || '';
|
|
34
|
+
const responseStatus = response.status;
|
|
35
|
+
|
|
27
36
|
const headers = Object.fromEntries(response.headers);
|
|
28
37
|
Object.assign(headers, passHeaders);
|
|
38
|
+
|
|
39
|
+
// 添加状态码区分的 headers
|
|
40
|
+
headers['Functions-Request-Id'] = requestId;
|
|
41
|
+
|
|
42
|
+
// 如果 Response 中已经设置了,使用它的值;否则使用 responseStatus
|
|
43
|
+
if (!headers['eo-pages-inner-scf-status']) {
|
|
44
|
+
headers['eo-pages-inner-scf-status'] = String(responseStatus);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// 如果 Response 中已经设置了,使用它的值;否则默认为 false
|
|
48
|
+
if (!headers['eo-pages-inner-status-intercept']) {
|
|
49
|
+
headers['eo-pages-inner-status-intercept'] = 'false';
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// 删除内部 header
|
|
29
53
|
if (response.headers.get('eop-client-geo')) {
|
|
30
|
-
// 删除 eop-client-geo 头部
|
|
31
54
|
response.headers.delete('eop-client-geo');
|
|
32
55
|
}
|
|
33
56
|
// 处理 set-cookie 头部
|
|
34
57
|
if (response.headers.has('set-cookie')) {
|
|
35
58
|
const cookieArr = response.headers.getSetCookie();
|
|
36
|
-
|
|
37
59
|
headers['set-cookie'] = cookieArr;
|
|
38
60
|
}
|
|
39
61
|
|
|
@@ -76,8 +98,11 @@ import { getTracer } from './.edgeone/dist/run/handlers/tracer.cjs';
|
|
|
76
98
|
}
|
|
77
99
|
} finally {
|
|
78
100
|
reader.releaseLock();
|
|
79
|
-
|
|
80
|
-
|
|
101
|
+
// scf可能会立即冻结环境上下文,导致后续日志无法输出,通过延时来确保日志输出
|
|
102
|
+
setTimeout(() => {
|
|
103
|
+
res.end();
|
|
104
|
+
}, 1);
|
|
105
|
+
}
|
|
81
106
|
}
|
|
82
107
|
} else {
|
|
83
108
|
// 普通响应
|
|
@@ -87,22 +112,30 @@ import { getTracer } from './.edgeone/dist/run/handlers/tracer.cjs';
|
|
|
87
112
|
}
|
|
88
113
|
} else {
|
|
89
114
|
// 非 Response 对象,直接返回 JSON
|
|
115
|
+
const requestId = passHeaders['functions-request-id'] || '';
|
|
90
116
|
res.writeHead(200, {
|
|
91
|
-
'Content-Type': 'application/json'
|
|
117
|
+
'Content-Type': 'application/json',
|
|
118
|
+
'Functions-Request-Id': requestId,
|
|
119
|
+
'eo-pages-inner-scf-status': '200',
|
|
120
|
+
'eo-pages-inner-status-intercept': 'false'
|
|
92
121
|
});
|
|
93
122
|
res.end(JSON.stringify(response));
|
|
94
123
|
}
|
|
95
124
|
} catch (error) {
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
res.writeHead(
|
|
125
|
+
// 用户函数内部错误 内部502 - 拦截
|
|
126
|
+
const requestId = passHeaders['functions-request-id'] || '';
|
|
127
|
+
res.writeHead(502, {
|
|
128
|
+
'Functions-Request-Id': requestId,
|
|
129
|
+
'eo-pages-inner-scf-status': '502',
|
|
130
|
+
'eo-pages-inner-status-intercept': 'true'
|
|
131
|
+
});
|
|
99
132
|
res.end(JSON.stringify({
|
|
100
133
|
error: "Internal Server Error",
|
|
101
134
|
message: error.message
|
|
102
135
|
}));
|
|
103
|
-
} finally {
|
|
136
|
+
} finally {
|
|
104
137
|
const endTime = Date.now();
|
|
105
|
-
console.log(`
|
|
138
|
+
console.log(`Pages response status: ${response?.status || 'unknown'}`);
|
|
106
139
|
}
|
|
107
140
|
}
|
|
108
141
|
|
|
@@ -132,8 +165,6 @@ export const config = {
|
|
|
132
165
|
};
|
|
133
166
|
|
|
134
167
|
const port = 9000;
|
|
135
|
-
// const port = 9000;
|
|
136
|
-
|
|
137
168
|
|
|
138
169
|
// 实时流转换函数
|
|
139
170
|
function createReadableStreamFromRequest(req) {
|
|
@@ -166,16 +197,21 @@ const server = createServer(async (req, res) => {
|
|
|
166
197
|
const requestStartTime = Date.now();
|
|
167
198
|
|
|
168
199
|
// 构造 handler 需要的 req 对象(可根据需要扩展)
|
|
200
|
+
// 用 eo-pages-host 替换 host
|
|
201
|
+
const originalHost = req.headers['eo-pages-host'] || req.headers['host'];
|
|
169
202
|
const handlerReq = {
|
|
170
203
|
...req,
|
|
171
204
|
headers: {
|
|
172
205
|
...req.headers,
|
|
173
206
|
'accept-encoding': 'identity',
|
|
207
|
+
'host': originalHost,
|
|
174
208
|
},
|
|
175
209
|
method: req.method,
|
|
176
210
|
url: req.url,
|
|
177
211
|
};
|
|
178
212
|
|
|
213
|
+
|
|
214
|
+
|
|
179
215
|
// 读取 body(如果有)
|
|
180
216
|
// let body = [];
|
|
181
217
|
// req.on('data', chunk => body.push(chunk));
|
|
@@ -188,20 +224,48 @@ const server = createServer(async (req, res) => {
|
|
|
188
224
|
|
|
189
225
|
const response = await handler(handlerReq, {});
|
|
190
226
|
|
|
191
|
-
|
|
227
|
+
// 不要在这里设置 functions-request-id,避免重复
|
|
228
|
+
// response.headers.set('functions-request-id', req.headers['x-scf-request-id'] || '');
|
|
229
|
+
// const requestEndTime = Date.now();
|
|
192
230
|
|
|
193
|
-
|
|
231
|
+
// 解析请求路径
|
|
194
232
|
const url = new URL(req.url, `http://${req.headers.host}`);
|
|
195
|
-
|
|
196
|
-
|
|
233
|
+
let pathname = url.pathname;
|
|
234
|
+
|
|
235
|
+
if (pathname !== '/' && pathname.endsWith('/')) {
|
|
236
|
+
pathname = pathname.slice(0, -1);
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
let fullPath = '';
|
|
240
|
+
if (req.headers.host === 'localhost:9000') {
|
|
241
|
+
fullPath = pathname;
|
|
242
|
+
} else {
|
|
243
|
+
const host = req.headers['eo-pages-host'];
|
|
244
|
+
const xForwardedProto = req.headers['x-forwarded-proto'];
|
|
245
|
+
|
|
246
|
+
fullPath = (xForwardedProto || 'https') + '://' + host + req.url;
|
|
247
|
+
|
|
248
|
+
if (fullPath.endsWith('?')) {
|
|
249
|
+
fullPath = fullPath.slice(0, -1);
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
console.log(`Pages request path: ${fullPath}`);
|
|
254
|
+
|
|
255
|
+
// console.log(`Request processing time: ${requestEndTime - requestStartTime}ms`);
|
|
197
256
|
await handleResponse(res, response, {
|
|
198
257
|
'functions-request-id': req.headers['x-scf-request-id'] || ''
|
|
199
258
|
});
|
|
200
259
|
return;
|
|
201
260
|
} catch (error) {
|
|
202
|
-
console.
|
|
203
|
-
|
|
261
|
+
console.log(`Pages response status: 502`);
|
|
262
|
+
// 用户函数内部错误 内部502 - 拦截
|
|
263
|
+
const requestId = req.headers['x-scf-request-id'] || '';
|
|
264
|
+
res.statusCode = 502;
|
|
204
265
|
res.setHeader('Content-Type', 'text/html; charset=utf-8');
|
|
266
|
+
res.setHeader('Functions-Request-Id', requestId);
|
|
267
|
+
res.setHeader('eo-pages-inner-scf-status', '502');
|
|
268
|
+
res.setHeader('eo-pages-inner-status-intercept', 'true');
|
|
205
269
|
res.end('<html><body><h1>Error</h1><p>'+error.message+'</p></body></html>');
|
|
206
270
|
}
|
|
207
271
|
});
|
|
@@ -28,7 +28,7 @@ module.exports = __toCommonJS(tags_handler_exports);
|
|
|
28
28
|
|
|
29
29
|
// package.json
|
|
30
30
|
var name = "@edgeone/opennextjs-pages";
|
|
31
|
-
var version = "0.0.
|
|
31
|
+
var version = "0.0.5";
|
|
32
32
|
|
|
33
33
|
// src/run/handlers/tags-handler.cts
|
|
34
34
|
var import_request_context = require("./request-context.cjs");
|