Some checks are pending
Docs Deploy / build_and_deploy (push) Waiting to run
Generate Docs / cli (push) Waiting to run
Generate Config Doc / cli (push) Waiting to run
Go formatting / go-formatting (push) Waiting to run
Check links / markdown-link-check (push) Waiting to run
Integration / pre-test (push) Waiting to run
Integration / test on (push) Blocked by required conditions
Integration / status (push) Blocked by required conditions
Lint / Lint Go code (push) Waiting to run
Test / test (ubuntu-latest) (push) Waiting to run
139 lines
2.7 KiB
Go
139 lines
2.7 KiB
Go
package xurl
|
|
|
|
import (
|
|
"fmt"
|
|
"net"
|
|
"net/url"
|
|
"strings"
|
|
|
|
"github.com/ignite/cli/v29/ignite/pkg/errors"
|
|
)
|
|
|
|
const (
|
|
schemeTCP = "tcp"
|
|
schemeHTTP = "http"
|
|
schemeHTTPS = "https"
|
|
schemeWS = "ws"
|
|
)
|
|
|
|
// TCP ensures that a URL contains a TCP scheme.
|
|
func TCP(s string) (string, error) {
|
|
u, err := parseURL(s)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
u.Scheme = schemeTCP
|
|
|
|
return u.String(), nil
|
|
}
|
|
|
|
// HTTP ensures that a URL contains an HTTP scheme.
|
|
func HTTP(s string) (string, error) {
|
|
u, err := parseURL(s)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
u.Scheme = schemeHTTP
|
|
|
|
return u.String(), nil
|
|
}
|
|
|
|
// HTTPS ensures that a URL contains an HTTPS scheme.
|
|
func HTTPS(s string) (string, error) {
|
|
u, err := parseURL(s)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
u.Scheme = schemeHTTPS
|
|
|
|
return u.String(), nil
|
|
}
|
|
|
|
// MightHTTPS ensures that a URL contains an HTTPS scheme when the current scheme is not HTTP.
|
|
// When the URL contains an HTTP scheme it is not modified.
|
|
func MightHTTPS(s string) (string, error) {
|
|
if strings.HasPrefix(strings.ToLower(s), "http://") {
|
|
return s, nil
|
|
}
|
|
|
|
return HTTPS(s)
|
|
}
|
|
|
|
// WS ensures that a URL contains a WS scheme.
|
|
func WS(s string) (string, error) {
|
|
u, err := parseURL(s)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
u.Scheme = schemeWS
|
|
|
|
return u.String(), nil
|
|
}
|
|
|
|
// HTTPEnsurePort ensures that url has a port number suits with the connection type.
|
|
func HTTPEnsurePort(s string) string {
|
|
u, err := url.Parse(s)
|
|
if err != nil || u.Port() != "" {
|
|
return s
|
|
}
|
|
|
|
port := "80"
|
|
|
|
if u.Scheme == schemeHTTPS {
|
|
port = "443"
|
|
}
|
|
|
|
u.Host = fmt.Sprintf("%s:%s", u.Hostname(), port)
|
|
|
|
return u.String()
|
|
}
|
|
|
|
// Address ensures that address contains localhost as host if non specified.
|
|
func Address(address string) string {
|
|
if strings.HasPrefix(address, ":") {
|
|
return "localhost" + address
|
|
}
|
|
return address
|
|
}
|
|
|
|
func IsHTTP(address string) bool {
|
|
return strings.HasPrefix(address, "http")
|
|
}
|
|
|
|
func parseURL(s string) (*url.URL, error) {
|
|
if s == "" {
|
|
return nil, errors.New("url is empty")
|
|
}
|
|
|
|
// Handle the case where the URI is an IP:PORT or HOST:PORT
|
|
// without scheme prefix because that case can't be URL parsed.
|
|
// When the URI has no scheme it is parsed as a path by "url.Parse"
|
|
// placing the colon within the path, which is invalid.
|
|
if host, isAddrPort := addressPort(s); isAddrPort {
|
|
return &url.URL{Host: host}, nil
|
|
}
|
|
|
|
p, err := url.Parse(Address(s))
|
|
return p, err
|
|
}
|
|
|
|
func addressPort(s string) (string, bool) {
|
|
// Check that the value doesn't contain a URI path
|
|
if strings.Contains(s, "/") {
|
|
return "", false
|
|
}
|
|
|
|
// Use the net split function to support IPv6 addresses
|
|
host, port, err := net.SplitHostPort(s)
|
|
if err != nil {
|
|
return "", false
|
|
}
|
|
if host == "" {
|
|
host = "0.0.0.0"
|
|
}
|
|
return net.JoinHostPort(host, port), true
|
|
}
|