mirror of
https://github.com/TwiN/gatus.git
synced 2026-02-15 06:50:07 +00:00
fix: handle HTTP header names case-insensitively (#1506)
Details: HTTP header names should be case-insensitive per RFC 7230. When the users configure the headers like 'user-agent' (lowercase), gatus was adding its own 'User-Agent' header because the case-sensitive map lookup failed to find the existing header. Fixed headers: - User-Agent - Content-Type - Host Fixes #1491" Co-authored-by: TwiN <twin@linux.com>
This commit is contained in:
@@ -21,6 +21,30 @@ import (
|
||||
"github.com/TwiN/gatus/v5/test"
|
||||
)
|
||||
|
||||
func TestHasHeader(t *testing.T) {
|
||||
scenarios := []struct {
|
||||
name string
|
||||
headers map[string]string
|
||||
lookup string
|
||||
expected bool
|
||||
}{
|
||||
{name: "exact-match", headers: map[string]string{"User-Agent": "test"}, lookup: "User-Agent", expected: true},
|
||||
{name: "lowercase-lookup", headers: map[string]string{"User-Agent": "test"}, lookup: "user-agent", expected: true},
|
||||
{name: "uppercase-lookup", headers: map[string]string{"user-agent": "test"}, lookup: "USER-AGENT", expected: true},
|
||||
{name: "mixed-case", headers: map[string]string{"UsEr-AgEnT": "test"}, lookup: "uSeR-aGeNt", expected: true},
|
||||
{name: "not-found", headers: map[string]string{"Content-Type": "test"}, lookup: "User-Agent", expected: false},
|
||||
{name: "empty-headers", headers: map[string]string{}, lookup: "User-Agent", expected: false},
|
||||
{name: "nil-headers", headers: nil, lookup: "User-Agent", expected: false},
|
||||
}
|
||||
for _, scenario := range scenarios {
|
||||
t.Run(scenario.name, func(t *testing.T) {
|
||||
if result := hasHeader(scenario.headers, scenario.lookup); result != scenario.expected {
|
||||
t.Errorf("expected %v, got %v", scenario.expected, result)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestEndpoint(t *testing.T) {
|
||||
defer client.InjectHTTPClient(nil)
|
||||
scenarios := []struct {
|
||||
@@ -722,6 +746,76 @@ func TestEndpoint_buildHTTPRequestWithHostHeader(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestEndpoint_buildHTTPRequestWithLowercaseUserAgent(t *testing.T) {
|
||||
condition := Condition("[STATUS] == 200")
|
||||
endpoint := Endpoint{
|
||||
Name: "website-health",
|
||||
URL: "https://twin.sh/health",
|
||||
Conditions: []Condition{condition},
|
||||
Headers: map[string]string{
|
||||
"user-agent": "CustomAgent/1.0",
|
||||
},
|
||||
}
|
||||
err := endpoint.ValidateAndSetDefaults()
|
||||
if err != nil {
|
||||
t.Fatal("did not expect an error, got", err)
|
||||
}
|
||||
if _, exists := endpoint.Headers[UserAgentHeader]; exists {
|
||||
t.Error("User-Agent header should not have been added since user-agent was already specified")
|
||||
}
|
||||
request := endpoint.buildHTTPRequest()
|
||||
if userAgent := request.Header.Get("User-Agent"); userAgent != "CustomAgent/1.0" {
|
||||
t.Errorf("request.Header.Get(User-Agent) should've been CustomAgent/1.0, but was %s", userAgent)
|
||||
}
|
||||
}
|
||||
|
||||
func TestEndpoint_buildHTTPRequestWithLowercaseContentType(t *testing.T) {
|
||||
condition := Condition("[STATUS] == 200")
|
||||
endpoint := Endpoint{
|
||||
Name: "website-graphql",
|
||||
URL: "https://twin.sh/graphql",
|
||||
Method: "POST",
|
||||
Conditions: []Condition{condition},
|
||||
GraphQL: true,
|
||||
Headers: map[string]string{
|
||||
"content-type": "application/graphql",
|
||||
},
|
||||
Body: `{ users { id } }`,
|
||||
}
|
||||
err := endpoint.ValidateAndSetDefaults()
|
||||
if err != nil {
|
||||
t.Fatal("did not expect an error, got", err)
|
||||
}
|
||||
if _, exists := endpoint.Headers[ContentTypeHeader]; exists {
|
||||
t.Error("Content-Type header should not have been added since content-type was already specified")
|
||||
}
|
||||
request := endpoint.buildHTTPRequest()
|
||||
if contentType := request.Header.Get("Content-Type"); contentType != "application/graphql" {
|
||||
t.Errorf("request.Header.Get(Content-Type) should've been application/graphql, but was %s", contentType)
|
||||
}
|
||||
}
|
||||
|
||||
func TestEndpoint_buildHTTPRequestWithLowercaseHostHeader(t *testing.T) {
|
||||
condition := Condition("[STATUS] == 200")
|
||||
endpoint := Endpoint{
|
||||
Name: "website-health",
|
||||
URL: "https://twin.sh/health",
|
||||
Method: "POST",
|
||||
Conditions: []Condition{condition},
|
||||
Headers: map[string]string{
|
||||
"host": "example.com",
|
||||
},
|
||||
}
|
||||
err := endpoint.ValidateAndSetDefaults()
|
||||
if err != nil {
|
||||
t.Fatal("did not expect an error, got", err)
|
||||
}
|
||||
request := endpoint.buildHTTPRequest()
|
||||
if request.Host != "example.com" {
|
||||
t.Error("request.Host should've been example.com, but was", request.Host)
|
||||
}
|
||||
}
|
||||
|
||||
func TestEndpoint_buildHTTPRequestWithGraphQLEnabled(t *testing.T) {
|
||||
condition := Condition("[STATUS] == 200")
|
||||
endpoint := Endpoint{
|
||||
|
||||
Reference in New Issue
Block a user