Merge branch v2.11 into v3.3
This commit is contained in:
commit
c910ceeb00
18 changed files with 144 additions and 86 deletions
|
@ -2,6 +2,7 @@ package httputil
|
|||
|
||||
import (
|
||||
"context"
|
||||
"crypto/tls"
|
||||
"errors"
|
||||
"io"
|
||||
stdlog "log"
|
||||
|
@ -112,7 +113,13 @@ func ErrorHandlerWithContext(ctx context.Context, w http.ResponseWriter, err err
|
|||
statusCode := ComputeStatusCode(err)
|
||||
|
||||
logger := log.Ctx(ctx)
|
||||
logger.Debug().Err(err).Msgf("%d %s", statusCode, statusText(statusCode))
|
||||
|
||||
// Log the error with error level if it is a TLS error related to configuration.
|
||||
if isTLSConfigError(err) {
|
||||
logger.Error().Err(err).Msgf("%d %s", statusCode, statusText(statusCode))
|
||||
} else {
|
||||
logger.Debug().Err(err).Msgf("%d %s", statusCode, statusText(statusCode))
|
||||
}
|
||||
|
||||
w.WriteHeader(statusCode)
|
||||
if _, werr := w.Write([]byte(statusText(statusCode))); werr != nil {
|
||||
|
@ -127,6 +134,22 @@ func statusText(statusCode int) string {
|
|||
return http.StatusText(statusCode)
|
||||
}
|
||||
|
||||
// isTLSConfigError returns true if the error is a TLS error which is related to configuration.
|
||||
// We assume that if the error is a tls.RecordHeaderError or a tls.CertificateVerificationError,
|
||||
// it is related to configuration, because the client should not send a TLS request to a non-TLS server,
|
||||
// and the client configuration should allow to verify the server certificate.
|
||||
func isTLSConfigError(err error) bool {
|
||||
// tls.RecordHeaderError is returned when the client sends a TLS request to a non-TLS server.
|
||||
var recordHeaderErr tls.RecordHeaderError
|
||||
if errors.As(err, &recordHeaderErr) {
|
||||
return true
|
||||
}
|
||||
|
||||
// tls.CertificateVerificationError is returned when the server certificate cannot be verified.
|
||||
var certVerificationErr *tls.CertificateVerificationError
|
||||
return errors.As(err, &certVerificationErr)
|
||||
}
|
||||
|
||||
// ComputeStatusCode computes the HTTP status code according to the given error.
|
||||
func ComputeStatusCode(err error) int {
|
||||
switch {
|
||||
|
|
|
@ -1,12 +1,15 @@
|
|||
package httputil
|
||||
|
||||
import (
|
||||
"crypto/tls"
|
||||
"errors"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"net/url"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
"github.com/traefik/traefik/v3/pkg/testhelpers"
|
||||
)
|
||||
|
||||
|
@ -100,3 +103,46 @@ func Test_directorBuilder(t *testing.T) {
|
|||
})
|
||||
}
|
||||
}
|
||||
|
||||
func Test_isTLSConfigError(t *testing.T) {
|
||||
testCases := []struct {
|
||||
desc string
|
||||
err error
|
||||
expected bool
|
||||
}{
|
||||
{
|
||||
desc: "nil",
|
||||
},
|
||||
{
|
||||
desc: "TLS ECHRejectionError",
|
||||
err: &tls.ECHRejectionError{},
|
||||
},
|
||||
{
|
||||
desc: "TLS AlertError",
|
||||
err: tls.AlertError(0),
|
||||
},
|
||||
{
|
||||
desc: "Random error",
|
||||
err: errors.New("random error"),
|
||||
},
|
||||
{
|
||||
desc: "TLS RecordHeaderError",
|
||||
err: tls.RecordHeaderError{},
|
||||
expected: true,
|
||||
},
|
||||
{
|
||||
desc: "TLS CertificateVerificationError",
|
||||
err: &tls.CertificateVerificationError{},
|
||||
expected: true,
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range testCases {
|
||||
t.Run(test.desc, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
actual := isTLSConfigError(test.err)
|
||||
require.Equal(t, test.expected, actual)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue