diff --git a/jsr.json b/jsr.json
index 8b281419..09c22785 100644
--- a/jsr.json
+++ b/jsr.json
@@ -88,6 +88,7 @@
"./utils/encode": "./src/utils/encode.ts",
"./utils/filepath": "./src/utils/filepath.ts",
"./utils/handler": "./src/utils/handler.ts",
+ "./utils/headers": "./src/utils/headers.ts",
"./utils/html": "./src/utils/html.ts",
"./utils/http-status": "./src/utils/http-status.ts",
"./utils/jwt": "./src/utils/jwt/index.ts",
diff --git a/src/context.ts b/src/context.ts
index b46783df..7acab14f 100644
--- a/src/context.ts
+++ b/src/context.ts
@@ -9,6 +9,7 @@ import type {
RouterRoute,
TypedResponse,
} from './types'
+import type { ResponseHeader } from './utils/headers'
import { HtmlEscapedCallbackPhase, resolveCallback } from './utils/html'
import type { RedirectStatusCode, StatusCode } from './utils/http-status'
import type { BaseMime } from './utils/mime'
@@ -236,77 +237,6 @@ interface SetHeadersOptions {
append?: boolean
}
-type ResponseHeader =
- | 'Access-Control-Allow-Credentials'
- | 'Access-Control-Allow-Headers'
- | 'Access-Control-Allow-Methods'
- | 'Access-Control-Allow-Origin'
- | 'Access-Control-Expose-Headers'
- | 'Access-Control-Max-Age'
- | 'Age'
- | 'Allow'
- | 'Cache-Control'
- | 'Clear-Site-Data'
- | 'Content-Disposition'
- | 'Content-Encoding'
- | 'Content-Language'
- | 'Content-Length'
- | 'Content-Location'
- | 'Content-Range'
- | 'Content-Security-Policy'
- | 'Content-Security-Policy-Report-Only'
- | 'Content-Type'
- | 'Cookie'
- | 'Cross-Origin-Embedder-Policy'
- | 'Cross-Origin-Opener-Policy'
- | 'Cross-Origin-Resource-Policy'
- | 'Date'
- | 'ETag'
- | 'Expires'
- | 'Last-Modified'
- | 'Location'
- | 'Permissions-Policy'
- | 'Pragma'
- | 'Retry-After'
- | 'Save-Data'
- | 'Sec-CH-Prefers-Color-Scheme'
- | 'Sec-CH-Prefers-Reduced-Motion'
- | 'Sec-CH-UA'
- | 'Sec-CH-UA-Arch'
- | 'Sec-CH-UA-Bitness'
- | 'Sec-CH-UA-Form-Factor'
- | 'Sec-CH-UA-Full-Version'
- | 'Sec-CH-UA-Full-Version-List'
- | 'Sec-CH-UA-Mobile'
- | 'Sec-CH-UA-Model'
- | 'Sec-CH-UA-Platform'
- | 'Sec-CH-UA-Platform-Version'
- | 'Sec-CH-UA-WoW64'
- | 'Sec-Fetch-Dest'
- | 'Sec-Fetch-Mode'
- | 'Sec-Fetch-Site'
- | 'Sec-Fetch-User'
- | 'Sec-GPC'
- | 'Server'
- | 'Server-Timing'
- | 'Service-Worker-Navigation-Preload'
- | 'Set-Cookie'
- | 'Strict-Transport-Security'
- | 'Timing-Allow-Origin'
- | 'Trailer'
- | 'Transfer-Encoding'
- | 'Upgrade'
- | 'Vary'
- | 'WWW-Authenticate'
- | 'Warning'
- | 'X-Content-Type-Options'
- | 'X-DNS-Prefetch-Control'
- | 'X-Frame-Options'
- | 'X-Permitted-Cross-Domain-Policies'
- | 'X-Powered-By'
- | 'X-Robots-Tag'
- | 'X-XSS-Protection'
-
interface SetHeaders {
(name: 'Content-Type', value?: BaseMime, options?: SetHeadersOptions): void
(name: ResponseHeader, value?: string, options?: SetHeadersOptions): void
diff --git a/src/helper/accepts/accepts.ts b/src/helper/accepts/accepts.ts
index f767da82..85052c3f 100644
--- a/src/helper/accepts/accepts.ts
+++ b/src/helper/accepts/accepts.ts
@@ -1,13 +1,5 @@
import type { Context } from '../../context'
-
-export type AcceptHeader =
- | 'Accept'
- | 'Accept-Charset'
- | 'Accept-Encoding'
- | 'Accept-Language'
- | 'Accept-Patch'
- | 'Accept-Post'
- | 'Accept-Ranges'
+import type { AcceptHeader } from '../../utils/headers'
export interface Accept {
type: string
diff --git a/src/helper/cookie/index.ts b/src/helper/cookie/index.ts
index f2ca99b3..a7060db3 100644
--- a/src/helper/cookie/index.ts
+++ b/src/helper/cookie/index.ts
@@ -93,7 +93,7 @@ export const setCookie = (c: Context, name: string, value: string, opt?: CookieO
} else {
cookie = serialize(name, value, { path: '/', ...opt })
}
- c.header('set-cookie', cookie, { append: true })
+ c.header('Set-Cookie', cookie, { append: true })
}
export const setSignedCookie = async (
diff --git a/src/request.ts b/src/request.ts
index ffd40fa6..63ab2a37 100644
--- a/src/request.ts
+++ b/src/request.ts
@@ -11,6 +11,7 @@ import type {
} from './types'
import { parseBody } from './utils/body'
import type { BodyData, ParseBodyOptions } from './utils/body'
+import type { CustomHeader, RequestHeader } from './utils/headers'
import type { Simplify, UnionToIntersection } from './utils/types'
import { decodeURIComponent_, getQueryParam, getQueryParams } from './utils/url'
@@ -171,8 +172,9 @@ export class HonoRequest
{
* })
* ```
*/
+ header(name: RequestHeader): string | undefined
header(name: string): string | undefined
- header(): Record
+ header(): Record
header(name?: string) {
if (name) {
return this.raw.headers.get(name.toLowerCase()) ?? undefined
diff --git a/src/types.ts b/src/types.ts
index e5b24003..09bfeb97 100644
--- a/src/types.ts
+++ b/src/types.ts
@@ -7,6 +7,7 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
import type { Context } from './context'
import type { Hono } from './hono'
+import type { CustomHeader, RequestHeader } from './utils/headers'
import type { StatusCode } from './utils/http-status'
import type {
IfAnyThenEmptyObject,
@@ -1924,7 +1925,7 @@ export type ValidationTargets
query: Record
param: Record
- header: Record
+ header: Record
cookie: Record
}
diff --git a/src/utils/headers.ts b/src/utils/headers.ts
new file mode 100644
index 00000000..dd899a8d
--- /dev/null
+++ b/src/utils/headers.ts
@@ -0,0 +1,333 @@
+/**
+ * @module
+ * HTTP Headers utility.
+ */
+
+// note: https://www.iana.org/assignments/http-fields/http-fields.xhtml
+
+export type RequestHeader =
+ | 'A-IM'
+ | 'Accept'
+ | 'Accept-Additions'
+ | 'Accept-CH'
+ | 'Accept-Charset'
+ | 'Accept-Datetime'
+ | 'Accept-Encoding'
+ | 'Accept-Features'
+ | 'Accept-Language'
+ | 'Accept-Patch'
+ | 'Accept-Post'
+ | 'Accept-Ranges'
+ | 'Accept-Signature'
+ | 'Access-Control'
+ | 'Access-Control-Allow-Credentials'
+ | 'Access-Control-Allow-Headers'
+ | 'Access-Control-Allow-Methods'
+ | 'Access-Control-Allow-Origin'
+ | 'Access-Control-Expose-Headers'
+ | 'Access-Control-Max-Age'
+ | 'Access-Control-Request-Headers'
+ | 'Access-Control-Request-Method'
+ | 'Age'
+ | 'Allow'
+ | 'ALPN'
+ | 'Alt-Svc'
+ | 'Alt-Used'
+ | 'Alternates'
+ | 'AMP-Cache-Transform'
+ | 'Apply-To-Redirect-Ref'
+ | 'Authentication-Control'
+ | 'Authentication-Info'
+ | 'Authorization'
+ | 'Available-Dictionary'
+ | 'C-Ext'
+ | 'C-Man'
+ | 'C-Opt'
+ | 'C-PEP'
+ | 'C-PEP-Info'
+ | 'Cache-Control'
+ | 'Cache-Status'
+ | 'Cal-Managed-ID'
+ | 'CalDAV-Timezones'
+ | 'Capsule-Protocol'
+ | 'CDN-Cache-Control'
+ | 'CDN-Loop'
+ | 'Cert-Not-After'
+ | 'Cert-Not-Before'
+ | 'Clear-Site-Data'
+ | 'Client-Cert'
+ | 'Client-Cert-Chain'
+ | 'Close'
+ | 'CMCD-Object'
+ | 'CMCD-Request'
+ | 'CMCD-Session'
+ | 'CMCD-Status'
+ | 'CMSD-Dynamic'
+ | 'CMSD-Static'
+ | 'Concealed-Auth-Export'
+ | 'Configuration-Context'
+ | 'Connection'
+ | 'Content-Base'
+ | 'Content-Digest'
+ | 'Content-Disposition'
+ | 'Content-Encoding'
+ | 'Content-ID'
+ | 'Content-Language'
+ | 'Content-Length'
+ | 'Content-Location'
+ | 'Content-MD5'
+ | 'Content-Range'
+ | 'Content-Script-Type'
+ | 'Content-Security-Policy'
+ | 'Content-Security-Policy-Report-Only'
+ | 'Content-Style-Type'
+ | 'Content-Type'
+ | 'Content-Version'
+ | 'Cookie'
+ | 'Cookie2'
+ | 'Cross-Origin-Embedder-Policy'
+ | 'Cross-Origin-Embedder-Policy-Report-Only'
+ | 'Cross-Origin-Opener-Policy'
+ | 'Cross-Origin-Opener-Policy-Report-Only'
+ | 'Cross-Origin-Resource-Policy'
+ | 'CTA-Common-Access-Token'
+ | 'DASL'
+ | 'Date'
+ | 'DAV'
+ | 'Default-Style'
+ | 'Delta-Base'
+ | 'Deprecation'
+ | 'Depth'
+ | 'Derived-From'
+ | 'Destination'
+ | 'Differential-ID'
+ | 'Dictionary-ID'
+ | 'Digest'
+ | 'DPoP'
+ | 'DPoP-Nonce'
+ | 'Early-Data'
+ | 'EDIINT-Features'
+ | 'ETag'
+ | 'Expect'
+ | 'Expect-CT'
+ | 'Expires'
+ | 'Ext'
+ | 'Forwarded'
+ | 'From'
+ | 'GetProfile'
+ | 'Hobareg'
+ | 'Host'
+ | 'HTTP2-Settings'
+ | 'If'
+ | 'If-Match'
+ | 'If-Modified-Since'
+ | 'If-None-Match'
+ | 'If-Range'
+ | 'If-Schedule-Tag-Match'
+ | 'If-Unmodified-Since'
+ | 'IM'
+ | 'Include-Referred-Token-Binding-ID'
+ | 'Isolation'
+ | 'Keep-Alive'
+ | 'Label'
+ | 'Last-Event-ID'
+ | 'Last-Modified'
+ | 'Link'
+ | 'Link-Template'
+ | 'Location'
+ | 'Lock-Token'
+ | 'Man'
+ | 'Max-Forwards'
+ | 'Memento-Datetime'
+ | 'Meter'
+ | 'Method-Check'
+ | 'Method-Check-Expires'
+ | 'MIME-Version'
+ | 'Negotiate'
+ | 'NEL'
+ | 'OData-EntityId'
+ | 'OData-Isolation'
+ | 'OData-MaxVersion'
+ | 'OData-Version'
+ | 'Opt'
+ | 'Optional-WWW-Authenticate'
+ | 'Ordering-Type'
+ | 'Origin'
+ | 'Origin-Agent-Cluster'
+ | 'OSCORE'
+ | 'OSLC-Core-Version'
+ | 'Overwrite'
+ | 'P3P'
+ | 'PEP'
+ | 'PEP-Info'
+ | 'Permissions-Policy'
+ | 'PICS-Label'
+ | 'Ping-From'
+ | 'Ping-To'
+ | 'Position'
+ | 'Pragma'
+ | 'Prefer'
+ | 'Preference-Applied'
+ | 'Priority'
+ | 'ProfileObject'
+ | 'Protocol'
+ | 'Protocol-Info'
+ | 'Protocol-Query'
+ | 'Protocol-Request'
+ | 'Proxy-Authenticate'
+ | 'Proxy-Authentication-Info'
+ | 'Proxy-Authorization'
+ | 'Proxy-Features'
+ | 'Proxy-Instruction'
+ | 'Proxy-Status'
+ | 'Public'
+ | 'Public-Key-Pins'
+ | 'Public-Key-Pins-Report-Only'
+ | 'Range'
+ | 'Redirect-Ref'
+ | 'Referer'
+ | 'Referer-Root'
+ | 'Referrer-Policy'
+ | 'Refresh'
+ | 'Repeatability-Client-ID'
+ | 'Repeatability-First-Sent'
+ | 'Repeatability-Request-ID'
+ | 'Repeatability-Result'
+ | 'Replay-Nonce'
+ | 'Reporting-Endpoints'
+ | 'Repr-Digest'
+ | 'Retry-After'
+ | 'Safe'
+ | 'Schedule-Reply'
+ | 'Schedule-Tag'
+ | 'Sec-GPC'
+ | 'Sec-Purpose'
+ | 'Sec-Token-Binding'
+ | 'Sec-WebSocket-Accept'
+ | 'Sec-WebSocket-Extensions'
+ | 'Sec-WebSocket-Key'
+ | 'Sec-WebSocket-Protocol'
+ | 'Sec-WebSocket-Version'
+ | 'Security-Scheme'
+ | 'Server'
+ | 'Server-Timing'
+ | 'Set-Cookie'
+ | 'Set-Cookie2'
+ | 'SetProfile'
+ | 'Signature'
+ | 'Signature-Input'
+ | 'SLUG'
+ | 'SoapAction'
+ | 'Status-URI'
+ | 'Strict-Transport-Security'
+ | 'Sunset'
+ | 'Surrogate-Capability'
+ | 'Surrogate-Control'
+ | 'TCN'
+ | 'TE'
+ | 'Timeout'
+ | 'Timing-Allow-Origin'
+ | 'Topic'
+ | 'Traceparent'
+ | 'Tracestate'
+ | 'Trailer'
+ | 'Transfer-Encoding'
+ | 'TTL'
+ | 'Upgrade'
+ | 'Urgency'
+ | 'URI'
+ | 'Use-As-Dictionary'
+ | 'User-Agent'
+ | 'Variant-Vary'
+ | 'Vary'
+ | 'Via'
+ | 'Want-Content-Digest'
+ | 'Want-Digest'
+ | 'Want-Repr-Digest'
+ | 'Warning'
+ | 'WWW-Authenticate'
+ | 'X-Content-Type-Options'
+ | 'X-Frame-Options'
+
+export type ResponseHeader =
+ | 'Access-Control-Allow-Credentials'
+ | 'Access-Control-Allow-Headers'
+ | 'Access-Control-Allow-Methods'
+ | 'Access-Control-Allow-Origin'
+ | 'Access-Control-Expose-Headers'
+ | 'Access-Control-Max-Age'
+ | 'Age'
+ | 'Allow'
+ | 'Cache-Control'
+ | 'Clear-Site-Data'
+ | 'Content-Disposition'
+ | 'Content-Encoding'
+ | 'Content-Language'
+ | 'Content-Length'
+ | 'Content-Location'
+ | 'Content-Range'
+ | 'Content-Security-Policy'
+ | 'Content-Security-Policy-Report-Only'
+ | 'Content-Type'
+ | 'Cookie'
+ | 'Cross-Origin-Embedder-Policy'
+ | 'Cross-Origin-Opener-Policy'
+ | 'Cross-Origin-Resource-Policy'
+ | 'Date'
+ | 'ETag'
+ | 'Expires'
+ | 'Last-Modified'
+ | 'Location'
+ | 'Permissions-Policy'
+ | 'Pragma'
+ | 'Retry-After'
+ | 'Save-Data'
+ | 'Sec-CH-Prefers-Color-Scheme'
+ | 'Sec-CH-Prefers-Reduced-Motion'
+ | 'Sec-CH-UA'
+ | 'Sec-CH-UA-Arch'
+ | 'Sec-CH-UA-Bitness'
+ | 'Sec-CH-UA-Form-Factor'
+ | 'Sec-CH-UA-Full-Version'
+ | 'Sec-CH-UA-Full-Version-List'
+ | 'Sec-CH-UA-Mobile'
+ | 'Sec-CH-UA-Model'
+ | 'Sec-CH-UA-Platform'
+ | 'Sec-CH-UA-Platform-Version'
+ | 'Sec-CH-UA-WoW64'
+ | 'Sec-Fetch-Dest'
+ | 'Sec-Fetch-Mode'
+ | 'Sec-Fetch-Site'
+ | 'Sec-Fetch-User'
+ | 'Sec-GPC'
+ | 'Server'
+ | 'Server-Timing'
+ | 'Service-Worker-Navigation-Preload'
+ | 'Set-Cookie'
+ | 'Strict-Transport-Security'
+ | 'Timing-Allow-Origin'
+ | 'Trailer'
+ | 'Transfer-Encoding'
+ | 'Upgrade'
+ | 'Vary'
+ | 'WWW-Authenticate'
+ | 'Warning'
+ | 'X-Content-Type-Options'
+ | 'X-DNS-Prefetch-Control'
+ | 'X-Frame-Options'
+ | 'X-Permitted-Cross-Domain-Policies'
+ | 'X-Powered-By'
+ | 'X-Robots-Tag'
+ | 'X-XSS-Protection'
+
+export type AcceptHeader =
+ | 'Accept'
+ | 'Accept-Charset'
+ | 'Accept-Encoding'
+ | 'Accept-Language'
+ | 'Accept-Patch'
+ | 'Accept-Post'
+ | 'Accept-Ranges'
+
+// note: `X-${string}` is deprecated
+export type CustomHeader = string & {}