honojs / node-server

Node.js Server for Hono
https://hono.dev
346 stars 42 forks source link

Proxy is not working #121

Open yusukebe opened 8 months ago

yusukebe commented 8 months ago

The following a "proxy pattern" is not working:

import { serve } from '@hono/node-server'
import { Hono } from 'hono'

const app = new Hono()

app.get('/proxy', async (c) => {
  const res = await fetch('https://example.com/')
  const newResponse = new Response(res.body, res)
  return newResponse
})

serve({
  fetch: app.fetch,
  port: 3000
})

Commented https://github.com/honojs/hono/issues/1491#issuecomment-1879889842

usualoma commented 7 months ago

Although fetch() returns decoded data, the content-encoding and content-length headers remain unchanged in the response, which seems to be causing the problem.

On my environment, the following code returned the correct content.

I have not yet figured out whether this process should be done by each app or by the node-server.

app.get('/proxy', async (c) => {
  const res = await fetch('https://example.com/')
  const headers = { ...res.headers }
  delete headers['content-encoding']
  delete headers['content-length']
  const newResponse = new Response(res.body, { headers })
  return newResponse
})
zhy0216 commented 4 months ago

this works well, modified from https://github.com/linnil1/hono-cf-proxy/blob/main/src/utils_basic.ts

function basicProxy(proxy_url = ""): Handler {
  return async (c) => {
    // remove prefix
    // prefix = /app1/*, path = /app1/a/b
    // => suffix_path = /a/b
    // let path = new URL(c.req.raw.url).pathname
    let path = c.req.path;
    path = path.replace(new RegExp(`^${c.req.routePath.replace("*", "")}`), "/");
    let url = proxy_url ? proxy_url + path : c.req.url;
    // add params to URL
    if (c.req.query()) url = url + "?" + new URLSearchParams(c.req.query());
    // request
    const rep = await fetch(url, {
      method: c.req.method,
      headers: c.req.raw.headers,
      body: c.req.raw.body,
      duplex: "half",
    });
    if (rep.status === 101) return rep;

    return new Response(rep.body, rep);
  };
}