ronantakizawa/codereview-bench huggingface dataset:
Repository: traefik/traefik
File: pkg/server/server_entrypoint_tcp.go (Go)

Code before:
			h.ServeHTTP(rw, r2)
		} else {
			h.ServeHTTP(rw, req)
		}
	})
}

// When go receives an HTTP request, it assumes the absence of fragment URL.
// However, it is still possible to send a fragment in the request.
// In this case, Traefik will encode the '#' character, altering the request's intended meaning.
// To avoid this behavior, the following function rejects requests that include a fragment in the URL.
func denyFragment(h http.Handler) http.Handler {
	return http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
		if strings.Contains(req.URL.RawPath, "#") {
			log.WithoutContext().Debugf("Rejecting request because it contains a fragment in the URL path: %s", req.URL.RawPath)
			rw.WriteHeader(http.StatusBadRequest)

			return
		}

		h.ServeHTTP(rw, req)
	})
}

// cleanPath is a http.Handler that cleans the URL path.
// It cleans the request URL path and rawPath, and updates the request URI.
func cleanPath(h http.Handler) http.Handler {
	return http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
		r2 := new(http.Request)
		*r2 = *req
		r2.URL = new(url.URL)
		*r2.URL = *req.URL

		r2.URL.Path = path.Clean(req.URL.Path)
		if r2.URL.Path != req.URL.Path && req.URL.RawPath != "" {
			r2.URL.RawPath = url.PathEscape(r2.URL.Path)
		}
		// Because the reverse proxy director is building query params from requestURI it needs to be updated as well.
		r2.RequestURI = r2.URL.RequestURI()

		h.ServeHTTP(rw, r2)
	})
}


Review comment (suggestion):
```suggestion
// It cleans the request URL Path and RawPath, and updates the request URI.
```

Code after:
			r2.RequestURI = r2.URL.RequestURI()

			h.ServeHTTP(rw, r2)
		} else {
			h.ServeHTTP(rw, req)
		}
	})
}

// When go receives an HTTP request, it assumes the absence of fragment URL.
// However, it is still possible to send a fragment in the request.
// In this case, Traefik will encode the '#' character, altering the request's intended meaning.
// To avoid this behavior, the following function rejects requests that include a fragment in the URL.
func denyFragment(h http.Handler) http.Handler {
	return http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
		if strings.Contains(req.URL.RawPath, "#") {
			log.WithoutContext().Debugf("Rejecting request because it contains a fragment in the URL path: %s", req.URL.RawPath)
			rw.WriteHeader(http.StatusBadRequest)

			return
		}

		h.ServeHTTP(rw, req)
	})
}

// sanitizePath removes the "..", "." and duplicate slash segments from the URL.
// It cleans the request URL Path and RawPath, and updates the request URI.
func sanitizePath(h http.Handler) http.Handler {
	return http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
		r2 := new(http.Request)
		*r2 = *req

		// Cleans the URL raw path and path.
		r2.URL = r2.URL.JoinPath()

		// Because the reverse proxy director is building query params from requestURI it needs to be updated as well.
		r2.RequestURI = r2.URL.RequestURI()

		h.ServeHTTP(rw, r2)
	})
}
Repository: traefik/traefik
File: cmd/healthcheck/healthcheck.go (Go)

Code before:
package healthcheck

import (
	"errors"
	"flag"
	"fmt"
	"net/http"
	"os"
	"time"

	"github.com/traefik/paerser/cli"
	"github.com/traefik/traefik/v3/pkg/config/static"
)

// NewCmd builds a new HealthCheck command.
func NewCmd(traefikConfiguration *static.Configuration, loaders []cli.ResourceLoader) *cli.Command {
	return &cli.Command{
		Name:          "healthcheck",
		Description:   `Calls Traefik /ping endpoint (disabled by default) to check the health of Traefik.`,
		Configuration: traefikConfiguration,
		Run:           runCmd(traefikConfiguration),
		Resources:     loaders,
		AllowArg:      true,
	}
}

