hono
hono copied to clipboard
Modify Req for Proxy scenario
What is the feature you are proposing?
In this example it takes the request and passes it to the url: https://hono.dev/guides/examples#proxy
In order to make the proxy functionality more useful, it would be helpful to be able to modify or replace the req via the Middleware in order to add headers, santize/transform the url, etc..
Example from Compute@Edge documenation for Adding Geo Information to the request to the downstream:
function handler(event) {
let clientGeo = event.client.geo
event.request.headers.set("client-geo-continent", clientGeo.continent)
event.request.headers.set("client-geo-country", clientGeo.country_code)
event.request.headers.set("client-geo-latitude", clientGeo.latitude)
event.request.headers.set("client-geo-longitude", clientGeo.longitude)
return fetch(event.request, { backend: "origin_0" })
}
addEventListener("fetch", (event) => event.respondWith(handler(event)))
Source: https://developer.fastly.com/solutions/examples/decorating-origin-requests-with-geoip/
I'm able to do it like this:
const newRequest = new Request(url,c.req.raw);
newRequest.headers.set('X-Connecting-IP',`${REALIP}`)
const res = await fetch(newRequest)
const newResponse = new Response(res.body, res)
newResponse.headers.set('X-Custom-Router', 'Hono')
return newResponse
})
Not sure if that's the best way to do it though...
@draco2003
I think you can do almost all things with a @alex8bitw 's method. We don't have to make a helper for proxies.
hi @yusukebe .. I'm trying @alex8bitw's method but c.req.raw
is empty for me always. I'm on 3.6
@eitelkrauss
I don't understand why c.req.raw
is empty, but you can try the following code:
import { Hono } from 'hono'
const app = new Hono()
app.get('/', async (c) => {
const newRequest = new Request('http://example.com')
const res = await fetch(newRequest)
const newResponse = new Response(res.body, res)
newResponse.headers.set('X-Message', 'Hello!')
return newResponse
})
export default app
@yusukebe this works when you have no params, but what would be the best way to include the raw request object like @alex8bitw?
I know ideally you would setup a proxy before reaching the hono server, but I'm still curious how could I implement this in a hono handler?
@eitelkrauss are you just trying to proxy everything?
The above is only half the solution then. You also need to send through the queries/params. I believe c.req.raw will send through POST requests, @yusukebe please confirm?
For the queries, I use app.all('/*',.....
Then you need to do something like this:
const path:string = c.req.path
const query = c.req.url.split("?")
var url
if (query[1]) {
url = new URL(path + "?" + query[1])
} else {
url = new URL(path)
}
In order to retain the query path part. Then you can do the rest of your code..
The above is only if you need to mess with path for the proxying. If you don't you can just do url = c.req.url. The above allows you to substitute path for something else.
Yes @alex8bitw is right.
Got it ... thought you could just use the same request object somehow.. thanks! @alex8bitw @yusukebe
hi @yusukebe .. I'm trying @alex8bitw's method but
c.req.raw
is empty for me always. I'm on 3.6
hey, new user of hono here. I am trying to build a simple proxy but c.req.raw
is also empty for me. no matter whether it's a unit test or an integration test via cf workers + vote.
Hi @psteinroe , what are you trying to do? Hono works really well for proxying. I'm on 3.12.8 currently. I think the gist is, you create a new request with the c.req.raw object. Here's an example for CF workers:
const newRequest = new Request(url,c.req.raw);
newRequest.headers.set('X-Forwarded-For',`${REALIP}`)
const res = await fetch(newRequest,{
cf: {
cacheTtl: CACHE_TIME,
cacheEverything: true,
cacheTags: [ 'worker', `${HONO_TAG}` ],
cacheKey: url.hostname + url.pathname,
}})
const newResponse = new Response(res.body, res)
newResponse.headers.set('X-Custom-Router', `${HONO_TAG}`)
return newResponse
The above modifies the connections by adding CF caching. Just wrap that in an app.all() with the proper query parsing you want to do (as shown a few messages above).
Hi @psteinroe , what are you trying to do? Hono works really well for proxying. I'm on 3.12.8 currently. I think the gist is, you create a new request with the c.req.raw object. Here's an example for CF workers:
const newRequest = new Request(url,c.req.raw); newRequest.headers.set('X-Forwarded-For',`${REALIP}`) const res = await fetch(newRequest,{ cf: { cacheTtl: CACHE_TIME, cacheEverything: true, cacheTags: [ 'worker', `${HONO_TAG}` ], cacheKey: url.hostname + url.pathname, }}) const newResponse = new Response(res.body, res) newResponse.headers.set('X-Custom-Router', `${HONO_TAG}`) return newResponse
The above modifies the connections by adding CF caching. Just wrap that in an app.all() with the proper query parsing you want to do (as shown a few messages above).
ahh thanks, that works!! I was passing c.req.raw
directly to fetch
, but creating a new Request
first does the trick.