Relevant source files
The following files were used as context for generating this wiki page:
- src/utils/cookie.ts
- src/jsx/components.ts
- src/middleware/secure-headers/secure-headers.ts
- src/helper/streaming/sse.ts
- src/client/utils.ts
- src/utils/url.ts
- src/jsx/streaming.ts
- src/utils/html.ts
- src/helper/cookie/index.ts
- src/helper/html/index.ts
- src/helper/proxy/index.ts
- src/adapter/aws-lambda/handler.ts
- src/context.ts
- src/helper/ssg/ssg.ts
- src/middleware/language/language.ts
- src/helper/streaming/text.ts
- src/types.ts
- src/utils/concurrent.ts
- src/client/fetch-result-please.ts
- src/utils/jwt/utf8.ts
- src/helper/streaming/stream.ts
- src/utils/headers.ts
- src/helper/css/common.ts
- src/utils/ipaddr.ts
- src/helper/streaming/utils.ts
- src/utils/stream.ts
- src/utils/http-status.ts
- src/utils/crypto.ts
- src/utils/encode.ts
- src/middleware/etag/digest.ts
Overview
The Hono framework provides a comprehensive set of low-level utilities and encoding helpers to support core operations, HTTP protocol management, templating, and request handling across diverse JavaScript runtimes. These modular helpers provide efficient mechanisms for cookie parsing, cryptographic signature verification, URI decoding, HTML escaping, Base64 and Base64Url data transformations, asynchronous task pooling, and status-code typing.
Sources: src/utils/cookie.ts:1-165, src/utils/url.ts:1-204, src/utils/html.ts:1-182, src/utils/encode.ts:1-34, src/utils/concurrent.ts:1-55, src/utils/http-status.ts:1-72
Cookie parsing and signature validation
Cookie Parsing and Helper Call Chains
Cookie parsing and retrieval are orchestrated through helper functions exposed in src/helper/cookie/index.ts backed by core algorithms in src/utils/cookie.ts. When a cookie is deleted or retrieved, request headers are inspected and processed through a deterministic execution flow.
deleteCookieinitiates removal by callinggetCookiewith the target context, cookie name, and optional prefix constraints. Sources: src/helper/cookie/index.ts:141-144getCookieextracts the rawCookieheader fromc.req.raw.headers, resolves cookie prefixes (__Secure-or__Host-), and invokesparse. Sources: src/helper/cookie/index.ts:27-41parsesplits the raw cookie string by semicolons and iterates over individual pairs, usingtrimCookieWhitespaceto strip leading and trailing spaces or tab characters from both names and values. Sources: src/utils/cookie.ts:79-115tryDecodehandles percent-encoded cookie values by attempting standard decoding and gracefully falling back on malformed or partially encoded byte sequences. Sources: src/utils/cookie.ts:128-130, src/utils/url.ts:80-93
Sources: src/helper/cookie/index.ts:27-144, src/utils/cookie.ts:79-130, src/utils/url.ts:80-93
Cryptographic Signature Validation
Signed cookies are parsed and verified using Web Crypto HMAC-SHA-256 operations via parseSigned. The implementation imports secrets into CryptoKey instances and validates base64-encoded signatures attached to cookie values.
const algorithm = { name: 'HMAC', hash: 'SHA-256' }
const getCryptoKey = async (secret: string | BufferSource): Promise<CryptoKey> => {
const secretBuf = typeof secret === 'string' ? new TextEncoder().encode(secret) : secret
return await crypto.subtle.importKey('raw', secretBuf, algorithm, false, ['sign', 'verify'])
}Sources: src/utils/cookie.ts:37-42
Note
parseSigned verifies that extracted signatures are exactly 44 characters long and terminate with an equals sign before invoking crypto.subtle.verify. If validation fails or throws an exception, the function assigns false to that cookie key in the returned record.
Sources: src/utils/cookie.ts:140-165
Cookie Validation Patterns
Cookie names and values are validated against strict regular expressions adhering to RFC 6265 specifications, with allowances for common real-world characters.
| Regex Constant | Target | Value / Pattern | Description |
|---|---|---|---|
validCookieNameRegEx | Cookie Name | /^[\w!#$%&'*.^|~+-]+$/` | Matches all alphanumeric characters and allowed punctuation symbols. |
validCookieValueRegEx | Cookie Value | /^[ !#-:<-[\]-~]*$/ | Matches ASCII characters 32 to 126, excluding double quotes, semicolons, and backslashes. |
Sources: src/utils/cookie.ts:70-77
Warning
While the cookie specification prohibits spaces and commas in values, validCookieValueRegEx explicitly permits them because they occur frequently in real-world deployments.
Sources: src/utils/cookie.ts:72-76
Cookie serialization and attribute formatting
Execution Walkthrough and Sequence
Cookie serialization converts key-value pairs and attribute options into well-formed Set-Cookie header strings. The serialization helpers enforce security constraints based on cookie prefixes and append options like domain, path, max-age, and same-site policies.
The generation and dispatch of cookie headers follow a strict sequence across helper and utility modules.
deleteCookieinitiates removal by capturing the current cookie value viagetCookieand delegating tosetCookiewith an empty string and amaxAgeof zero. Sources: src/helper/cookie/index.ts:141-144setCookiepasses the cookie name, value, and options togenerateCookieto format the complete attribute string. Sources: src/helper/cookie/index.ts:99-102generateCookieevaluates prefix options (secureorhost), enforces strict path and domain requirements, and invokesserialize. Sources: src/helper/cookie/index.ts:78-97
Sources: src/helper/cookie/index.ts:78-144
Caution
Cookie names prefixed with __Secure- require the secure attribute to be enabled, while those prefixed with __Host- require secure: true, a path of /, and an undefined domain attribute.
Sources: src/helper/cookie/index.ts:79-82, src/utils/cookie.ts:174-179
URL path manipulation and decoding
Path Normalization and Segment Splitting
URL paths are split into array segments and merged through dedicated utilities that handle trailing slashes, root prefixes, and subpath concatenation. splitPath splits a path string by forward slashes and shifts off any leading empty element created by a leading slash. mergePath accepts multiple path arguments, recursively resolves nested inputs, normalizes leading forward slashes on subpaths, and preserves trailing slashes only when explicitly designated at the end of the base or subpath.
Sources: src/utils/url.ts:8-14, src/utils/url.ts:158-169
export const splitPath = (path: string): string[] => {
const paths = path.split('/')
if (paths[0] === '') {
paths.shift()
}
return paths
}Sources: src/utils/url.ts:8-14
Note
getPathNoStrict wraps getPath to enforce lenient routing rules; if strict routing is disabled, it strips any trailing slash from paths longer than one character so that paths like /hello/hey/ and /hello/hey resolve identically.
Sources: src/utils/url.ts:141-146
Group Mark Replacement and Parameter Extraction
Routing paths containing parameter blocks or braces are normalized via group extraction and replacement routines. extractGroupsFromPath scans path strings for bracketed expressions, extracts them into key-value group pairs, and substitutes temporary placeholder marks formatted as @${index}. splitRoutingPath combines this extraction step with segment splitting and replaceGroupMarks to reconstruct the original segments with their group placeholders intact.
Sources: src/utils/url.ts:16-21, src/utils/url.ts:23-33, src/utils/url.ts:35-48
| Function Name | Input Signature | Description |
|---|---|---|
splitPath | path: string | Splits path by / and removes leading empty segments. |
extractGroupsFromPath | path: string | Replaces {...} groups with @index markers and collects pairs. |
replaceGroupMarks | paths: string[], groups: [string, string][] | Re-inserts original group values into path segment arrays. |
checkOptionalParameter | path: string | Evaluates trailing question marks on path parameters and returns generated base route variants or null. |
Sources: src/utils/url.ts:8-14, src/utils/url.ts:23-48, src/utils/url.ts:171-203
Warning
checkOptionalParameter returns null if the path does not end with a question mark character code (63) or lacks a colon parameter marker.
Sources: src/utils/url.ts:178-180
Fault-Tolerant URI Decoding
URI decoding utilities wrap native decoding functions with recovery logic to handle malformed percent-encoded strings and invalid UTF-8 sequences without throwing uncaught exceptions. tryDecode attempts to execute a provided decoder function, falling back to a regex-based matcher that isolates percent-encoded byte sequences and decodes valid sub-segments individually. tryDecodeURI applies this fault-tolerant behavior directly to decodeURI.
Sources: src/utils/url.ts:80-104
export const tryDecode = (str: string, decoder: Decoder): string => {
try {
return decoder(str)
} catch {
return str.replace(/(?:%[0-9A-Fa-f]{2})+/g, (match) => {
try {
return decoder(match)
} catch {
return match
}
})
}
}Sources: src/utils/url.ts:81-93
Tip
When getPath encounters a percent character (37) in a request URL, it locates query strings and hash boundaries using indexOf, slices out the path substring, and replaces %25 with %2525 prior to passing the result to tryDecodeURI.
Sources: src/utils/url.ts:110-127
HTML escaping and template rendering
Escaped String Wrappers and Buffer Escape Mechanics
The HTML helper system relies on branded string types and buffer utilities to manage template tags src/utils/html.ts:17-21, src/helper/html/index.ts:11-14. The raw function constructs an HtmlEscapedString object wrapping an underlying value, setting its isEscaped flag to true and attaching optional callbacks src/utils/html.ts:40-46. Text escaping is handled by escapeToBuffer, which scans strings for characters matching the regular expression /[&<>'\"]/ and appends entity codes to a StringBuffer src/utils/html.ts:51-51, src/utils/html.ts:90-127.
| Character Code | Character | Escaped Entity |
|---|---|---|
34 | " | " |
39 | ' | ' |
38 | & | & |
60 | < | < |
62 | > | > |
Sources: src/utils/html.ts:102-117
Note
escapeToBuffer exits immediately if str.search(escapeRe) returns -1, appending the raw string directly to buffer[0] without iteration.
Sources: src/utils/html.ts:91-95
Template Tag Processing and StringBuffer Resolution
The html tagged template function iterates over template strings and interpolated values, flattening array children and handling strings, numbers, booleans, null, undefined, escaped objects, and promises src/helper/html/index.ts:11-48. Interpolated items containing active callbacks or asynchronous promises cause the buffer to prepend items via buffer.unshift('', child), alternating strings and promises src/helper/html/index.ts:33-44. stringBufferToString processes these buffers from tail to head, resolving promises and collecting embedded callbacks src/utils/html.ts:53-88.
* StringBuffer contains string and Promise<string> alternately
* The length of the array will be odd, the odd numbered element will be a string,
* and the even numbered element will be a Promise<string>.
* When concatenating into a single string, it must be processed from the tail.
* @example
* [
* 'framework.',
* Promise.resolve('ultra fast'),
* 'a ',
* Promise.resolve('is '),
* 'Hono',
* ]
*/Sources: src/utils/html.ts:24-36
Warning
A StringBuffer must always have an odd length where odd-numbered elements are strings and even-numbered elements are promises; concatenation must proceed strictly from the tail.
Sources: src/utils/html.ts:24-27
Synchronous and Asynchronous Callback Resolution
Callback resolution supports distinct execution phases defined by HtmlEscapedCallbackPhase src/utils/html.ts:6-10. resolveCallbackSync evaluates stringification callbacks synchronously when no asynchronous promises or streams are present src/utils/html.ts:129-140. For asynchronous rendering flows, resolveCallback awaits promises, maps over callback functions with specific execution phases, filters truthy results, and recursively resolves nested values src/utils/html.ts:142-182.
| Phase Name | Numeric Value | Description |
|---|---|---|
Stringify | 1 | Phase triggered during string conversion of template components. |
BeforeStream | 2 | Phase executed immediately preceding stream rendering. |
Stream | 3 | Phase active during chunked stream transmission. |
Sources: src/utils/html.ts:6-10
Tip
When preserveCallbacks is enabled in resolveCallback, the resulting string retains its callback array wrapped via raw(), whereas setting it to false strips the callbacks from the final output src/utils/html.ts:145-145, src/utils/html.ts:177-181.
Binary and Base64 encoding helpers
Base64 and Base64Url Operations
Encoding and decoding binary buffers and URL-safe strings rely on standard Base64 transformations combined with custom character substitutions. encodeBase64 converts any ArrayBufferLike into a Base64 string by iterating over its bytes via Uint8Array, converting each character code to a binary string, and passing the result to btoa src/utils/encode.ts:15-22. Conversely, decodeBase64 decodes a Base64 string using atob and populates a Uint8Array from both ends simultaneously src/utils/encode.ts:25-33. For URL-safe representations, encodeBase64Url replaces forward slashes with underscores and plus signs with hyphens, while decodeBase64Url reverses these substitutions prior to decoding src/utils/encode.ts:6-11. UTF-8 text encoding and decoding utilities are exposed directly through utf8Encoder and utf8Decoder instances src/utils/jwt/utf8.ts:6-7.
Sources: src/utils/encode.ts:6-33, src/utils/jwt/utf8.ts:6-7
Warning
decodeBase64 iterates from both ends toward the middle (i and j) to populate the Uint8Array buffer in a single pass over half the binary length.
Sources: src/utils/encode.ts:28-32
Cryptographic Hashing Wrappers
Cryptographic hashing utilities generate message digests using the Web Crypto API's crypto.subtle.digest interface src/utils/crypto.ts:45-56. The createHash function accepts data in various formats, stringifying JSON objects and encoding plain strings with TextEncoder when the input is not already an ArrayBuffer or ArrayBufferView [src/utils/crypto.ts:33-43]. The resulting digest buffer is converted into a hexadecimal string by mapping each byte to a zero-padded hex representation src/utils/crypto.ts:52-55. Specific algorithm wrappers provide pre-configured parameters for standard hash functions.
| Function Name | Algorithm Name | Algorithm Alias | Return Type | Sources |
|---|---|---|---|---|
sha256 | SHA-256 | sha256 | Promise<string | null> | src/utils/crypto.ts:15-19 |
sha1 | SHA-1 | sha1 | Promise<string | null> | src/utils/crypto.ts:21-25 |
md5 | MD5 | md5 | Promise<string | null> | src/utils/crypto.ts:27-31 |
Sources: src/utils/crypto.ts:15-31
Note
If crypto or crypto.subtle is unavailable in the current runtime environment, createHash returns null rather than throwing an error src/utils/crypto.ts:45-57.
Sources: src/utils/crypto.ts:45-57
Concurrency control and task pools
Task Throttling and Execution Pools
Managing concurrent asynchronous execution pools is handled via the createPool helper, which limits simultaneous task execution during batch operations src/utils/concurrent.ts:12-18. By default, pools enforce a maximum concurrency limit of 1024 active tasks when no options are provided src/utils/concurrent.ts:6, src/utils/concurrent.ts:19. The returned Pool interface exposes a single run method that accepts a task function returning a value or a promise src/utils/concurrent.ts:8-10.
export const createPool = ({
concurrency,
interval,
}: {
concurrency?: number
interval?: number
} = {}): Pool => {
concurrency ||= DEFAULT_CONCURRENCY
if (concurrency === Infinity) {
// unlimited
return {
run: async (fn) => fn(),
}
}
const pool: Set<{}> = new Set()
const run = async <T>(
fn: () => T,
promise?: Promise<T>,
resolve?: (result: T) => void
): Promise<T> => {
if (pool.size >= (concurrency as number)) {
promise ||= new Promise<T>((r) => (resolve = r))
setTimeout(() => run(fn, promise, resolve))
return promise
}
const marker = {}
pool.add(marker)
const result = await fn()
if (interval) {
setTimeout(() => pool.delete(marker), interval)
} else {
pool.delete(marker)
}
if (resolve) {
resolve(result)
return promise as Promise<T>
} else {
return result
}
}
return { run }Sources: src/utils/concurrent.ts:12-54
When the pool's active set size reaches the configured concurrency threshold, incoming execution requests queue up by returning a deferred promise that re-evaluates via setTimeout src/utils/concurrent.ts:34-38. If concurrency is explicitly set to Infinity, throttling is disabled entirely, executing tasks immediately without tracking or queuing src/utils/concurrent.ts:21-26.
Warning
Setting concurrency to Infinity bypasses all pool tracking and marker allocations, causing run to invoke the task function directly without backpressure src/utils/concurrent.ts:21-26.
Sources: src/utils/concurrent.ts:21-26
Pool Configuration Options
The createPool function accepts a configuration object defining concurrency limits and release intervals src/utils/concurrent.ts:12-18.
| Option Name | Type | Default | Description | Sources |
|---|---|---|---|---|
concurrency | number | 1024 | Maximum number of concurrent tasks allowed in the execution pool | src/utils/concurrent.ts:6, src/utils/concurrent.ts:16, src/utils/concurrent.ts:19 |
interval | number | undefined | Delay in milliseconds before removing a completed task marker from the active pool set | src/utils/concurrent.ts:17, src/utils/concurrent.ts:42-43 |
Sources: src/utils/concurrent.ts:6, src/utils/concurrent.ts:16-17, src/utils/concurrent.ts:19, src/utils/concurrent.ts:42-43
Tip
Specifying an interval delays the deletion of task markers from the internal Set, enforcing a cool-down period between task completions and slot availability src/utils/concurrent.ts:42-46.
Sources: src/utils/concurrent.ts:42-46
HTTP headers and status codes
HTTP Status Code Mappings
Hono provides comprehensive TypeScript type definitions categorizing standard HTTP status codes by their functional classification src/utils/http-status.ts:6-40. These types include informatory responses, successful operations, redirects, client errors, and server errors src/utils/http-status.ts:6-40. Unofficial or custom status codes can be cast using UnofficialStatusCode (-1) when interacting with non-standard server extensions src/utils/http-status.ts:43-52.
| Status Category | Status Codes | Sources |
|---|---|---|
InfoStatusCode | 100, 101, 102, 103 | src/utils/http-status.ts:6 |
SuccessStatusCode | 200, 201, 202, 203, 204, 205, 206, 207, 208, 226 | src/utils/http-status.ts:7 |
DeprecatedStatusCode | 305, 306 | src/utils/http-status.ts:8 |
RedirectStatusCode | 300, 301, 302, 303, 304, 305, 306, 307, 308 | src/utils/http-status.ts:9 |
ClientErrorStatusCode | 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 421, 422, 423, 424, 425, 426, 428, 429, 431, 451 | src/utils/http-status.ts:10-39 |
ServerErrorStatusCode | 500, 501, 502, 503, 504, 505, 506, 507, 508, 510, 511 | src/utils/http-status.ts:40 |
Sources: src/utils/http-status.ts:6-40
Note
ContentlessStatusCode aggregates specific response codes (101, 204, 205, 304) that typically omit a response body, while ContentfulStatusCode excludes them from the broader StatusCode union src/utils/http-status.ts:71-72.
Sources: src/utils/http-status.ts:71-72
Header Utilities and Proxy Management
Typed utilities define strict unions for request and response headers in src/utils/headers.ts, covering standard IANA HTTP field names src/utils/headers.ts:8-322. Additionally, proxy helpers process hop-by-hop headers such as connection, keep-alive, proxy-authenticate, proxy-authorization, te, trailer, transfer-encoding, and upgrade src/helper/proxy/index.ts:10-19. When strictConnectionProcessing is enabled, connection header values are validated against ALLOWED_TOKEN_PATTERN (/^[!#$%&'*+\-.0-9A-Z^_a-z|~]+$/`) before stripping listed headers src/helper/proxy/index.ts:22-22, src/helper/proxy/index.ts:63-76.
Warning
By default, strictConnectionProcessing is set to false, completely ignoring incoming connection headers to prevent potential Hop-by-Hop Header Injection attacks src/helper/proxy/index.ts:33-43.
Sources: src/helper/proxy/index.ts:33-43
Related
On This Page
OverviewCookie parsing and signature validationCookie Parsing and Helper Call ChainsCryptographic Signature ValidationCookie Validation PatternsCookie serialization and attribute formattingExecution Walkthrough and SequenceURL path manipulation and decodingPath Normalization and Segment SplittingGroup Mark Replacement and Parameter ExtractionFault-Tolerant URI DecodingHTML escaping and template renderingEscaped String Wrappers and Buffer Escape MechanicsTemplate Tag Processing and StringBuffer ResolutionSynchronous and Asynchronous Callback ResolutionBinary and Base64 encoding helpersBase64 and Base64Url OperationsCryptographic Hashing WrappersConcurrency control and task poolsTask Throttling and Execution PoolsPool Configuration OptionsHTTP headers and status codesHTTP Status Code MappingsHeader Utilities and Proxy ManagementRelated