NewSingleHostReverseProxy sets only X-Forwarded-For, so a backend that writes its own addresses saw the plain hop from the proxy: Gitea's Go import tag named an http clone URL and go get refused the SDK's module path. The proxy now sets X-Forwarded-Proto, -Host and -For from the request it received, and keeps the Host header as it was.
30 lines
1.2 KiB
Go
30 lines
1.2 KiB
Go
package main
|
|
|
|
import (
|
|
"crypto/tls"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"net/url"
|
|
"testing"
|
|
)
|
|
|
|
// A backend behind the proxy learns the client used TLS and which name it asked for, so the addresses
|
|
// it writes into its own pages are the ones a client can use (2026-10-03: a forge's Go import tag
|
|
// named an http clone URL, and Go refused the module path).
|
|
func TestABackendIsToldTheRequestWasHTTPSAndForWhichName(t *testing.T) {
|
|
var proto, host, fwdHost, fwdFor string
|
|
backend := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
proto, host, fwdHost, fwdFor = r.Header.Get("X-Forwarded-Proto"), r.Host, r.Header.Get("X-Forwarded-Host"), r.Header.Get("X-Forwarded-For")
|
|
}))
|
|
defer backend.Close()
|
|
where, _ := url.Parse(backend.URL)
|
|
req := httptest.NewRequest(http.MethodGet, "https://git.example.org/novox/mesh-sdk/go?go-get=1", nil)
|
|
req.TLS = &tls.ConnectionState{}
|
|
req.Host = "git.example.org"
|
|
req.RemoteAddr = "192.0.2.7:51000"
|
|
towards(where).ServeHTTP(httptest.NewRecorder(), req)
|
|
if proto != "https" || fwdHost != "git.example.org" || host != "git.example.org" || fwdFor != "192.0.2.7" {
|
|
t.Errorf("the backend was told proto=%q host=%q forwarded-host=%q for=%q", proto, host, fwdHost, fwdFor)
|
|
}
|
|
}
|