Proxy ヘルパー
Proxy ヘルパーは、Hono アプリケーションを(リバース)プロキシとして使う際に便利な関数を提供します。
インポート
ts
import { Hono } from 'hono'
import { proxy } from 'hono/proxy'proxy()
proxy() はプロキシ用の fetch() API のラッパーです。プロキシ専用のオプションを除き、引数と戻り値は fetch() と同じです。
Accept-Encoding ヘッダーは、現在のランタイムが処理できるエンコーディングに置き換えられます。不要なレスポンスヘッダーを削除し、ハンドラーから送信できる Response オブジェクトを返します。
例
簡単な使い方:
ts
app.get('/proxy/:path', (c) => {
return proxy(`http://${originServer}/${c.req.param('path')}`)
})複雑な使い方:
ts
app.get('/proxy/:path', async (c) => {
const res = await proxy(
`http://${originServer}/${c.req.param('path')}`,
{
headers: {
...c.req.header(), // optional, specify only when forwarding all the request data (including credentials) is necessary.
'X-Forwarded-For': '127.0.0.1',
'X-Forwarded-Host': c.req.header('host'),
Authorization: undefined, // do not propagate request headers contained in c.req.header('Authorization')
},
}
)
res.headers.delete('Set-Cookie')
return res
})c.req を引数として渡すこともできます。
ts
app.all('/proxy/:path', (c) => {
return proxy(`http://${originServer}/${c.req.param('path')}`, {
...c.req, // optional, specify only when forwarding all the request data (including credentials) is necessary.
headers: {
...c.req.header(),
'X-Forwarded-For': '127.0.0.1',
'X-Forwarded-Host': c.req.header('host'),
Authorization: undefined, // do not propagate request headers contained in c.req.header('Authorization')
},
})
})customFetch オプションで、デフォルトのグローバル fetch 関数を置き換えられます。
ts
app.get('/proxy', (c) => {
return proxy('https://example.com/', {
customFetch,
})
})Connection ヘッダーの処理
デフォルトでは、proxy() はホップごとのヘッダーインジェクション攻撃を防ぐため、Connection ヘッダーを無視します。strictConnectionProcessing オプションで、RFC 9110 に厳密に準拠する処理を有効にできます。
ts
// Default behavior (recommended for untrusted clients)
app.get('/proxy/:path', (c) => {
return proxy(`http://${originServer}/${c.req.param('path')}`, c.req)
})
// Strict RFC 9110 compliance (use only in trusted environments)
app.get('/internal-proxy/:path', (c) => {
return proxy(`http://${internalServer}/${c.req.param('path')}`, {
...c.req,
strictConnectionProcessing: true,
})
})ProxyFetch
proxy() の型は ProxyFetch として次のように定義されています。
ts
interface ProxyRequestInit extends Omit<RequestInit, 'headers'> {
raw?: Request
customFetch?: (request: Request) => Promise<Response>
strictConnectionProcessing?: boolean
headers?:
| HeadersInit
| [string, string][]
| Record<RequestHeader, string | undefined>
| Record<string, string | undefined>
}
interface ProxyFetch {
(
input: string | URL | Request,
init?: ProxyRequestInit
): Promise<Response>
}