rclone/vendor/storj.io/common/storj/nodeurl.go
Caleb Case e7bd392a69 backend/tardigrade: Upgrade to uplink v1.0.6
This fixes an important bug with listing that affects users with more
than 500 objects in a listing operation.
2020-05-29 18:00:08 +01:00

137 lines
2.8 KiB
Go

// Copyright (C) 2019 Storj Labs, Inc.
// See LICENSE for copying information.
package storj
import (
"net/url"
"strings"
"github.com/zeebo/errs"
)
var (
// ErrNodeURL is used when something goes wrong with a node url.
ErrNodeURL = errs.Class("node URL error")
)
// NodeURL defines a structure for connecting to a node.
type NodeURL struct {
ID NodeID
Address string
}
// ParseNodeURL parses node URL string.
//
// Examples:
//
// raw IP:
// 33.20.0.1:7777
// [2001:db8:1f70::999:de8:7648:6e8]:7777
//
// with NodeID:
// 12vha9oTFnerxYRgeQ2BZqoFrLrnmmf5UWTCY2jA77dF3YvWew7@33.20.0.1:7777
// 12vha9oTFnerxYRgeQ2BZqoFrLrnmmf5UWTCY2jA77dF3YvWew7@[2001:db8:1f70::999:de8:7648:6e8]:7777
//
// without host:
// 12vha9oTFnerxYRgeQ2BZqoFrLrnmmf5UWTCY2jA77dF3YvWew7@
func ParseNodeURL(s string) (NodeURL, error) {
if s == "" {
return NodeURL{}, nil
}
if !strings.HasPrefix(s, "storj://") {
if !strings.Contains(s, "://") {
s = "storj://" + s
}
}
u, err := url.Parse(s)
if err != nil {
return NodeURL{}, ErrNodeURL.Wrap(err)
}
if u.Scheme != "" && u.Scheme != "storj" {
return NodeURL{}, ErrNodeURL.New("unknown scheme %q", u.Scheme)
}
var node NodeURL
if u.User != nil {
node.ID, err = NodeIDFromString(u.User.String())
if err != nil {
return NodeURL{}, ErrNodeURL.Wrap(err)
}
}
node.Address = u.Host
return node, nil
}
// IsZero returns whether the url is empty.
func (url NodeURL) IsZero() bool {
return url == NodeURL{}
}
// String converts NodeURL to a string.
func (url NodeURL) String() string {
if url.ID.IsZero() {
return url.Address
}
return url.ID.String() + "@" + url.Address
}
// Set implements flag.Value interface.
func (url *NodeURL) Set(s string) error {
parsed, err := ParseNodeURL(s)
if err != nil {
return ErrNodeURL.Wrap(err)
}
*url = parsed
return nil
}
// Type implements pflag.Value.
func (NodeURL) Type() string { return "storj.NodeURL" }
// NodeURLs defines a comma delimited flag for defining a list node url-s.
type NodeURLs []NodeURL
// ParseNodeURLs parses comma delimited list of node urls.
func ParseNodeURLs(s string) (NodeURLs, error) {
var urls NodeURLs
if s == "" {
return nil, nil
}
for _, s := range strings.Split(s, ",") {
u, err := ParseNodeURL(s)
if err != nil {
return nil, ErrNodeURL.Wrap(err)
}
urls = append(urls, u)
}
return urls, nil
}
// String converts NodeURLs to a string.
func (urls NodeURLs) String() string {
var xs []string
for _, u := range urls {
xs = append(xs, u.String())
}
return strings.Join(xs, ",")
}
// Set implements flag.Value interface.
func (urls *NodeURLs) Set(s string) error {
parsed, err := ParseNodeURLs(s)
if err != nil {
return ErrNodeURL.Wrap(err)
}
*urls = parsed
return nil
}
// Type implements pflag.Value.
func (NodeURLs) Type() string { return "storj.NodeURLs" }