Repository: corazawaf/coraza (go)

Issue:
Expose ErrorLogCallback
`coraza.ErrorLogCallback` was moved to internal package, but it's used in a public interface. Please expose it again.

Pull request description:
chore: dropping internal logger type used in the public API.
I went for removing the type as it was meaningless IMO.

Closes #555


Patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index cf1ed95..8f7e29b 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -24,7 +24,7 @@ IMPROVEMENTS:
 
 NOTES:
 
-**Migrate from Corza v1**
+**Migrate from Coraza v1**
 
 * Rollback `SecAuditLog` to the legacy syntax (serial/concurrent)
 * Attach an error log handler using `waf.SetErrorLogCb(cb)` (optional)
diff --git a/config.go b/config.go
index 2503818..ceda8fb 100644
--- a/config.go
+++ b/config.go
@@ -39,8 +39,10 @@ type WAFConfig interface {
 	// WithDebugLogger configures a debug logger.
 	WithDebugLogger(logger loggers.DebugLogger) WAFConfig
 
-	// WithErrorLogger configures an error logger.
-	WithErrorLogger(logger corazawaf.ErrorLogCallback) WAFConfig
+	// WithErrorCallback configures an error callback that can be used
+	// to log errors triggered by the WAF.
+	// It contains the severity so the cb can decide to skip it or not
+	WithErrorCallback(logger func(rule types.MatchedRule)) WAFConfig
 
 	// WithRootFS configures the root file system.
 	WithRootFS(fs fs.FS) WAFConfig
@@ -110,7 +112,7 @@ type wafConfig struct {
 	requestBody      *requestBodyConfig
 	responseBody     *responseBodyConfig
 	debugLogger      loggers.DebugLogger
-	errorLogger      corazawaf.ErrorLogCallback
+	errorCallback    func(rule types.MatchedRule)
 	fsRoot           fs.FS
 }
 
@@ -168,9 +170,9 @@ func (c *wafConfig) WithDebugLogger(logger loggers.DebugLogger) WAFConfig {
 	return ret
 }
 
-func (c *wafConfig) WithErrorLogger(logger corazawaf.ErrorLogCallback) WAFConfig {
+func (c *wafConfig) WithErrorCallback(logger func(rule types.MatchedRule)) WAFConfig {
 	ret := c.clone()
-	ret.errorLogger = logger
+	ret.errorCallback = logger
 	return ret
 }
 
diff --git a/examples/http-server/main.go b/examples/http-server/main.go
index fb5fc6a..4325ec7 100644
--- a/examples/http-server/main.go
+++ b/examples/http-server/main.go
@@ -47,7 +47,7 @@ func createWAF() coraza.WAF {
 
 	waf, err := coraza.NewWAF(
 		coraza.NewWAFConfig().
-			WithErrorLogger(logError).
+			WithErrorCallback(logError).
 			WithDirectivesFromFile(directivesFile),
 	)
 	if err != nil {
diff --git a/internal/corazawaf/waf.go b/internal/corazawaf/waf.go
index e5823f5..d7ae178 100644
--- a/internal/corazawaf/waf.go
+++ b/internal/corazawaf/waf.go
@@ -21,10 +21,8 @@ import (
 	"github.com/corazawaf/coraza/v3/types"
 )
 
-// ErrorLogCallback is used to set a callback function to log errors
-// It is triggered when an error is raised by the WAF
-// It contains the severity so the cb can decide to log it or not
-type ErrorLogCallback = func(rule types.MatchedRule)
+// Initializing pool for transactions
+var transactionPool = sync.NewPool(func() interface{} { return new(Transaction) })
 
 // WAF instance is used to store configurations and rules
 // Every web application should have a different WAF instance,
@@ -128,7 +126,7 @@ type WAF struct {
 	// Used for the debug logger
 	Logger loggers.DebugLogger
 
-	ErrorLogCb ErrorLogCallback
+	ErrorLogCb func(rule types.MatchedRule)
 
 	// AuditLogWriter is used to write audit logs
 	AuditLogWriter loggers.LogWriter
@@ -305,9 +303,9 @@ func (w *WAF) SetDebugLogLevel(lvl int) error {
 	return nil
 }
 
-// SetErrorLogCb sets the callback function for error logging
+// SetErrorCallback sets the callback function for error logging
 // The error callback receives all the error data and some
 // helpers to write modsecurity style logs
-func (w *WAF) SetErrorLogCb(cb ErrorLogCallback) {
+func (w *WAF) SetErrorCallback(cb func(rule types.MatchedRule)) {
 	w.ErrorLogCb = cb
 }
diff --git a/waf.go b/waf.go
index c630428..9eb7572 100644
--- a/waf.go
+++ b/waf.go
@@ -91,8 +91,8 @@ func NewWAF(config WAFConfig) (WAF, error) {
 		waf.ResponseBodyLimit = int64(r.limit)
 	}
 
-	if c.errorLogger != nil {
-		waf.ErrorLogCb = c.errorLogger
+	if c.errorCallback != nil {
+		waf.ErrorLogCb = c.errorCallback
 	}
 
 	return wafWrapper{waf: waf}, nil


Test patch:
diff --git a/http/middleware_test.go b/http/middleware_test.go
index a72bf67..bafe8f8 100644
--- a/http/middleware_test.go
+++ b/http/middleware_test.go
@@ -298,7 +298,7 @@ func TestHttpServer(t *testing.T) {
 		SecRule REQUEST_BODY "@contains eval" "id:100, phase:2,deny, status:403,msg:'Invalid request body',log,auditlog"
 		SecRule RESPONSE_HEADERS:Foo "@pm bar" "id:199,phase:3,deny,t:lowercase,deny, status:401,msg:'Invalid response header',log,auditlog"
 		SecRule RESPONSE_BODY "@contains password" "id:200, phase:4,deny, status:403,msg:'Invalid response body',log,auditlog"
-	`).WithErrorLogger(errLogger(t)).WithDebugLogger(&debugLogger{t: t})
+	`).WithErrorCallback(errLogger(t)).WithDebugLogger(&debugLogger{t: t})
 			if l := tCase.reqBodyLimit; l > 0 {
 				conf = conf.WithRequestBodyAccess(coraza.NewRequestBodyConfig().WithLimit(l).WithInMemoryLimit(l))
 			}
@@ -345,7 +345,7 @@ func TestHttpServerWithRuleEngineOff(t *testing.T) {
 			SecRequestBodyAccess On
 			SecRule ARGS:id "@eq 0" "id:1, phase:1,deny, status:403,msg:'Invalid id',log,auditlog"
 			SecRule REQUEST_BODY "@contains eval" "id:100, phase:2,deny, status:403,msg:'Invalid request body',log,auditlog"
-			`).WithErrorLogger(errLogger(t)).WithDebugLogger(&debugLogger{t: t}))
+			`).WithErrorCallback(errLogger(t)).WithDebugLogger(&debugLogger{t: t}))
 			if err != nil {
 				t.Fatal(err)
 			}
diff --git a/internal/corazawaf/transaction_test.go b/internal/corazawaf/transaction_test.go
index ec05271..ab95f20 100644
--- a/internal/corazawaf/transaction_test.go
+++ b/internal/corazawaf/transaction_test.go
@@ -357,7 +357,7 @@ func TestRelevantAuditLogging(t *testing.T) {
 func TestLogCallback(t *testing.T) {
 	waf := NewWAF()
 	buffer := ""
-	waf.SetErrorLogCb(func(mr types.MatchedRule) {
+	waf.SetErrorCallback(func(mr types.MatchedRule) {
 		buffer = mr.ErrorLog(403)
 	})
 	tx := waf.NewTransaction()
diff --git a/internal/seclang/rules_test.go b/internal/seclang/rules_test.go
index 61099eb..d2474bf 100644
--- a/internal/seclang/rules_test.go
+++ b/internal/seclang/rules_test.go
@@ -131,7 +131,7 @@ func TestSecAuditLogs(t *testing.T) {
 func TestRuleLogging(t *testing.T) {
 	waf := corazawaf.NewWAF()
 	var logs []string
-	waf.SetErrorLogCb(func(mr types.MatchedRule) {
+	waf.SetErrorCallback(func(mr types.MatchedRule) {
 		logs = append(logs, mr.ErrorLog(403))
 	})
 	parser := NewParser(waf)
@@ -192,7 +192,7 @@ func TestRuleChains(t *testing.T) {
 func TestTagsAreNotPrintedTwice(t *testing.T) {
 	waf := corazawaf.NewWAF()
 	var logs []string
-	waf.SetErrorLogCb(func(mr types.MatchedRule) {
+	waf.SetErrorCallback(func(mr types.MatchedRule) {
 		logs = append(logs, mr.ErrorLog(403))
 	})
 	parser := NewParser(waf)
@@ -224,7 +224,7 @@ func TestTagsAreNotPrintedTwice(t *testing.T) {
 func TestStatusFromInterruptions(t *testing.T) {
 	waf := corazawaf.NewWAF()
 	var logs []string
-	waf.SetErrorLogCb(func(mr types.MatchedRule) {
+	waf.SetErrorCallback(func(mr types.MatchedRule) {
 		logs = append(logs, mr.ErrorLog(403))
 	})
 	parser := NewParser(waf)
@@ -262,7 +262,7 @@ func TestChainWithUnconditionalMatch(t *testing.T) {
 func TestLogsAreNotPrintedManyTimes(t *testing.T) {
 	waf := corazawaf.NewWAF()
 	var logs []string
-	waf.SetErrorLogCb(func(mr types.MatchedRule) {
+	waf.SetErrorCallback(func(mr types.MatchedRule) {
 		logs = append(logs, mr.ErrorLog(403))
 	})
 	parser := NewParser(waf)
diff --git a/testing/coreruleset/coreruleset_test.go b/testing/coreruleset/coreruleset_test.go
index d89d6cd..23d40d5 100644
--- a/testing/coreruleset/coreruleset_test.go
+++ b/testing/coreruleset/coreruleset_test.go
@@ -217,7 +217,7 @@ SecRule REQUEST_HEADERS:X-CRS-Test "@rx ^.*$" \
 		t.Fatalf("failed to create error log: %v", err)
 	}
 	errorWriter := bufio.NewWriter(errorFile)
-	conf = conf.WithErrorLogger(func(rule types.MatchedRule) {
+	conf = conf.WithErrorCallback(func(rule types.MatchedRule) {
 		msg := rule.ErrorLog(0)
 		if _, err := io.WriteString(errorWriter, msg); err != nil {
 			t.Fatal(err)