-
Notifications
You must be signed in to change notification settings - Fork 77
feat(request): support x-forwarded-proto header for protocol detection
#268
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
|
Hi @usualoma ! I think the comment #146 (comment) makes sense. It has to look up the |
|
Hi @yusukebe, thank you for creating the pull request. As mentioned in #146 (comment), I believe that caution should be exercised when referencing koaIn koa, https://github.com/koajs/koa/blob/cb22d8dcdeb7c0e4e1bdee5eaa5be183ef23a1f2/lib/request.js#L388-L405 Plack::Middleware::ReverseProxyPlack has dedicated middleware for performing such processing. This kind of processing is not only necessary for Node.js, but also for bun and deno in some cases, so we may need a middleware called My opinion on this pull requestI don't believe it's a good idea to check |
|
Hi @usualoma Thank you for the understandable explanation! As you mentioned, I reconsider that we should handle But I also think it's hard for users if they have to write the logic by themselves, like this #146 (comment) So, is it a good idea to implement middleware like Plack::Middleware::ReverseProxy? (For Hono, I sometimes confuse whether the Hono app is a reverse proxy or backed for a reverse proxy since I often use the Hono app as a reverse proxy on Cloudflare/CDN, so the naming should be considered.) If so, it can support |
|
Ah, but there is room for discussion as to whether this should be done in Hono's application layer. It may be good that the URL in |
|
I also think there is room for consideration as to whether standard middleware is appropriate.
|
|
If we solve this on the application side, I think the following is one way to do it. |
|
Ah, creating Reverse Proxy Helper is interesting! I'll consider it. Thanks. |
|
Adding There is another way to handle the reverse proxy-specific headers. You can write it before Hono's // Cloudflare Workers / Deno / Bun
import { Hono } from 'hono'
const app = new Hono()
//...
export default {
fetch: (req: Request) => {
const url = new URL(req.url)
url.protocol = req.headers.get('x-forwarded-proto') ?? url.protocol
return app.fetch(new Request(url, req))
}
}// Node.js
import { Hono } from 'hono'
import { serve } from '@hono/node-server'
const app = new Hono()
serve({
fetch: (req) => {
const url = new URL(req.url)
url.protocol = req.headers.get('x-forwarded-proto') ?? url.protocol
return app.fetch(new Request(url, req))
}
})Or, it may be too much, but we can make a helper: import { Hono } from 'hono'
import { handleRequest } from 'hono/reverse-proxy'
const app = new Hono()
export default {
fetch: (req: Request) => {
return app.fetch(handleRequest(req))
}
}In the So, honojs/hono#4336 is a great idea, but we may not accept it and we may not be in a hurry. |
|
That's true, I agree with that opinion.
|
|
Does this preserve other parts of the request? if (IS_DEVELOPMENT) {
console.log('Starting development server');
const viteDevServer = await import('vite').then((vite) =>
vite.createServer({
server: { middlewareMode: true },
}),
);
app.use('*', async (c, next) => {
return new Promise((resolve, reject) => {
const incoming = /** @type {any} */ (c.env).incoming;
const outgoing = /** @type {any} */ (c.env).outgoing;
viteDevServer.middlewares(
incoming,
outgoing,
/** @param {any} err */ (err) => {
if (err) {
reject(err);
} else {
next().then(resolve).catch(reject);
}
},
);
});
});
app.use('*', async (c, next) => {
try {
const source = await viteDevServer.ssrLoadModule('./src/server.ts');
const response = await source.app.fetch(c.req.raw, c.env);
return response;
} catch (error) {
if (typeof error === 'object' && error instanceof Error) {
viteDevServer.ssrFixStacktrace(error);
}
return next();
}
});
} else {
console.log('Starting production server');
const { serveStatic } = await import('@hono/node-server/serve-static');
app.use(
'/assets/*',
serveStatic({
root: './build/client',
rewriteRequestPath: (path) => path,
}),
);
app.use('*', serveStatic({ root: './build/client' }));
const BUILD_PATH = './build/server/index.js';
const { app: serverApp } = await import(BUILD_PATH);
app.route('/', serverApp);
}
serve(
{
fetch: (req) => {
const forwardedProto = req.headers.get('x-forwarded-proto');
if (forwardedProto) {
console.log('Forwarded proto', forwardedProto);
const url = new URL(req.url);
url.protocol = forwardedProto;
return app.fetch(new Request(url, req));
}
return app.fetch(req);
},
port: PORT,
},
() => {
console.log(`Server is running on http://localhost:${PORT}`);
},
);but get this error: Server is running on http://localhost:9000
TypeError: Cannot read properties of undefined (reading 'incoming')
at file:///Users/pthieu/www/lab46/p-stack/index.js:28:51
at new Promise (<anonymous>)
at file:///Users/pthieu/www/lab46/p-stack/index.js:27:12Seems like just doing the UPDATE: took a look at the |
Fixes #146 (comment)