func runCmd(traefikConfiguration *static.Configuration) func(args []string) error {
	return func(args []string) error {
		fs := flag.NewFlagSet("healthcheck", flag.ContinueOnError)
		urlFlag := fs.String("url", "", "override the healthcheck path (e.g. https://test.traefik.com/healthz")
		fs.SetOutput(os.Stderr)
		if err := fs.Parse(args); err != nil {
			return err
		}

		traefikConfiguration.SetEffectiveConfiguration()

		var resp *http.Response
		var errPing error
		if *urlFlag != "" {
			client := &http.Client{Timeout: 5 * time.Second}
			resp, errPing = client.Head(*urlFlag)
		} else {
			resp, errPing = Do(*traefikConfiguration)
		}

		if resp != nil {
			resp.Body.Close()

Review comment (suggestion):
After some testing, it seems that this option doesn't require to be set to true.
```suggestion
```

Code after:
package healthcheck

import (
	"errors"
	"flag"
	"fmt"
	"net/http"
	"os"
	"time"

	"github.com/traefik/paerser/cli"
	"github.com/traefik/traefik/v3/pkg/config/static"
)

// NewCmd builds a new HealthCheck command.
func NewCmd(traefikConfiguration *static.Configuration, loaders []cli.ResourceLoader) *cli.Command {
	return &cli.Command{
		Name:          "healthcheck",
		Description:   `Calls Traefik /ping endpoint (disabled by default) to check the health of Traefik.`,
		Configuration: traefikConfiguration,
		Run:           runCmd(traefikConfiguration),
		Resources:     loaders,
	}
}

func runCmd(traefikConfiguration *static.Configuration) func(args []string) error {
	return func(args []string) error {
		fs := flag.NewFlagSet("healthcheck", flag.ContinueOnError)
		urlFlag := fs.String("url", "", "")
		fs.SetOutput(os.Stderr)
		if err := fs.Parse(args); err != nil {
			return err
		}

		traefikConfiguration.SetEffectiveConfiguration()

		var resp *http.Response
		var errPing error
		if *urlFlag != "" {
			client := &http.Client{Timeout: 5 * time.Second}
			resp, errPing = client.Head(*urlFlag)
		} else {
			resp, errPing = Do(*traefikConfiguration)
		}

		if resp != nil {
			resp.Body.Close()
		}
Repository: traefik/traefik
File: cmd/healthcheck/healthcheck.go (Go)

Code before:
	"flag"
	"fmt"
	"net/http"
	"os"
	"time"

	"github.com/traefik/paerser/cli"
	"github.com/traefik/traefik/v3/pkg/config/static"
)

// NewCmd builds a new HealthCheck command.
func NewCmd(traefikConfiguration *static.Configuration, loaders []cli.ResourceLoader) *cli.Command {
	return &cli.Command{
		Name:          "healthcheck",
		Description:   `Calls Traefik /ping endpoint (disabled by default) to check the health of Traefik.`,
		Configuration: traefikConfiguration,
		Run:           runCmd(traefikConfiguration),
		Resources:     loaders,
		AllowArg:      true,
	}
}

func runCmd(traefikConfiguration *static.Configuration) func(args []string) error {
	return func(args []string) error {
		fs := flag.NewFlagSet("healthcheck", flag.ContinueOnError)
		urlFlag := fs.String("url", "", "override the healthcheck path (e.g. https://test.traefik.com/healthz")
		fs.SetOutput(os.Stderr)
		if err := fs.Parse(args); err != nil {
			return err
		}

		traefikConfiguration.SetEffectiveConfiguration()

		var resp *http.Response
		var errPing error
		if *urlFlag != "" {
			client := &http.Client{Timeout: 5 * time.Second}
			resp, errPing = client.Head(*urlFlag)
		} else {
			resp, errPing = Do(*traefikConfiguration)
		}

		if resp != nil {
			resp.Body.Close()
		}
		if errPing != nil {
			fmt.Printf("Error calling healthcheck: %s\n", errPing)
			os.Exit(1)
		}

		if resp.StatusCode != http.StatusOK {

Review comment (suggestion):
The documentation isn't printed as healthcheck is a sub command, so it seems not necessary to provide it.

```suggestion
		urlFlag := fs.String("url", "", "")
```

Code after:
	"flag"
	"fmt"
	"net/http"
	"os"
	"time"

	"github.com/traefik/paerser/cli"
	"github.com/traefik/traefik/v3/pkg/config/static"
)

// NewCmd builds a new HealthCheck command.
func NewCmd(traefikConfiguration *static.Configuration, loaders []cli.ResourceLoader) *cli.Command {
	return &cli.Command{
		Name:          "healthcheck",
		Description:   `Calls Traefik /ping endpoint (disabled by default) to check the health of Traefik.`,
		Configuration: traefikConfiguration,
		Run:           runCmd(traefikConfiguration),
		Resources:     loaders,
	}
}

func runCmd(traefikConfiguration *static.Configuration) func(args []string) error {
	return func(args []string) error {
		fs := flag.NewFlagSet("healthcheck", flag.ContinueOnError)
		urlFlag := fs.String("url", "", "")
		fs.SetOutput(os.Stderr)
		if err := fs.Parse(args); err != nil {
			return err
		}

		traefikConfiguration.SetEffectiveConfiguration()

		var resp *http.Response
		var errPing error
		if *urlFlag != "" {
			client := &http.Client{Timeout: 5 * time.Second}
			resp, errPing = client.Head(*urlFlag)
		} else {
			resp, errPing = Do(*traefikConfiguration)
		}

		if resp != nil {
			resp.Body.Close()
		}
		if errPing != nil {
			fmt.Printf("Error calling healthcheck: %s\n", errPing)
			os.Exit(1)
		}

		if resp.StatusCode != http.StatusOK {
			fmt.Printf("Bad healthcheck status: %s\n", resp.Status)
Repository: traefik/traefik
File: pkg/cli/loader_flag.go (Go)

Code before:
	"fmt"
	"strings"

	"github.com/rs/zerolog/log"
	"github.com/traefik/paerser/cli"
	"github.com/traefik/paerser/flag"
)

// FlagLoader loads configuration from flags.
type FlagLoader struct{}

// Load loads the command's configuration from flag arguments.
func (*FlagLoader) Load(args []string, cmd *cli.Command) (bool, error) {
	if len(args) == 0 {
		return false, nil
	}

	if cmd.Name == "healthcheck" {
		for _, a := range args {
			if strings.HasPrefix(a, "--url") {
				log.Print("Skipping flag load for healthcheck (url provided)")
				return false, nil
			}
		}
	}

	if err := flag.Decode(args, cmd.Configuration); err != nil {
		return false, fmt.Errorf("failed to decode configuration from flags: %w", err)
	}

	log.Print("Configuration loaded from flags")

	return true, nil
}


Review comment (suggestion):
Avoiding parsing of the static configuration seems superfluous, just ignoring it in the healthcheck command is enough.
```suggestion
```

Code after:
package cli

import (
	"fmt"

	"github.com/rs/zerolog/log"
	"github.com/traefik/paerser/cli"
	"github.com/traefik/paerser/flag"
)

// FlagLoader loads configuration from flags.
type FlagLoader struct{}

// Load loads the command's configuration from flag arguments.
func (*FlagLoader) Load(args []string, cmd *cli.Command) (bool, error) {
	if len(args) == 0 {
		return false, nil
	}

	if err := flag.Decode(args, cmd.Configuration); err != nil {
		return false, fmt.Errorf("failed to decode configuration from flags: %w", err)
	}

	log.Print("Configuration loaded from flags")

	return true, nil
}
Repository: traefik/traefik
File: internal/testsci/genmatrix.go (Go)

Code before:
	"encoding/json"
	"fmt"
	"os"
	"strings"

	"github.com/traefik/traefik/v2/pkg/log"
	"golang.org/x/tools/go/packages"
)

const groupCount = 12

type Group struct {
	Group string `json:"group"`
}

func main() {
	logger := log.WithoutContext()

	cfg := &packages.Config{
		Mode: packages.NeedName,
		Dir:  ".",
	}

	pkgs, err := packages.Load(cfg, "./cmd/...", "./pkg/...")
	if err != nil {
		logger.Fatalf("loading packages: %v", err)
	}

	var packageNames []string
	for _, pkg := range pkgs {
		if pkg.PkgPath != "" {
			packageNames = append(packageNames, pkg.PkgPath)
		}
	}

	total := len(packageNames)
	perGroup := (total + groupCount - 1) / groupCount

	fmt.Fprintf(os.Stderr, "Total packages: %d\n", total)
	fmt.Fprintf(os.Stderr, "Packages per group: %d\n", perGroup)

	var matrix []Group
	for i := range groupCount {
		start := i * perGroup
		end := start + perGroup
		if start >= total {
			break
		}
		if end > total {
			end = total
		}

Review comment (suggestion):
```suggestion
		logger.Fatalf("Loading packages: %v", err)
```

Code after:
	"encoding/json"
	"fmt"
	"os"
	"strings"

	"github.com/traefik/traefik/v2/pkg/log"
	"golang.org/x/tools/go/packages"
)

const groupCount = 12

type group struct {
	Group string `json:"group"`
}

func main() {
	logger := log.WithoutContext()

	cfg := &packages.Config{
		Mode: packages.NeedName,
		Dir:  ".",
	}

	pkgs, err := packages.Load(cfg, "./cmd/...", "./pkg/...")
	if err != nil {
		logger.Fatalf("Loading packages: %v", err)
	}

	var packageNames []string
	for _, pkg := range pkgs {
		if pkg.PkgPath != "" {
			packageNames = append(packageNames, pkg.PkgPath)
		}
	}

	total := len(packageNames)
	perGroup := (total + groupCount - 1) / groupCount

	fmt.Fprintf(os.Stderr, "Total packages: %d\n", total)
	fmt.Fprintf(os.Stderr, "Packages per group: %d\n", perGroup)

	var matrix []group
	for i := range groupCount {
		start := i * perGroup
		end := start + perGroup
		if start >= total {
			break
		}
		if end > total {
			end = total
		}
Repository: traefik/traefik
File: internal/testsci/genmatrix.go (Go)

Code before:
		}
	}

	total := len(packageNames)
	perGroup := (total + groupCount - 1) / groupCount

	fmt.Fprintf(os.Stderr, "Total packages: %d\n", total)
	fmt.Fprintf(os.Stderr, "Packages per group: %d\n", perGroup)

	var matrix []Group
	for i := range groupCount {
		start := i * perGroup
		end := start + perGroup
		if start >= total {
			break
		}
		if end > total {
			end = total
		}
		group := strings.Join(packageNames[start:end], " ")
		matrix = append(matrix, Group{Group: group})
	}

	jsonBytes, err := json.Marshal(matrix)
	if err != nil {
		logger.Fatalf("failed to marshal matrix: %v", err)
	}

	// Output for GitHub Actions
	fmt.Printf("matrix=%s\n", string(jsonBytes))
}


Review comment (bug):
```suggestion
		logger.Fatalf("Failed to marshal matrix: %v", err)
```

Code after:
		}
	}

	total := len(packageNames)
	perGroup := (total + groupCount - 1) / groupCount

	fmt.Fprintf(os.Stderr, "Total packages: %d\n", total)
	fmt.Fprintf(os.Stderr, "Packages per group: %d\n", perGroup)

	var matrix []group
	for i := range groupCount {
		start := i * perGroup
		end := start + perGroup
		if start >= total {
			break
		}
		if end > total {
			end = total
		}
		g := strings.Join(packageNames[start:end], " ")
		matrix = append(matrix, group{Group: g})
	}

	jsonBytes, err := json.Marshal(matrix)
	if err != nil {
		logger.Fatalf("Failed to marshal matrix: %v", err)
	}

	// Output for GitHub Actions
	fmt.Printf("matrix=%s\n", string(jsonBytes))
}
Repository: traefik/traefik
File: pkg/muxer/http/mux.go (Go)

Code before:
package http

import (
	"fmt"
	"net/http"
	"sort"

	"github.com/rs/zerolog/log"
	"github.com/traefik/traefik/v3/pkg/rules"
)

type matcherFuncs map[string]MatcherFunc

type MatcherFunc func(*matchersTree, ...string) error

// Muxer handles routing with rules.
type Muxer struct {
	routes         routes
	parser         SyntaxParser
	defaultHandler http.Handler
}

// NewMuxer returns a new muxer instance.
func NewMuxer(parser SyntaxParser) *Muxer {
	return &Muxer{
		parser:         parser,
		defaultHandler: http.NotFoundHandler(),
	}
}

// ServeHTTP forwards the connection to the matching HTTP handler.
// Serves 404 if no handler is found.
func (m *Muxer) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
	for _, route := range m.routes {
		if route.matchers.match(req) {
			route.handler.ServeHTTP(rw, req)
			return

Review comment (suggestion):
```suggestion
type MatcherFuncs map[string]MatcherFunc
```

Code after:
package http

import (
	"fmt"
	"net/http"
	"sort"

	"github.com/rs/zerolog/log"
	"github.com/traefik/traefik/v3/pkg/rules"
)

type matcherBuilderFuncs map[string]matcherBuilderFunc

type matcherBuilderFunc func(*matchersTree, ...string) error

type MatcherFunc func(*http.Request) bool

// Muxer handles routing with rules.
type Muxer struct {
	routes         routes
	parser         SyntaxParser
	defaultHandler http.Handler
}

// NewMuxer returns a new muxer instance.
func NewMuxer(parser SyntaxParser) *Muxer {
	return &Muxer{
		parser:         parser,
		defaultHandler: http.NotFoundHandler(),
	}
}

// ServeHTTP forwards the connection to the matching HTTP handler.
// Serves 404 if no handler is found.
func (m *Muxer) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
	for _, route := range m.routes {
		if route.matchers.match(req) {
Repository: traefik/traefik
File: pkg/plugins/client.go (Go)

Code before:

	for _, f := range archive.File {
		err = unzipFile(f, dest)
		if err != nil {
			return fmt.Errorf("unable to unzip %s: %w", f.Name, err)
		}
	}

	return nil
}

func unzipFile(f *zipa.File, dest string) error {
	rc, err := f.Open()
	if err != nil {
		return err
	}

	defer func() { _ = rc.Close() }()

	// Split to discard the first part of the path, which is [organization]-[project]-[release commit sha1] when the archive is a Yaegi go plugin with vendoring.
	pathParts := strings.SplitN(f.Name, "/", 2)
	if len(pathParts) < 2 {
		return fmt.Errorf("no root directory: %s", f.Name)
	}

	// Validate and sanitize the file path
	cleanName := filepath.Clean(pathParts[1])
	if strings.Contains(cleanName, "..") {
		return fmt.Errorf("invalid file path in archive: %s", f.Name)
	}

	filePath := filepath.Join(dest, cleanName)
	absFilePath, err := filepath.Abs(filePath)
	if err != nil {
		return fmt.Errorf("resolving file path: %w", err)
	}

	absDest, err := filepath.Abs(dest)
	if err != nil {
		return fmt.Errorf("resolving destination directory: %w", err)
	}

	if !strings.HasPrefix(absFilePath, absDest) {
		return fmt.Errorf("file path escapes destination directory: %s", absFilePath)
	}

	if f.FileInfo().IsDir() {
		err = os.MkdirAll(filePath, f.Mode())
		if err != nil {
			return fmt.Errorf("unable to create archive directory %s: %w", filePath, err)
		}

Review comment (security):
```suggestion
	// Validate and sanitize the file path.
```

Code after:

	for _, f := range archive.File {
		err = unzipFile(f, dest)
		if err != nil {
			return fmt.Errorf("unable to unzip %s: %w", f.Name, err)
		}
	}

	return nil
}

func unzipFile(f *zipa.File, dest string) error {
	rc, err := f.Open()
	if err != nil {
		return err
	}

	defer func() { _ = rc.Close() }()

	// Split to discard the first part of the path, which is [organization]-[project]-[release commit sha1] when the archive is a Yaegi go plugin with vendoring.
	pathParts := strings.SplitN(f.Name, "/", 2)
	if len(pathParts) < 2 {
		return fmt.Errorf("no root directory: %s", f.Name)
	}

	// Validate and sanitize the file path.
	cleanName := filepath.Clean(pathParts[1])
	if strings.Contains(cleanName, "..") {
		return fmt.Errorf("invalid file path in archive: %s", f.Name)
	}

	filePath := filepath.Join(dest, cleanName)
	absFilePath, err := filepath.Abs(filePath)
	if err != nil {
		return fmt.Errorf("resolving file path: %w", err)
	}

	absDest, err := filepath.Abs(dest)
	if err != nil {
		return fmt.Errorf("resolving destination directory: %w", err)
	}

	if !strings.HasPrefix(absFilePath, absDest) {
		return fmt.Errorf("file path escapes destination directory: %s", absFilePath)
	}

	if f.FileInfo().IsDir() {
		err = os.MkdirAll(filePath, f.Mode())
		if err != nil {
			return fmt.Errorf("unable to create archive directory %s: %w", filePath, err)
		}
Repository: traefik/traefik
File: pkg/provider/kubernetes/gateway/httproute.go (Go)

Code before:
		sets[string(header.Name)] = header.Value
	}

	adds := map[string]string{}
	for _, header := range filter.Add {
		adds[string(header.Name)] = header.Value
	}

	return &dynamic.Middleware{
		ResponseHeaderModifier: &dynamic.HeaderModifier{
			Set:    sets,
			Add:    adds,
			Remove: filter.Remove,
		},
	}
}

func createRequestRedirect(filter *gatev1.HTTPRequestRedirectFilter, pathMatch gatev1.HTTPPathMatch) *dynamic.Middleware {
	var hostname *string
	if filter.Hostname != nil {
		hostname = ptr.To(string(*filter.Hostname))
	}

	var port *string
	filterScheme := ptr.Deref(filter.Scheme, "")
	if strings.EqualFold(filterScheme, schemeHTTP) || strings.EqualFold(filterScheme, schemeHTTPS) {
		port = ptr.To("")
	}
	if filter.Port != nil {
		port = ptr.To(fmt.Sprintf("%d", *filter.Port))
	}

	var path *string
	var pathPrefix *string
	if filter.Path != nil {
		switch filter.Path.Type {
		case gatev1.FullPathHTTPPathModifier:
			path = filter.Path.ReplaceFullPath
		case gatev1.PrefixMatchHTTPPathModifier:
			path = filter.Path.ReplacePrefixMatch
			pathPrefix = pathMatch.Value
		}
	}

	return &dynamic.Middleware{
		RequestRedirect: &dynamic.RequestRedirect{
			Scheme:     filter.Scheme,
			Hostname:   hostname,
			Port:       port,
			Path:       path,
			PathPrefix: pathPrefix,

Review comment (suggestion):
```suggestion
	if filterScheme == schemeHTTP || filterScheme == schemeHTTPS {
```

This part should not be affected because the issue at hand is supporting case insensitivity for the AppProtocol only.

Code after:
		sets[string(header.Name)] = header.Value
	}

	adds := map[string]string{}
	for _, header := range filter.Add {
		adds[string(header.Name)] = header.Value
	}

	return &dynamic.Middleware{
		ResponseHeaderModifier: &dynamic.HeaderModifier{
			Set:    sets,
			Add:    adds,
			Remove: filter.Remove,
		},
	}
}

func createRequestRedirect(filter *gatev1.HTTPRequestRedirectFilter, pathMatch gatev1.HTTPPathMatch) *dynamic.Middleware {
	var hostname *string
	if filter.Hostname != nil {
		hostname = ptr.To(string(*filter.Hostname))
	}

	var port *string
	filterScheme := ptr.Deref(filter.Scheme, "")
	if filterScheme == schemeHTTP || filterScheme == schemeHTTPS {
		port = ptr.To("")
	}
	if filter.Port != nil {
		port = ptr.To(fmt.Sprintf("%d", *filter.Port))
	}

	var path *string
	var pathPrefix *string
	if filter.Path != nil {
		switch filter.Path.Type {
		case gatev1.FullPathHTTPPathModifier:
			path = filter.Path.ReplaceFullPath
		case gatev1.PrefixMatchHTTPPathModifier:
			path = filter.Path.ReplacePrefixMatch
			pathPrefix = pathMatch.Value
		}
	}

	return &dynamic.Middleware{
		RequestRedirect: &dynamic.RequestRedirect{
			Scheme:     filter.Scheme,
			Hostname:   hostname,
			Port:       port,
			Path:       path,
			PathPrefix: pathPrefix,
Repository: traefik/traefik
File: integration/dual_logging_test.go (Go)

Code before:
func (s *DualLoggingSuite) SetupSuite() {
	s.BaseSuite.SetupSuite()

	// Clean up any existing log files
	os.Remove(traefikTestLogFile)
	os.Remove(traefikTestOTLPLogFile)
}

func (s *DualLoggingSuite) TearDownSuite() {
	s.BaseSuite.TearDownSuite()

	// Clean up log files
	generatedFiles := []string{
		traefikTestLogFile,
		traefikTestOTLPLogFile,
	}

	for _, filename := range generatedFiles {
		if err := os.Remove(filename); err != nil {
			s.T().Logf("Failed to remove %s: %v", filename, err)
		}
	}

	if s.collector != nil {
		s.collector.Close()
	}
}

func (s *DualLoggingSuite) SetupTest() {
	s.otlpLogs = []string{}

	// Create mock OTLP collector
	s.collector = httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		defer r.Body.Close()

		gzr, err := gzip.NewReader(r.Body)
		if err != nil {
			s.T().Logf("Error creating gzip reader: %v", err)
			http.Error(w, err.Error(), http.StatusBadRequest)
			return
		}
		defer gzr.Close()

		body, err := io.ReadAll(gzr)
		if err != nil {
			s.T().Logf("Error reading gzipped body: %v", err)
			http.Error(w, err.Error(), http.StatusBadRequest)
			return
		}

		req := plogotlp.NewExportRequest()

Review comment (suggestion):
```suggestion
```
Already done in the `TearDownTest` func

Code after:
	// Clean up any existing log files
	os.Remove(traefikTestLogFile)
	os.Remove(traefikTestOTLPLogFile)
}

func (s *DualLoggingSuite) TearDownSuite() {
	s.BaseSuite.TearDownSuite()

	// Clean up log files
	generatedFiles := []string{
		traefikTestLogFile,
		traefikTestOTLPLogFile,
	}

	for _, filename := range generatedFiles {
		if err := os.Remove(filename); err != nil {
			s.T().Logf("Failed to remove %s: %v", filename, err)
		}
	}
}

func (s *DualLoggingSuite) SetupTest() {
	s.otlpLogs = []string{}

	// Create mock OTLP collector
	s.collector = httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		defer r.Body.Close()

		gzr, err := gzip.NewReader(r.Body)
		if err != nil {
			s.T().Logf("Error creating gzip reader: %v", err)
			http.Error(w, err.Error(), http.StatusBadRequest)
			return
		}
		defer gzr.Close()

		body, err := io.ReadAll(gzr)
		if err != nil {
			s.T().Logf("Error reading gzipped body: %v", err)
			http.Error(w, err.Error(), http.StatusBadRequest)
			return
		}

		req := plogotlp.NewExportRequest()
		err = req.UnmarshalProto(body)
		if err != nil {
			s.T().Logf("Error unmarshaling protobuf: %v", err)
			http.Error(w, err.Error(), http.StatusBadRequest)
			return
		}