yeqown / fasthttp-reverse-proxy

reverse http / websocket proxy based on fasthttp
MIT License
213 stars 56 forks source link

[Quetion] URL Path overriding #39

Closed LdDl closed 7 months ago

LdDl commented 8 months ago

Hello @yeqown I'm trying to achieve URL modification before proxing: my reverse proxy server should accept some data, process it and prepare wildcard for actual websocket server. Do you have any tips on how to achieve that? E.g.:

// ...
once.Do(func() {
    var err error
    proxyServer, err = proxy.NewWSReverseProxyWith(
        proxy.WithURL_OptionWS("ws://localhost:3001/ws"),
        proxy.WithUpgrader_OptionWS(&websocket.FastHTTPUpgrader{
            CheckOrigin: func(r *fasthttp.RequestCtx) bool { return true },
        }),
    )
    if err != nil {
        panic(err)
    }
})
// ...Some data processing before reverse proxy...
x := "some unique ID based on data"
y := "some query parameter"
switch string(ctx.Path()) {
case "/wall/path":
    newPath := fmt.Sprintf("another/route/path/%s", x)
        ctx.QueryArgs().Set("q", y)
    ctx.Request.URI().SetPath(newPath)
    proxyServer.ServeHTTP(fastHttpCtx)
default:
    // Handle unsupported path
}

I suppose the line ctx.Request.URI().SetPath(newPath) won't affect dialing because of _dialer.Dial(w.option.target.String(), forwardHeader)_, right? Would it be correct to replace this line in your package with something like code below?

// connBackend, respBackend, err := dialer.Dial(w.option.target.String(), forwardHeader)
// replace with: 
overridePath := ctx.Request.Header.Peek("Override-Path")
if len(overridePath) == 0 {
    overridePath = []byte(w.option.target.Path)
}
ref := &url.URL{Path: string(overridePath), RawQuery: string(ctx.QueryArgs().QueryString())}
newURL := w.option.target.ResolveReference(ref)
connBackend, respBackend, err := dialer.Dial(newURL.String(), forwardHeader)

and then in user defined server:

// ....
ctx.QueryArgs().Set("q", y)
ctx.Request.Header.Set("Override-Path", newPath)
proxyServer.ServeHTTP(fastHttpCtx)
// newURL should now look like "http://localhost:3001/another/route/path/some_wildcard?q=some_query_param_value"
// ...

should work. If you could spot me some drawbacks / mistakes of such approach, I would appreciate it!

yeqown commented 8 months ago

yup, the WS reverse proxy doesn't support dynamic target yet. Your code looks feasible, have you tried and what's result?

LdDl commented 8 months ago

Thanks for attention! I guess it works for my needs... I'll make end-user example (plain JS-client and Go-client) and provide more info on results.

LdDl commented 8 months ago

done a bit of coding for today: https://github.com/yeqown/fasthttp-reverse-proxy/pull/40 I was struggling during doing client example, but it seems to work just fine

yeqown commented 8 months ago

I would check later😀

yeqown commented 7 months ago

This feature has been released in v2.2.3