43 lines
987 B
Go
43 lines
987 B
Go
package fastrp
|
|
|
|
import (
|
|
"context"
|
|
"net"
|
|
"net/http"
|
|
"net/http/httputil"
|
|
"net/url"
|
|
"sync"
|
|
)
|
|
|
|
// FastRP takes an incoming request and sends it fast to another server, proxying the response back to the client fast.
|
|
type FastRP struct {
|
|
rp *httputil.ReverseProxy
|
|
connPool *sync.Pool
|
|
}
|
|
|
|
func NewRP(network, address string, url *url.URL) *FastRP {
|
|
roundTripper := &http.Transport{
|
|
DialContext: func(_ context.Context, _ string, _ string) (net.Conn, error) {
|
|
return net.Dial(network, address)
|
|
},
|
|
MaxIdleConns: 10,
|
|
}
|
|
frp := &FastRP{
|
|
rp: httputil.NewSingleHostReverseProxy(url),
|
|
connPool: &sync.Pool{
|
|
New: func() any {
|
|
return roundTripper.Clone()
|
|
},
|
|
},
|
|
}
|
|
frp.rp.Transport = frp.connPool.Get().(http.RoundTripper)
|
|
return frp
|
|
}
|
|
|
|
func (frp *FastRP) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
|
roundTripper := frp.connPool.Get().(http.RoundTripper)
|
|
defer frp.connPool.Put(roundTripper)
|
|
frp.rp.Transport = roundTripper
|
|
frp.rp.ServeHTTP(w, r)
|
|
}
|