ronantakizawa/codereview-bench huggingface dataset:
Repository: traefik/traefik
File: integration/retry_test.go (Go)

Code before:
	defer s.killCmd(cmd)

	err = try.GetRequest("http://127.0.0.1:8080/api/rawdata", 60*time.Second, try.BodyContains("PathPrefix(`/`)"))
	c.Assert(err, checker.IsNil)

	response, err := http.Get("http://127.0.0.1:8000/")
	c.Assert(err, checker.IsNil)

	// The test only verifies that the retry middleware allows finally to reach the working service.
	c.Assert(response.StatusCode, checker.Equals, http.StatusOK)
}

func (s *RetrySuite) TestRetryWebsocket(c *check.C) {
	file := s.adaptFile(c, "fixtures/retry/simple.toml", struct{ WhoamiIP string }{s.whoamiIP})
	defer os.Remove(file)

	cmd, display := s.traefikCmd(withConfigFile(file))
	defer display(c)
	err := cmd.Start()
	c.Assert(err, checker.IsNil)
	defer s.killCmd(cmd)

	err = try.GetRequest("http://127.0.0.1:8080/api/rawdata", 60*time.Second, try.BodyContains("PathPrefix(`/`)"))
	c.Assert(err, checker.IsNil)

	// The test only verifies that the retry middleware allows finally to reach the working service.
	_, response, err := websocket.DefaultDialer.Dial("ws://127.0.0.1:8000/echo", nil)
	c.Assert(err, checker.IsNil)
	c.Assert(response.StatusCode, checker.Equals, http.StatusSwitchingProtocols)

	// The test only verifies that the retry middleware allows finally to reach the working service (a second time).
	_, response, err = websocket.DefaultDialer.Dial("ws://127.0.0.1:8000/echo", nil)
	c.Assert(err, checker.IsNil)
	c.Assert(response.StatusCode, checker.Equals, http.StatusSwitchingProtocols)
}


Review comment (suggestion):
```suggestion
	// The test only verifies that the retry middleware makes sure that the working service is eventually reached.
```

Code after:
	defer s.killCmd(cmd)

	err = try.GetRequest("http://127.0.0.1:8080/api/rawdata", 60*time.Second, try.BodyContains("PathPrefix(`/`)"))
	c.Assert(err, checker.IsNil)

	response, err := http.Get("http://127.0.0.1:8000/")
	c.Assert(err, checker.IsNil)

	// The test only verifies that the retry middleware allows finally to reach the working service.
	c.Assert(response.StatusCode, checker.Equals, http.StatusOK)
}

func (s *RetrySuite) TestRetryWebsocket(c *check.C) {
	file := s.adaptFile(c, "fixtures/retry/simple.toml", struct{ WhoamiIP string }{s.whoamiIP})
	defer os.Remove(file)

	cmd, display := s.traefikCmd(withConfigFile(file))
	defer display(c)
	err := cmd.Start()
	c.Assert(err, checker.IsNil)
	defer s.killCmd(cmd)

	err = try.GetRequest("http://127.0.0.1:8080/api/rawdata", 60*time.Second, try.BodyContains("PathPrefix(`/`)"))
	c.Assert(err, checker.IsNil)

	// The test only verifies that the retry middleware makes sure that the working service is eventually reached.
	_, response, err := websocket.DefaultDialer.Dial("ws://127.0.0.1:8000/echo", nil)
	c.Assert(err, checker.IsNil)
	c.Assert(response.StatusCode, checker.Equals, http.StatusSwitchingProtocols)

	// The test verifies a second time that the working service is eventually reached.
	_, response, err = websocket.DefaultDialer.Dial("ws://127.0.0.1:8000/echo", nil)
	c.Assert(err, checker.IsNil)
	c.Assert(response.StatusCode, checker.Equals, http.StatusSwitchingProtocols)
}
Repository: traefik/traefik
File: pkg/server/service/tcp/service.go (Go)

Code before:
package tcp

