1 // Copyright (C) The Arvados Authors. All rights reserved.
3 // SPDX-License-Identifier: AGPL-3.0
13 "git.curoverse.com/arvados.git/sdk/go/arvados"
14 "git.curoverse.com/arvados.git/sdk/go/arvadosclient"
15 "git.curoverse.com/arvados.git/sdk/go/auth"
16 "git.curoverse.com/arvados.git/sdk/go/keepclient"
19 type remoteProxy struct {
20 clients map[string]*keepclient.KeepClient
24 func (rp *remoteProxy) Get(w http.ResponseWriter, r *http.Request, cluster *arvados.Cluster) {
25 var remoteClient *keepclient.KeepClient
27 for i, part := range strings.Split(r.URL.Path[1:], "+") {
30 // don't try to parse hash part as hint
31 case strings.HasPrefix(part, "A"):
32 // drop local permission hint
34 case len(part) > 7 && part[0] == 'R' && part[6] == '-':
36 remote, ok := cluster.RemoteClusters[remoteID]
38 http.Error(w, "remote cluster not configured", http.StatusBadGateway)
41 token := GetAPIToken(r)
43 http.Error(w, "no token provided in Authorization header", http.StatusUnauthorized)
46 kc, err := rp.remoteClient(remoteID, remote, token)
47 if err == auth.ErrObsoleteToken {
48 http.Error(w, err.Error(), http.StatusBadRequest)
50 } else if err != nil {
51 http.Error(w, err.Error(), http.StatusInternalServerError)
57 parts = append(parts, part)
59 if remoteClient == nil {
60 http.Error(w, "bad request", http.StatusBadRequest)
63 locator := strings.Join(parts, "+")
64 rdr, _, _, err := remoteClient.Get(locator)
69 case *keepclient.ErrNotFound:
70 http.Error(w, err.Error(), http.StatusNotFound)
72 http.Error(w, err.Error(), http.StatusBadGateway)
76 func (rp *remoteProxy) remoteClient(remoteID string, remoteCluster arvados.RemoteCluster, token string) (*keepclient.KeepClient, error) {
78 kc, ok := rp.clients[remoteID]
82 APIHost: remoteCluster.Host,
84 Insecure: remoteCluster.Insecure,
86 ac, err := arvadosclient.New(c)
90 kc, err = keepclient.MakeKeepClient(ac)
96 if rp.clients == nil {
97 rp.clients = map[string]*keepclient.KeepClient{remoteID: kc}
99 rp.clients[remoteID] = kc
103 accopy := *kc.Arvados
104 accopy.ApiToken = token
106 kccopy.Arvados = &accopy
107 token, err := auth.SaltToken(token, remoteID)
111 kccopy.Arvados.ApiToken = token