fixes
This commit is contained in:
+44
-4
@@ -69,7 +69,15 @@ func (m *MockResponseWriter) WriteHeader(statusCode int) {
|
||||
m.StatusCode = statusCode
|
||||
}
|
||||
|
||||
func NewRemoteHost[V any](host string) (*RemoteHost[V], error) {
|
||||
// NewRemoteHost connects to a peer node. httpPort overrides the peer's HTTP
|
||||
// port used for request proxying (defaults to "8080"); the gRPC control port
|
||||
// is always 1337.
|
||||
func NewRemoteHost[V any](host string, httpPort ...string) (*RemoteHost[V], error) {
|
||||
|
||||
port := "8080"
|
||||
if len(httpPort) > 0 && httpPort[0] != "" {
|
||||
port = httpPort[0]
|
||||
}
|
||||
|
||||
target := fmt.Sprintf("%s:1337", host)
|
||||
|
||||
@@ -85,14 +93,18 @@ func NewRemoteHost[V any](host string) (*RemoteHost[V], error) {
|
||||
transport := &http.Transport{
|
||||
MaxIdleConns: 100,
|
||||
MaxIdleConnsPerHost: 100,
|
||||
DisableKeepAlives: false,
|
||||
IdleConnTimeout: 120 * time.Second,
|
||||
// Bound concurrently-open connections to this peer so a load spike
|
||||
// can't exhaust file handles. Excess requests wait for a free conn
|
||||
// rather than opening unbounded sockets.
|
||||
MaxConnsPerHost: 256,
|
||||
DisableKeepAlives: false,
|
||||
IdleConnTimeout: 120 * time.Second,
|
||||
}
|
||||
client := &http.Client{Transport: transport, Timeout: 10 * time.Second}
|
||||
|
||||
return &RemoteHost[V]{
|
||||
host: host,
|
||||
httpBase: fmt.Sprintf("http://%s:8080", host),
|
||||
httpBase: fmt.Sprintf("http://%s:%s", host, port),
|
||||
conn: conn,
|
||||
transport: transport,
|
||||
client: client,
|
||||
@@ -101,6 +113,25 @@ func NewRemoteHost[V any](host string) (*RemoteHost[V], error) {
|
||||
}, nil
|
||||
}
|
||||
|
||||
// hopByHopHeaders are connection-specific headers that must not be forwarded
|
||||
// by a proxy (RFC 7230 §6.1).
|
||||
var hopByHopHeaders = map[string]struct{}{
|
||||
"Connection": {},
|
||||
"Proxy-Connection": {},
|
||||
"Keep-Alive": {},
|
||||
"Proxy-Authenticate": {},
|
||||
"Proxy-Authorization": {},
|
||||
"Te": {},
|
||||
"Trailer": {},
|
||||
"Transfer-Encoding": {},
|
||||
"Upgrade": {},
|
||||
}
|
||||
|
||||
func isHopByHopHeader(key string) bool {
|
||||
_, ok := hopByHopHeaders[http.CanonicalHeaderKey(key)]
|
||||
return ok
|
||||
}
|
||||
|
||||
func (h *RemoteHost[V]) Name() string {
|
||||
return h.host
|
||||
}
|
||||
@@ -277,6 +308,12 @@ func (h *RemoteHost[V]) Proxy(id uint64, w http.ResponseWriter, r *http.Request,
|
||||
req.Header.Set("X-Forwarded-Host", r.Host)
|
||||
|
||||
for k, v := range r.Header {
|
||||
if isHopByHopHeader(k) {
|
||||
// Don't forward connection-management headers (notably an inbound
|
||||
// "Connection: close" would disable keep-alive on the proxied leg
|
||||
// and churn outbound connections / file handles).
|
||||
continue
|
||||
}
|
||||
for _, vv := range v {
|
||||
req.Header.Add(k, vv)
|
||||
}
|
||||
@@ -290,6 +327,9 @@ func (h *RemoteHost[V]) Proxy(id uint64, w http.ResponseWriter, r *http.Request,
|
||||
defer res.Body.Close()
|
||||
span.SetAttributes(attribute.Int("status_code", res.StatusCode))
|
||||
for k, v := range res.Header {
|
||||
if isHopByHopHeader(k) {
|
||||
continue
|
||||
}
|
||||
for _, vv := range v {
|
||||
w.Header().Add(k, vv)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user