♻️ v3 (enhancement): replace c.Hostname() -> c.Host() & add c.Hostname() that returns host without port

This commit is contained in:
Muhammed Efe Çetin 2022-09-06 18:43:06 +03:00
parent 90c1c4c5a3
commit e3282f6408
No known key found for this signature in database
GPG Key ID: 0AA4D45CBAA86F73
7 changed files with 86 additions and 29 deletions

4
app.go
View File

@ -349,12 +349,12 @@ type Config struct {
// If request ip in TrustedProxies whitelist then:
// 1. c.Scheme() get value from X-Forwarded-Proto, X-Forwarded-Protocol, X-Forwarded-Ssl or X-Url-Scheme header
// 2. c.IP() get value from ProxyHeader header.
// 3. c.Hostname() get value from X-Forwarded-Host header
// 3. c.Host() and c.Hostname() get value from X-Forwarded-Host header
// But if request ip NOT in Trusted Proxies whitelist then:
// 1. c.Scheme() WON't get value from X-Forwarded-Proto, X-Forwarded-Protocol, X-Forwarded-Ssl or X-Url-Scheme header,
// will return https in case when tls connection is handled by the app, of http otherwise
// 2. c.IP() WON'T get value from ProxyHeader header, will return RemoteIP() from fasthttp context
// 3. c.Hostname() WON'T get value from X-Forwarded-Host header, fasthttp.Request.URI().Host()
// 3. c.Host() and c.Hostname() WON'T get value from X-Forwarded-Host header, fasthttp.Request.URI().Host()
// will be used to get the hostname.
//
// Default: false

View File

@ -31,7 +31,7 @@ func Test_Client_Invalid_URL(t *testing.T) {
app := New(Config{DisableStartupMessage: true})
app.Get("/", func(c Ctx) error {
return c.SendString(c.Hostname())
return c.SendString(c.Host())
})
go func() { require.Nil(t, app.Listener(ln)) }()
@ -69,7 +69,7 @@ func Test_Client_Get(t *testing.T) {
app := New(Config{DisableStartupMessage: true})
app.Get("/", func(c Ctx) error {
return c.SendString(c.Hostname())
return c.SendString(c.Host())
})
go func() { require.Nil(t, app.Listener(ln)) }()
@ -394,7 +394,7 @@ func Test_Client_Agent_Host(t *testing.T) {
app := New(Config{DisableStartupMessage: true})
app.Get("/", func(c Ctx) error {
return c.SendString(c.Hostname())
return c.SendString(c.Host())
})
go func() { require.Nil(t, app.Listener(ln)) }()

18
ctx.go
View File

@ -210,7 +210,7 @@ func (c *DefaultCtx) BaseURL() string {
if c.baseURI != "" {
return c.baseURI
}
c.baseURI = c.Scheme() + "://" + c.Hostname()
c.baseURI = c.Scheme() + "://" + c.Host()
return c.baseURI
}
@ -468,11 +468,11 @@ func (c *DefaultCtx) GetRespHeader(key string, defaultValue ...string) string {
return defaultString(c.app.getString(c.fasthttp.Response.Header.Peek(key)), defaultValue)
}
// Hostname contains the hostname derived from the X-Forwarded-Host or Host HTTP header.
// Host contains the host derived from the X-Forwarded-Host or Host HTTP header.
// Returned value is only valid within the handler. Do not store any references.
// Make copies or use the Immutable setting instead.
// Please use Config.EnableTrustedProxyCheck to prevent header spoofing, in case when your app is behind the proxy.
func (c *DefaultCtx) Hostname() string {
func (c *DefaultCtx) Host() string {
if c.IsProxyTrusted() {
if host := c.Get(HeaderXForwardedHost); len(host) > 0 {
return host
@ -481,6 +481,16 @@ func (c *DefaultCtx) Hostname() string {
return c.app.getString(c.fasthttp.Request.URI().Host())
}
// Hostname contains the hostname derived from the X-Forwarded-Host or Host HTTP header using the c.Host() method.
// Returned value is only valid within the handler. Do not store any references.
// Make copies or use the Immutable setting instead.
// Please use Config.EnableTrustedProxyCheck to prevent header spoofing, in case when your app is behind the proxy.
func (c *DefaultCtx) Hostname() string {
addr, _ := parseAddr(c.Host())
return addr
}
// Port returns the remote port of the request.
func (c *DefaultCtx) Port() string {
port := c.fasthttp.RemoteAddr().(*net.TCPAddr).Port
@ -1238,7 +1248,7 @@ func (c *DefaultCtx) Subdomains(offset ...int) []string {
if len(offset) > 0 {
o = offset[0]
}
subdomains := strings.Split(c.Hostname(), ".")
subdomains := strings.Split(c.Host(), ".")
l := len(subdomains) - o
// Check index to avoid slice bounds out of range panic
if l < 0 {

View File

@ -123,7 +123,13 @@ type Ctx interface {
// Make copies or use the Immutable setting instead.
GetRespHeader(key string, defaultValue ...string) string
// Hostname contains the hostname derived from the X-Forwarded-Host or Host HTTP header.
// Host contains the host derived from the X-Forwarded-Host or Host HTTP header.
// Returned value is only valid within the handler. Do not store any references.
// Make copies or use the Immutable setting instead.
// Please use Config.EnableTrustedProxyCheck to prevent header spoofing, in case when your app is behind the proxy.
Host() string
// Hostname contains the hostname derived from the X-Forwarded-Host or Host HTTP header using the c.Host() method.
// Returned value is only valid within the handler. Do not store any references.
// Make copies or use the Immutable setting instead.
// Please use Config.EnableTrustedProxyCheck to prevent header spoofing, in case when your app is behind the proxy.

View File

@ -772,18 +772,18 @@ func Test_Ctx_Get(t *testing.T) {
require.Equal(t, "default", c.Get("unknown", "default"))
}
// go test -run Test_Ctx_Hostname
func Test_Ctx_Hostname(t *testing.T) {
// go test -run Test_Ctx_Host
func Test_Ctx_Host(t *testing.T) {
t.Parallel()
app := New()
c := app.NewCtx(&fasthttp.RequestCtx{})
c.Request().SetRequestURI("http://google.com/test")
require.Equal(t, "google.com", c.Hostname())
require.Equal(t, "google.com", c.Host())
}
// go test -run Test_Ctx_Hostname_Untrusted
func Test_Ctx_Hostname_UntrustedProxy(t *testing.T) {
// go test -run Test_Ctx_Host_UntrustedProxy
func Test_Ctx_Host_UntrustedProxy(t *testing.T) {
t.Parallel()
// Don't trust any proxy
{
@ -791,7 +791,7 @@ func Test_Ctx_Hostname_UntrustedProxy(t *testing.T) {
c := app.NewCtx(&fasthttp.RequestCtx{})
c.Request().SetRequestURI("http://google.com/test")
c.Request().Header.Set(HeaderXForwardedHost, "google1.com")
require.Equal(t, "google.com", c.Hostname())
require.Equal(t, "google.com", c.Host())
app.ReleaseCtx(c)
}
// Trust to specific proxy list
@ -800,48 +800,89 @@ func Test_Ctx_Hostname_UntrustedProxy(t *testing.T) {
c := app.NewCtx(&fasthttp.RequestCtx{})
c.Request().SetRequestURI("http://google.com/test")
c.Request().Header.Set(HeaderXForwardedHost, "google1.com")
require.Equal(t, "google.com", c.Hostname())
require.Equal(t, "google.com", c.Host())
app.ReleaseCtx(c)
}
}
// go test -run Test_Ctx_Hostname_Trusted
func Test_Ctx_Hostname_TrustedProxy(t *testing.T) {
// go test -run Test_Ctx_Host_TrustedProxy
func Test_Ctx_Host_TrustedProxy(t *testing.T) {
t.Parallel()
{
app := New(Config{EnableTrustedProxyCheck: true, TrustedProxies: []string{"0.0.0.0", "0.8.0.1"}})
c := app.NewCtx(&fasthttp.RequestCtx{})
c.Request().SetRequestURI("http://google.com/test")
c.Request().Header.Set(HeaderXForwardedHost, "google1.com")
require.Equal(t, "google1.com", c.Hostname())
require.Equal(t, "google1.com", c.Host())
app.ReleaseCtx(c)
}
}
// go test -run Test_Ctx_Hostname_UntrustedProxyRange
func Test_Ctx_Hostname_TrustedProxyRange(t *testing.T) {
// go test -run Test_Ctx_Host_TrustedProxyRange
func Test_Ctx_Host_TrustedProxyRange(t *testing.T) {
t.Parallel()
app := New(Config{EnableTrustedProxyCheck: true, TrustedProxies: []string{"0.0.0.0/30"}})
c := app.NewCtx(&fasthttp.RequestCtx{})
c.Request().SetRequestURI("http://google.com/test")
c.Request().Header.Set(HeaderXForwardedHost, "google1.com")
require.Equal(t, "google1.com", c.Hostname())
require.Equal(t, "google1.com", c.Host())
app.ReleaseCtx(c)
}
// go test -run Test_Ctx_Hostname_UntrustedProxyRange
func Test_Ctx_Hostname_UntrustedProxyRange(t *testing.T) {
// go test -run Test_Ctx_Host_UntrustedProxyRange
func Test_Ctx_Host_UntrustedProxyRange(t *testing.T) {
t.Parallel()
app := New(Config{EnableTrustedProxyCheck: true, TrustedProxies: []string{"1.0.0.0/30"}})
c := app.NewCtx(&fasthttp.RequestCtx{})
c.Request().SetRequestURI("http://google.com/test")
c.Request().Header.Set(HeaderXForwardedHost, "google1.com")
require.Equal(t, "google.com", c.Hostname())
require.Equal(t, "google.com", c.Host())
app.ReleaseCtx(c)
}
// go test -v -run=^$ -bench=Benchmark_Ctx_Host -benchmem -count=4
func Benchmark_Ctx_Host(b *testing.B) {
app := New()
c := app.NewCtx(&fasthttp.RequestCtx{})
c.Request().SetRequestURI("http://google.com/test")
var host string
b.ReportAllocs()
b.ResetTimer()
for n := 0; n < b.N; n++ {
host = c.Host()
}
require.Equal(b, "google.com", host)
}
// go test -run Test_Ctx_Hostname
func Test_Ctx_Hostname(t *testing.T) {
t.Parallel()
app := New()
c := app.NewCtx(&fasthttp.RequestCtx{})
c.Request().SetRequestURI("http://google.com/test")
require.Equal(t, "google.com", c.Hostname())
c.Request().SetRequestURI("http://google.com:8080/test")
require.Equal(t, "google.com", c.Hostname())
}
// go test -v -run=^$ -bench=Benchmark_Ctx_Hostname -benchmem -count=4
func Benchmark_Ctx_Hostname(b *testing.B) {
app := New()
c := app.NewCtx(&fasthttp.RequestCtx{})
c.Request().SetRequestURI("http://google.com:8080/test")
var hostname string
b.ReportAllocs()
b.ResetTimer()
for n := 0; n < b.N; n++ {
hostname = c.Hostname()
}
require.Equal(b, "google.com", hostname)
}
// go test -run Test_Ctx_Port
func Test_Ctx_Port(t *testing.T) {
t.Parallel()

View File

@ -245,8 +245,8 @@ func testFiberToHandlerFunc(t *testing.T, checkDefaultPort bool, app ...*fiber.A
if contentLength != expectedContentLength {
t.Fatalf("unexpected contentLength %d. Expecting %d", contentLength, expectedContentLength)
}
if c.Hostname() != expectedHost {
t.Fatalf("unexpected host %q. Expecting %q", c.Hostname(), expectedHost)
if c.Host() != expectedHost {
t.Fatalf("unexpected host %q. Expecting %q", c.Host(), expectedHost)
}
remoteAddr := c.Context().RemoteAddr().String()
if remoteAddr != expectedRemoteAddr {

View File

@ -88,7 +88,7 @@ func defaultLogger(c fiber.Ctx, data LoggerData, cfg Config) error {
case TagIPs:
return buf.WriteString(c.Get(fiber.HeaderXForwardedFor))
case TagHost:
return buf.WriteString(c.Hostname())
return buf.WriteString(c.Host())
case TagPath:
return buf.WriteString(c.Path())
case TagURL: