unix.go 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. /*
  2. *
  3. * Copyright 2020 gRPC authors.
  4. *
  5. * Licensed under the Apache License, Version 2.0 (the "License");
  6. * you may not use this file except in compliance with the License.
  7. * You may obtain a copy of the License at
  8. *
  9. * http://www.apache.org/licenses/LICENSE-2.0
  10. *
  11. * Unless required by applicable law or agreed to in writing, software
  12. * distributed under the License is distributed on an "AS IS" BASIS,
  13. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. * See the License for the specific language governing permissions and
  15. * limitations under the License.
  16. *
  17. */
  18. // Package unix implements a resolver for unix targets.
  19. package unix
  20. import (
  21. "fmt"
  22. "google.golang.org/grpc/internal/transport/networktype"
  23. "google.golang.org/grpc/resolver"
  24. )
  25. const unixScheme = "unix"
  26. const unixAbstractScheme = "unix-abstract"
  27. type builder struct {
  28. scheme string
  29. }
  30. func (b *builder) Build(target resolver.Target, cc resolver.ClientConn, _ resolver.BuildOptions) (resolver.Resolver, error) {
  31. if target.URL.Host != "" {
  32. return nil, fmt.Errorf("invalid (non-empty) authority: %v", target.URL.Host)
  33. }
  34. // gRPC was parsing the dial target manually before PR #4817, and we
  35. // switched to using url.Parse() in that PR. To avoid breaking existing
  36. // resolver implementations we ended up stripping the leading "/" from the
  37. // endpoint. This obviously does not work for the "unix" scheme. Hence we
  38. // end up using the parsed URL instead.
  39. endpoint := target.URL.Path
  40. if endpoint == "" {
  41. endpoint = target.URL.Opaque
  42. }
  43. addr := resolver.Address{Addr: endpoint}
  44. if b.scheme == unixAbstractScheme {
  45. // We can not prepend \0 as c++ gRPC does, as in Golang '@' is used to signify we do
  46. // not want trailing \0 in address.
  47. addr.Addr = "@" + addr.Addr
  48. }
  49. cc.UpdateState(resolver.State{Addresses: []resolver.Address{networktype.Set(addr, "unix")}})
  50. return &nopResolver{}, nil
  51. }
  52. func (b *builder) Scheme() string {
  53. return b.scheme
  54. }
  55. func (b *builder) OverrideAuthority(resolver.Target) string {
  56. return "localhost"
  57. }
  58. type nopResolver struct {
  59. }
  60. func (*nopResolver) ResolveNow(resolver.ResolveNowOptions) {}
  61. func (*nopResolver) Close() {}
  62. func init() {
  63. resolver.Register(&builder{scheme: unixScheme})
  64. resolver.Register(&builder{scheme: unixAbstractScheme})
  65. }