move internal/net to pkg/net package (#12505)

This commit is contained in:
Harshavardhana 2021-06-14 14:54:37 -07:00 committed by GitHub
parent ed6cc66cf4
commit da74e2f167
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
45 changed files with 45 additions and 1096 deletions

View file

@ -47,8 +47,8 @@ import (
"github.com/minio/minio/internal/kms"
"github.com/minio/minio/internal/logger"
"github.com/minio/minio/internal/logger/message/log"
xnet "github.com/minio/minio/internal/net"
iampolicy "github.com/minio/pkg/iam/policy"
xnet "github.com/minio/pkg/net"
)
const (

View file

@ -41,7 +41,7 @@ import (
"github.com/minio/minio/internal/event/target"
"github.com/minio/minio/internal/kms"
"github.com/minio/minio/internal/logger"
xnet "github.com/minio/minio/internal/net"
xnet "github.com/minio/pkg/net"
"github.com/minio/pkg/quick"
)

View file

@ -25,8 +25,8 @@ import (
"github.com/minio/minio/internal/logger"
"github.com/minio/minio/internal/logger/message/log"
"github.com/minio/minio/internal/logger/target/console"
xnet "github.com/minio/minio/internal/net"
"github.com/minio/minio/internal/pubsub"
xnet "github.com/minio/pkg/net"
)
// number of log messages to buffer

View file

@ -39,8 +39,8 @@ import (
xhttp "github.com/minio/minio/internal/http"
"github.com/minio/minio/internal/logger"
"github.com/minio/minio/internal/mountinfo"
xnet "github.com/minio/minio/internal/net"
"github.com/minio/pkg/env"
xnet "github.com/minio/pkg/net"
)
// EndpointType - enum for endpoint type.

View file

@ -28,8 +28,8 @@ import (
"github.com/minio/minio/internal/hash"
xhttp "github.com/minio/minio/internal/http"
"github.com/minio/minio/internal/logger"
xnet "github.com/minio/minio/internal/net"
"github.com/minio/pkg/env"
xnet "github.com/minio/pkg/net"
minio "github.com/minio/minio-go/v7"
)

View file

@ -42,8 +42,8 @@ import (
"github.com/minio/minio-go/v7/pkg/s3utils"
minio "github.com/minio/minio/cmd"
"github.com/minio/minio/internal/logger"
xnet "github.com/minio/minio/internal/net"
"github.com/minio/pkg/env"
xnet "github.com/minio/pkg/net"
)
const (

View file

@ -28,7 +28,7 @@ import (
"github.com/minio/minio-go/v7/pkg/set"
"github.com/minio/minio/internal/config"
"github.com/minio/minio/internal/logger"
xnet "github.com/minio/minio/internal/net"
xnet "github.com/minio/pkg/net"
)
// IPv4 addresses of local host.

View file

@ -41,9 +41,9 @@ import (
"github.com/minio/minio/internal/event"
xhttp "github.com/minio/minio/internal/http"
"github.com/minio/minio/internal/logger"
xnet "github.com/minio/minio/internal/net"
"github.com/minio/minio/internal/sync/errgroup"
"github.com/minio/pkg/bucket/policy"
xnet "github.com/minio/pkg/net"
)
// NotificationSys - notification system.

View file

@ -55,10 +55,10 @@ import (
"github.com/minio/minio/internal/ioutil"
"github.com/minio/minio/internal/kms"
"github.com/minio/minio/internal/logger"
xnet "github.com/minio/minio/internal/net"
"github.com/minio/minio/internal/s3select"
"github.com/minio/pkg/bucket/policy"
iampolicy "github.com/minio/pkg/iam/policy"
xnet "github.com/minio/pkg/net"
"github.com/minio/sio"
)

View file

@ -38,8 +38,8 @@ import (
"github.com/minio/minio/internal/http"
xhttp "github.com/minio/minio/internal/http"
"github.com/minio/minio/internal/logger"
xnet "github.com/minio/minio/internal/net"
"github.com/minio/minio/internal/rest"
xnet "github.com/minio/pkg/net"
"github.com/tinylib/msgp/msgp"
)

View file

@ -31,8 +31,8 @@ import (
"github.com/minio/minio/internal/crypto"
"github.com/minio/minio/internal/ioutil"
"github.com/minio/minio/internal/logger"
xnet "github.com/minio/minio/internal/net"
"github.com/minio/pkg/bucket/policy"
xnet "github.com/minio/pkg/net"
"github.com/minio/zipindex"
)

View file

@ -29,7 +29,7 @@ import (
color "github.com/minio/minio/internal/color"
"github.com/minio/minio/internal/config"
"github.com/minio/minio/internal/logger"
xnet "github.com/minio/minio/internal/net"
xnet "github.com/minio/pkg/net"
)
// Documentation links, these are part of message printing code.

View file

@ -34,8 +34,8 @@ import (
xhttp "github.com/minio/minio/internal/http"
"github.com/minio/minio/internal/logger"
xnet "github.com/minio/minio/internal/net"
"github.com/minio/minio/internal/rest"
xnet "github.com/minio/pkg/net"
xbufio "github.com/philhofer/fwd"
"github.com/tinylib/msgp/msgp"
)

View file

@ -43,7 +43,7 @@ import (
xhttp "github.com/minio/minio/internal/http"
xjwt "github.com/minio/minio/internal/jwt"
"github.com/minio/minio/internal/logger"
xnet "github.com/minio/minio/internal/net"
xnet "github.com/minio/pkg/net"
)
var errDiskStale = errors.New("disk stale")

View file

@ -27,7 +27,7 @@ import (
"github.com/gorilla/mux"
"github.com/minio/minio/internal/config"
xnet "github.com/minio/minio/internal/net"
xnet "github.com/minio/pkg/net"
)
///////////////////////////////////////////////////////////////////////////////

View file

@ -37,8 +37,8 @@ import (
xhttp "github.com/minio/minio/internal/http"
"github.com/minio/minio/internal/logger"
xnet "github.com/minio/minio/internal/net"
"github.com/minio/pkg/env"
xnet "github.com/minio/pkg/net"
"github.com/minio/selfupdate"
)

6
go.mod
View file

@ -44,10 +44,10 @@ require (
github.com/minio/csvparser v1.0.0
github.com/minio/highwayhash v1.0.2
github.com/minio/kes v0.14.0
github.com/minio/madmin-go v1.0.11
github.com/minio/madmin-go v1.0.12
github.com/minio/minio-go/v7 v7.0.11-0.20210302210017-6ae69c73ce78
github.com/minio/parquet-go v1.0.0
github.com/minio/pkg v1.0.4
github.com/minio/pkg v1.0.7
github.com/minio/rpc v1.0.0
github.com/minio/selfupdate v0.3.1
github.com/minio/sha256-simd v1.0.0
@ -55,7 +55,7 @@ require (
github.com/minio/sio v0.3.0
github.com/minio/zipindex v0.2.0
github.com/mitchellh/go-homedir v1.1.0
github.com/montanaflynn/stats v0.5.0
github.com/montanaflynn/stats v0.6.6
github.com/nats-io/nats-server/v2 v2.1.9
github.com/nats-io/nats-streaming-server v0.21.2 // indirect
github.com/nats-io/nats.go v1.10.0

12
go.sum
View file

@ -483,8 +483,8 @@ github.com/minio/highwayhash v1.0.2 h1:Aak5U0nElisjDCfPSG79Tgzkn2gl66NxOMspRrKnA
github.com/minio/highwayhash v1.0.2/go.mod h1:BQskDq+xkJ12lmlUUi7U0M5Swg3EWR+dLTk+kldvVxY=
github.com/minio/kes v0.14.0 h1:plCGm4LwR++T1P1sXsJbyFRX54CE1WRuo9PAPj6MC3Q=
github.com/minio/kes v0.14.0/go.mod h1:OUensXz2BpgMfiogslKxv7Anyx/wj+6bFC6qA7BQcfA=
github.com/minio/madmin-go v1.0.11 h1:oyTsINMIgyF1OrjtAgef+gfbwH0i6Kxk3waY1mAcN58=
github.com/minio/madmin-go v1.0.11/go.mod h1:BK+z4XRx7Y1v8SFWXsuLNqQqnq5BO/axJ8IDJfgyvfs=
github.com/minio/madmin-go v1.0.12 h1:5FjqXgPR6rK6QX+HS88u+FCAiFLKleAiMuRvdDhWNPc=
github.com/minio/madmin-go v1.0.12/go.mod h1:BK+z4XRx7Y1v8SFWXsuLNqQqnq5BO/axJ8IDJfgyvfs=
github.com/minio/md5-simd v1.1.0 h1:QPfiOqlZH+Cj9teu0t9b1nTBfPbyTl16Of5MeuShdK4=
github.com/minio/md5-simd v1.1.0/go.mod h1:XpBqgZULrMYD3R+M28PcmP0CkI7PEMzB3U77ZrKZ0Gw=
github.com/minio/minio-go/v7 v7.0.10/go.mod h1:td4gW1ldOsj1PbSNS+WYK43j+P1XVhX/8W8awaYlBFo=
@ -492,8 +492,8 @@ github.com/minio/minio-go/v7 v7.0.11-0.20210302210017-6ae69c73ce78 h1:v7OMbUnWky
github.com/minio/minio-go/v7 v7.0.11-0.20210302210017-6ae69c73ce78/go.mod h1:mTh2uJuAbEqdhMVl6CMIIZLUeiMiWtJR4JB8/5g2skw=
github.com/minio/parquet-go v1.0.0 h1:fcWsEvub04Nsl/4hiRBDWlbqd6jhacQieV07a+nhiIk=
github.com/minio/parquet-go v1.0.0/go.mod h1:aQlkSOfOq2AtQKkuou3mosNVMwNokd+faTacxxk/oHA=
github.com/minio/pkg v1.0.4 h1:+BmaCENP6BaMm9PsGK6L1L5MKulWDxl4qobvJYf6m/E=
github.com/minio/pkg v1.0.4/go.mod h1:obU54TZ9QlMv0TRaDgQ/JTzf11ZSXxnSfLrm4tMtBP8=
github.com/minio/pkg v1.0.7 h1:+vUH/qWfjVpysbVJeebkhCh8QqQ8H6uYdmqLfb34X2E=
github.com/minio/pkg v1.0.7/go.mod h1:32x/3OmGB0EOi1N+3ggnp+B5VFkSBBB9svPMVfpnf14=
github.com/minio/rpc v1.0.0 h1:tJCHyLfQF6k6HlMQFpKy2FO/7lc2WP8gLDGMZp18E70=
github.com/minio/rpc v1.0.0/go.mod h1:b9xqF7J0xeMXr0cM4pnBlP7Te7PDsG5JrRxl5dG6Ldk=
github.com/minio/selfupdate v0.3.1 h1:BWEFSNnrZVMUWXbXIgLDNDjbejkmpAmZvy/nCz1HlEs=
@ -529,8 +529,8 @@ github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJ
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI=
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
github.com/montanaflynn/stats v0.5.0 h1:2EkzeTSqBB4V4bJwWrt5gIIrZmpJBcoIRGS2kWLgzmk=
github.com/montanaflynn/stats v0.5.0/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc=
github.com/montanaflynn/stats v0.6.6 h1:Duep6KMIDpY4Yo11iFsvyqJDyfzLF9+sndUKT+v64GQ=
github.com/montanaflynn/stats v0.6.6/go.mod h1:etXPPgVO6n31NxCd9KQUMvCM+ve0ruNzt6R8Bnaayow=
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
github.com/nats-io/jwt v0.3.0/go.mod h1:fRYCDE99xlTsqUzISS1Bi75UBJ6ljOJQOAAu5VglpSg=

View file

@ -24,8 +24,8 @@ import (
"time"
"github.com/minio/minio/internal/config"
xnet "github.com/minio/minio/internal/net"
"github.com/minio/pkg/env"
xnet "github.com/minio/pkg/net"
clientv3 "go.etcd.io/etcd/client/v3"
"go.etcd.io/etcd/client/v3/namespace"
"go.uber.org/zap"

View file

@ -32,9 +32,9 @@ import (
jwtgo "github.com/dgrijalva/jwt-go"
"github.com/minio/minio/internal/auth"
"github.com/minio/minio/internal/config"
xnet "github.com/minio/minio/internal/net"
"github.com/minio/pkg/env"
iampolicy "github.com/minio/pkg/iam/policy"
xnet "github.com/minio/pkg/net"
)
// Config - OpenID Config

View file

@ -25,7 +25,7 @@ import (
"testing"
"time"
xnet "github.com/minio/minio/internal/net"
xnet "github.com/minio/pkg/net"
)
func TestUpdateClaimsExpiry(t *testing.T) {

View file

@ -22,7 +22,7 @@ import (
"net/http/httptest"
"testing"
xnet "github.com/minio/minio/internal/net"
xnet "github.com/minio/pkg/net"
)
type errorValidator struct{}

View file

@ -31,8 +31,8 @@ import (
"github.com/minio/minio/internal/event"
"github.com/minio/minio/internal/event/target"
"github.com/minio/minio/internal/logger"
xnet "github.com/minio/minio/internal/net"
"github.com/minio/pkg/env"
xnet "github.com/minio/pkg/net"
)
const (

View file

@ -25,9 +25,9 @@ import (
"net/http"
"github.com/minio/minio/internal/config"
xnet "github.com/minio/minio/internal/net"
"github.com/minio/pkg/env"
iampolicy "github.com/minio/pkg/iam/policy"
xnet "github.com/minio/pkg/net"
)
// Env IAM OPA URL

View file

@ -29,7 +29,7 @@ import (
"sync"
"github.com/minio/minio/internal/event"
xnet "github.com/minio/minio/internal/net"
xnet "github.com/minio/pkg/net"
"github.com/streadway/amqp"
)

View file

@ -34,7 +34,7 @@ import (
"time"
"github.com/minio/minio/internal/event"
xnet "github.com/minio/minio/internal/net"
xnet "github.com/minio/pkg/net"
"github.com/pkg/errors"
elasticsearch7 "github.com/elastic/go-elasticsearch/v7"

View file

@ -29,7 +29,7 @@ import (
"path/filepath"
"github.com/minio/minio/internal/event"
xnet "github.com/minio/minio/internal/net"
xnet "github.com/minio/pkg/net"
sarama "github.com/Shopify/sarama"
saramatls "github.com/Shopify/sarama/tools/tls"

View file

@ -31,7 +31,7 @@ import (
mqtt "github.com/eclipse/paho.mqtt.golang"
"github.com/minio/minio/internal/event"
xnet "github.com/minio/minio/internal/net"
xnet "github.com/minio/pkg/net"
)
const (

View file

@ -32,7 +32,7 @@ import (
"github.com/go-sql-driver/mysql"
"github.com/minio/minio/internal/event"
xnet "github.com/minio/minio/internal/net"
xnet "github.com/minio/pkg/net"
)
const (

View file

@ -28,7 +28,7 @@ import (
"path/filepath"
"github.com/minio/minio/internal/event"
xnet "github.com/minio/minio/internal/net"
xnet "github.com/minio/pkg/net"
"github.com/nats-io/nats.go"
"github.com/nats-io/stan.go"
)

View file

@ -19,7 +19,7 @@ package target
import (
"testing"
xnet "github.com/minio/minio/internal/net"
xnet "github.com/minio/pkg/net"
natsserver "github.com/nats-io/nats-server/v2/test"
)

View file

@ -21,7 +21,7 @@ import (
"path/filepath"
"testing"
xnet "github.com/minio/minio/internal/net"
xnet "github.com/minio/pkg/net"
natsserver "github.com/nats-io/nats-server/v2/test"
)

View file

@ -29,7 +29,7 @@ import (
"github.com/nsqio/go-nsq"
"github.com/minio/minio/internal/event"
xnet "github.com/minio/minio/internal/net"
xnet "github.com/minio/pkg/net"
)
// NSQ constants

View file

@ -20,7 +20,7 @@ package target
import (
"testing"
xnet "github.com/minio/minio/internal/net"
xnet "github.com/minio/pkg/net"
)
func TestNSQArgs_Validate(t *testing.T) {

View file

@ -33,7 +33,7 @@ import (
_ "github.com/lib/pq" // Register postgres driver
"github.com/minio/minio/internal/event"
xnet "github.com/minio/minio/internal/net"
xnet "github.com/minio/pkg/net"
)
const (

View file

@ -30,7 +30,7 @@ import (
"github.com/gomodule/redigo/redis"
"github.com/minio/minio/internal/event"
xnet "github.com/minio/minio/internal/net"
xnet "github.com/minio/pkg/net"
)
// Redis constants

View file

@ -33,8 +33,8 @@ import (
"time"
"github.com/minio/minio/internal/event"
xnet "github.com/minio/minio/internal/net"
"github.com/minio/pkg/certs"
xnet "github.com/minio/pkg/net"
)
// Webhook constants

View file

@ -1,97 +0,0 @@
// Copyright (c) 2015-2021 MinIO, Inc.
//
// This file is part of MinIO Object Storage stack
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
package net
import (
"github.com/minio/madmin-go"
"github.com/montanaflynn/stats"
)
// ComputePerfStats takes arrays of Latency & Throughput to compute Statistics
func ComputePerfStats(latencies, throughputs []float64) (madmin.NetLatency, madmin.NetThroughput, error) {
var avgLatency float64
var percentile50Latency float64
var percentile90Latency float64
var percentile99Latency float64
var minLatency float64
var maxLatency float64
var avgThroughput float64
var percentile50Throughput float64
var percentile90Throughput float64
var percentile99Throughput float64
var minThroughput float64
var maxThroughput float64
var err error
if avgLatency, err = stats.Mean(latencies); err != nil {
return madmin.NetLatency{}, madmin.NetThroughput{}, err
}
if percentile50Latency, err = stats.Percentile(latencies, 50); err != nil {
return madmin.NetLatency{}, madmin.NetThroughput{}, err
}
if percentile90Latency, err = stats.Percentile(latencies, 90); err != nil {
return madmin.NetLatency{}, madmin.NetThroughput{}, err
}
if percentile99Latency, err = stats.Percentile(latencies, 99); err != nil {
return madmin.NetLatency{}, madmin.NetThroughput{}, err
}
if maxLatency, err = stats.Max(latencies); err != nil {
return madmin.NetLatency{}, madmin.NetThroughput{}, err
}
if minLatency, err = stats.Min(latencies); err != nil {
return madmin.NetLatency{}, madmin.NetThroughput{}, err
}
l := madmin.NetLatency{
Avg: avgLatency,
Percentile50: percentile50Latency,
Percentile90: percentile90Latency,
Percentile99: percentile99Latency,
Min: minLatency,
Max: maxLatency,
}
if avgThroughput, err = stats.Mean(throughputs); err != nil {
return madmin.NetLatency{}, madmin.NetThroughput{}, err
}
if percentile50Throughput, err = stats.Percentile(throughputs, 50); err != nil {
return madmin.NetLatency{}, madmin.NetThroughput{}, err
}
if percentile90Throughput, err = stats.Percentile(throughputs, 90); err != nil {
return madmin.NetLatency{}, madmin.NetThroughput{}, err
}
if percentile99Throughput, err = stats.Percentile(throughputs, 99); err != nil {
return madmin.NetLatency{}, madmin.NetThroughput{}, err
}
if maxThroughput, err = stats.Max(throughputs); err != nil {
return madmin.NetLatency{}, madmin.NetThroughput{}, err
}
if minThroughput, err = stats.Min(throughputs); err != nil {
return madmin.NetLatency{}, madmin.NetThroughput{}, err
}
t := madmin.NetThroughput{
Avg: avgThroughput,
Percentile50: percentile50Throughput,
Percentile90: percentile90Throughput,
Percentile99: percentile99Throughput,
Min: minThroughput,
Max: maxThroughput,
}
return l, t, nil
}

View file

@ -1,171 +0,0 @@
// Copyright (c) 2015-2021 MinIO, Inc.
//
// This file is part of MinIO Object Storage stack
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
package net
import (
"encoding/json"
"errors"
"net"
"regexp"
"strings"
)
var hostLabelRegexp = regexp.MustCompile("^[a-zA-Z0-9]([a-zA-Z0-9-]*[a-zA-Z0-9])?$")
// Host - holds network host IP/name and its port.
type Host struct {
Name string
Port Port
IsPortSet bool
}
// IsEmpty - returns whether Host is empty or not
func (host Host) IsEmpty() bool {
return host.Name == ""
}
// String - returns string representation of Host.
func (host Host) String() string {
if !host.IsPortSet {
return host.Name
}
return net.JoinHostPort(host.Name, host.Port.String())
}
// Equal - checks whether given host is equal or not.
func (host Host) Equal(compHost Host) bool {
return host.String() == compHost.String()
}
// MarshalJSON - converts Host into JSON data
func (host Host) MarshalJSON() ([]byte, error) {
return json.Marshal(host.String())
}
// UnmarshalJSON - parses data into Host.
func (host *Host) UnmarshalJSON(data []byte) (err error) {
var s string
if err = json.Unmarshal(data, &s); err != nil {
return err
}
// Allow empty string
if s == "" {
*host = Host{}
return nil
}
var h *Host
if h, err = ParseHost(s); err != nil {
return err
}
*host = *h
return nil
}
// ParseHost - parses string into Host
func ParseHost(s string) (*Host, error) {
if s == "" {
return nil, errors.New("invalid argument")
}
isValidHost := func(host string) bool {
if host == "" {
return true
}
if ip := net.ParseIP(host); ip != nil {
return true
}
// host is not a valid IPv4 or IPv6 address
// host may be a hostname
// refer https://en.wikipedia.org/wiki/Hostname#Restrictions_on_valid_host_names
// why checks are done like below
if len(host) < 1 || len(host) > 253 {
return false
}
for _, label := range strings.Split(host, ".") {
if len(label) < 1 || len(label) > 63 {
return false
}
if !hostLabelRegexp.MatchString(label) {
return false
}
}
return true
}
var port Port
var isPortSet bool
host, portStr, err := net.SplitHostPort(s)
if err != nil {
if !strings.Contains(err.Error(), "missing port in address") {
return nil, err
}
host = s
} else {
if port, err = ParsePort(portStr); err != nil {
return nil, err
}
isPortSet = true
}
if host != "" {
host, err = trimIPv6(host)
if err != nil {
return nil, err
}
}
// IPv6 requires a link-local address on every network interface.
// `%interface` should be preserved.
trimmedHost := host
if i := strings.LastIndex(trimmedHost, "%"); i > -1 {
// `%interface` can be skipped for validity check though.
trimmedHost = trimmedHost[:i]
}
if !isValidHost(trimmedHost) {
return nil, errors.New("invalid hostname")
}
return &Host{
Name: host,
Port: port,
IsPortSet: isPortSet,
}, nil
}
// IPv6 can be embedded with square brackets.
func trimIPv6(host string) (string, error) {
// `missing ']' in host` error is already handled in `SplitHostPort`
if host[len(host)-1] == ']' {
if host[0] != '[' {
return "", errors.New("missing '[' in host")
}
return host[1:][:len(host)-2], nil
}
return host, nil
}

View file

@ -1,251 +0,0 @@
// Copyright (c) 2015-2021 MinIO, Inc.
//
// This file is part of MinIO Object Storage stack
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
package net
import (
"reflect"
"testing"
)
func TestHostIsEmpty(t *testing.T) {
testCases := []struct {
host Host
expectedResult bool
}{
{Host{"", 0, false}, true},
{Host{"", 0, true}, true},
{Host{"play", 9000, false}, false},
{Host{"play", 9000, true}, false},
}
for i, testCase := range testCases {
result := testCase.host.IsEmpty()
if result != testCase.expectedResult {
t.Fatalf("test %v: result: expected: %v, got: %v", i+1, testCase.expectedResult, result)
}
}
}
func TestHostString(t *testing.T) {
testCases := []struct {
host Host
expectedStr string
}{
{Host{"", 0, false}, ""},
{Host{"", 0, true}, ":0"},
{Host{"play", 9000, false}, "play"},
{Host{"play", 9000, true}, "play:9000"},
}
for i, testCase := range testCases {
str := testCase.host.String()
if str != testCase.expectedStr {
t.Fatalf("test %v: string: expected: %v, got: %v", i+1, testCase.expectedStr, str)
}
}
}
func TestHostEqual(t *testing.T) {
testCases := []struct {
host Host
compHost Host
expectedResult bool
}{
{Host{"", 0, false}, Host{"", 0, true}, false},
{Host{"play", 9000, true}, Host{"play", 9000, false}, false},
{Host{"", 0, true}, Host{"", 0, true}, true},
{Host{"play", 9000, false}, Host{"play", 9000, false}, true},
{Host{"play", 9000, true}, Host{"play", 9000, true}, true},
}
for i, testCase := range testCases {
result := testCase.host.Equal(testCase.compHost)
if result != testCase.expectedResult {
t.Fatalf("test %v: string: expected: %v, got: %v", i+1, testCase.expectedResult, result)
}
}
}
func TestHostMarshalJSON(t *testing.T) {
testCases := []struct {
host Host
expectedData []byte
expectErr bool
}{
{Host{}, []byte(`""`), false},
{Host{"play", 0, false}, []byte(`"play"`), false},
{Host{"play", 0, true}, []byte(`"play:0"`), false},
{Host{"play", 9000, true}, []byte(`"play:9000"`), false},
{Host{"play.min.io", 0, false}, []byte(`"play.min.io"`), false},
{Host{"play.min.io", 9000, true}, []byte(`"play.min.io:9000"`), false},
{Host{"147.75.201.93", 0, false}, []byte(`"147.75.201.93"`), false},
{Host{"147.75.201.93", 9000, true}, []byte(`"147.75.201.93:9000"`), false},
{Host{"play12", 0, false}, []byte(`"play12"`), false},
{Host{"12play", 0, false}, []byte(`"12play"`), false},
{Host{"play-minio-io", 0, false}, []byte(`"play-minio-io"`), false},
{Host{"play--min.io", 0, false}, []byte(`"play--min.io"`), false},
}
for i, testCase := range testCases {
data, err := testCase.host.MarshalJSON()
expectErr := (err != nil)
if expectErr != testCase.expectErr {
t.Fatalf("test %v: error: expected: %v, got: %v", i+1, testCase.expectErr, expectErr)
}
if !testCase.expectErr {
if !reflect.DeepEqual(data, testCase.expectedData) {
t.Fatalf("test %v: data: expected: %v, got: %v", i+1, string(testCase.expectedData), string(data))
}
}
}
}
func TestHostUnmarshalJSON(t *testing.T) {
testCases := []struct {
data []byte
expectedHost *Host
expectErr bool
}{
{[]byte(`""`), &Host{}, false},
{[]byte(`"play"`), &Host{"play", 0, false}, false},
{[]byte(`"play:0"`), &Host{"play", 0, true}, false},
{[]byte(`"play:9000"`), &Host{"play", 9000, true}, false},
{[]byte(`"play.min.io"`), &Host{"play.min.io", 0, false}, false},
{[]byte(`"play.min.io:9000"`), &Host{"play.min.io", 9000, true}, false},
{[]byte(`"147.75.201.93"`), &Host{"147.75.201.93", 0, false}, false},
{[]byte(`"147.75.201.93:9000"`), &Host{"147.75.201.93", 9000, true}, false},
{[]byte(`"play12"`), &Host{"play12", 0, false}, false},
{[]byte(`"12play"`), &Host{"12play", 0, false}, false},
{[]byte(`"play-minio-io"`), &Host{"play-minio-io", 0, false}, false},
{[]byte(`"play--min.io"`), &Host{"play--min.io", 0, false}, false},
{[]byte(`":9000"`), &Host{"", 9000, true}, false},
{[]byte(`"[fe80::8097:76eb:b397:e067%wlp2s0]"`), &Host{"fe80::8097:76eb:b397:e067%wlp2s0", 0, false}, false},
{[]byte(`"[fe80::8097:76eb:b397:e067]:9000"`), &Host{"fe80::8097:76eb:b397:e067", 9000, true}, false},
{[]byte(`"fe80::8097:76eb:b397:e067%wlp2s0"`), nil, true},
{[]byte(`"fe80::8097:76eb:b397:e067%wlp2s0]"`), nil, true},
{[]byte(`"[fe80::8097:76eb:b397:e067%wlp2s0"`), nil, true},
{[]byte(`"[[fe80::8097:76eb:b397:e067%wlp2s0]]"`), nil, true},
{[]byte(`"[[fe80::8097:76eb:b397:e067%wlp2s0"`), nil, true},
{[]byte(`"play:"`), nil, true},
{[]byte(`"play::"`), nil, true},
{[]byte(`"play:90000"`), nil, true},
{[]byte(`"play:-10"`), nil, true},
{[]byte(`"play-"`), nil, true},
{[]byte(`"play.minio..io"`), nil, true},
{[]byte(`":"`), nil, true},
}
for _, testCase := range testCases {
testCase := testCase
t.Run("", func(t *testing.T) {
var host Host
err := host.UnmarshalJSON(testCase.data)
expectErr := (err != nil)
if expectErr != testCase.expectErr {
t.Errorf("error: expected: %v, got: %v", testCase.expectErr, expectErr)
}
if !testCase.expectErr {
if !reflect.DeepEqual(&host, testCase.expectedHost) {
t.Errorf("host: expected: %#v, got: %#v", testCase.expectedHost, host)
}
}
})
}
}
func TestParseHost(t *testing.T) {
testCases := []struct {
s string
expectedHost *Host
expectErr bool
}{
{"play", &Host{"play", 0, false}, false},
{"play:0", &Host{"play", 0, true}, false},
{"play:9000", &Host{"play", 9000, true}, false},
{"play.min.io", &Host{"play.min.io", 0, false}, false},
{"play.min.io:9000", &Host{"play.min.io", 9000, true}, false},
{"147.75.201.93", &Host{"147.75.201.93", 0, false}, false},
{"147.75.201.93:9000", &Host{"147.75.201.93", 9000, true}, false},
{"play12", &Host{"play12", 0, false}, false},
{"12play", &Host{"12play", 0, false}, false},
{"play-minio-io", &Host{"play-minio-io", 0, false}, false},
{"play--min.io", &Host{"play--min.io", 0, false}, false},
{":9000", &Host{"", 9000, true}, false},
{"play:", nil, true},
{"play::", nil, true},
{"play:90000", nil, true},
{"play:-10", nil, true},
{"play-", nil, true},
{"play.minio..io", nil, true},
{":", nil, true},
{"", nil, true},
}
for _, testCase := range testCases {
testCase := testCase
t.Run("", func(t *testing.T) {
host, err := ParseHost(testCase.s)
expectErr := (err != nil)
if expectErr != testCase.expectErr {
t.Errorf("error: expected: %v, got: %v", testCase.expectErr, expectErr)
}
if !testCase.expectErr {
if !reflect.DeepEqual(host, testCase.expectedHost) {
t.Errorf("host: expected: %#v, got: %#v", testCase.expectedHost, host)
}
}
})
}
}
func TestTrimIPv6(t *testing.T) {
testCases := []struct {
IP string
expectedIP string
expectErr bool
}{
{"[fe80::8097:76eb:b397:e067%wlp2s0]", "fe80::8097:76eb:b397:e067%wlp2s0", false},
{"fe80::8097:76eb:b397:e067%wlp2s0]", "fe80::8097:76eb:b397:e067%wlp2s0", true},
{"[fe80::8097:76eb:b397:e067%wlp2s0]]", "fe80::8097:76eb:b397:e067%wlp2s0]", false},
{"[[fe80::8097:76eb:b397:e067%wlp2s0]]", "[fe80::8097:76eb:b397:e067%wlp2s0]", false},
}
for i, testCase := range testCases {
ip, err := trimIPv6(testCase.IP)
expectErr := (err != nil)
if expectErr != testCase.expectErr {
t.Fatalf("test %v: error: expected: %v, got: %v", i+1, testCase.expectErr, expectErr)
}
if !testCase.expectErr {
if ip != testCase.expectedIP {
t.Fatalf("test %v: IP: expected: %#v, got: %#v", i+1, testCase.expectedIP, ip)
}
}
}
}

View file

@ -1,51 +0,0 @@
// Copyright (c) 2015-2021 MinIO, Inc.
//
// This file is part of MinIO Object Storage stack
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
package net
import (
"errors"
"strconv"
)
// Port - network port
type Port uint16
// String - returns string representation of port.
func (p Port) String() string {
return strconv.Itoa(int(p))
}
// ParsePort - parses string into Port
func ParsePort(s string) (p Port, err error) {
if s == "https" {
return Port(443), nil
} else if s == "http" {
return Port(80), nil
}
var i int
if i, err = strconv.Atoi(s); err != nil {
return p, errors.New("invalid port number")
}
if i < 0 || i > 65535 {
return p, errors.New("port must be between 0 to 65535")
}
return Port(i), nil
}

View file

@ -1,75 +0,0 @@
// Copyright (c) 2015-2021 MinIO, Inc.
//
// This file is part of MinIO Object Storage stack
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
package net
import (
"testing"
)
func TestPortString(t *testing.T) {
testCases := []struct {
port Port
expectedStr string
}{
{Port(0), "0"},
{Port(9000), "9000"},
{Port(65535), "65535"},
{Port(1024), "1024"},
}
for i, testCase := range testCases {
str := testCase.port.String()
if str != testCase.expectedStr {
t.Fatalf("test %v: error: port: %v, got: %v", i+1, testCase.expectedStr, str)
}
}
}
func TestParsePort(t *testing.T) {
testCases := []struct {
s string
expectedPort Port
expectErr bool
}{
{"0", Port(0), false},
{"9000", Port(9000), false},
{"65535", Port(65535), false},
{"http", Port(80), false},
{"https", Port(443), false},
{"90000", Port(0), true},
{"-10", Port(0), true},
{"", Port(0), true},
{" 1024", Port(0), true},
}
for i, testCase := range testCases {
port, err := ParsePort(testCase.s)
expectErr := (err != nil)
if expectErr != testCase.expectErr {
t.Fatalf("test %v: error: expected: %v, got: %v", i+1, testCase.expectErr, expectErr)
}
if !testCase.expectErr {
if port != testCase.expectedPort {
t.Fatalf("test %v: error: port: %v, got: %v", i+1, testCase.expectedPort, port)
}
}
}
}

View file

@ -1,201 +0,0 @@
// Copyright (c) 2015-2021 MinIO, Inc.
//
// This file is part of MinIO Object Storage stack
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
package net
import (
"context"
"encoding/json"
"errors"
"fmt"
"net"
"net/url"
"path"
"strings"
)
// URL - improved JSON friendly url.URL.
type URL url.URL
// IsEmpty - checks URL is empty or not.
func (u URL) IsEmpty() bool {
return u.String() == ""
}
// String - returns string representation of URL.
func (u URL) String() string {
// if port number 80 and 443, remove for http and https scheme respectively
if u.Host != "" {
host, err := ParseHost(u.Host)
if err != nil {
panic(err)
}
switch {
case u.Scheme == "http" && host.Port == 80:
fallthrough
case u.Scheme == "https" && host.Port == 443:
u.Host = host.Name
}
}
uu := url.URL(u)
return uu.String()
}
// MarshalJSON - converts to JSON string data.
func (u URL) MarshalJSON() ([]byte, error) {
return json.Marshal(u.String())
}
// UnmarshalJSON - parses given data into URL.
func (u *URL) UnmarshalJSON(data []byte) (err error) {
var s string
if err = json.Unmarshal(data, &s); err != nil {
return err
}
// Allow empty string
if s == "" {
*u = URL{}
return nil
}
var ru *URL
if ru, err = ParseURL(s); err != nil {
return err
}
*u = *ru
return nil
}
// ParseHTTPURL - parses a string into HTTP URL, string is
// expected to be of form http:// or https://
func ParseHTTPURL(s string) (u *URL, err error) {
u, err = ParseURL(s)
if err != nil {
return nil, err
}
switch u.Scheme {
default:
return nil, fmt.Errorf("unexpected scheme found %s", u.Scheme)
case "http", "https":
return u, nil
}
}
// ParseURL - parses string into URL.
func ParseURL(s string) (u *URL, err error) {
var uu *url.URL
if uu, err = url.Parse(s); err != nil {
return nil, err
}
if uu.Hostname() == "" {
if uu.Scheme != "" {
return nil, errors.New("scheme appears with empty host")
}
} else {
portStr := uu.Port()
if portStr == "" {
switch uu.Scheme {
case "http":
portStr = "80"
case "https":
portStr = "443"
}
}
if _, err = ParseHost(net.JoinHostPort(uu.Hostname(), portStr)); err != nil {
return nil, err
}
}
// Clean path in the URL.
// Note: path.Clean() is used on purpose because in MS Windows filepath.Clean() converts
// `/` into `\` ie `/foo` becomes `\foo`
if uu.Path != "" {
uu.Path = path.Clean(uu.Path)
}
// path.Clean removes the trailing '/' and converts '//' to '/'.
if strings.HasSuffix(s, "/") && !strings.HasSuffix(uu.Path, "/") {
uu.Path += "/"
}
v := URL(*uu)
u = &v
return u, nil
}
// IsNetworkOrHostDown - if there was a network error or if the host is down.
// expectTimeouts indicates that *context* timeouts are expected and does not
// indicate a downed host. Other timeouts still returns down.
func IsNetworkOrHostDown(err error, expectTimeouts bool) bool {
if err == nil {
return false
}
if errors.Is(err, context.Canceled) {
return false
}
if expectTimeouts && errors.Is(err, context.DeadlineExceeded) {
return false
}
// We need to figure if the error either a timeout
// or a non-temporary error.
urlErr := &url.Error{}
if errors.As(err, &urlErr) {
switch urlErr.Err.(type) {
case *net.DNSError, *net.OpError, net.UnknownNetworkError:
return true
}
}
var e net.Error
if errors.As(err, &e) {
if e.Timeout() {
return true
}
}
// Fallback to other mechanisms.
switch {
case strings.Contains(err.Error(), "Connection closed by foreign host"):
return true
case strings.Contains(err.Error(), "TLS handshake timeout"):
// If error is - tlsHandshakeTimeoutError.
return true
case strings.Contains(err.Error(), "i/o timeout"):
// If error is - tcp timeoutError.
return true
case strings.Contains(err.Error(), "connection timed out"):
// If err is a net.Dial timeout.
return true
case strings.Contains(err.Error(), "connection reset by peer"):
// IF err is a peer reset on a socket.
return true
case strings.Contains(err.Error(), "broken pipe"):
// IF err is a broken pipe on a socket.
return true
case strings.Contains(strings.ToLower(err.Error()), "503 service unavailable"):
// Denial errors
return true
}
return false
}

View file

@ -1,205 +0,0 @@
// Copyright (c) 2015-2021 MinIO, Inc.
//
// This file is part of MinIO Object Storage stack
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
package net
import (
"reflect"
"testing"
)
func TestURLIsEmpty(t *testing.T) {
testCases := []struct {
url URL
expectedResult bool
}{
{URL{}, true},
{URL{Scheme: "http", Host: "play"}, false},
{URL{Path: "path/to/play"}, false},
}
for i, testCase := range testCases {
result := testCase.url.IsEmpty()
if result != testCase.expectedResult {
t.Fatalf("test %v: result: expected: %v, got: %v", i+1, testCase.expectedResult, result)
}
}
}
func TestURLString(t *testing.T) {
testCases := []struct {
url URL
expectedStr string
}{
{URL{}, ""},
{URL{Scheme: "http", Host: "play"}, "http://play"},
{URL{Scheme: "https", Host: "play:443"}, "https://play"},
{URL{Scheme: "https", Host: "play.min.io:80"}, "https://play.min.io:80"},
{URL{Scheme: "https", Host: "147.75.201.93:9000", Path: "/"}, "https://147.75.201.93:9000/"},
{URL{Scheme: "https", Host: "s3.amazonaws.com", Path: "/", RawQuery: "location"}, "https://s3.amazonaws.com/?location"},
{URL{Scheme: "http", Host: "myminio:10000", Path: "/mybucket/myobject"}, "http://myminio:10000/mybucket/myobject"},
{URL{Scheme: "ftp", Host: "myftp.server:10000", Path: "/myuser"}, "ftp://myftp.server:10000/myuser"},
{URL{Path: "path/to/play"}, "path/to/play"},
}
for i, testCase := range testCases {
str := testCase.url.String()
if str != testCase.expectedStr {
t.Fatalf("test %v: string: expected: %v, got: %v", i+1, testCase.expectedStr, str)
}
}
}
func TestURLMarshalJSON(t *testing.T) {
testCases := []struct {
url URL
expectedData []byte
expectErr bool
}{
{URL{}, []byte(`""`), false},
{URL{Scheme: "http", Host: "play"}, []byte(`"http://play"`), false},
{URL{Scheme: "https", Host: "play.min.io:0"}, []byte(`"https://play.min.io:0"`), false},
{URL{Scheme: "https", Host: "147.75.201.93:9000", Path: "/"}, []byte(`"https://147.75.201.93:9000/"`), false},
{URL{Scheme: "https", Host: "s3.amazonaws.com", Path: "/", RawQuery: "location"}, []byte(`"https://s3.amazonaws.com/?location"`), false},
{URL{Scheme: "http", Host: "myminio:10000", Path: "/mybucket/myobject"}, []byte(`"http://myminio:10000/mybucket/myobject"`), false},
{URL{Scheme: "ftp", Host: "myftp.server:10000", Path: "/myuser"}, []byte(`"ftp://myftp.server:10000/myuser"`), false},
}
for i, testCase := range testCases {
data, err := testCase.url.MarshalJSON()
expectErr := (err != nil)
if expectErr != testCase.expectErr {
t.Fatalf("test %v: error: expected: %v, got: %v", i+1, testCase.expectErr, expectErr)
}
if !testCase.expectErr {
if !reflect.DeepEqual(data, testCase.expectedData) {
t.Fatalf("test %v: data: expected: %v, got: %v", i+1, string(testCase.expectedData), string(data))
}
}
}
}
func TestURLUnmarshalJSON(t *testing.T) {
testCases := []struct {
data []byte
expectedURL *URL
expectErr bool
}{
{[]byte(`""`), &URL{}, false},
{[]byte(`"http://play"`), &URL{Scheme: "http", Host: "play"}, false},
{[]byte(`"https://play.min.io:0"`), &URL{Scheme: "https", Host: "play.min.io:0"}, false},
{[]byte(`"https://147.75.201.93:9000/"`), &URL{Scheme: "https", Host: "147.75.201.93:9000", Path: "/"}, false},
{[]byte(`"https://s3.amazonaws.com/?location"`), &URL{Scheme: "https", Host: "s3.amazonaws.com", Path: "/", RawQuery: "location"}, false},
{[]byte(`"http://myminio:10000/mybucket/myobject//"`), &URL{Scheme: "http", Host: "myminio:10000", Path: "/mybucket/myobject/"}, false},
{[]byte(`"ftp://myftp.server:10000/myuser"`), &URL{Scheme: "ftp", Host: "myftp.server:10000", Path: "/myuser"}, false},
{[]byte(`"http://webhook.server:10000/mywebhook/"`), &URL{Scheme: "http", Host: "webhook.server:10000", Path: "/mywebhook/"}, false},
{[]byte(`"myserver:1000"`), nil, true},
{[]byte(`"http://:1000/mybucket"`), nil, true},
{[]byte(`"https://147.75.201.93:90000/"`), nil, true},
{[]byte(`"http:/play"`), nil, true},
}
for i, testCase := range testCases {
var url URL
err := url.UnmarshalJSON(testCase.data)
expectErr := (err != nil)
if expectErr != testCase.expectErr {
t.Fatalf("test %v: error: expected: %v, got: %v", i+1, testCase.expectErr, expectErr)
}
if !testCase.expectErr {
if !reflect.DeepEqual(&url, testCase.expectedURL) {
t.Fatalf("test %v: host: expected: %#v, got: %#v", i+1, testCase.expectedURL, url)
}
}
}
}
func TestParseHTTPURL(t *testing.T) {
testCases := []struct {
s string
expectedURL *URL
expectErr bool
}{
{"http://play", &URL{Scheme: "http", Host: "play"}, false},
{"https://play.min.io:0", &URL{Scheme: "https", Host: "play.min.io:0"}, false},
{"https://147.75.201.93:9000/", &URL{Scheme: "https", Host: "147.75.201.93:9000", Path: "/"}, false},
{"https://s3.amazonaws.com/?location", &URL{Scheme: "https", Host: "s3.amazonaws.com", Path: "/", RawQuery: "location"}, false},
{"http://myminio:10000/mybucket//myobject/", &URL{Scheme: "http", Host: "myminio:10000", Path: "/mybucket/myobject/"}, false},
{"ftp://myftp.server:10000/myuser", nil, true},
{"https://my.server:10000000/myuser", nil, true},
{"myserver:1000", nil, true},
{"http://:1000/mybucket", nil, true},
{"https://147.75.201.93:90000/", nil, true},
{"http:/play", nil, true},
}
for _, testCase := range testCases {
testCase := testCase
t.Run(testCase.s, func(t *testing.T) {
url, err := ParseHTTPURL(testCase.s)
expectErr := (err != nil)
if expectErr != testCase.expectErr {
t.Fatalf("error: expected: %v, got: %v", testCase.expectErr, expectErr)
}
if !testCase.expectErr {
if !reflect.DeepEqual(url, testCase.expectedURL) {
t.Fatalf("host: expected: %#v, got: %#v", testCase.expectedURL, url)
}
}
})
}
}
func TestParseURL(t *testing.T) {
testCases := []struct {
s string
expectedURL *URL
expectErr bool
}{
{"http://play", &URL{Scheme: "http", Host: "play"}, false},
{"https://play.min.io:0", &URL{Scheme: "https", Host: "play.min.io:0"}, false},
{"https://147.75.201.93:9000/", &URL{Scheme: "https", Host: "147.75.201.93:9000", Path: "/"}, false},
{"https://s3.amazonaws.com/?location", &URL{Scheme: "https", Host: "s3.amazonaws.com", Path: "/", RawQuery: "location"}, false},
{"http://myminio:10000/mybucket//myobject/", &URL{Scheme: "http", Host: "myminio:10000", Path: "/mybucket/myobject/"}, false},
{"ftp://myftp.server:10000/myuser", &URL{Scheme: "ftp", Host: "myftp.server:10000", Path: "/myuser"}, false},
{"myserver:1000", nil, true},
{"http://:1000/mybucket", nil, true},
{"https://147.75.201.93:90000/", nil, true},
{"http:/play", nil, true},
}
for i, testCase := range testCases {
url, err := ParseURL(testCase.s)
expectErr := (err != nil)
if expectErr != testCase.expectErr {
t.Fatalf("test %v: error: expected: %v, got: %v", i+1, testCase.expectErr, expectErr)
}
if !testCase.expectErr {
if !reflect.DeepEqual(url, testCase.expectedURL) {
t.Fatalf("test %v: host: expected: %#v, got: %#v", i+1, testCase.expectedURL, url)
}
}
}
}

View file

@ -31,7 +31,7 @@ import (
xhttp "github.com/minio/minio/internal/http"
"github.com/minio/minio/internal/logger"
xnet "github.com/minio/minio/internal/net"
xnet "github.com/minio/pkg/net"
)
// DefaultTimeout - default REST timeout is 10 seconds.