import (
	"context"
	"errors"
	"fmt"
	"math/rand"
	"net"
	"time"

	"github.com/traefik/traefik/v2/pkg/config/dynamic"
	"github.com/traefik/traefik/v2/pkg/config/runtime"
	"github.com/traefik/traefik/v2/pkg/log"
	"github.com/traefik/traefik/v2/pkg/server/provider"
	"github.com/traefik/traefik/v2/pkg/tcp"
)

// Manager is the TCPHandlers factory.
type Manager struct {
	configs map[string]*runtime.TCPServiceInfo
	rand    *rand.Rand
}

// NewManager creates a new manager.
func NewManager(conf *runtime.Configuration) *Manager {
	return &Manager{
		configs: conf.TCPServices,
		rand:    rand.New(rand.NewSource(time.Now().UnixNano())),
	}
}

// BuildTCP Creates a tcp.Handler for a service configuration.
func (m *Manager) BuildTCP(rootCtx context.Context, serviceName string) (tcp.Handler, error) {
	serviceQualifiedName := provider.GetQualifiedName(rootCtx, serviceName)
	ctx := provider.AddInContext(rootCtx, serviceQualifiedName)
	ctx = log.With(ctx, log.Str(log.ServiceName, serviceName))

	conf, ok := m.configs[serviceQualifiedName]
	if !ok {
		return nil, fmt.Errorf("the service %q does not exist", serviceQualifiedName)
	}

	if conf.LoadBalancer != nil && conf.Weighted != nil {
		err := errors.New("cannot create service: multi-types service not supported, consider declaring two different pieces of service instead")
		conf.AddError(err, true)
		return nil, err

Review comment (suggestion):
```suggestion
	rand    *rand.Rand // for the initial shuffling of load-balancers
```

Code after:
package tcp

import (
	"context"
	"errors"
	"fmt"
	"math/rand"
	"net"
	"time"

	"github.com/traefik/traefik/v2/pkg/config/runtime"
	"github.com/traefik/traefik/v2/pkg/log"
	"github.com/traefik/traefik/v2/pkg/server/provider"
	"github.com/traefik/traefik/v2/pkg/tcp"
)

// Manager is the TCPHandlers factory.
type Manager struct {
	configs map[string]*runtime.TCPServiceInfo
	rand    *rand.Rand // For the initial shuffling of load-balancers.
}

// NewManager creates a new manager.
func NewManager(conf *runtime.Configuration) *Manager {
	return &Manager{
		configs: conf.TCPServices,
		rand:    rand.New(rand.NewSource(time.Now().UnixNano())),
	}
}

// BuildTCP Creates a tcp.Handler for a service configuration.
func (m *Manager) BuildTCP(rootCtx context.Context, serviceName string) (tcp.Handler, error) {
	serviceQualifiedName := provider.GetQualifiedName(rootCtx, serviceName)
	ctx := provider.AddInContext(rootCtx, serviceQualifiedName)
	ctx = log.With(ctx, log.Str(log.ServiceName, serviceName))

	conf, ok := m.configs[serviceQualifiedName]
	if !ok {
		return nil, fmt.Errorf("the service %q does not exist", serviceQualifiedName)
	}

	if conf.LoadBalancer != nil && conf.Weighted != nil {
		err := errors.New("cannot create service: multi-types service not supported, consider declaring two different pieces of service instead")
		conf.AddError(err, true)
		return nil, err
	}
Repository: traefik/traefik
File: integration/retry_test.go (Go)

Code before:
	response, err := http.Get("http://127.0.0.1:8000/")
	c.Assert(err, checker.IsNil)

	// The test only verifies that the retry middleware allows finally to reach the working service.
	c.Assert(response.StatusCode, checker.Equals, http.StatusOK)
}

func (s *RetrySuite) TestRetryWebsocket(c *check.C) {
	file := s.adaptFile(c, "fixtures/retry/simple.toml", struct{ WhoamiIP string }{s.whoamiIP})
	defer os.Remove(file)

	cmd, display := s.traefikCmd(withConfigFile(file))
	defer display(c)
	err := cmd.Start()
	c.Assert(err, checker.IsNil)
	defer s.killCmd(cmd)

	err = try.GetRequest("http://127.0.0.1:8080/api/rawdata", 60*time.Second, try.BodyContains("PathPrefix(`/`)"))
	c.Assert(err, checker.IsNil)

	// The test only verifies that the retry middleware allows finally to reach the working service.
	_, response, err := websocket.DefaultDialer.Dial("ws://127.0.0.1:8000/echo", nil)
	c.Assert(err, checker.IsNil)
	c.Assert(response.StatusCode, checker.Equals, http.StatusSwitchingProtocols)

	// The test only verifies that the retry middleware allows finally to reach the working service (a second time).
	_, response, err = websocket.DefaultDialer.Dial("ws://127.0.0.1:8000/echo", nil)
	c.Assert(err, checker.IsNil)
	c.Assert(response.StatusCode, checker.Equals, http.StatusSwitchingProtocols)
}


Review comment (suggestion):
```suggestion
	// The test verifies a second time that the working service is eventually reached.
```

Code after:
	response, err := http.Get("http://127.0.0.1:8000/")
	c.Assert(err, checker.IsNil)

	// The test only verifies that the retry middleware allows finally to reach the working service.
	c.Assert(response.StatusCode, checker.Equals, http.StatusOK)
}

func (s *RetrySuite) TestRetryWebsocket(c *check.C) {
	file := s.adaptFile(c, "fixtures/retry/simple.toml", struct{ WhoamiIP string }{s.whoamiIP})
	defer os.Remove(file)

	cmd, display := s.traefikCmd(withConfigFile(file))
	defer display(c)
	err := cmd.Start()
	c.Assert(err, checker.IsNil)
	defer s.killCmd(cmd)

	err = try.GetRequest("http://127.0.0.1:8080/api/rawdata", 60*time.Second, try.BodyContains("PathPrefix(`/`)"))
	c.Assert(err, checker.IsNil)

	// The test only verifies that the retry middleware makes sure that the working service is eventually reached.
	_, response, err := websocket.DefaultDialer.Dial("ws://127.0.0.1:8000/echo", nil)
	c.Assert(err, checker.IsNil)
	c.Assert(response.StatusCode, checker.Equals, http.StatusSwitchingProtocols)

	// The test verifies a second time that the working service is eventually reached.
	_, response, err = websocket.DefaultDialer.Dial("ws://127.0.0.1:8000/echo", nil)
	c.Assert(err, checker.IsNil)
	c.Assert(response.StatusCode, checker.Equals, http.StatusSwitchingProtocols)
}
Repository: traefik/traefik
File: cmd/traefik/traefik.go (Go)

Code before:
	serverEntryPointsTCP, err := server.NewTCPEntryPoints(staticConfiguration.EntryPoints, staticConfiguration.HostResolver)
	if err != nil {
		return nil, err
	}

	serverEntryPointsUDP, err := server.NewUDPEntryPoints(staticConfiguration.EntryPoints)
	if err != nil {
		return nil, err
	}

	// Pilot

	var aviator *pilot.Pilot
	var pilotRegistry *metrics.PilotRegistry
	if isPilotEnabled(staticConfiguration) {
		pilotRegistry = metrics.RegisterPilot()

		aviator = pilot.New(staticConfiguration.Pilot.Token, pilotRegistry, routinesPool)

		routinesPool.GoCtx(func(ctx context.Context) {
			aviator.Tick(ctx)
		})
	}

	if staticConfiguration.Pilot != nil {
		log.WithoutContext().Warn("Traefik Pilot is deprecated and will be removed soon. Please check our Blog for migration instructions later this year")

		version.PilotEnabled = staticConfiguration.Pilot.Dashboard
	}

	// Plugins

	pluginBuilder, err := createPluginBuilder(staticConfiguration)
	if err != nil {
		return nil, err
	}

	// Providers plugins

	for name, conf := range staticConfiguration.Providers.Plugin {
		p, err := pluginBuilder.BuildProvider(name, conf)
		if err != nil {
			return nil, fmt.Errorf("plugin: failed to build provider: %w", err)
		}

		err = providerAggregator.AddProvider(p)
		if err != nil {
			return nil, fmt.Errorf("plugin: failed to add provider: %w", err)
		}
	}


Review comment (suggestion):
```suggestion
		log.WithoutContext().Warn("Traefik Pilot is deprecated and will be removed soon. Please check our Blog for migration instructions later this year.")
```

Code after:
	serverEntryPointsTCP, err := server.NewTCPEntryPoints(staticConfiguration.EntryPoints, staticConfiguration.HostResolver)
	if err != nil {
		return nil, err
	}

	serverEntryPointsUDP, err := server.NewUDPEntryPoints(staticConfiguration.EntryPoints)
	if err != nil {
		return nil, err
	}

	// Pilot

	var aviator *pilot.Pilot
	var pilotRegistry *metrics.PilotRegistry
	if isPilotEnabled(staticConfiguration) {
		pilotRegistry = metrics.RegisterPilot()

		aviator = pilot.New(staticConfiguration.Pilot.Token, pilotRegistry, routinesPool)

		routinesPool.GoCtx(func(ctx context.Context) {
			aviator.Tick(ctx)
		})
	}

	if staticConfiguration.Pilot != nil {
		log.WithoutContext().Warn("Traefik Pilot is deprecated and will be removed soon. Please check our Blog for migration instructions later this year.")
	}

	// Plugins

	pluginBuilder, err := createPluginBuilder(staticConfiguration)
	if err != nil {
		return nil, err
	}

	// Providers plugins

	for name, conf := range staticConfiguration.Providers.Plugin {
		p, err := pluginBuilder.BuildProvider(name, conf)
		if err != nil {
			return nil, fmt.Errorf("plugin: failed to build provider: %w", err)
		}

		err = providerAggregator.AddProvider(p)
		if err != nil {
			return nil, fmt.Errorf("plugin: failed to add provider: %w", err)
		}
	}

	// Traefik Hub
Repository: traefik/traefik
File: pkg/types/domains.go (Go)

Code before:
package types

import (
	"strings"
)

// +k8s:deepcopy-gen=true

// Domain holds a domain name with SANs.
type Domain struct {
	// Main defines the main fully qualified domain name
	Main string   `description:"Default subject name." json:"main,omitempty" toml:"main,omitempty" yaml:"main,omitempty"`
	// SANs is a list of alternatives domains to add in the certificate.
	SANs []string `description:"Subject alternative names." json:"sans,omitempty" toml:"sans,omitempty" yaml:"sans,omitempty"`
}

// ToStrArray convert a domain into an array of strings.
func (d *Domain) ToStrArray() []string {
	var domains []string
	if len(d.Main) > 0 {
		domains = []string{d.Main}
	}
	return append(domains, d.SANs...)
}

// Set sets a domains from an array of strings.
func (d *Domain) Set(domains []string) {
	if len(domains) > 0 {
		d.Main = domains[0]
		d.SANs = domains[1:]
	}
}

// MatchDomain returns true if a domain match the cert domain.
func MatchDomain(domain, certDomain string) bool {
	if domain == certDomain {

Review comment (suggestion):
```suggestion
	// Main defines the main domain name.
```

Code after:
package types

import (
	"strings"
)

// +k8s:deepcopy-gen=true

// Domain holds a domain name with SANs.
type Domain struct {
	// Main defines the main domain name.
	Main string `description:"Default subject name." json:"main,omitempty" toml:"main,omitempty" yaml:"main,omitempty"`
	// SANs defines the subject alternative domain names.
	SANs []string `description:"Subject alternative names." json:"sans,omitempty" toml:"sans,omitempty" yaml:"sans,omitempty"`
}

// ToStrArray convert a domain into an array of strings.
func (d *Domain) ToStrArray() []string {
	var domains []string
	if len(d.Main) > 0 {
		domains = []string{d.Main}
	}
	return append(domains, d.SANs...)
}

// Set sets a domains from an array of strings.
func (d *Domain) Set(domains []string) {
	if len(domains) > 0 {
		d.Main = domains[0]
		d.SANs = domains[1:]
	}
}

// MatchDomain returns true if a domain match the cert domain.
func MatchDomain(domain, certDomain string) bool {
	if domain == certDomain {
Repository: traefik/traefik
File: pkg/types/domains.go (Go)

Code before:
package types

import (
	"strings"
)

// +k8s:deepcopy-gen=true

// Domain holds a domain name with SANs.
type Domain struct {
	// Main defines the main fully qualified domain name
	Main string   `description:"Default subject name." json:"main,omitempty" toml:"main,omitempty" yaml:"main,omitempty"`
	// SANs is a list of alternatives domains to add in the certificate.
	SANs []string `description:"Subject alternative names." json:"sans,omitempty" toml:"sans,omitempty" yaml:"sans,omitempty"`
}

// ToStrArray convert a domain into an array of strings.
func (d *Domain) ToStrArray() []string {
	var domains []string
	if len(d.Main) > 0 {
		domains = []string{d.Main}
	}
	return append(domains, d.SANs...)
}

// Set sets a domains from an array of strings.
func (d *Domain) Set(domains []string) {
	if len(domains) > 0 {
		d.Main = domains[0]
		d.SANs = domains[1:]
	}
}

// MatchDomain returns true if a domain match the cert domain.
func MatchDomain(domain, certDomain string) bool {
	if domain == certDomain {
		return true
	}

Review comment (suggestion):
```suggestion
	// SANs defines the subject alternative domain names.
```

Code after:
package types

import (
	"strings"
)

// +k8s:deepcopy-gen=true

// Domain holds a domain name with SANs.
type Domain struct {
	// Main defines the main domain name.
	Main string `description:"Default subject name." json:"main,omitempty" toml:"main,omitempty" yaml:"main,omitempty"`
	// SANs defines the subject alternative domain names.
	SANs []string `description:"Subject alternative names." json:"sans,omitempty" toml:"sans,omitempty" yaml:"sans,omitempty"`
}

// ToStrArray convert a domain into an array of strings.
func (d *Domain) ToStrArray() []string {
	var domains []string
	if len(d.Main) > 0 {
		domains = []string{d.Main}
	}
	return append(domains, d.SANs...)
}

// Set sets a domains from an array of strings.
func (d *Domain) Set(domains []string) {
	if len(domains) > 0 {
		d.Main = domains[0]
		d.SANs = domains[1:]
	}
}

// MatchDomain returns true if a domain match the cert domain.
func MatchDomain(domain, certDomain string) bool {
	if domain == certDomain {
		return true
	}
Repository: traefik/traefik
File: integration/integration_test.go (Go)

Code before:
	"github.com/fatih/structs"
	"github.com/go-check/check"
	"github.com/traefik/traefik/v2/pkg/log"
	checker "github.com/vdemeester/shakers"
)

var (
	integration = flag.Bool("integration", false, "run integration tests")
	showLog     = flag.Bool("tlog", false, "always show Traefik logs")
)

func Test(t *testing.T) {
	if !*integration {
		log.WithoutContext().Info("Integration tests disabled.")
		return
	}

	// TODO(mpl): very niche optimization: do not start tailscale if none of the
	// wanted tests actually need it (e.g. KeepAliveSuite does not).
	var (
		vpn    *tailscaleNotSuite
		useVPN bool
	)
	if os.Getenv("IN_DOCKER") != "true" {
		vpn = setupVPN(nil, "tailscale.secret")
		if vpn != nil {
			defer vpn.TearDownSuite(nil)
			useVPN = true
		}
	}

	check.Suite(&AccessLogSuite{})
	if !useVPN {
		check.Suite(&AcmeSuite{})
	}
	check.Suite(&ConsulCatalogSuite{})
	check.Suite(&ConsulSuite{})
	check.Suite(&DockerComposeSuite{})
	check.Suite(&DockerSuite{})
	check.Suite(&ErrorPagesSuite{})
	check.Suite(&EtcdSuite{})
	check.Suite(&FileSuite{})
	check.Suite(&GRPCSuite{})
	check.Suite(&HeadersSuite{})
	check.Suite(&HealthCheckSuite{})
	check.Suite(&HostResolverSuite{})
	check.Suite(&HTTPSSuite{})
	check.Suite(&HTTPSuite{})
	if !useVPN {
		check.Suite(&K8sSuite{})
	}

Review comment (security):
```suggestion
		if vpn = setupVPN(nil, "tailscale.secret"); vpn != nil {
```

Code after:
	"github.com/fatih/structs"
	"github.com/go-check/check"
	"github.com/traefik/traefik/v2/pkg/log"
	checker "github.com/vdemeester/shakers"
)

var (
	integration = flag.Bool("integration", false, "run integration tests")
	showLog     = flag.Bool("tlog", false, "always show Traefik logs")
)

func Test(t *testing.T) {
	if !*integration {
		log.WithoutContext().Info("Integration tests disabled.")
		return
	}

	// TODO(mpl): very niche optimization: do not start tailscale if none of the
	// wanted tests actually need it (e.g. KeepAliveSuite does not).
	var (
		vpn    *tailscaleNotSuite
		useVPN bool
	)
	if os.Getenv("IN_DOCKER") != "true" {
		if vpn = setupVPN(nil, "tailscale.secret"); vpn != nil {
			defer vpn.TearDownSuite(nil)
			useVPN = true
		}
	}

	check.Suite(&AccessLogSuite{})
	if !useVPN {
		check.Suite(&AcmeSuite{})
	}
	check.Suite(&ConsulCatalogSuite{})
	check.Suite(&ConsulSuite{})
	check.Suite(&DockerComposeSuite{})
	check.Suite(&DockerSuite{})
	check.Suite(&ErrorPagesSuite{})
	check.Suite(&EtcdSuite{})
	check.Suite(&FileSuite{})
	check.Suite(&GRPCSuite{})
	check.Suite(&HeadersSuite{})
	check.Suite(&HealthCheckSuite{})
	check.Suite(&HostResolverSuite{})
	check.Suite(&HTTPSSuite{})
	check.Suite(&HTTPSuite{})
	if !useVPN {
		check.Suite(&K8sSuite{})
	}
	check.Suite(&KeepAliveSuite{})
Repository: traefik/traefik
File: integration/integration_test.go (Go)

Code before:
// containers in the docker subnet:
//
// "autoApprovers": {
//   // Allow myself to automatically advertize routes for docker networks
//   "routes": {
//     "172.0.0.0/8": ["your_tailscale_identity"],
//   },
// },
//
// TODO(mpl): we could maybe even move this setup to the Makefile, to start it
// and let it run (forever, or until voluntarily stopped).
func setupVPN(c *check.C, keyFile string) *tailscaleNotSuite {
	data, err := ioutil.ReadFile(keyFile)
	if err != nil {
		if !errors.Is(err, fs.ErrNotExist) {
			log.Fatal(err)
		}
		return nil
	}
	authKey := strings.TrimSpace(string(data))
	// TODO: copy and create versions that don't need a check.C?
	vpn := &tailscaleNotSuite{}
	vpn.createComposeProject(c, "tailscale")
	vpn.composeUp(c)
	time.Sleep(5 * time.Second)
	// TODO(mpl): make sure this docker subnet stays the same as the one we setup in Makefile.
	vpn.composeExec(c, "tailscaled", "tailscale", "up", "--authkey="+authKey, "--advertise-routes=172.31.42.0/24")
	return vpn
}


Review comment (suggestion):
```suggestion
	// If we ever change the docker subnet in the Makefile,
	// we need to change this one below correspondingly.
```

Code after:
// containers in the docker subnet:
//
// "autoApprovers": {
//   // Allow myself to automatically advertize routes for docker networks
//   "routes": {
//     "172.0.0.0/8": ["your_tailscale_identity"],
//   },
// },
//
// TODO(mpl): we could maybe even move this setup to the Makefile, to start it
// and let it run (forever, or until voluntarily stopped).
func setupVPN(c *check.C, keyFile string) *tailscaleNotSuite {
	data, err := ioutil.ReadFile(keyFile)
	if err != nil {
		if !errors.Is(err, fs.ErrNotExist) {
			log.Fatal(err)
		}
		return nil
	}
	authKey := strings.TrimSpace(string(data))
	// TODO: copy and create versions that don't need a check.C?
	vpn := &tailscaleNotSuite{}
	vpn.createComposeProject(c, "tailscale")
	vpn.composeUp(c)
	time.Sleep(5 * time.Second)
	// If we ever change the docker subnet in the Makefile,
	// we need to change this one below correspondingly.
	vpn.composeExec(c, "tailscaled", "tailscale", "up", "--authkey="+authKey, "--advertise-routes=172.31.42.0/24")
	return vpn
}
Repository: traefik/traefik
File: pkg/middlewares/redirect/redirect_scheme.go (Go)

Code before:
		port = ":" + port
	}
	uri := req.RequestURI

	if match := uriRegexp.FindStringSubmatch(req.RequestURI); len(match) > 0 {
		scheme = match[1]

		if len(match[2]) > 0 {
			host = match[2]
		}

		if len(match[3]) > 0 {
			port = match[3]
		}

		uri = match[4]
	}

	if req.TLS != nil {
		scheme = schemeHTTPS
	}

	if xProto := req.Header.Get(xForwardedProto); xProto != "" {
		// X-Forwarded-Proto header can be set to ws(s) when the client sends a websocket
		// connection upgrade request whereas the request is made through the HTTP(S) protocol.
		// As this middleware is supporting only HTTP(S) request, we ignore the websocket
		// protocols and converts them to the HTTP(S) protocol.
		switch strings.ToLower(xProto) {
		case "ws", "http":
			scheme = schemeHTTP
		case "wss", "https":
			scheme = schemeHTTPS
		}
	}

	if scheme == schemeHTTP && port == ":80" || scheme == schemeHTTPS && port == ":443" {
		port = ""
	}

	return strings.Join([]string{scheme, "://", host, port, uri}, "")
}


Review comment (suggestion):
```suggestion
		// As this middleware supports only HTTP(S) requests, we ignore the websocket
```

Code after:
		port = ":" + port
	}
	uri := req.RequestURI

	if match := uriRegexp.FindStringSubmatch(req.RequestURI); len(match) > 0 {
		scheme = match[1]

		if len(match[2]) > 0 {
			host = match[2]
		}

		if len(match[3]) > 0 {
			port = match[3]
		}

		uri = match[4]
	}

	if req.TLS != nil {
		scheme = schemeHTTPS
	}

	if xProto := req.Header.Get(xForwardedProto); xProto != "" {
		// When the initial request is a connection upgrade request,
		// X-Forwarded-Proto header might have been set by a previous hop to ws(s),
		// even though the actual protocol used so far is HTTP(s).
		// Given that we're in a middleware that is only used in the context of HTTP(s) requests,
		// the only possible valid schemes are one of "http" or "https", so we convert back to them.
		switch {
		case strings.EqualFold(xProto, "ws"):
			scheme = schemeHTTP
		case strings.EqualFold(xProto, "wss"):
			scheme = schemeHTTPS
		default:
			scheme = xProto
		}
	}

	if scheme == schemeHTTP && port == ":80" || scheme == schemeHTTPS && port == ":443" {
		port = ""
	}

	return strings.Join([]string{scheme, "://", host, port, uri}, "")
}