Lotus API endpoint are by default expressed as multiaddresses (i.e. lotus auth api-info) which end in /http, although they can be provided as standard URLs too. There is an inconsistency here because despite the "http" part, Lotus will use "ws" protocol. This lets lotus default to "ws" but honor whatever the user puts in the multiaddress (i.e. /dns4/my.lotus.node/tcp/443/https) would work now using https, where before it uses "ws".
99 lines
1.9 KiB
Go
99 lines
1.9 KiB
Go
package cliutil
|
|
|
|
import (
|
|
"net/http"
|
|
"net/url"
|
|
"regexp"
|
|
"strings"
|
|
|
|
logging "github.com/ipfs/go-log/v2"
|
|
"github.com/multiformats/go-multiaddr"
|
|
manet "github.com/multiformats/go-multiaddr/net"
|
|
)
|
|
|
|
var log = logging.Logger("cliutil")
|
|
|
|
var (
|
|
infoWithToken = regexp.MustCompile("^[a-zA-Z0-9\\-_]+?\\.[a-zA-Z0-9\\-_]+?\\.([a-zA-Z0-9\\-_]+)?:.+$")
|
|
)
|
|
|
|
type APIInfo struct {
|
|
Addr string
|
|
Token []byte
|
|
}
|
|
|
|
func ParseApiInfo(s string) APIInfo {
|
|
var tok []byte
|
|
if infoWithToken.Match([]byte(s)) {
|
|
sp := strings.SplitN(s, ":", 2)
|
|
tok = []byte(sp[0])
|
|
s = sp[1]
|
|
}
|
|
|
|
return APIInfo{
|
|
Addr: s,
|
|
Token: tok,
|
|
}
|
|
}
|
|
|
|
func (a APIInfo) DialArgs() (string, error) {
|
|
ma, err := multiaddr.NewMultiaddr(a.Addr)
|
|
if err == nil {
|
|
_, addr, err := manet.DialArgs(ma)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
protocol := "ws"
|
|
|
|
// If the user specifies the multiaddress as
|
|
// /something/tcp/1234/http or/something/tcp/1234/https
|
|
// or /something/tcp/1234/wss then honor that.
|
|
for _, p := range []int{
|
|
multiaddr.P_HTTP,
|
|
multiaddr.P_HTTPS,
|
|
multiaddr.P_WSS,
|
|
} {
|
|
if _, err := ma.ValueForProtocol(p); err == nil {
|
|
protocol = multiaddr.ProtocolWithCode(p).Name
|
|
break
|
|
}
|
|
}
|
|
return protocol + "://" + addr + "/rpc/v0", nil
|
|
}
|
|
|
|
_, err = url.Parse(a.Addr)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
return a.Addr + "/rpc/v0", nil
|
|
}
|
|
|
|
func (a APIInfo) Host() (string, error) {
|
|
ma, err := multiaddr.NewMultiaddr(a.Addr)
|
|
if err == nil {
|
|
_, addr, err := manet.DialArgs(ma)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
return addr, nil
|
|
}
|
|
|
|
spec, err := url.Parse(a.Addr)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
return spec.Host, nil
|
|
}
|
|
|
|
func (a APIInfo) AuthHeader() http.Header {
|
|
if len(a.Token) != 0 {
|
|
headers := http.Header{}
|
|
headers.Add("Authorization", "Bearer "+string(a.Token))
|
|
return headers
|
|
}
|
|
log.Warn("API Token not set and requested, capabilities might be limited.")
|
|
return nil
|
|
}
|