Merge current v2.4 into master
This commit is contained in:
commit
ce2e02b690
119 changed files with 4628 additions and 4165 deletions
|
@ -190,7 +190,7 @@
|
|||
},
|
||||
"rateLimit": {
|
||||
"average": 42,
|
||||
"period": 42,
|
||||
"period": "42ns",
|
||||
"burst": 42,
|
||||
"sourceCriterion": {
|
||||
"ipStrategy": {
|
||||
|
@ -306,7 +306,7 @@
|
|||
},
|
||||
"retry": {
|
||||
"attempts": 42,
|
||||
"initialInterval": 42
|
||||
"initialInterval": "42ns"
|
||||
},
|
||||
"contentType": {
|
||||
"autoDetect": true
|
||||
|
@ -352,9 +352,9 @@
|
|||
],
|
||||
"maxIdleConnsPerHost": 42,
|
||||
"forwardingTimeouts": {
|
||||
"dialTimeout": 42,
|
||||
"responseHeaderTimeout": 42,
|
||||
"idleConnTimeout": 42
|
||||
"dialTimeout": "42ns",
|
||||
"responseHeaderTimeout": "42ns",
|
||||
"idleConnTimeout": "42ns"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -473,4 +473,4 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -12,9 +12,9 @@
|
|||
],
|
||||
"maxIdleConnsPerHost": 111,
|
||||
"forwardingTimeouts": {
|
||||
"dialTimeout": 111000000000,
|
||||
"responseHeaderTimeout": 111000000000,
|
||||
"idleConnTimeout": 111000000000
|
||||
"dialTimeout": "1m51s",
|
||||
"responseHeaderTimeout": "1m51s",
|
||||
"idleConnTimeout": "1m51s"
|
||||
}
|
||||
},
|
||||
"entryPoints": {
|
||||
|
@ -22,13 +22,13 @@
|
|||
"address": "xxxx",
|
||||
"transport": {
|
||||
"lifeCycle": {
|
||||
"requestAcceptGraceTimeout": 111000000000,
|
||||
"graceTimeOut": 111000000000
|
||||
"requestAcceptGraceTimeout": "1m51s",
|
||||
"graceTimeOut": "1m51s"
|
||||
},
|
||||
"respondingTimeouts": {
|
||||
"readTimeout": 111000000000,
|
||||
"writeTimeout": 111000000000,
|
||||
"idleTimeout": 111000000000
|
||||
"readTimeout": "1m51s",
|
||||
"writeTimeout": "1m51s",
|
||||
"idleTimeout": "1m51s"
|
||||
}
|
||||
},
|
||||
"proxyProtocol": {
|
||||
|
@ -75,7 +75,7 @@
|
|||
}
|
||||
},
|
||||
"providers": {
|
||||
"providersThrottleDuration": 111000000000,
|
||||
"providersThrottleDuration": "1m51s",
|
||||
"docker": {
|
||||
"constraints": "Label(\"foo\", \"bar\")",
|
||||
"watch": true,
|
||||
|
@ -92,8 +92,8 @@
|
|||
"useBindPortIP": true,
|
||||
"swarmMode": true,
|
||||
"network": "MyNetwork",
|
||||
"swarmModeRefreshSeconds": 42,
|
||||
"httpClientTimeout": 42
|
||||
"swarmModeRefreshSeconds": "42ns",
|
||||
"httpClientTimeout": "42ns"
|
||||
},
|
||||
"file": {
|
||||
"directory": "file Directory",
|
||||
|
@ -116,10 +116,10 @@
|
|||
"key": "xxxx",
|
||||
"insecureSkipVerify": true
|
||||
},
|
||||
"dialerTimeout": 42,
|
||||
"responseHeaderTimeout": 42,
|
||||
"tlsHandshakeTimeout": 42,
|
||||
"keepAlive": 42,
|
||||
"dialerTimeout": "42ns",
|
||||
"responseHeaderTimeout": "42ns",
|
||||
"tlsHandshakeTimeout": "42ns",
|
||||
"keepAlive": "42ns",
|
||||
"forceTaskHostname": true,
|
||||
"basic": {
|
||||
"httpBasicAuthUser": "xxxx",
|
||||
|
@ -142,7 +142,7 @@
|
|||
"hostname": "xxxx",
|
||||
"publishedService": "xxxx"
|
||||
},
|
||||
"throttleDuration": 111000000000
|
||||
"throttleDuration": "1m51s"
|
||||
},
|
||||
"kubernetesCRD": {
|
||||
"endpoint": "xxxx",
|
||||
|
@ -154,7 +154,7 @@
|
|||
],
|
||||
"labelSelector": "myLabelSelector",
|
||||
"ingressClass": "MyIngressClass",
|
||||
"throttleDuration": 111000000000
|
||||
"throttleDuration": "1m51s"
|
||||
},
|
||||
"kubernetesGateway": {
|
||||
"endpoint": "xxxx",
|
||||
|
@ -165,7 +165,7 @@
|
|||
"b"
|
||||
],
|
||||
"labelSelector": "myLabelSelector",
|
||||
"throttleDuration": 111000000000
|
||||
"throttleDuration": "1m51s"
|
||||
},
|
||||
"rest": {
|
||||
"insecure": true
|
||||
|
@ -198,10 +198,10 @@
|
|||
"username": "xxxx",
|
||||
"password": "xxxx"
|
||||
},
|
||||
"endpointWaitTime": 42
|
||||
"endpointWaitTime": "42ns"
|
||||
},
|
||||
"prefix": "MyPrefix",
|
||||
"refreshInterval": 42,
|
||||
"refreshInterval": "42ns",
|
||||
"requireConsistent": true,
|
||||
"stale": true,
|
||||
"cache": true,
|
||||
|
@ -272,8 +272,8 @@
|
|||
},
|
||||
"http": {
|
||||
"endpoint": "xxxx",
|
||||
"pollInterval": 42,
|
||||
"pollTimeout": 42,
|
||||
"pollInterval": "42ns",
|
||||
"pollTimeout": "42ns",
|
||||
"tls": {
|
||||
"ca": "xxxx",
|
||||
"caOptional": true,
|
||||
|
@ -303,13 +303,13 @@
|
|||
},
|
||||
"datadog": {
|
||||
"address": "xxxx",
|
||||
"pushInterval": 42,
|
||||
"pushInterval": "42ns",
|
||||
"addEntryPointsLabels": true,
|
||||
"addServicesLabels": true
|
||||
},
|
||||
"statsD": {
|
||||
"address": "xxxx",
|
||||
"pushInterval": 42,
|
||||
"pushInterval": "42ns",
|
||||
"addEntryPointsLabels": true,
|
||||
"addServicesLabels": true,
|
||||
"prefix": "MyPrefix"
|
||||
|
@ -317,7 +317,7 @@
|
|||
"influxDB": {
|
||||
"address": "xxxx",
|
||||
"protocol": "xxxx",
|
||||
"pushInterval": 42,
|
||||
"pushInterval": "42ns",
|
||||
"database": "myDB",
|
||||
"retentionPolicy": "12",
|
||||
"username": "xxxx",
|
||||
|
@ -345,7 +345,7 @@
|
|||
"500"
|
||||
],
|
||||
"retryAttempts": true,
|
||||
"minDuration": 42
|
||||
"minDuration": "42ns"
|
||||
},
|
||||
"fields": {
|
||||
"defaultMode": "drop",
|
||||
|
@ -428,7 +428,7 @@
|
|||
"keyType": "MyKeyType",
|
||||
"dnsChallenge": {
|
||||
"provider": "DNSProvider",
|
||||
"delayBeforeCheck": 42,
|
||||
"delayBeforeCheck": "42ns",
|
||||
"resolvers": [
|
||||
"xxxx",
|
||||
"xxxx"
|
||||
|
|
22
pkg/api/testdata/entrypoints.json
vendored
22
pkg/api/testdata/entrypoints.json
vendored
|
@ -19,13 +19,13 @@
|
|||
},
|
||||
"transport": {
|
||||
"lifeCycle": {
|
||||
"graceTimeOut": 2,
|
||||
"requestAcceptGraceTimeout": 1
|
||||
"graceTimeOut": "2ns",
|
||||
"requestAcceptGraceTimeout": "1ns"
|
||||
},
|
||||
"respondingTimeouts": {
|
||||
"idleTimeout": 5,
|
||||
"readTimeout": 3,
|
||||
"writeTimeout": 4
|
||||
"idleTimeout": "5ns",
|
||||
"readTimeout": "3ns",
|
||||
"writeTimeout": "4ns"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -49,14 +49,14 @@
|
|||
},
|
||||
"transport": {
|
||||
"lifeCycle": {
|
||||
"graceTimeOut": 20,
|
||||
"requestAcceptGraceTimeout": 10
|
||||
"graceTimeOut": "20ns",
|
||||
"requestAcceptGraceTimeout": "10ns"
|
||||
},
|
||||
"respondingTimeouts": {
|
||||
"idleTimeout": 50,
|
||||
"readTimeout": 30,
|
||||
"writeTimeout": 40
|
||||
"idleTimeout": "50ns",
|
||||
"readTimeout": "30ns",
|
||||
"writeTimeout": "40ns"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
]
|
||||
|
|
|
@ -246,7 +246,7 @@ type IPStrategy struct {
|
|||
|
||||
// Get an IP selection strategy.
|
||||
// If nil return the RemoteAddr strategy
|
||||
// else return a strategy base on the configuration using the X-Forwarded-For Header.
|
||||
// else return a strategy based on the configuration using the X-Forwarded-For Header.
|
||||
// Depth override the ExcludedIPs.
|
||||
func (s *IPStrategy) Get() (ip.Strategy, error) {
|
||||
if s == nil {
|
||||
|
@ -264,7 +264,7 @@ func (s *IPStrategy) Get() (ip.Strategy, error) {
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &ip.CheckerStrategy{
|
||||
return &ip.PoolStrategy{
|
||||
Checker: checker,
|
||||
}, nil
|
||||
}
|
||||
|
|
|
@ -15,14 +15,8 @@ func (c *Configuration) GetTCPRoutersByEntryPoints(ctx context.Context, entryPoi
|
|||
for rtName, rt := range c.TCPRouters {
|
||||
logger := log.FromContext(log.With(ctx, log.Str(log.RouterName, rtName)))
|
||||
|
||||
eps := rt.EntryPoints
|
||||
if len(eps) == 0 {
|
||||
logger.Debugf("No entryPoint defined for this router, using the default one(s) instead: %+v", entryPoints)
|
||||
eps = entryPoints
|
||||
}
|
||||
|
||||
entryPointsCount := 0
|
||||
for _, entryPointName := range eps {
|
||||
for _, entryPointName := range rt.EntryPoints {
|
||||
if !contains(entryPoints, entryPointName) {
|
||||
rt.AddError(fmt.Errorf("entryPoint %q doesn't exist", entryPointName), false)
|
||||
logger.WithField(log.EntryPointName, entryPointName).
|
||||
|
|
|
@ -43,14 +43,16 @@ func (s *DepthStrategy) GetIP(req *http.Request) string {
|
|||
return strings.TrimSpace(xffs[len(xffs)-s.Depth])
|
||||
}
|
||||
|
||||
// CheckerStrategy a strategy based on an IP Checker
|
||||
// allows to check that addresses are in a trusted IPs.
|
||||
type CheckerStrategy struct {
|
||||
// PoolStrategy is a strategy based on an IP Checker.
|
||||
// It allows to check whether addresses are in a given pool of IPs.
|
||||
type PoolStrategy struct {
|
||||
Checker *Checker
|
||||
}
|
||||
|
||||
// GetIP return the selected IP.
|
||||
func (s *CheckerStrategy) GetIP(req *http.Request) string {
|
||||
// GetIP checks the list of Forwarded IPs (most recent first) against the
|
||||
// Checker pool of IPs. It returns the first IP that is not in the pool, or the
|
||||
// empty string otherwise.
|
||||
func (s *PoolStrategy) GetIP(req *http.Request) string {
|
||||
if s.Checker == nil {
|
||||
return ""
|
||||
}
|
||||
|
@ -60,9 +62,13 @@ func (s *CheckerStrategy) GetIP(req *http.Request) string {
|
|||
|
||||
for i := len(xffs) - 1; i >= 0; i-- {
|
||||
xffTrimmed := strings.TrimSpace(xffs[i])
|
||||
if len(xffTrimmed) == 0 {
|
||||
continue
|
||||
}
|
||||
if contain, _ := s.Checker.Contains(xffTrimmed); !contain {
|
||||
return xffTrimmed
|
||||
}
|
||||
}
|
||||
|
||||
return ""
|
||||
}
|
||||
|
|
|
@ -74,34 +74,35 @@ func TestDepthStrategy_GetIP(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestExcludedIPsStrategy_GetIP(t *testing.T) {
|
||||
func TestTrustedIPsStrategy_GetIP(t *testing.T) {
|
||||
testCases := []struct {
|
||||
desc string
|
||||
excludedIPs []string
|
||||
trustedIPs []string
|
||||
xForwardedFor string
|
||||
expected string
|
||||
useRemote bool
|
||||
}{
|
||||
{
|
||||
desc: "Use excluded all IPs",
|
||||
excludedIPs: []string{"10.0.0.4", "10.0.0.3", "10.0.0.2", "10.0.0.1"},
|
||||
desc: "Trust all IPs",
|
||||
trustedIPs: []string{"10.0.0.4", "10.0.0.3", "10.0.0.2", "10.0.0.1"},
|
||||
xForwardedFor: "10.0.0.4,10.0.0.3,10.0.0.2,10.0.0.1",
|
||||
expected: "",
|
||||
},
|
||||
{
|
||||
desc: "Use excluded IPs",
|
||||
excludedIPs: []string{"10.0.0.2", "10.0.0.1"},
|
||||
desc: "Do not trust all IPs",
|
||||
trustedIPs: []string{"10.0.0.2", "10.0.0.1"},
|
||||
xForwardedFor: "10.0.0.4,10.0.0.3,10.0.0.2,10.0.0.1",
|
||||
expected: "10.0.0.3",
|
||||
},
|
||||
{
|
||||
desc: "Use excluded IPs CIDR",
|
||||
excludedIPs: []string{"10.0.0.1/24"},
|
||||
desc: "Do not trust all IPs with CIDR",
|
||||
trustedIPs: []string{"10.0.0.1/24"},
|
||||
xForwardedFor: "127.0.0.1,10.0.0.4,10.0.0.3,10.0.0.2,10.0.0.1",
|
||||
expected: "127.0.0.1",
|
||||
},
|
||||
{
|
||||
desc: "Use excluded all IPs CIDR",
|
||||
excludedIPs: []string{"10.0.0.1/24"},
|
||||
desc: "Trust all IPs with CIDR",
|
||||
trustedIPs: []string{"10.0.0.1/24"},
|
||||
xForwardedFor: "10.0.0.4,10.0.0.3,10.0.0.2,10.0.0.1",
|
||||
expected: "",
|
||||
},
|
||||
|
@ -112,10 +113,10 @@ func TestExcludedIPsStrategy_GetIP(t *testing.T) {
|
|||
t.Run(test.desc, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
checker, err := NewChecker(test.excludedIPs)
|
||||
checker, err := NewChecker(test.trustedIPs)
|
||||
require.NoError(t, err)
|
||||
|
||||
strategy := CheckerStrategy{Checker: checker}
|
||||
strategy := PoolStrategy{Checker: checker}
|
||||
req := httptest.NewRequest(http.MethodGet, "http://127.0.0.1", nil)
|
||||
req.Header.Set(xForwardedFor, test.xForwardedFor)
|
||||
actual := strategy.GetIP(req)
|
||||
|
|
|
@ -56,7 +56,7 @@ func (n MockSpan) Tracer() opentracing.Tracer { retu
|
|||
func (n MockSpan) LogEvent(event string) {}
|
||||
func (n MockSpan) LogEventWithPayload(event string, payload interface{}) {}
|
||||
func (n MockSpan) Log(data opentracing.LogData) {}
|
||||
func (n MockSpan) Reset() {
|
||||
func (n *MockSpan) Reset() {
|
||||
n.Tags = make(map[string]interface{})
|
||||
}
|
||||
|
||||
|
|
|
@ -281,7 +281,7 @@ func unzipFile(f *zipa.File, dest string) error {
|
|||
|
||||
defer func() { _ = rc.Close() }()
|
||||
|
||||
pathParts := strings.SplitN(f.Name, string(os.PathSeparator), 2)
|
||||
pathParts := strings.SplitN(f.Name, "/", 2)
|
||||
p := filepath.Join(dest, pathParts[1])
|
||||
|
||||
if f.FileInfo().IsDir() {
|
||||
|
|
|
@ -473,9 +473,10 @@ func (p *Provider) resolveCertificate(ctx context.Context, domain types.Domain,
|
|||
}
|
||||
|
||||
request := certificate.ObtainRequest{
|
||||
Domains: domains,
|
||||
Bundle: true,
|
||||
MustStaple: oscpMustStaple,
|
||||
Domains: domains,
|
||||
Bundle: true,
|
||||
MustStaple: oscpMustStaple,
|
||||
PreferredChain: p.PreferredChain,
|
||||
}
|
||||
|
||||
cert, err := client.Certificate.Obtain(request)
|
||||
|
|
|
@ -26,7 +26,7 @@ var _ provider.Provider = (*Provider)(nil)
|
|||
|
||||
// Provider holds configurations of the provider.
|
||||
type Provider struct {
|
||||
Directory string `description:"Load dynamic configuration from one or more .toml or .yml files in a directory." json:"directory,omitempty" toml:"directory,omitempty" yaml:"directory,omitempty" export:"true"`
|
||||
Directory string `description:"Load dynamic configuration from one or more .yml or .toml files in a directory." json:"directory,omitempty" toml:"directory,omitempty" yaml:"directory,omitempty" export:"true"`
|
||||
Watch bool `description:"Watch provider." json:"watch,omitempty" toml:"watch,omitempty" yaml:"watch,omitempty" export:"true"`
|
||||
Filename string `description:"Load dynamic configuration from a file." json:"filename,omitempty" toml:"filename,omitempty" yaml:"filename,omitempty" export:"true"`
|
||||
DebugLogGeneratedTemplate bool `description:"Enable debug logging of generated configuration template." json:"debugLogGeneratedTemplate,omitempty" toml:"debugLogGeneratedTemplate,omitempty" yaml:"debugLogGeneratedTemplate,omitempty" export:"true"`
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
kind: Endpoints
|
||||
apiVersion: v1
|
||||
metadata:
|
||||
name: service1
|
||||
namespace: testing
|
||||
|
||||
subsets:
|
||||
- addresses:
|
||||
- ip: 10.10.0.1
|
||||
- ip: 10.10.0.2
|
||||
ports:
|
||||
- name: tchouk
|
||||
port: 8089
|
||||
- addresses:
|
||||
- ip: 10.10.0.1
|
||||
- ip: 10.10.0.2
|
||||
- ip: 10.10.0.3
|
||||
ports:
|
||||
- name: carotte
|
||||
port: 8090
|
|
@ -0,0 +1,15 @@
|
|||
kind: Ingress
|
||||
apiVersion: networking.k8s.io/v1beta1
|
||||
metadata:
|
||||
name: ""
|
||||
namespace: testing
|
||||
|
||||
spec:
|
||||
rules:
|
||||
- host: traefik.tchouk
|
||||
http:
|
||||
paths:
|
||||
- path: /bar
|
||||
backend:
|
||||
serviceName: service1
|
||||
servicePort: tchouk
|
|
@ -0,0 +1,14 @@
|
|||
kind: Service
|
||||
apiVersion: v1
|
||||
metadata:
|
||||
name: service1
|
||||
namespace: testing
|
||||
|
||||
spec:
|
||||
ports:
|
||||
- name: carotte
|
||||
port: 8082
|
||||
- name: tchouk
|
||||
port: 80
|
||||
clusterIP: 10.0.0.1
|
||||
|
|
@ -555,8 +555,8 @@ func loadService(client Client, namespace string, backend networkingv1.IngressBa
|
|||
return nil, errors.New("endpoints not found")
|
||||
}
|
||||
|
||||
var port int32
|
||||
for _, subset := range endpoints.Subsets {
|
||||
var port int32
|
||||
for _, p := range subset.Ports {
|
||||
if portName == p.Name {
|
||||
port = p.Port
|
||||
|
|
|
@ -647,6 +647,36 @@ func TestLoadConfigurationFromIngresses(t *testing.T) {
|
|||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
desc: "Ingress with a named port matching subset of service pods",
|
||||
expected: &dynamic.Configuration{
|
||||
TCP: &dynamic.TCPConfiguration{},
|
||||
HTTP: &dynamic.HTTPConfiguration{
|
||||
Middlewares: map[string]*dynamic.Middleware{},
|
||||
Routers: map[string]*dynamic.Router{
|
||||
"testing-traefik-tchouk-bar": {
|
||||
Rule: "Host(`traefik.tchouk`) && PathPrefix(`/bar`)",
|
||||
Service: "testing-service1-tchouk",
|
||||
},
|
||||
},
|
||||
Services: map[string]*dynamic.Service{
|
||||
"testing-service1-tchouk": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
PassHostHeader: Bool(true),
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
URL: "http://10.10.0.1:8089",
|
||||
},
|
||||
{
|
||||
URL: "http://10.10.0.2:8089",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
desc: "2 ingresses in different namespace with same service name",
|
||||
expected: &dynamic.Configuration{
|
||||
|
|
|
@ -62,6 +62,12 @@ func mergeConfiguration(configurations dynamic.Configurations, defaultEntryPoint
|
|||
|
||||
if configuration.TCP != nil {
|
||||
for routerName, router := range configuration.TCP.Routers {
|
||||
if len(router.EntryPoints) == 0 {
|
||||
log.WithoutContext().
|
||||
WithField(log.RouterName, routerName).
|
||||
Debugf("No entryPoint defined for this TCP router, using the default one(s) instead: %+v", defaultEntryPoints)
|
||||
router.EntryPoints = defaultEntryPoints
|
||||
}
|
||||
conf.TCP.Routers[provider.MakeQualifiedName(pvd, routerName)] = router
|
||||
}
|
||||
for middlewareName, middleware := range configuration.TCP.Middlewares {
|
||||
|
|
|
@ -449,6 +449,36 @@ func Test_mergeConfiguration_tlsStore(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func Test_mergeConfiguration_defaultTCPEntryPoint(t *testing.T) {
|
||||
given := dynamic.Configurations{
|
||||
"provider-1": &dynamic.Configuration{
|
||||
TCP: &dynamic.TCPConfiguration{
|
||||
Routers: map[string]*dynamic.TCPRouter{
|
||||
"router-1": {},
|
||||
},
|
||||
Services: map[string]*dynamic.TCPService{
|
||||
"service-1": {},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
expected := &dynamic.TCPConfiguration{
|
||||
Routers: map[string]*dynamic.TCPRouter{
|
||||
"router-1@provider-1": {
|
||||
EntryPoints: []string{"defaultEP"},
|
||||
},
|
||||
},
|
||||
Middlewares: map[string]*dynamic.TCPMiddleware{},
|
||||
Services: map[string]*dynamic.TCPService{
|
||||
"service-1@provider-1": {},
|
||||
},
|
||||
}
|
||||
|
||||
actual := mergeConfiguration(given, []string{"defaultEP"})
|
||||
assert.Equal(t, expected, actual.TCP)
|
||||
}
|
||||
|
||||
func Test_applyModel(t *testing.T) {
|
||||
testCases := []struct {
|
||||
desc string
|
||||
|
|
|
@ -15,6 +15,8 @@ import (
|
|||
"github.com/traefik/traefik/v2/pkg/types"
|
||||
)
|
||||
|
||||
const defaultBufSize = 4096
|
||||
|
||||
// Router is a TCP router.
|
||||
type Router struct {
|
||||
routingTable map[string]Handler
|
||||
|
@ -238,6 +240,11 @@ func clientHelloServerName(br *bufio.Reader) (string, bool, string, error) {
|
|||
}
|
||||
|
||||
recLen := int(hdr[3])<<8 | int(hdr[4]) // ignoring version in hdr[1:3]
|
||||
|
||||
if recordHeaderLen+recLen > defaultBufSize {
|
||||
br = bufio.NewReaderSize(br, recordHeaderLen+recLen)
|
||||
}
|
||||
|
||||
helloBytes, err := br.Peek(recordHeaderLen + recLen)
|
||||
if err != nil {
|
||||
log.Errorf("Error while Hello: %s", err)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue