if !remote.Proxy {
continue
}
- remotes[id] = rpc.NewConn(id, &url.URL{Scheme: remote.Scheme, Host: remote.Host}, remote.Insecure, saltedTokenProvider(local, id))
+ conn := rpc.NewConn(id, &url.URL{Scheme: remote.Scheme, Host: remote.Host}, remote.Insecure, saltedTokenProvider(local, id))
+ // Older versions of controller rely on the Via header
+ // to detect loops.
+ conn.SendHeader = http.Header{"Via": {"HTTP/1.1 arvados-controller"}}
+ remotes[id] = conn
}
return &Conn{
}
func (conn *Conn) CollectionGet(ctx context.Context, options arvados.GetOptions) (arvados.Collection, error) {
+ downstream := options.ForwardedFor
+ options.ForwardedFor = conn.cluster.ClusterID + "-" + downstream
if len(options.UUID) == 27 {
// UUID is really a UUID
c, err := conn.chooseBackend(options.UUID).CollectionGet(ctx, options)
// UUID is a PDH
first := make(chan arvados.Collection, 1)
err := conn.tryLocalThenRemotes(ctx, func(ctx context.Context, remoteID string, be backend) error {
+ if remoteID != "" && downstream != "" {
+ // If remoteID isn't in downstream, we
+ // might find the collection by taking
+ // another hop, but we don't bother:
+ // token salting and blob signature
+ // rewriting don't work over multiple
+ // hops.
+ return notFoundError{}
+ }
c, err := be.CollectionGet(ctx, options)
if err != nil {
return err
"prefs": true,
"username": true,
+ "etag": false,
"full_name": false,
"identity_url": false,
"is_invited": false,
"owner_uuid": false,
"uuid": false,
+ "writable_by": false,
}
func (conn *Conn) UserList(ctx context.Context, options arvados.ListOptions) (arvados.UserList, error) {