fix: replace nil with http.NoBody in various test cases for consistency
This commit is contained in:
@@ -197,7 +197,9 @@ func TestRecoveryNoPanicNormalFlow(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// TestRecoveryPanicWithNilValue tests recovery from panic(nil).
|
||||
// TestRecoveryPanicWithNilValue tests recovery from panic with a nil-like value.
|
||||
// Note: panic(nil) behavior changed in Go 1.21+ and triggers linter warnings,
|
||||
// so we use an explicit error value instead.
|
||||
func TestRecoveryPanicWithNilValue(t *testing.T) {
|
||||
old := log.Writer()
|
||||
buf := &bytes.Buffer{}
|
||||
@@ -210,22 +212,20 @@ func TestRecoveryPanicWithNilValue(t *testing.T) {
|
||||
router.Use(RequestID())
|
||||
router.Use(Recovery(false))
|
||||
router.GET("/panic-nil", func(c *gin.Context) {
|
||||
panic(nil)
|
||||
panic("intentional test panic with nil-like value")
|
||||
})
|
||||
|
||||
req := httptest.NewRequest(http.MethodGet, "/panic-nil", http.NoBody)
|
||||
w := httptest.NewRecorder()
|
||||
router.ServeHTTP(w, req)
|
||||
|
||||
// panic(nil) does not trigger recovery in Go 1.21+ (returns nil from recover())
|
||||
// Prior versions would catch it. This test documents the expected behavior.
|
||||
// With Go 1.21+, the request should complete normally since recover() returns nil
|
||||
if w.Code == http.StatusInternalServerError {
|
||||
out := buf.String()
|
||||
// If it was caught, should log the nil panic
|
||||
if !strings.Contains(out, "PANIC") {
|
||||
t.Log("panic(nil) was caught but no PANIC in log")
|
||||
}
|
||||
// Verify the panic was recovered and returned 500
|
||||
if w.Code != http.StatusInternalServerError {
|
||||
t.Errorf("expected status 500, got %d", w.Code)
|
||||
}
|
||||
|
||||
out := buf.String()
|
||||
if !strings.Contains(out, "PANIC") {
|
||||
t.Error("expected PANIC in log output")
|
||||
}
|
||||
// Either outcome is acceptable depending on Go version
|
||||
}
|
||||
|
||||
@@ -171,7 +171,7 @@ func TestSecurityHeaders_COOP_DevelopmentMode(t *testing.T) {
|
||||
c.Status(http.StatusOK)
|
||||
})
|
||||
|
||||
req := httptest.NewRequest("GET", "/test", nil)
|
||||
req := httptest.NewRequest("GET", "/test", http.NoBody)
|
||||
resp := httptest.NewRecorder()
|
||||
router.ServeHTTP(resp, req)
|
||||
|
||||
@@ -188,7 +188,7 @@ func TestSecurityHeaders_COOP_ProductionMode(t *testing.T) {
|
||||
c.Status(http.StatusOK)
|
||||
})
|
||||
|
||||
req := httptest.NewRequest("GET", "/test", nil)
|
||||
req := httptest.NewRequest("GET", "/test", http.NoBody)
|
||||
resp := httptest.NewRecorder()
|
||||
router.ServeHTTP(resp, req)
|
||||
|
||||
|
||||
@@ -1286,11 +1286,12 @@ func buildPermissionsPolicyString(permissionsJSON string) (string, error) {
|
||||
// Convert allowlist items to policy format
|
||||
items := make([]string, len(perm.Allowlist))
|
||||
for i, item := range perm.Allowlist {
|
||||
if item == "self" {
|
||||
switch item {
|
||||
case "self":
|
||||
items[i] = "self"
|
||||
} else if item == "*" {
|
||||
case "*":
|
||||
items[i] = "*"
|
||||
} else {
|
||||
default:
|
||||
items[i] = fmt.Sprintf("\"%s\"", item)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -372,7 +372,7 @@ func TestValidateRedirectTarget_EmptyHostname(t *testing.T) {
|
||||
}
|
||||
|
||||
// Create request with empty hostname
|
||||
req, _ := http.NewRequest("GET", "http:///path", nil)
|
||||
req, _ := http.NewRequest("GET", "http:///path", http.NoBody)
|
||||
err := validateRedirectTarget(req, opts)
|
||||
if err == nil {
|
||||
t.Error("expected error for empty hostname")
|
||||
@@ -386,7 +386,7 @@ func TestValidateRedirectTarget_Localhost(t *testing.T) {
|
||||
}
|
||||
|
||||
// Test localhost blocked
|
||||
req, _ := http.NewRequest("GET", "http://localhost/path", nil)
|
||||
req, _ := http.NewRequest("GET", "http://localhost/path", http.NoBody)
|
||||
err := validateRedirectTarget(req, opts)
|
||||
if err == nil {
|
||||
t.Error("expected error for localhost when AllowLocalhost=false")
|
||||
@@ -406,7 +406,7 @@ func TestValidateRedirectTarget_127(t *testing.T) {
|
||||
DialTimeout: time.Second,
|
||||
}
|
||||
|
||||
req, _ := http.NewRequest("GET", "http://127.0.0.1/path", nil)
|
||||
req, _ := http.NewRequest("GET", "http://127.0.0.1/path", http.NoBody)
|
||||
err := validateRedirectTarget(req, opts)
|
||||
if err == nil {
|
||||
t.Error("expected error for 127.0.0.1 when AllowLocalhost=false")
|
||||
@@ -425,7 +425,7 @@ func TestValidateRedirectTarget_IPv6Loopback(t *testing.T) {
|
||||
DialTimeout: time.Second,
|
||||
}
|
||||
|
||||
req, _ := http.NewRequest("GET", "http://[::1]/path", nil)
|
||||
req, _ := http.NewRequest("GET", "http://[::1]/path", http.NoBody)
|
||||
err := validateRedirectTarget(req, opts)
|
||||
if err == nil {
|
||||
t.Error("expected error for ::1 when AllowLocalhost=false")
|
||||
@@ -550,7 +550,7 @@ func TestValidateRedirectTarget_DNSFailure(t *testing.T) {
|
||||
}
|
||||
|
||||
// Use a domain that will fail DNS resolution
|
||||
req, _ := http.NewRequest("GET", "http://this-domain-does-not-exist-12345.invalid/path", nil)
|
||||
req, _ := http.NewRequest("GET", "http://this-domain-does-not-exist-12345.invalid/path", http.NoBody)
|
||||
err := validateRedirectTarget(req, opts)
|
||||
if err == nil {
|
||||
t.Error("expected error for DNS resolution failure")
|
||||
@@ -578,7 +578,7 @@ func TestValidateRedirectTarget_PrivateIPInRedirect(t *testing.T) {
|
||||
|
||||
for _, url := range privateHosts {
|
||||
t.Run(url, func(t *testing.T) {
|
||||
req, _ := http.NewRequest("GET", url, nil)
|
||||
req, _ := http.NewRequest("GET", url, http.NoBody)
|
||||
err := validateRedirectTarget(req, opts)
|
||||
if err == nil {
|
||||
t.Errorf("expected error for redirect to private IP: %s", url)
|
||||
@@ -725,7 +725,7 @@ func TestValidateRedirectTarget_AllowedLocalhost(t *testing.T) {
|
||||
|
||||
for _, url := range localhostURLs {
|
||||
t.Run(url, func(t *testing.T) {
|
||||
req, _ := http.NewRequest("GET", url, nil)
|
||||
req, _ := http.NewRequest("GET", url, http.NoBody)
|
||||
err := validateRedirectTarget(req, opts)
|
||||
if err != nil {
|
||||
t.Errorf("expected no error for %s when AllowLocalhost=true, got: %v", url, err)
|
||||
|
||||
@@ -43,7 +43,7 @@ func TestGetPublicURL_WithConfiguredURL(t *testing.T) {
|
||||
gin.SetMode(gin.TestMode)
|
||||
w := httptest.NewRecorder()
|
||||
c, _ := gin.CreateTestContext(w)
|
||||
req := httptest.NewRequest(http.MethodGet, "http://localhost:8080/test", nil)
|
||||
req := httptest.NewRequest(http.MethodGet, "http://localhost:8080/test", http.NoBody)
|
||||
c.Request = req
|
||||
|
||||
// Test GetPublicURL
|
||||
@@ -68,7 +68,7 @@ func TestGetPublicURL_WithTrailingSlash(t *testing.T) {
|
||||
gin.SetMode(gin.TestMode)
|
||||
w := httptest.NewRecorder()
|
||||
c, _ := gin.CreateTestContext(w)
|
||||
req := httptest.NewRequest(http.MethodGet, "http://localhost:8080/test", nil)
|
||||
req := httptest.NewRequest(http.MethodGet, "http://localhost:8080/test", http.NoBody)
|
||||
c.Request = req
|
||||
|
||||
publicURL := GetPublicURL(db, c)
|
||||
@@ -87,7 +87,7 @@ func TestGetPublicURL_Fallback_HTTPSWithTLS(t *testing.T) {
|
||||
c, _ := gin.CreateTestContext(w)
|
||||
|
||||
// Create request with TLS
|
||||
req := httptest.NewRequest(http.MethodGet, "https://myapp.com:8443/path", nil)
|
||||
req := httptest.NewRequest(http.MethodGet, "https://myapp.com:8443/path", http.NoBody)
|
||||
req.TLS = &tls.ConnectionState{} // Simulate TLS connection
|
||||
c.Request = req
|
||||
|
||||
@@ -104,7 +104,7 @@ func TestGetPublicURL_Fallback_HTTP(t *testing.T) {
|
||||
gin.SetMode(gin.TestMode)
|
||||
w := httptest.NewRecorder()
|
||||
c, _ := gin.CreateTestContext(w)
|
||||
req := httptest.NewRequest(http.MethodGet, "http://localhost:8080/test", nil)
|
||||
req := httptest.NewRequest(http.MethodGet, "http://localhost:8080/test", http.NoBody)
|
||||
c.Request = req
|
||||
|
||||
publicURL := GetPublicURL(db, c)
|
||||
@@ -120,7 +120,7 @@ func TestGetPublicURL_Fallback_XForwardedProto(t *testing.T) {
|
||||
gin.SetMode(gin.TestMode)
|
||||
w := httptest.NewRecorder()
|
||||
c, _ := gin.CreateTestContext(w)
|
||||
req := httptest.NewRequest(http.MethodGet, "http://internal-server:8080/test", nil)
|
||||
req := httptest.NewRequest(http.MethodGet, "http://internal-server:8080/test", http.NoBody)
|
||||
req.Header.Set("X-Forwarded-Proto", "https")
|
||||
c.Request = req
|
||||
|
||||
@@ -145,7 +145,7 @@ func TestGetPublicURL_EmptyValue(t *testing.T) {
|
||||
gin.SetMode(gin.TestMode)
|
||||
w := httptest.NewRecorder()
|
||||
c, _ := gin.CreateTestContext(w)
|
||||
req := httptest.NewRequest(http.MethodGet, "http://localhost:9000/test", nil)
|
||||
req := httptest.NewRequest(http.MethodGet, "http://localhost:9000/test", http.NoBody)
|
||||
c.Request = req
|
||||
|
||||
publicURL := GetPublicURL(db, c)
|
||||
@@ -162,7 +162,7 @@ func TestGetPublicURL_NoSettingInDB(t *testing.T) {
|
||||
gin.SetMode(gin.TestMode)
|
||||
w := httptest.NewRecorder()
|
||||
c, _ := gin.CreateTestContext(w)
|
||||
req := httptest.NewRequest(http.MethodGet, "http://fallback-host.com/test", nil)
|
||||
req := httptest.NewRequest(http.MethodGet, "http://fallback-host.com/test", http.NoBody)
|
||||
c.Request = req
|
||||
|
||||
publicURL := GetPublicURL(db, c)
|
||||
@@ -423,7 +423,7 @@ func TestGetBaseURL(t *testing.T) {
|
||||
if tc.hasTLS {
|
||||
scheme = "https"
|
||||
}
|
||||
req := httptest.NewRequest(http.MethodGet, scheme+"://"+tc.host+"/test", nil)
|
||||
req := httptest.NewRequest(http.MethodGet, scheme+"://"+tc.host+"/test", http.NoBody)
|
||||
|
||||
// Set TLS if needed
|
||||
if tc.hasTLS {
|
||||
@@ -451,7 +451,7 @@ func TestGetBaseURL_PrecedenceOrder(t *testing.T) {
|
||||
c, _ := gin.CreateTestContext(w)
|
||||
|
||||
// Request with TLS but also X-Forwarded-Proto
|
||||
req := httptest.NewRequest(http.MethodGet, "https://example.com/test", nil)
|
||||
req := httptest.NewRequest(http.MethodGet, "https://example.com/test", http.NoBody)
|
||||
req.TLS = &tls.ConnectionState{}
|
||||
req.Header.Set("X-Forwarded-Proto", "http") // Should be ignored when TLS is present
|
||||
c.Request = req
|
||||
@@ -467,7 +467,7 @@ func TestGetBaseURL_EmptyHost(t *testing.T) {
|
||||
gin.SetMode(gin.TestMode)
|
||||
w := httptest.NewRecorder()
|
||||
c, _ := gin.CreateTestContext(w)
|
||||
req := httptest.NewRequest(http.MethodGet, "http:///test", nil)
|
||||
req := httptest.NewRequest(http.MethodGet, "http:///test", http.NoBody)
|
||||
req.Host = "" // Empty host
|
||||
c.Request = req
|
||||
|
||||
|
||||
@@ -173,7 +173,7 @@ func TestURLConnectivity(rawURL string, transport ...http.RoundTripper) (reachab
|
||||
// Transform error message for backward compatibility with existing tests
|
||||
// The security package uses lowercase in error messages, but tests expect mixed case
|
||||
errMsg = strings.Replace(errMsg, "dns resolution failed", "DNS resolution failed", 1)
|
||||
errMsg = strings.Replace(errMsg, "private ip", "private IP", -1)
|
||||
errMsg = strings.ReplaceAll(errMsg, "private ip", "private IP")
|
||||
// Cloud metadata endpoints are considered private IPs for test compatibility
|
||||
if strings.Contains(errMsg, "cloud metadata endpoints") {
|
||||
errMsg = strings.Replace(errMsg, "access to cloud metadata endpoints is blocked for security", "connection to private IP addresses is blocked for security", 1)
|
||||
@@ -235,7 +235,7 @@ func TestURLConnectivity(rawURL string, transport ...http.RoundTripper) (reachab
|
||||
// Perform HTTP HEAD request with strict timeout
|
||||
ctx := context.Background()
|
||||
start := time.Now()
|
||||
req, err := http.NewRequestWithContext(ctx, http.MethodHead, requestURL, nil)
|
||||
req, err := http.NewRequestWithContext(ctx, http.MethodHead, requestURL, http.NoBody)
|
||||
if err != nil {
|
||||
return false, 0, fmt.Errorf("failed to create request: %w", err)
|
||||
}
|
||||
|
||||
@@ -331,7 +331,7 @@ func TestValidateRedirectTarget(t *testing.T) {
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
// Create a request for the redirect target
|
||||
req, err := http.NewRequest("GET", tt.url, nil)
|
||||
req, err := http.NewRequest("GET", tt.url, http.NoBody)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to create request: %v", err)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user