hono 4.12.20 → 4.12.22

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.
@@ -22,6 +22,16 @@ var expandIPv6 = (ipV6) => {
22
22
  };
23
23
  var IPV4_OCTET_PART = "(?:25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])";
24
24
  var IPV4_REGEX = new RegExp(`^(?:${IPV4_OCTET_PART}\\.){3}${IPV4_OCTET_PART}$`);
25
+ var INVALID_IP_ADDRESS_ERROR_CODE = "ERR_INVALID_IP_ADDRESS";
26
+ var CHAR_CODE_0 = 48;
27
+ var CHAR_CODE_9 = 57;
28
+ var CHAR_CODE_A = 65;
29
+ var CHAR_CODE_F = 70;
30
+ var CHAR_CODE_a = 97;
31
+ var CHAR_CODE_f = 102;
32
+ var CHAR_CODE_DOT = 46;
33
+ var CHAR_CODE_COLON = 58;
34
+ var CHAR_CODE_PERCENT = 37;
25
35
  var distinctRemoteAddr = (remoteAddr) => {
26
36
  if (IPV4_REGEX.test(remoteAddr)) {
27
37
  return "IPv4";
@@ -30,21 +40,187 @@ var distinctRemoteAddr = (remoteAddr) => {
30
40
  return "IPv6";
31
41
  }
32
42
  };
33
- var convertIPv4ToBinary = (ipv4) => {
34
- const parts = ipv4.split(".");
43
+ var createInvalidIPAddressError = (message) => {
44
+ const error = new TypeError(message);
45
+ error.code = INVALID_IP_ADDRESS_ERROR_CODE;
46
+ return error;
47
+ };
48
+ var throwInvalidIPv4Address = (ipv4) => {
49
+ throw createInvalidIPAddressError(`Invalid IPv4 address: ${ipv4}`);
50
+ };
51
+ var throwInvalidIPv6Address = (ipv6) => {
52
+ throw createInvalidIPAddressError(`Invalid IPv6 address: ${ipv6}`);
53
+ };
54
+ var parseIPv4ToBinary = (ipv4, start, end, onInvalid) => {
35
55
  let result = 0n;
36
- for (let i = 0; i < 4; i++) {
37
- result <<= 8n;
38
- result += BigInt(parts[i]);
56
+ let octets = 0;
57
+ let octet = 0;
58
+ let digits = 0;
59
+ let firstDigit = 0;
60
+ for (let i = start; i <= end; i++) {
61
+ const code = i < end ? ipv4.charCodeAt(i) : CHAR_CODE_DOT;
62
+ if (code >= CHAR_CODE_0 && code <= CHAR_CODE_9) {
63
+ if (digits === 0) {
64
+ firstDigit = code;
65
+ } else if (firstDigit === CHAR_CODE_0) {
66
+ onInvalid();
67
+ }
68
+ octet = octet * 10 + code - CHAR_CODE_0;
69
+ if (octet > 255) {
70
+ onInvalid();
71
+ }
72
+ digits++;
73
+ continue;
74
+ }
75
+ if (code !== CHAR_CODE_DOT || digits === 0 || octets === 4) {
76
+ onInvalid();
77
+ }
78
+ result = (result << 8n) + BigInt(octet);
79
+ octets++;
80
+ octet = 0;
81
+ digits = 0;
82
+ }
83
+ if (octets !== 4) {
84
+ onInvalid();
39
85
  }
40
86
  return result;
41
87
  };
88
+ var parseIPv6HexCode = (code) => {
89
+ if (code >= CHAR_CODE_0 && code <= CHAR_CODE_9) {
90
+ return code - CHAR_CODE_0;
91
+ }
92
+ if (code >= CHAR_CODE_A && code <= CHAR_CODE_F) {
93
+ return code - CHAR_CODE_A + 10;
94
+ }
95
+ if (code >= CHAR_CODE_a && code <= CHAR_CODE_f) {
96
+ return code - CHAR_CODE_a + 10;
97
+ }
98
+ return -1;
99
+ };
100
+ var isIPv6LinkLocal = (ipv6binary) => ipv6binary >> 118n === 0x3fan;
101
+ var convertIPv4ToBinary = (ipv4) => {
102
+ return parseIPv4ToBinary(ipv4, 0, ipv4.length, () => throwInvalidIPv4Address(ipv4));
103
+ };
42
104
  var convertIPv6ToBinary = (ipv6) => {
43
- const sections = expandIPv6(ipv6).split(":");
105
+ const length = ipv6.length;
106
+ const sections = [];
107
+ let hasZoneId = false;
108
+ let compressAt = -1;
109
+ let index = 0;
110
+ if (length === 0) {
111
+ throwInvalidIPv6Address(ipv6);
112
+ }
113
+ while (index < length) {
114
+ if (sections.length > 8) {
115
+ throwInvalidIPv6Address(ipv6);
116
+ }
117
+ let code = ipv6.charCodeAt(index);
118
+ if (code === CHAR_CODE_PERCENT) {
119
+ if (index + 1 === length) {
120
+ throwInvalidIPv6Address(ipv6);
121
+ }
122
+ hasZoneId = true;
123
+ break;
124
+ }
125
+ if (code === CHAR_CODE_COLON) {
126
+ if (index + 1 < length && ipv6.charCodeAt(index + 1) === CHAR_CODE_COLON) {
127
+ if (compressAt !== -1) {
128
+ throwInvalidIPv6Address(ipv6);
129
+ }
130
+ compressAt = sections.length;
131
+ index += 2;
132
+ continue;
133
+ }
134
+ throwInvalidIPv6Address(ipv6);
135
+ }
136
+ let value = 0;
137
+ let digits = 0;
138
+ const sectionStart = index;
139
+ while (index < length) {
140
+ code = ipv6.charCodeAt(index);
141
+ const hex = parseIPv6HexCode(code);
142
+ if (hex === -1) {
143
+ break;
144
+ }
145
+ if (digits === 4) {
146
+ throwInvalidIPv6Address(ipv6);
147
+ }
148
+ value = value << 4 | hex;
149
+ digits++;
150
+ index++;
151
+ }
152
+ if (index < length && ipv6.charCodeAt(index) === CHAR_CODE_DOT) {
153
+ let ipv4End = length;
154
+ for (let i = index; i < length; i++) {
155
+ if (ipv6.charCodeAt(i) === CHAR_CODE_PERCENT) {
156
+ if (i + 1 === length) {
157
+ throwInvalidIPv6Address(ipv6);
158
+ }
159
+ hasZoneId = true;
160
+ ipv4End = i;
161
+ break;
162
+ }
163
+ }
164
+ const ipv4 = parseIPv4ToBinary(
165
+ ipv6,
166
+ sectionStart,
167
+ ipv4End,
168
+ () => throwInvalidIPv6Address(ipv6)
169
+ );
170
+ sections.push(Number(ipv4 >> 16n & 0xffffn), Number(ipv4 & 0xffffn));
171
+ index = length;
172
+ break;
173
+ }
174
+ if (digits === 0) {
175
+ throwInvalidIPv6Address(ipv6);
176
+ }
177
+ sections.push(value);
178
+ if (index === length) {
179
+ break;
180
+ }
181
+ code = ipv6.charCodeAt(index);
182
+ if (code === CHAR_CODE_PERCENT) {
183
+ if (index + 1 === length) {
184
+ throwInvalidIPv6Address(ipv6);
185
+ }
186
+ hasZoneId = true;
187
+ break;
188
+ }
189
+ if (code !== CHAR_CODE_COLON) {
190
+ throwInvalidIPv6Address(ipv6);
191
+ }
192
+ if (index + 1 < length && ipv6.charCodeAt(index + 1) === CHAR_CODE_COLON) {
193
+ if (compressAt !== -1) {
194
+ throwInvalidIPv6Address(ipv6);
195
+ }
196
+ compressAt = sections.length;
197
+ index += 2;
198
+ continue;
199
+ }
200
+ index++;
201
+ if (index === length) {
202
+ throwInvalidIPv6Address(ipv6);
203
+ }
204
+ }
205
+ if (compressAt === -1 ? sections.length !== 8 : sections.length >= 8) {
206
+ throwInvalidIPv6Address(ipv6);
207
+ }
44
208
  let result = 0n;
45
- for (let i = 0; i < 8; i++) {
209
+ const zeros = compressAt === -1 ? 0 : 8 - sections.length;
210
+ const firstSectionEnd = compressAt === -1 ? sections.length : compressAt;
211
+ for (let i = 0; i < firstSectionEnd; i++) {
46
212
  result <<= 16n;
47
- result += BigInt(parseInt(sections[i], 16));
213
+ result += BigInt(sections[i]);
214
+ }
215
+ for (let i = 0; i < zeros; i++) {
216
+ result <<= 16n;
217
+ }
218
+ for (let i = firstSectionEnd; i < sections.length; i++) {
219
+ result <<= 16n;
220
+ result += BigInt(sections[i]);
221
+ }
222
+ if (hasZoneId && !isIPv6LinkLocal(result)) {
223
+ throwInvalidIPv6Address(ipv6);
48
224
  }
49
225
  return result;
50
226
  };
@@ -95,6 +271,7 @@ var convertIPv6BinaryToString = (ipV6) => {
95
271
  return sections.join(":").replace(/:{2,}/g, "::");
96
272
  };
97
273
  export {
274
+ INVALID_IP_ADDRESS_ERROR_CODE,
98
275
  convertIPv4BinaryToString,
99
276
  convertIPv4MappedIPv6ToIPv4,
100
277
  convertIPv4ToBinary,
@@ -5,15 +5,13 @@ var getMimeType = (filename, mimes = baseMimes) => {
5
5
  if (!match) {
6
6
  return;
7
7
  }
8
- let mimeType = mimes[match[1].toLowerCase()];
9
- if (mimeType && mimeType.startsWith("text")) {
10
- mimeType += "; charset=utf-8";
11
- }
12
- return mimeType;
8
+ return mimes[match[1].toLowerCase()];
13
9
  };
14
10
  var getExtension = (mimeType) => {
11
+ const baseType = mimeType.split(";", 1)[0].trim();
15
12
  for (const ext in baseMimes) {
16
- if (baseMimes[ext] === mimeType) {
13
+ const stored = baseMimes[ext];
14
+ if (stored === mimeType || stored.split(";", 1)[0].trim() === baseType) {
17
15
  return ext;
18
16
  }
19
17
  }
@@ -25,25 +23,25 @@ var _baseMimes = {
25
23
  av1: "video/av1",
26
24
  bin: "application/octet-stream",
27
25
  bmp: "image/bmp",
28
- css: "text/css",
29
- csv: "text/csv",
26
+ css: "text/css; charset=utf-8",
27
+ csv: "text/csv; charset=utf-8",
30
28
  eot: "application/vnd.ms-fontobject",
31
29
  epub: "application/epub+zip",
32
30
  gif: "image/gif",
33
31
  gz: "application/gzip",
34
- htm: "text/html",
35
- html: "text/html",
32
+ htm: "text/html; charset=utf-8",
33
+ html: "text/html; charset=utf-8",
36
34
  ico: "image/x-icon",
37
- ics: "text/calendar",
35
+ ics: "text/calendar; charset=utf-8",
38
36
  jpeg: "image/jpeg",
39
37
  jpg: "image/jpeg",
40
- js: "text/javascript",
38
+ js: "text/javascript; charset=utf-8",
41
39
  json: "application/json",
42
40
  jsonld: "application/ld+json",
43
41
  map: "application/json",
44
42
  mid: "audio/x-midi",
45
43
  midi: "audio/x-midi",
46
- mjs: "text/javascript",
44
+ mjs: "text/javascript; charset=utf-8",
47
45
  mp3: "audio/mpeg",
48
46
  mp4: "video/mp4",
49
47
  mpeg: "video/mpeg",
@@ -55,12 +53,12 @@ var _baseMimes = {
55
53
  pdf: "application/pdf",
56
54
  png: "image/png",
57
55
  rtf: "application/rtf",
58
- svg: "image/svg+xml",
56
+ svg: "image/svg+xml; charset=utf-8",
59
57
  tif: "image/tiff",
60
58
  tiff: "image/tiff",
61
59
  ts: "video/mp2t",
62
60
  ttf: "font/ttf",
63
- txt: "text/plain",
61
+ txt: "text/plain; charset=utf-8",
64
62
  wasm: "application/wasm",
65
63
  webm: "video/webm",
66
64
  weba: "audio/webm",
@@ -68,8 +66,8 @@ var _baseMimes = {
68
66
  webp: "image/webp",
69
67
  woff: "font/woff",
70
68
  woff2: "font/woff2",
71
- xhtml: "application/xhtml+xml",
72
- xml: "application/xml",
69
+ xhtml: "application/xhtml+xml; charset=utf-8",
70
+ xml: "application/xml; charset=utf-8",
73
71
  zip: "application/zip",
74
72
  "3gp": "video/3gpp",
75
73
  "3g2": "video/3gpp2",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hono",
3
- "version": "4.12.20",
3
+ "version": "4.12.22",
4
4
  "description": "Web framework built on Web Standards",
5
5
  "main": "dist/cjs/index.js",
6
6
  "type": "module",
@@ -663,7 +663,7 @@
663
663
  "@types/node": "^24.3.0",
664
664
  "@types/ws": "^8.18.1",
665
665
  "@typescript/native-preview": "7.0.0-dev.20260210.1",
666
- "@vitest/coverage-v8": "^3.2.4",
666
+ "@vitest/coverage-v8": "^4.1.7",
667
667
  "arg": "^5.0.2",
668
668
  "bun-types": "^1.2.20",
669
669
  "editorconfig-checker": "6.1.1",
@@ -680,7 +680,7 @@
680
680
  "typescript": "^5.9.2",
681
681
  "undici": "^6.21.3",
682
682
  "vite-plugin-fastly-js-compute": "^0.4.2",
683
- "vitest": "^3.2.4",
683
+ "vitest": "^4.1.7",
684
684
  "wrangler": "4.12.0",
685
685
  "ws": "^8.18.0",
686
686
  "zod": "^3.23.8"