h3 1.6.1 → 1.6.3
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/README.md +2 -2
- package/dist/index.cjs +56 -22
- package/dist/index.d.ts +5 -2
- package/dist/index.mjs +55 -23
- package/package.json +8 -8
package/README.md
CHANGED
|
@@ -98,7 +98,7 @@ Routes are internally stored in a [Radix Tree](https://en.wikipedia.org/wiki/Rad
|
|
|
98
98
|
|
|
99
99
|
```js
|
|
100
100
|
// Handle can directly return object or Promise<object> for JSON response
|
|
101
|
-
app.use('/api', eventHandler((event) => ({ url: event.node.req.url }))
|
|
101
|
+
app.use('/api', eventHandler((event) => ({ url: event.node.req.url })))
|
|
102
102
|
|
|
103
103
|
// We can have better matching other than quick prefix match
|
|
104
104
|
app.use('/odd', eventHandler(() => 'Is odd!'), { match: url => url.substr(1) % 2 })
|
|
@@ -121,7 +121,7 @@ app.use('/api', eventHandler((event) => proxyRequest('https://example.com', {
|
|
|
121
121
|
cookiePathRewrite: {
|
|
122
122
|
"/": "/api"
|
|
123
123
|
},
|
|
124
|
-
}))
|
|
124
|
+
})))
|
|
125
125
|
|
|
126
126
|
// Legacy middleware with 3rd argument are automatically promisified
|
|
127
127
|
app.use(fromNodeMiddleware((req, res, next) => { req.setHeader('x-foo', 'bar'); next() }))
|
package/dist/index.cjs
CHANGED
|
@@ -108,10 +108,10 @@ class H3Error extends Error {
|
|
|
108
108
|
toJSON() {
|
|
109
109
|
const obj = {
|
|
110
110
|
message: this.message,
|
|
111
|
-
statusCode: this.statusCode
|
|
111
|
+
statusCode: sanitizeStatusCode(this.statusCode, 500)
|
|
112
112
|
};
|
|
113
113
|
if (this.statusMessage) {
|
|
114
|
-
obj.statusMessage = this.statusMessage;
|
|
114
|
+
obj.statusMessage = sanitizeStatusMessage(this.statusMessage);
|
|
115
115
|
}
|
|
116
116
|
if (this.data !== void 0) {
|
|
117
117
|
obj.data = this.data;
|
|
@@ -150,15 +150,24 @@ function createError(input) {
|
|
|
150
150
|
err.data = input.data;
|
|
151
151
|
}
|
|
152
152
|
if (input.statusCode) {
|
|
153
|
-
err.statusCode = input.statusCode;
|
|
153
|
+
err.statusCode = sanitizeStatusCode(input.statusCode, err.statusCode);
|
|
154
154
|
} else if (input.status) {
|
|
155
|
-
err.statusCode = input.status;
|
|
155
|
+
err.statusCode = sanitizeStatusCode(input.status, err.statusCode);
|
|
156
156
|
}
|
|
157
157
|
if (input.statusMessage) {
|
|
158
158
|
err.statusMessage = input.statusMessage;
|
|
159
159
|
} else if (input.statusText) {
|
|
160
160
|
err.statusMessage = input.statusText;
|
|
161
161
|
}
|
|
162
|
+
if (err.statusMessage) {
|
|
163
|
+
const originalMessage = err.statusMessage;
|
|
164
|
+
const sanitizedMessage = sanitizeStatusMessage(err.statusMessage);
|
|
165
|
+
if (sanitizedMessage !== originalMessage) {
|
|
166
|
+
console.warn(
|
|
167
|
+
"[h3] Please prefer using `message` for longer error messages instead of `statusMessage`. In the future `statusMessage` will be sanitized by default."
|
|
168
|
+
);
|
|
169
|
+
}
|
|
170
|
+
}
|
|
162
171
|
if (input.fatal !== void 0) {
|
|
163
172
|
err.fatal = input.fatal;
|
|
164
173
|
}
|
|
@@ -267,13 +276,11 @@ const ParsedBodySymbol = Symbol.for("h3ParsedBody");
|
|
|
267
276
|
const PayloadMethods$1 = ["PATCH", "POST", "PUT", "DELETE"];
|
|
268
277
|
function readRawBody(event, encoding = "utf8") {
|
|
269
278
|
assertMethod(event, PayloadMethods$1);
|
|
270
|
-
|
|
271
|
-
|
|
279
|
+
const _rawBody = event.node.req[RawBodySymbol] || event.node.req.body;
|
|
280
|
+
if (_rawBody) {
|
|
281
|
+
const promise2 = Promise.resolve(_rawBody);
|
|
272
282
|
return encoding ? promise2.then((buff) => buff.toString(encoding)) : promise2;
|
|
273
283
|
}
|
|
274
|
-
if ("body" in event.node.req) {
|
|
275
|
-
return Promise.resolve(event.node.req.body);
|
|
276
|
-
}
|
|
277
284
|
if (!Number.parseInt(event.node.req.headers["content-length"] || "")) {
|
|
278
285
|
return Promise.resolve(void 0);
|
|
279
286
|
}
|
|
@@ -296,7 +303,7 @@ async function readBody(event) {
|
|
|
296
303
|
if (ParsedBodySymbol in event.node.req) {
|
|
297
304
|
return event.node.req[ParsedBodySymbol];
|
|
298
305
|
}
|
|
299
|
-
const body = await readRawBody(event);
|
|
306
|
+
const body = await readRawBody(event, "utf8");
|
|
300
307
|
if (event.node.req.headers["content-type"] === "application/x-www-form-urlencoded") {
|
|
301
308
|
const form = new URLSearchParams(body);
|
|
302
309
|
const parsedForm = /* @__PURE__ */ Object.create(null);
|
|
@@ -446,6 +453,23 @@ function splitCookiesString(cookiesString) {
|
|
|
446
453
|
return cookiesStrings;
|
|
447
454
|
}
|
|
448
455
|
|
|
456
|
+
const DISALLOWED_STATUS_CHARS = /[^\u0009\u0020-\u007E]/g;
|
|
457
|
+
function sanitizeStatusMessage(statusMessage = "") {
|
|
458
|
+
return statusMessage.replace(DISALLOWED_STATUS_CHARS, "");
|
|
459
|
+
}
|
|
460
|
+
function sanitizeStatusCode(statusCode, defaultStatusCode = 200) {
|
|
461
|
+
if (!statusCode) {
|
|
462
|
+
return defaultStatusCode;
|
|
463
|
+
}
|
|
464
|
+
if (typeof statusCode === "string") {
|
|
465
|
+
statusCode = Number.parseInt(statusCode, 10);
|
|
466
|
+
}
|
|
467
|
+
if (statusCode < 100 || statusCode > 999) {
|
|
468
|
+
return defaultStatusCode;
|
|
469
|
+
}
|
|
470
|
+
return statusCode;
|
|
471
|
+
}
|
|
472
|
+
|
|
449
473
|
const PayloadMethods = /* @__PURE__ */ new Set(["PATCH", "POST", "PUT", "DELETE"]);
|
|
450
474
|
const ignoredHeaders = /* @__PURE__ */ new Set([
|
|
451
475
|
"transfer-encoding",
|
|
@@ -483,8 +507,11 @@ async function sendProxy(event, target, opts = {}) {
|
|
|
483
507
|
headers: opts.headers,
|
|
484
508
|
...opts.fetchOptions
|
|
485
509
|
});
|
|
486
|
-
event.node.res.statusCode =
|
|
487
|
-
|
|
510
|
+
event.node.res.statusCode = sanitizeStatusCode(
|
|
511
|
+
response.status,
|
|
512
|
+
event.node.res.statusCode
|
|
513
|
+
);
|
|
514
|
+
event.node.res.statusMessage = sanitizeStatusMessage(response.statusText);
|
|
488
515
|
for (const [key, value] of response.headers.entries()) {
|
|
489
516
|
if (key === "content-encoding") {
|
|
490
517
|
continue;
|
|
@@ -589,7 +616,7 @@ function send(event, data, type) {
|
|
|
589
616
|
});
|
|
590
617
|
}
|
|
591
618
|
function sendNoContent(event, code = 204) {
|
|
592
|
-
event.node.res.statusCode = code;
|
|
619
|
+
event.node.res.statusCode = sanitizeStatusCode(code, 204);
|
|
593
620
|
if (event.node.res.statusCode === 204) {
|
|
594
621
|
event.node.res.removeHeader("content-length");
|
|
595
622
|
}
|
|
@@ -597,14 +624,13 @@ function sendNoContent(event, code = 204) {
|
|
|
597
624
|
}
|
|
598
625
|
function setResponseStatus(event, code, text) {
|
|
599
626
|
if (code) {
|
|
600
|
-
event.node.res.statusCode =
|
|
627
|
+
event.node.res.statusCode = sanitizeStatusCode(
|
|
628
|
+
code,
|
|
629
|
+
event.node.res.statusCode
|
|
630
|
+
);
|
|
601
631
|
}
|
|
602
632
|
if (text) {
|
|
603
|
-
event.node.res.statusMessage = text
|
|
604
|
-
// eslint-disable-next-line no-control-regex
|
|
605
|
-
/[^\u0009\u0020-\u007E]/g,
|
|
606
|
-
""
|
|
607
|
-
);
|
|
633
|
+
event.node.res.statusMessage = sanitizeStatusMessage(text);
|
|
608
634
|
}
|
|
609
635
|
}
|
|
610
636
|
function getResponseStatus(event) {
|
|
@@ -619,7 +645,10 @@ function defaultContentType(event, type) {
|
|
|
619
645
|
}
|
|
620
646
|
}
|
|
621
647
|
function sendRedirect(event, location, code = 302) {
|
|
622
|
-
event.node.res.statusCode =
|
|
648
|
+
event.node.res.statusCode = sanitizeStatusCode(
|
|
649
|
+
code,
|
|
650
|
+
event.node.res.statusCode
|
|
651
|
+
);
|
|
623
652
|
event.node.res.setHeader("location", location);
|
|
624
653
|
const encodedLoc = location.replace(/"/g, "%22");
|
|
625
654
|
const html = `<!DOCTYPE html><html><head><meta http-equiv="refresh" content="0; url=${encodedLoc}"></head></html>`;
|
|
@@ -1070,10 +1099,13 @@ class H3Event {
|
|
|
1070
1099
|
this.res.setHeader(key, value);
|
|
1071
1100
|
}
|
|
1072
1101
|
if (response.status) {
|
|
1073
|
-
this.res.statusCode =
|
|
1102
|
+
this.res.statusCode = sanitizeStatusCode(
|
|
1103
|
+
response.status,
|
|
1104
|
+
this.res.statusCode
|
|
1105
|
+
);
|
|
1074
1106
|
}
|
|
1075
1107
|
if (response.statusText) {
|
|
1076
|
-
this.res.statusMessage = response.statusText;
|
|
1108
|
+
this.res.statusMessage = sanitizeStatusMessage(response.statusText);
|
|
1077
1109
|
}
|
|
1078
1110
|
if (response.redirected) {
|
|
1079
1111
|
this.res.setHeader("location", response.url);
|
|
@@ -1465,6 +1497,8 @@ exports.proxyRequest = proxyRequest;
|
|
|
1465
1497
|
exports.readBody = readBody;
|
|
1466
1498
|
exports.readMultipartFormData = readMultipartFormData;
|
|
1467
1499
|
exports.readRawBody = readRawBody;
|
|
1500
|
+
exports.sanitizeStatusCode = sanitizeStatusCode;
|
|
1501
|
+
exports.sanitizeStatusMessage = sanitizeStatusMessage;
|
|
1468
1502
|
exports.sealSession = sealSession;
|
|
1469
1503
|
exports.send = send;
|
|
1470
1504
|
exports.sendError = sendError;
|
package/dist/index.d.ts
CHANGED
|
@@ -346,7 +346,7 @@ declare function send(event: H3Event, data?: any, type?: string): Promise<void>;
|
|
|
346
346
|
* @param code status code to be send. By default, it is `204 No Content`.
|
|
347
347
|
*/
|
|
348
348
|
declare function sendNoContent(event: H3Event, code?: number): void;
|
|
349
|
-
declare function setResponseStatus(event: H3Event, code
|
|
349
|
+
declare function setResponseStatus(event: H3Event, code?: number, text?: string): void;
|
|
350
350
|
declare function getResponseStatus(event: H3Event): number;
|
|
351
351
|
declare function getResponseStatusText(event: H3Event): string;
|
|
352
352
|
declare function defaultContentType(event: H3Event, type?: string): void;
|
|
@@ -384,6 +384,9 @@ declare function isCorsOriginAllowed(origin: ReturnType<typeof getRequestHeaders
|
|
|
384
384
|
declare function appendCorsPreflightHeaders(event: H3Event, options: H3CorsOptions): void;
|
|
385
385
|
declare function appendCorsHeaders(event: H3Event, options: H3CorsOptions): void;
|
|
386
386
|
|
|
387
|
+
declare function sanitizeStatusMessage(statusMessage?: string): string;
|
|
388
|
+
declare function sanitizeStatusCode(statusCode: string | number, defaultStatusCode?: number): number;
|
|
389
|
+
|
|
387
390
|
type RouterMethod = Lowercase<HTTPMethod>;
|
|
388
391
|
type RouterUse = (path: string, handler: EventHandler, method?: RouterMethod | RouterMethod[]) => Router;
|
|
389
392
|
type AddRouteShortcuts = Record<RouterMethod, RouterUse>;
|
|
@@ -399,4 +402,4 @@ interface CreateRouterOptions {
|
|
|
399
402
|
}
|
|
400
403
|
declare function createRouter(opts?: CreateRouterOptions): Router;
|
|
401
404
|
|
|
402
|
-
export { AddRouteShortcuts, App, AppOptions, AppUse, CacheConditions, CreateRouterOptions, DynamicEventHandler, Encoding, EventHandler, EventHandlerResponse, H3CorsOptions, H3Error, H3Event, H3EventContext, H3Headers, H3Response, HTTPMethod, InputLayer, InputStack, Layer, LazyEventHandler, MIMES, Matcher, MultiPartData, NodeEventContext, NodeListener, NodeMiddleware, NodePromisifiedHandler, ProxyOptions, RequestHeaders, Router, RouterMethod, RouterUse, Session, SessionConfig, SessionData, Stack, appendCorsHeaders, appendCorsPreflightHeaders, appendHeader, appendHeaders, appendResponseHeader, appendResponseHeaders, assertMethod, callNodeListener, clearSession, createApp, createAppEventHandler, createError, createEvent, createRouter, defaultContentType, defineEventHandler, defineLazyEventHandler, defineNodeListener, defineNodeMiddleware, deleteCookie, dynamicEventHandler, eventHandler, fetchWithEvent, fromNodeMiddleware, getCookie, getHeader, getHeaders, getMethod, getProxyRequestHeaders, getQuery, getRequestHeader, getRequestHeaders, getRequestHost, getRequestProtocol, getRequestURL, getResponseHeader, getResponseHeaders, getResponseStatus, getResponseStatusText, getRouterParam, getRouterParams, getSession, handleCacheHeaders, handleCors, isCorsOriginAllowed, isError, isEvent, isEventHandler, isMethod, isPreflightRequest, isStream, lazyEventHandler, parseCookies, promisifyNodeListener, proxyRequest, readBody, readMultipartFormData, readRawBody, sealSession, send, sendError, sendNoContent, sendProxy, sendRedirect, sendStream, setCookie, setHeader, setHeaders, setResponseHeader, setResponseHeaders, setResponseStatus, splitCookiesString, toEventHandler, toNodeListener, unsealSession, updateSession, use, useBase, useSession, writeEarlyHints };
|
|
405
|
+
export { AddRouteShortcuts, App, AppOptions, AppUse, CacheConditions, CreateRouterOptions, DynamicEventHandler, Encoding, EventHandler, EventHandlerResponse, H3CorsOptions, H3Error, H3Event, H3EventContext, H3Headers, H3Response, HTTPMethod, InputLayer, InputStack, Layer, LazyEventHandler, MIMES, Matcher, MultiPartData, NodeEventContext, NodeListener, NodeMiddleware, NodePromisifiedHandler, ProxyOptions, RequestHeaders, Router, RouterMethod, RouterUse, Session, SessionConfig, SessionData, Stack, appendCorsHeaders, appendCorsPreflightHeaders, appendHeader, appendHeaders, appendResponseHeader, appendResponseHeaders, assertMethod, callNodeListener, clearSession, createApp, createAppEventHandler, createError, createEvent, createRouter, defaultContentType, defineEventHandler, defineLazyEventHandler, defineNodeListener, defineNodeMiddleware, deleteCookie, dynamicEventHandler, eventHandler, fetchWithEvent, fromNodeMiddleware, getCookie, getHeader, getHeaders, getMethod, getProxyRequestHeaders, getQuery, getRequestHeader, getRequestHeaders, getRequestHost, getRequestProtocol, getRequestURL, getResponseHeader, getResponseHeaders, getResponseStatus, getResponseStatusText, getRouterParam, getRouterParams, getSession, handleCacheHeaders, handleCors, isCorsOriginAllowed, isError, isEvent, isEventHandler, isMethod, isPreflightRequest, isStream, lazyEventHandler, parseCookies, promisifyNodeListener, proxyRequest, readBody, readMultipartFormData, readRawBody, sanitizeStatusCode, sanitizeStatusMessage, sealSession, send, sendError, sendNoContent, sendProxy, sendRedirect, sendStream, setCookie, setHeader, setHeaders, setResponseHeader, setResponseHeaders, setResponseStatus, splitCookiesString, toEventHandler, toNodeListener, unsealSession, updateSession, use, useBase, useSession, writeEarlyHints };
|
package/dist/index.mjs
CHANGED
|
@@ -106,10 +106,10 @@ class H3Error extends Error {
|
|
|
106
106
|
toJSON() {
|
|
107
107
|
const obj = {
|
|
108
108
|
message: this.message,
|
|
109
|
-
statusCode: this.statusCode
|
|
109
|
+
statusCode: sanitizeStatusCode(this.statusCode, 500)
|
|
110
110
|
};
|
|
111
111
|
if (this.statusMessage) {
|
|
112
|
-
obj.statusMessage = this.statusMessage;
|
|
112
|
+
obj.statusMessage = sanitizeStatusMessage(this.statusMessage);
|
|
113
113
|
}
|
|
114
114
|
if (this.data !== void 0) {
|
|
115
115
|
obj.data = this.data;
|
|
@@ -148,15 +148,24 @@ function createError(input) {
|
|
|
148
148
|
err.data = input.data;
|
|
149
149
|
}
|
|
150
150
|
if (input.statusCode) {
|
|
151
|
-
err.statusCode = input.statusCode;
|
|
151
|
+
err.statusCode = sanitizeStatusCode(input.statusCode, err.statusCode);
|
|
152
152
|
} else if (input.status) {
|
|
153
|
-
err.statusCode = input.status;
|
|
153
|
+
err.statusCode = sanitizeStatusCode(input.status, err.statusCode);
|
|
154
154
|
}
|
|
155
155
|
if (input.statusMessage) {
|
|
156
156
|
err.statusMessage = input.statusMessage;
|
|
157
157
|
} else if (input.statusText) {
|
|
158
158
|
err.statusMessage = input.statusText;
|
|
159
159
|
}
|
|
160
|
+
if (err.statusMessage) {
|
|
161
|
+
const originalMessage = err.statusMessage;
|
|
162
|
+
const sanitizedMessage = sanitizeStatusMessage(err.statusMessage);
|
|
163
|
+
if (sanitizedMessage !== originalMessage) {
|
|
164
|
+
console.warn(
|
|
165
|
+
"[h3] Please prefer using `message` for longer error messages instead of `statusMessage`. In the future `statusMessage` will be sanitized by default."
|
|
166
|
+
);
|
|
167
|
+
}
|
|
168
|
+
}
|
|
160
169
|
if (input.fatal !== void 0) {
|
|
161
170
|
err.fatal = input.fatal;
|
|
162
171
|
}
|
|
@@ -265,13 +274,11 @@ const ParsedBodySymbol = Symbol.for("h3ParsedBody");
|
|
|
265
274
|
const PayloadMethods$1 = ["PATCH", "POST", "PUT", "DELETE"];
|
|
266
275
|
function readRawBody(event, encoding = "utf8") {
|
|
267
276
|
assertMethod(event, PayloadMethods$1);
|
|
268
|
-
|
|
269
|
-
|
|
277
|
+
const _rawBody = event.node.req[RawBodySymbol] || event.node.req.body;
|
|
278
|
+
if (_rawBody) {
|
|
279
|
+
const promise2 = Promise.resolve(_rawBody);
|
|
270
280
|
return encoding ? promise2.then((buff) => buff.toString(encoding)) : promise2;
|
|
271
281
|
}
|
|
272
|
-
if ("body" in event.node.req) {
|
|
273
|
-
return Promise.resolve(event.node.req.body);
|
|
274
|
-
}
|
|
275
282
|
if (!Number.parseInt(event.node.req.headers["content-length"] || "")) {
|
|
276
283
|
return Promise.resolve(void 0);
|
|
277
284
|
}
|
|
@@ -294,7 +301,7 @@ async function readBody(event) {
|
|
|
294
301
|
if (ParsedBodySymbol in event.node.req) {
|
|
295
302
|
return event.node.req[ParsedBodySymbol];
|
|
296
303
|
}
|
|
297
|
-
const body = await readRawBody(event);
|
|
304
|
+
const body = await readRawBody(event, "utf8");
|
|
298
305
|
if (event.node.req.headers["content-type"] === "application/x-www-form-urlencoded") {
|
|
299
306
|
const form = new URLSearchParams(body);
|
|
300
307
|
const parsedForm = /* @__PURE__ */ Object.create(null);
|
|
@@ -444,6 +451,23 @@ function splitCookiesString(cookiesString) {
|
|
|
444
451
|
return cookiesStrings;
|
|
445
452
|
}
|
|
446
453
|
|
|
454
|
+
const DISALLOWED_STATUS_CHARS = /[^\u0009\u0020-\u007E]/g;
|
|
455
|
+
function sanitizeStatusMessage(statusMessage = "") {
|
|
456
|
+
return statusMessage.replace(DISALLOWED_STATUS_CHARS, "");
|
|
457
|
+
}
|
|
458
|
+
function sanitizeStatusCode(statusCode, defaultStatusCode = 200) {
|
|
459
|
+
if (!statusCode) {
|
|
460
|
+
return defaultStatusCode;
|
|
461
|
+
}
|
|
462
|
+
if (typeof statusCode === "string") {
|
|
463
|
+
statusCode = Number.parseInt(statusCode, 10);
|
|
464
|
+
}
|
|
465
|
+
if (statusCode < 100 || statusCode > 999) {
|
|
466
|
+
return defaultStatusCode;
|
|
467
|
+
}
|
|
468
|
+
return statusCode;
|
|
469
|
+
}
|
|
470
|
+
|
|
447
471
|
const PayloadMethods = /* @__PURE__ */ new Set(["PATCH", "POST", "PUT", "DELETE"]);
|
|
448
472
|
const ignoredHeaders = /* @__PURE__ */ new Set([
|
|
449
473
|
"transfer-encoding",
|
|
@@ -481,8 +505,11 @@ async function sendProxy(event, target, opts = {}) {
|
|
|
481
505
|
headers: opts.headers,
|
|
482
506
|
...opts.fetchOptions
|
|
483
507
|
});
|
|
484
|
-
event.node.res.statusCode =
|
|
485
|
-
|
|
508
|
+
event.node.res.statusCode = sanitizeStatusCode(
|
|
509
|
+
response.status,
|
|
510
|
+
event.node.res.statusCode
|
|
511
|
+
);
|
|
512
|
+
event.node.res.statusMessage = sanitizeStatusMessage(response.statusText);
|
|
486
513
|
for (const [key, value] of response.headers.entries()) {
|
|
487
514
|
if (key === "content-encoding") {
|
|
488
515
|
continue;
|
|
@@ -587,7 +614,7 @@ function send(event, data, type) {
|
|
|
587
614
|
});
|
|
588
615
|
}
|
|
589
616
|
function sendNoContent(event, code = 204) {
|
|
590
|
-
event.node.res.statusCode = code;
|
|
617
|
+
event.node.res.statusCode = sanitizeStatusCode(code, 204);
|
|
591
618
|
if (event.node.res.statusCode === 204) {
|
|
592
619
|
event.node.res.removeHeader("content-length");
|
|
593
620
|
}
|
|
@@ -595,14 +622,13 @@ function sendNoContent(event, code = 204) {
|
|
|
595
622
|
}
|
|
596
623
|
function setResponseStatus(event, code, text) {
|
|
597
624
|
if (code) {
|
|
598
|
-
event.node.res.statusCode =
|
|
625
|
+
event.node.res.statusCode = sanitizeStatusCode(
|
|
626
|
+
code,
|
|
627
|
+
event.node.res.statusCode
|
|
628
|
+
);
|
|
599
629
|
}
|
|
600
630
|
if (text) {
|
|
601
|
-
event.node.res.statusMessage = text
|
|
602
|
-
// eslint-disable-next-line no-control-regex
|
|
603
|
-
/[^\u0009\u0020-\u007E]/g,
|
|
604
|
-
""
|
|
605
|
-
);
|
|
631
|
+
event.node.res.statusMessage = sanitizeStatusMessage(text);
|
|
606
632
|
}
|
|
607
633
|
}
|
|
608
634
|
function getResponseStatus(event) {
|
|
@@ -617,7 +643,10 @@ function defaultContentType(event, type) {
|
|
|
617
643
|
}
|
|
618
644
|
}
|
|
619
645
|
function sendRedirect(event, location, code = 302) {
|
|
620
|
-
event.node.res.statusCode =
|
|
646
|
+
event.node.res.statusCode = sanitizeStatusCode(
|
|
647
|
+
code,
|
|
648
|
+
event.node.res.statusCode
|
|
649
|
+
);
|
|
621
650
|
event.node.res.setHeader("location", location);
|
|
622
651
|
const encodedLoc = location.replace(/"/g, "%22");
|
|
623
652
|
const html = `<!DOCTYPE html><html><head><meta http-equiv="refresh" content="0; url=${encodedLoc}"></head></html>`;
|
|
@@ -1068,10 +1097,13 @@ class H3Event {
|
|
|
1068
1097
|
this.res.setHeader(key, value);
|
|
1069
1098
|
}
|
|
1070
1099
|
if (response.status) {
|
|
1071
|
-
this.res.statusCode =
|
|
1100
|
+
this.res.statusCode = sanitizeStatusCode(
|
|
1101
|
+
response.status,
|
|
1102
|
+
this.res.statusCode
|
|
1103
|
+
);
|
|
1072
1104
|
}
|
|
1073
1105
|
if (response.statusText) {
|
|
1074
|
-
this.res.statusMessage = response.statusText;
|
|
1106
|
+
this.res.statusMessage = sanitizeStatusMessage(response.statusText);
|
|
1075
1107
|
}
|
|
1076
1108
|
if (response.redirected) {
|
|
1077
1109
|
this.res.setHeader("location", response.url);
|
|
@@ -1400,4 +1432,4 @@ function createRouter(opts = {}) {
|
|
|
1400
1432
|
return router;
|
|
1401
1433
|
}
|
|
1402
1434
|
|
|
1403
|
-
export { H3Error, H3Event, H3Headers, H3Response, MIMES, appendCorsHeaders, appendCorsPreflightHeaders, appendHeader, appendHeaders, appendResponseHeader, appendResponseHeaders, assertMethod, callNodeListener, clearSession, createApp, createAppEventHandler, createError, createEvent, createRouter, defaultContentType, defineEventHandler, defineLazyEventHandler, defineNodeListener, defineNodeMiddleware, deleteCookie, dynamicEventHandler, eventHandler, fetchWithEvent, fromNodeMiddleware, getCookie, getHeader, getHeaders, getMethod, getProxyRequestHeaders, getQuery, getRequestHeader, getRequestHeaders, getRequestHost, getRequestProtocol, getRequestURL, getResponseHeader, getResponseHeaders, getResponseStatus, getResponseStatusText, getRouterParam, getRouterParams, getSession, handleCacheHeaders, handleCors, isCorsOriginAllowed, isError, isEvent, isEventHandler, isMethod, isPreflightRequest, isStream, lazyEventHandler, parseCookies, promisifyNodeListener, proxyRequest, readBody, readMultipartFormData, readRawBody, sealSession, send, sendError, sendNoContent, sendProxy, sendRedirect, sendStream, setCookie, setHeader, setHeaders, setResponseHeader, setResponseHeaders, setResponseStatus, splitCookiesString, toEventHandler, toNodeListener, unsealSession, updateSession, use, useBase, useSession, writeEarlyHints };
|
|
1435
|
+
export { H3Error, H3Event, H3Headers, H3Response, MIMES, appendCorsHeaders, appendCorsPreflightHeaders, appendHeader, appendHeaders, appendResponseHeader, appendResponseHeaders, assertMethod, callNodeListener, clearSession, createApp, createAppEventHandler, createError, createEvent, createRouter, defaultContentType, defineEventHandler, defineLazyEventHandler, defineNodeListener, defineNodeMiddleware, deleteCookie, dynamicEventHandler, eventHandler, fetchWithEvent, fromNodeMiddleware, getCookie, getHeader, getHeaders, getMethod, getProxyRequestHeaders, getQuery, getRequestHeader, getRequestHeaders, getRequestHost, getRequestProtocol, getRequestURL, getResponseHeader, getResponseHeaders, getResponseStatus, getResponseStatusText, getRouterParam, getRouterParams, getSession, handleCacheHeaders, handleCors, isCorsOriginAllowed, isError, isEvent, isEventHandler, isMethod, isPreflightRequest, isStream, lazyEventHandler, parseCookies, promisifyNodeListener, proxyRequest, readBody, readMultipartFormData, readRawBody, sanitizeStatusCode, sanitizeStatusMessage, sealSession, send, sendError, sendNoContent, sendProxy, sendRedirect, sendStream, setCookie, setHeader, setHeaders, setResponseHeader, setResponseHeaders, setResponseStatus, splitCookiesString, toEventHandler, toNodeListener, unsealSession, updateSession, use, useBase, useSession, writeEarlyHints };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "h3",
|
|
3
|
-
"version": "1.6.
|
|
3
|
+
"version": "1.6.3",
|
|
4
4
|
"description": "Tiny JavaScript Server",
|
|
5
5
|
"repository": "unjs/h3",
|
|
6
6
|
"license": "MIT",
|
|
@@ -24,16 +24,16 @@
|
|
|
24
24
|
"defu": "^6.1.2",
|
|
25
25
|
"destr": "^1.2.2",
|
|
26
26
|
"iron-webcrypto": "^0.6.0",
|
|
27
|
-
"radix3": "^1.0.
|
|
27
|
+
"radix3": "^1.0.1",
|
|
28
28
|
"ufo": "^1.1.1",
|
|
29
29
|
"uncrypto": "^0.1.2"
|
|
30
30
|
},
|
|
31
31
|
"devDependencies": {
|
|
32
32
|
"0x": "^5.5.0",
|
|
33
33
|
"@types/express": "^4.17.17",
|
|
34
|
-
"@types/node": "^18.15.
|
|
34
|
+
"@types/node": "^18.15.10",
|
|
35
35
|
"@types/supertest": "^2.0.12",
|
|
36
|
-
"@vitest/coverage-c8": "^0.29.
|
|
36
|
+
"@vitest/coverage-c8": "^0.29.7",
|
|
37
37
|
"autocannon": "^7.10.0",
|
|
38
38
|
"changelogen": "^0.5.1",
|
|
39
39
|
"connect": "^3.7.0",
|
|
@@ -44,13 +44,13 @@
|
|
|
44
44
|
"jiti": "^1.18.2",
|
|
45
45
|
"listhen": "^1.0.4",
|
|
46
46
|
"node-fetch-native": "^1.0.2",
|
|
47
|
-
"prettier": "^2.8.
|
|
47
|
+
"prettier": "^2.8.7",
|
|
48
48
|
"supertest": "^6.3.3",
|
|
49
|
-
"typescript": "^
|
|
49
|
+
"typescript": "^5.0.2",
|
|
50
50
|
"unbuild": "^1.1.2",
|
|
51
|
-
"vitest": "^0.29.
|
|
51
|
+
"vitest": "^0.29.7"
|
|
52
52
|
},
|
|
53
|
-
"packageManager": "pnpm@
|
|
53
|
+
"packageManager": "pnpm@8.0.0",
|
|
54
54
|
"scripts": {
|
|
55
55
|
"build": "unbuild",
|
|
56
56
|
"dev": "vitest",
|