feat: make secure url to grpcs://127.0.0.1/ (#2072)

* feat:make secure url to grpcs://127.0.0.1/
pull/2078/head
haiyux 2 years ago committed by GitHub
parent 1b3529fd0b
commit ad5e9032a3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 38
      internal/endpoint/endpoint.go
  2. 57
      internal/endpoint/endpoint_test.go
  3. 2
      transport/grpc/resolver/discovery/resolver.go
  4. 2
      transport/grpc/server.go
  5. 2
      transport/http/resolver.go
  6. 5
      transport/http/server.go

@ -6,29 +6,42 @@ import (
) )
// NewEndpoint new an Endpoint URL. // NewEndpoint new an Endpoint URL.
func NewEndpoint(scheme, host string, isSecure bool) *url.URL { func NewEndpoint(scheme, host string) *url.URL {
var query string return &url.URL{Scheme: scheme, Host: host}
if isSecure {
query = "isSecure=true"
}
return &url.URL{Scheme: scheme, Host: host, RawQuery: query}
} }
// ParseEndpoint parses an Endpoint URL. // ParseEndpoint parses an Endpoint URL.
func ParseEndpoint(endpoints []string, scheme string, isSecure bool) (string, error) { func ParseEndpoint(endpoints []string, scheme string) (string, error) {
for _, e := range endpoints { for _, e := range endpoints {
u, err := url.Parse(e) u, err := url.Parse(e)
if err != nil { if err != nil {
return "", err return "", err
} }
if u.Scheme == scheme && IsSecure(u) == isSecure {
// TODO: Compatibility processing
// Function is to convert grpc:/127.0.0.1/?isSecure=true into grpcs:/127.0.0.1/
// It will be deleted in about a month
u = legacyURLToNew(u)
if u.Scheme == scheme {
return u.Host, nil return u.Host, nil
} }
} }
return "", nil return "", nil
} }
func legacyURLToNew(u *url.URL) *url.URL {
if u.Scheme == "https" || u.Scheme == "grpcs" {
return u
}
if IsSecure(u) {
return &url.URL{Scheme: u.Scheme + "s", Host: u.Host}
}
return u
}
// IsSecure parses isSecure for Endpoint URL. // IsSecure parses isSecure for Endpoint URL.
// Note: It will be deleted after some time,
// unified use grpcs://127.0.0.1:8080 instead of grpc://127.0.0.1:8080?isSecure=true
func IsSecure(u *url.URL) bool { func IsSecure(u *url.URL) bool {
ok, err := strconv.ParseBool(u.Query().Get("isSecure")) ok, err := strconv.ParseBool(u.Query().Get("isSecure"))
if err != nil { if err != nil {
@ -36,3 +49,12 @@ func IsSecure(u *url.URL) bool {
} }
return ok return ok
} }
// Scheme is the scheme of endpoint url.
// examples: scheme="http",isSecure=true get "https"
func Scheme(scheme string, isSecure bool) string {
if isSecure {
return scheme + "s"
}
return scheme
}

@ -18,17 +18,17 @@ func TestEndPoint(t *testing.T) {
// TODO: Add test cases. // TODO: Add test cases.
{ {
name: "grpc://127.0.0.1?isSecure=false", name: "grpc://127.0.0.1?isSecure=false",
args: args{NewEndpoint("grpc", "127.0.0.1", false)}, args: args{&url.URL{Scheme: "grpc", Host: "127.0.0.1", RawQuery: "isSecure=false"}},
want: false, want: false,
}, },
{ {
name: "grpc://127.0.0.1?isSecure=true", name: "grpc://127.0.0.1?isSecure=true",
args: args{NewEndpoint("http", "127.0.0.1", true)}, args: args{&url.URL{Scheme: "grpc", Host: "127.0.0.1", RawQuery: "isSecure=true"}},
want: true, want: true,
}, },
{ {
name: "grpc://127.0.0.1", name: "grpc://127.0.0.1",
args: args{NewEndpoint("grpc", "localhost", false)}, args: args{&url.URL{Scheme: "grpc", Host: "127.0.0.1"}},
want: false, want: false,
}, },
} }
@ -43,9 +43,8 @@ func TestEndPoint(t *testing.T) {
func TestNewEndpoint(t *testing.T) { func TestNewEndpoint(t *testing.T) {
type args struct { type args struct {
scheme string scheme string
host string host string
isSecure bool
} }
tests := []struct { tests := []struct {
name string name string
@ -54,18 +53,23 @@ func TestNewEndpoint(t *testing.T) {
}{ }{
{ {
name: "https://github.com/go-kratos/kratos/", name: "https://github.com/go-kratos/kratos/",
args: args{"https", "github.com/go-kratos/kratos/", false}, args: args{"https", "github.com/go-kratos/kratos/"},
want: &url.URL{Scheme: "https", Host: "github.com/go-kratos/kratos/"}, want: &url.URL{Scheme: "https", Host: "github.com/go-kratos/kratos/"},
}, },
{ {
name: "https://go-kratos.dev/", name: "https://go-kratos.dev/",
args: args{"https", "go-kratos.dev/", true}, args: args{"https", "go-kratos.dev/"},
want: &url.URL{Scheme: "https", Host: "go-kratos.dev/", RawQuery: "isSecure=true"}, want: &url.URL{Scheme: "https", Host: "go-kratos.dev/"},
},
{
name: "https://www.google.com/",
args: args{"https", "www.google.com/"},
want: &url.URL{Scheme: "https", Host: "www.google.com/"},
}, },
} }
for _, tt := range tests { for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) { t.Run(tt.name, func(t *testing.T) {
if got := NewEndpoint(tt.args.scheme, tt.args.host, tt.args.isSecure); !reflect.DeepEqual(got, tt.want) { if got := NewEndpoint(tt.args.scheme, tt.args.host); !reflect.DeepEqual(got, tt.want) {
t.Errorf("NewEndpoint() = %v, want %v", got, tt.want) t.Errorf("NewEndpoint() = %v, want %v", got, tt.want)
} }
}) })
@ -76,7 +80,6 @@ func TestParseEndpoint(t *testing.T) {
type args struct { type args struct {
endpoints []string endpoints []string
scheme string scheme string
isSecure bool
} }
tests := []struct { tests := []struct {
name string name string
@ -86,20 +89,46 @@ func TestParseEndpoint(t *testing.T) {
}{ }{
{ {
name: "kratos", name: "kratos",
args: args{endpoints: []string{"https://github.com/go-kratos/kratos?isSecure=true"}, scheme: "https", isSecure: true}, args: args{endpoints: []string{"https://github.com/go-kratos/kratos"}, scheme: "https"},
want: "github.com", want: "github.com",
wantErr: false, wantErr: false,
}, },
{ {
name: "test", name: "test",
args: args{endpoints: []string{"https://go-kratos.dev/"}, scheme: "http", isSecure: true}, args: args{endpoints: []string{"http://go-kratos.dev/"}, scheme: "https"},
want: "",
wantErr: false,
},
{
name: "localhost:8080",
args: args{endpoints: []string{"grpcs://localhost:8080/"}, scheme: "grpcs"},
want: "localhost:8080",
wantErr: false,
},
{
name: "localhost:8081",
args: args{endpoints: []string{"grpcs://localhost:8080/"}, scheme: "grpc"},
want: "", want: "",
wantErr: false, wantErr: false,
}, },
// Legacy
{
name: "google",
args: args{endpoints: []string{"grpc://www.google.com/?isSecure=true"}, scheme: "grpcs"},
want: "www.google.com",
wantErr: false,
},
{
name: "baidu",
args: args{endpoints: []string{"http://www.baidu.com/?isSecure=true"}, scheme: "https"},
want: "www.baidu.com",
wantErr: false,
},
} }
for _, tt := range tests { for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) { t.Run(tt.name, func(t *testing.T) {
got, err := ParseEndpoint(tt.args.endpoints, tt.args.scheme, tt.args.isSecure) got, err := ParseEndpoint(tt.args.endpoints, tt.args.scheme)
if (err != nil) != tt.wantErr { if (err != nil) != tt.wantErr {
t.Errorf("ParseEndpoint() error = %v, wantErr %v", err, tt.wantErr) t.Errorf("ParseEndpoint() error = %v, wantErr %v", err, tt.wantErr)
return return

@ -49,7 +49,7 @@ func (r *discoveryResolver) update(ins []*registry.ServiceInstance) {
addrs := make([]resolver.Address, 0) addrs := make([]resolver.Address, 0)
endpoints := make(map[string]struct{}) endpoints := make(map[string]struct{})
for _, in := range ins { for _, in := range ins {
endpoint, err := endpoint.ParseEndpoint(in.Endpoints, "grpc", !r.insecure) endpoint, err := endpoint.ParseEndpoint(in.Endpoints, endpoint.Scheme("grpc", !r.insecure))
if err != nil { if err != nil {
log.Errorf("[resolver] Failed to parse discovery endpoint: %v", err) log.Errorf("[resolver] Failed to parse discovery endpoint: %v", err)
continue continue

@ -207,6 +207,6 @@ func (s *Server) listenAndEndpoint() error {
_ = s.lis.Close() _ = s.lis.Close()
return err return err
} }
s.endpoint = endpoint.NewEndpoint("grpc", addr, s.tlsConf != nil) s.endpoint = endpoint.NewEndpoint(endpoint.Scheme("grpc", s.tlsConf != nil), addr)
return nil return nil
} }

@ -112,7 +112,7 @@ func newResolver(ctx context.Context, discovery registry.Discovery, target *Targ
func (r *resolver) update(services []*registry.ServiceInstance) bool { func (r *resolver) update(services []*registry.ServiceInstance) bool {
nodes := make([]selector.Node, 0) nodes := make([]selector.Node, 0)
for _, ins := range services { for _, ins := range services {
ept, err := endpoint.ParseEndpoint(ins.Endpoints, "http", !r.insecure) ept, err := endpoint.ParseEndpoint(ins.Endpoints, endpoint.Scheme("http", !r.insecure))
if err != nil { if err != nil {
log.Errorf("Failed to parse (%v) discovery endpoint: %v error %v", r.target, ins.Endpoints, err) log.Errorf("Failed to parse (%v) discovery endpoint: %v error %v", r.target, ins.Endpoints, err)
continue continue

@ -224,7 +224,8 @@ func (s *Server) filter() mux.MiddlewareFunc {
// Endpoint return a real address to registry endpoint. // Endpoint return a real address to registry endpoint.
// examples: // examples:
// http://127.0.0.1:8000?isSecure=false // https://127.0.0.1:8000
// Legacy: http://127.0.0.1:8000?isSecure=false
func (s *Server) Endpoint() (*url.URL, error) { func (s *Server) Endpoint() (*url.URL, error) {
if s.err != nil { if s.err != nil {
return nil, s.err return nil, s.err
@ -272,6 +273,6 @@ func (s *Server) listenAndEndpoint() error {
_ = s.lis.Close() _ = s.lis.Close()
return err return err
} }
s.endpoint = endpoint.NewEndpoint("http", addr, s.tlsConf != nil) s.endpoint = endpoint.NewEndpoint(endpoint.Scheme("http", s.tlsConf != nil), addr)
return nil return nil
} }

Loading…
Cancel
Save