Merge ""cmd/principal": No third-party code on Macaroon receiving page"
diff --git a/profiles/internal/rpc/server.go b/profiles/internal/rpc/server.go
index da73807..d289516 100644
--- a/profiles/internal/rpc/server.go
+++ b/profiles/internal/rpc/server.go
@@ -51,6 +51,7 @@
errFailedToListenForProxy = reg(".errFailedToListenForProxy", "failed to listen on {3}{:4}")
errInternalTypeConversion = reg(".errInternalTypeConversion", "failed to convert {3} to v.io/x/ref/profiles/internal/naming.Endpoint")
errFailedToParseIP = reg(".errFailedToParseIP", "failed to parse {3} as an IP host")
+ errUnexpectedSuffix = reg(".errUnexpectedSuffix", "suffix {3} was not expected because either server has the option IsLeaf set to true or it served an object and not a dispatcher")
)
// state for each requested listen address
@@ -216,6 +217,8 @@
s.blessings = opt.Blessings
case options.ServesMountTable:
s.servesMountTable = bool(opt)
+ case options.IsLeaf:
+ s.isLeaf = bool(opt)
case ReservedNameDispatcher:
s.dispReserved = opt.Dispatcher
case PreferredServerResolveProtocols:
@@ -1177,6 +1180,9 @@
disp := fs.disp
if naming.IsReserved(suffix) {
disp = fs.server.dispReserved
+ } else if fs.server.isLeaf && suffix != "" {
+ innerErr := verror.New(errUnexpectedSuffix, fs.ctx, suffix)
+ return nil, nil, verror.New(verror.ErrUnknownSuffix, fs.ctx, suffix, innerErr)
}
if disp != nil {
obj, auth, err := disp.Lookup(suffix)
diff --git a/profiles/internal/rpc/server_test.go b/profiles/internal/rpc/server_test.go
index a5d1b7d..59d3658 100644
--- a/profiles/internal/rpc/server_test.go
+++ b/profiles/internal/rpc/server_test.go
@@ -16,6 +16,7 @@
"v.io/v23"
"v.io/v23/context"
"v.io/v23/naming"
+ "v.io/v23/options"
"v.io/v23/rpc"
"v.io/v23/security"
"v.io/v23/verror"
@@ -637,7 +638,43 @@
t.Fatalf("timed out waiting for changes to take effect")
}
}
+}
+func TestIsLeafServerOption(t *testing.T) {
+ ctx, shutdown := initForTest()
+ defer shutdown()
+ sm := imanager.InternalNew(naming.FixedRoutingID(0x555555555))
+ defer sm.Shutdown()
+ ns := tnaming.NewSimpleNamespace()
+ pclient, pserver := newClientServerPrincipals()
+ server, err := testInternalNewServer(ctx, sm, ns, pserver, options.IsLeaf(true))
+ if err != nil {
+ t.Fatal(err)
+ }
+ defer server.Stop()
+
+ disp := &testServerDisp{&testServer{}}
+
+ if _, err := server.Listen(listenSpec); err != nil {
+ t.Fatalf("Listen failed: %v", err)
+ }
+
+ if err := server.ServeDispatcher("leafserver", disp); err != nil {
+ t.Fatalf("ServeDispatcher failed: %v", err)
+ }
+ client, err := InternalNewClient(sm, ns)
+ if err != nil {
+ t.Fatalf("InternalNewClient failed: %v", err)
+ }
+ ctx, _ = v23.WithPrincipal(ctx, pclient)
+ ctx, _ = context.WithDeadline(ctx, time.Now().Add(10*time.Second))
+ var result string
+ // we have set IsLeaf to true, sending any suffix to leafserver should result
+ // in an suffix was not expected error.
+ callErr := client.Call(ctx, "leafserver/unwantedSuffix", "Echo", []interface{}{"Mirror on the wall"}, []interface{}{&result})
+ if callErr == nil {
+ t.Fatalf("Call should have failed with suffix was not expected error")
+ }
}
func setLeafEndpoints(eps []naming.Endpoint) {
diff --git a/services/wspr/internal/app/app.go b/services/wspr/internal/app/app.go
index 85ce453..05da65a 100644
--- a/services/wspr/internal/app/app.go
+++ b/services/wspr/internal/app/app.go
@@ -235,6 +235,24 @@
return callOpts, nil
}
+// serverOpts turns a slice of type []RpcServerOptions object into an array of rpc.ServerOpt.
+func (c *Controller) serverOpts(opts []RpcServerOption) ([]rpc.ServerOpt, error) {
+ var serverOpts []rpc.ServerOpt
+
+ for _, opt := range opts {
+ switch v := opt.(type) {
+ case RpcServerOptionIsLeaf:
+ serverOpts = append(serverOpts, options.IsLeaf(v.Value))
+ case RpcServerOptionServesMountTable:
+ serverOpts = append(serverOpts, options.ServesMountTable(v.Value))
+ default:
+ return nil, fmt.Errorf("Unknown RpcServerOption type %T", v)
+ }
+ }
+
+ return serverOpts, nil
+}
+
func (c *Controller) startCall(ctx *context.T, w lib.ClientWriter, msg *RpcRequest, inArgs []interface{}) (rpc.ClientCall, error) {
methodName := lib.UppercaseFirstCharacter(msg.Method)
callOpts, err := c.callOpts(msg.CallOptions)
@@ -574,13 +592,13 @@
vlog.Errorf("close called on non-existent call: %v", id)
}
-func (c *Controller) maybeCreateServer(serverId uint32) (*server.Server, error) {
+func (c *Controller) maybeCreateServer(serverId uint32, opts ...rpc.ServerOpt) (*server.Server, error) {
c.Lock()
defer c.Unlock()
if server, ok := c.servers[serverId]; ok {
return server, nil
}
- server, err := server.NewServer(serverId, c.listenSpec, c)
+ server, err := server.NewServer(serverId, c.listenSpec, c, opts...)
if err != nil {
return nil, err
}
@@ -620,8 +638,13 @@
// Serve instructs WSPR to start listening for calls on behalf
// of a javascript server.
-func (c *Controller) Serve(_ *context.T, _ rpc.ServerCall, name string, serverId uint32) error {
- server, err := c.maybeCreateServer(serverId)
+func (c *Controller) Serve(_ *context.T, _ rpc.ServerCall, name string, serverId uint32, rpcServerOpts []RpcServerOption) error {
+
+ opts, err := c.serverOpts(rpcServerOpts)
+ if err != nil {
+ return verror.Convert(verror.ErrInternal, nil, err)
+ }
+ server, err := c.maybeCreateServer(serverId, opts...)
if err != nil {
return verror.Convert(verror.ErrInternal, nil, err)
}
diff --git a/services/wspr/internal/app/app.vdl b/services/wspr/internal/app/app.vdl
index 0c06832..c62b9e4 100644
--- a/services/wspr/internal/app/app.vdl
+++ b/services/wspr/internal/app/app.vdl
@@ -27,8 +27,8 @@
CallOptions []RpcCallOption
}
-// TODO(nlacasse): It would be nice if RpcCallOption were a struct with
-// optional types, like:
+// TODO(nlacasse): It would be nice if RpcCallOption and RpcServerOption
+// were a struct with optional types, like:
//
// type RpcCallOptions struct {
// AllowedServersPolicy ?[]security.BlessingPattern
@@ -38,6 +38,7 @@
// Unfortunately, optional types are currently only supported for structs, not
// slices or primitive types. Once optional types are better supported, switch
// this to a struct with optional types.
+// Waiting for v.io/i/213
type RpcCallOption union {
AllowedServersPolicy []security.BlessingPattern
@@ -45,6 +46,11 @@
Granter GranterHandle
}
+type RpcServerOption union {
+ IsLeaf bool
+ ServesMountTable bool
+}
+
type RpcResponse struct {
OutArgs []any
TraceResponse vtrace.Response
diff --git a/services/wspr/internal/app/app.vdl.go b/services/wspr/internal/app/app.vdl.go
index bb46e83..b3dce5d 100644
--- a/services/wspr/internal/app/app.vdl.go
+++ b/services/wspr/internal/app/app.vdl.go
@@ -84,6 +84,43 @@
func (x RpcCallOptionGranter) Name() string { return "Granter" }
func (x RpcCallOptionGranter) __VDLReflect(__RpcCallOptionReflect) {}
+type (
+ // RpcServerOption represents any single field of the RpcServerOption union type.
+ RpcServerOption interface {
+ // Index returns the field index.
+ Index() int
+ // Interface returns the field value as an interface.
+ Interface() interface{}
+ // Name returns the field name.
+ Name() string
+ // __VDLReflect describes the RpcServerOption union type.
+ __VDLReflect(__RpcServerOptionReflect)
+ }
+ // RpcServerOptionIsLeaf represents field IsLeaf of the RpcServerOption union type.
+ RpcServerOptionIsLeaf struct{ Value bool }
+ // RpcServerOptionServesMountTable represents field ServesMountTable of the RpcServerOption union type.
+ RpcServerOptionServesMountTable struct{ Value bool }
+ // __RpcServerOptionReflect describes the RpcServerOption union type.
+ __RpcServerOptionReflect struct {
+ Name string "v.io/x/ref/services/wspr/internal/app.RpcServerOption"
+ Type RpcServerOption
+ Union struct {
+ IsLeaf RpcServerOptionIsLeaf
+ ServesMountTable RpcServerOptionServesMountTable
+ }
+ }
+)
+
+func (x RpcServerOptionIsLeaf) Index() int { return 0 }
+func (x RpcServerOptionIsLeaf) Interface() interface{} { return x.Value }
+func (x RpcServerOptionIsLeaf) Name() string { return "IsLeaf" }
+func (x RpcServerOptionIsLeaf) __VDLReflect(__RpcServerOptionReflect) {}
+
+func (x RpcServerOptionServesMountTable) Index() int { return 1 }
+func (x RpcServerOptionServesMountTable) Interface() interface{} { return x.Value }
+func (x RpcServerOptionServesMountTable) Name() string { return "ServesMountTable" }
+func (x RpcServerOptionServesMountTable) __VDLReflect(__RpcServerOptionReflect) {}
+
type RpcResponse struct {
OutArgs []*vdl.Value
TraceResponse vtrace.Response
@@ -124,6 +161,7 @@
func init() {
vdl.Register((*RpcRequest)(nil))
vdl.Register((*RpcCallOption)(nil))
+ vdl.Register((*RpcServerOption)(nil))
vdl.Register((*RpcResponse)(nil))
vdl.Register((*GranterHandle)(nil))
vdl.Register((*GranterRequest)(nil))
diff --git a/services/wspr/internal/app/app_test.go b/services/wspr/internal/app/app_test.go
index 9821146..05c02cf 100644
--- a/services/wspr/internal/app/app_test.go
+++ b/services/wspr/internal/app/app_test.go
@@ -337,10 +337,10 @@
req, err := makeRequest(RpcRequest{
Name: "__controller",
Method: "Serve",
- NumInArgs: 2,
+ NumInArgs: 3,
NumOutArgs: 1,
Deadline: vdltime.Deadline{},
- }, "adder", 0)
+ }, "adder", 0, []RpcServerOption{})
controller.HandleVeyronRequest(ctx, 0, req, writer)
testWriter, _ := writer.(*testwriter.Writer)
diff --git a/services/wspr/internal/app/controller.vdl b/services/wspr/internal/app/controller.vdl
index 68376f0..95daf5b 100644
--- a/services/wspr/internal/app/controller.vdl
+++ b/services/wspr/internal/app/controller.vdl
@@ -14,7 +14,7 @@
type Controller interface {
// Serve instructs WSPR to start listening for calls on behalf
// of a javascript server.
- Serve(name string, serverId uint32) error
+ Serve(name string, serverId uint32, serverOpts []RpcServerOption) error
// Stop instructs WSPR to stop listening for calls for the
// given javascript server.
Stop(serverId uint32) error
diff --git a/services/wspr/internal/app/controller.vdl.go b/services/wspr/internal/app/controller.vdl.go
index f8b6c0d..4ffd6c6 100644
--- a/services/wspr/internal/app/controller.vdl.go
+++ b/services/wspr/internal/app/controller.vdl.go
@@ -24,7 +24,7 @@
type ControllerClientMethods interface {
// Serve instructs WSPR to start listening for calls on behalf
// of a javascript server.
- Serve(ctx *context.T, name string, serverId uint32, opts ...rpc.CallOpt) error
+ Serve(ctx *context.T, name string, serverId uint32, serverOpts []RpcServerOption, opts ...rpc.CallOpt) error
// Stop instructs WSPR to stop listening for calls for the
// given javascript server.
Stop(ctx *context.T, serverId uint32, opts ...rpc.CallOpt) error
@@ -68,8 +68,8 @@
name string
}
-func (c implControllerClientStub) Serve(ctx *context.T, i0 string, i1 uint32, opts ...rpc.CallOpt) (err error) {
- err = v23.GetClient(ctx).Call(ctx, c.name, "Serve", []interface{}{i0, i1}, nil, opts...)
+func (c implControllerClientStub) Serve(ctx *context.T, i0 string, i1 uint32, i2 []RpcServerOption, opts ...rpc.CallOpt) (err error) {
+ err = v23.GetClient(ctx).Call(ctx, c.name, "Serve", []interface{}{i0, i1, i2}, nil, opts...)
return
}
@@ -138,7 +138,7 @@
type ControllerServerMethods interface {
// Serve instructs WSPR to start listening for calls on behalf
// of a javascript server.
- Serve(ctx *context.T, call rpc.ServerCall, name string, serverId uint32) error
+ Serve(ctx *context.T, call rpc.ServerCall, name string, serverId uint32, serverOpts []RpcServerOption) error
// Stop instructs WSPR to stop listening for calls for the
// given javascript server.
Stop(ctx *context.T, call rpc.ServerCall, serverId uint32) error
@@ -202,8 +202,8 @@
gs *rpc.GlobState
}
-func (s implControllerServerStub) Serve(ctx *context.T, call rpc.ServerCall, i0 string, i1 uint32) error {
- return s.impl.Serve(ctx, call, i0, i1)
+func (s implControllerServerStub) Serve(ctx *context.T, call rpc.ServerCall, i0 string, i1 uint32, i2 []RpcServerOption) error {
+ return s.impl.Serve(ctx, call, i0, i1, i2)
}
func (s implControllerServerStub) Stop(ctx *context.T, call rpc.ServerCall, i0 uint32) error {
@@ -274,8 +274,9 @@
Name: "Serve",
Doc: "// Serve instructs WSPR to start listening for calls on behalf\n// of a javascript server.",
InArgs: []rpc.ArgDesc{
- {"name", ``}, // string
- {"serverId", ``}, // uint32
+ {"name", ``}, // string
+ {"serverId", ``}, // uint32
+ {"serverOpts", ``}, // []RpcServerOption
},
},
{
diff --git a/services/wspr/internal/rpc/server/server.go b/services/wspr/internal/rpc/server/server.go
index ac7d2b5..9ce5ac9 100644
--- a/services/wspr/internal/rpc/server/server.go
+++ b/services/wspr/internal/rpc/server/server.go
@@ -102,7 +102,7 @@
type serverContextKey struct{}
-func NewServer(id uint32, listenSpec *rpc.ListenSpec, helper ServerHelper) (*Server, error) {
+func NewServer(id uint32, listenSpec *rpc.ListenSpec, helper ServerHelper, opts ...rpc.ServerOpt) (*Server, error) {
server := &Server{
id: id,
helper: helper,
@@ -114,7 +114,7 @@
var err error
ctx := helper.Context()
ctx = context.WithValue(ctx, serverContextKey{}, server)
- if server.server, err = v23.NewServer(ctx); err != nil {
+ if server.server, err = v23.NewServer(ctx, opts...); err != nil {
return nil, err
}
return server, nil