Skip to content

Commit

Permalink
Feat/dtynn/introduce dial args (#4804)
Browse files Browse the repository at this point in the history
* feat: introduce APIInfo from venus-common-utils/apiinfo

* feat: update template for client gen, re-gen for all shared apis
  • Loading branch information
dtynn authored Feb 25, 2022
1 parent c69627b commit ed9c00d
Show file tree
Hide file tree
Showing 13 changed files with 461 additions and 0 deletions.
20 changes: 20 additions & 0 deletions venus-devtool/api-gen/client.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

140 changes: 140 additions & 0 deletions venus-shared/api/api_info.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
package api

import (
"fmt"
"net/http"
"net/url"
"regexp"
"strings"

multiaddr "github.com/multiformats/go-multiaddr"
manet "github.com/multiformats/go-multiaddr/net"
)

var (
infoWithToken = regexp.MustCompile("^[a-zA-Z0-9\\-_]+?\\.[a-zA-Z0-9\\-_]+?\\.([a-zA-Z0-9\\-_]+)?:.+$") // nolint:gosimple
)

func VerString(ver uint32) string {
return fmt.Sprintf("v%d", ver)
}

type APIInfo struct { // nolint
Addr string
Token []byte
}

func NewAPIInfo(addr, token string) APIInfo {
return APIInfo{
Addr: addr,
Token: []byte(token),
}
}

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,
}
}

//DialArgs parser libp2p address to http/ws protocol, the version argument can be override by address in version
func (a APIInfo) DialArgs(version string) (string, error) {
return DialArgs(a.Addr, version)
}

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{}
a.SetAuthHeader(headers)
return headers
}

return nil
}

func (a APIInfo) SetAuthHeader(h http.Header) {
if len(a.Token) != 0 {
h.Add(AuthorizationHeader, "Bearer "+string(a.Token))
}
}

func DialArgs(addr, version string) (string, error) {
ma, err := multiaddr.NewMultiaddr(addr)
if err == nil {
_, addr, err := manet.DialArgs(ma)
if err != nil {
return "", fmt.Errorf("parser libp2p url fail %w", err)
}

//override version
val, err := ma.ValueForProtocol(ProtoVersion)
if err == nil {
version = val
} else if err != multiaddr.ErrProtocolNotFound {
return "", err
}

_, err = ma.ValueForProtocol(multiaddr.P_WSS)
if err == nil {
return "wss://" + addr + "/rpc/" + version, nil
} else if err != multiaddr.ErrProtocolNotFound {
return "", err
}

_, err = ma.ValueForProtocol(multiaddr.P_HTTPS)
if err == nil {
return "https://" + addr + "/rpc/" + version, nil
} else if err != multiaddr.ErrProtocolNotFound {
return "", err
}

_, err = ma.ValueForProtocol(multiaddr.P_WS)
if err == nil {
return "ws://" + addr + "/rpc/" + version, nil
} else if err != multiaddr.ErrProtocolNotFound {
return "", err
}

_, err = ma.ValueForProtocol(multiaddr.P_HTTP)
if err == nil {
return "http://" + addr + "/rpc/" + version, nil
} else if err != multiaddr.ErrProtocolNotFound {
return "", err
}

return "ws://" + addr + "/rpc/" + version, nil
}

_, err = url.Parse(addr)
if err != nil {
return "", fmt.Errorf("parser address fail %w", err)
}

return strings.TrimRight(addr, "/") + "/rpc/" + version, nil
}
50 changes: 50 additions & 0 deletions venus-shared/api/api_info_protocol.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package api

import (
"fmt"
"strconv"
"strings"

"github.com/multiformats/go-multiaddr"
)

const ProtoVersion = multiaddr.P_WSS + 1

func init() {
err := multiaddr.AddProtocol(multiaddr.Protocol{
Name: "version",
Code: ProtoVersion,
VCode: multiaddr.CodeToVarint(ProtoVersion),
Size: multiaddr.LengthPrefixedVarSize,
Transcoder: multiaddr.NewTranscoderFromFunctions(func(s string) ([]byte, error) {
if !strings.HasPrefix(s, "v") {
return nil, fmt.Errorf("version must start with version prefix v")
}
if len(s) < 2 {
return nil, fmt.Errorf("must give a specify version such as v0")
}
_, err := strconv.Atoi(s[1:])
if err != nil {
return nil, fmt.Errorf("version part must be number")
}
return []byte(s), nil
}, func(bytes []byte) (string, error) {
vStr := string(bytes)
if !strings.HasPrefix(vStr, "v") {
return "", fmt.Errorf("version must start with version prefix v")
}
if len(vStr) < 2 {
return "", fmt.Errorf("must give a specify version such as v0")
}
_, err := strconv.Atoi(vStr[1:])
if err != nil {
return "", fmt.Errorf("version part must be number")
}
return vStr, nil
}, nil),
})

if err != nil {
panic(fmt.Errorf("add `version` protocol into multiaddr: %w", err))
}
}
90 changes: 90 additions & 0 deletions venus-shared/api/api_info_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
package api

import (
"fmt"
"testing"
)

func TestAPIInfo_DialArgs(t *testing.T) {
tests := []struct {
name string
addr string
want string
wantErr bool
}{
{
"common",
"http://192.168.5.61:3453",
"http://192.168.5.61:3453/rpc/v0",
false,
},
{
"wss",
"/ip4/192.168.5.61/tcp/3453/wss",
"wss://192.168.5.61:3453/rpc/v0",
false,
},
{
"ws",
"/ip4/192.168.5.61/tcp/3453/ws",
"ws://192.168.5.61:3453/rpc/v0",
false,
},
{
"http",
"/ip4/192.168.5.61/tcp/34531/http",
"http://192.168.5.61:34531/rpc/v0",
false,
},
{
"https",
"/ip4/192.168.5.61/tcp/34531/https",
"https://192.168.5.61:34531/rpc/v0",
false,
},
{
"default to ws ",
"/ip4/192.168.5.61/tcp/34532",
"ws://192.168.5.61:34532/rpc/v0",
false,
},

{
"version",
"/ip4/192.168.5.61/tcp/34532/version/v1",
"ws://192.168.5.61:34532/rpc/v1",
false,
},
{
"version",
"/ip4/192.168.5.61/tcp/34532/version/v0",
"ws://192.168.5.61:34532/rpc/v0",
false,
},
{
"error version",
"/ip4/192.168.5.61/tcp/34532/version/1v",
"/ip4/192.168.5.61/tcp/34532/version/1v/rpc/v0",
false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if tt.name == "error version" {
fmt.Println()
}
a := APIInfo{
Addr: tt.addr,
}

got, err := a.DialArgs("v0")
if (err != nil) != tt.wantErr {
t.Errorf("DialArgs() error = %v, wantErr %v", err, tt.wantErr)
return
}
if got != tt.want {
t.Errorf("DialArgs() got = %v, want %v", got, tt.want)
}
})
}
}
20 changes: 20 additions & 0 deletions venus-shared/api/chain/v0/client_gen.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

20 changes: 20 additions & 0 deletions venus-shared/api/chain/v1/client_gen.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

20 changes: 20 additions & 0 deletions venus-shared/api/gateway/v0/client_gen.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit ed9c00d

Please sign in to comment.