X-Git-Url: https://git.arvados.org/arvados.git/blobdiff_plain/52fa01051f4633e3bbbfcdf8c55994e7cd91212a..841d8e9643b622457474b74d075b36dcb67c871b:/sdk/go/keepclient/gateway_shim.go diff --git a/sdk/go/keepclient/gateway_shim.go b/sdk/go/keepclient/gateway_shim.go index 262d612640..260824453d 100644 --- a/sdk/go/keepclient/gateway_shim.go +++ b/sdk/go/keepclient/gateway_shim.go @@ -6,13 +6,23 @@ package keepclient import ( "context" + "fmt" "io" + "net/http" + "strings" + "time" "git.arvados.org/arvados.git/sdk/go/arvados" ) // keepViaHTTP implements arvados.KeepGateway by using a KeepClient to // do upstream requests to keepstore and keepproxy. +// +// This enables KeepClient to use KeepGateway wrappers (like +// arvados.DiskCache) to wrap its own HTTP client back-end methods +// (getOrHead, httpBlockWrite). +// +// See (*KeepClient)upstreamGateway() for the relevant glue. type keepViaHTTP struct { *KeepClient } @@ -36,32 +46,33 @@ func (kvh *keepViaHTTP) BlockRead(ctx context.Context, opts arvados.BlockReadOpt if err != nil { return 0, err } - defer rdr.Close() n, err := io.Copy(opts.WriteTo, rdr) + errClose := rdr.Close() + if err == nil { + err = errClose + } return int(n), err } -// keepViaBlockCache implements arvados.KeepGateway by using the given -// KeepClient's BlockCache with the wrapped KeepGateway. -// -// Note the whole KeepClient gets passed in instead of just its -// cache. This ensures the new BlockCache gets used if it changes -// after keepViaBlockCache is initialized. -type keepViaBlockCache struct { - kc *KeepClient - arvados.KeepGateway -} - -func (kvbc *keepViaBlockCache) ReadAt(locator string, dst []byte, offset int) (int, error) { - return kvbc.kc.cache().ReadAt(kvbc.KeepGateway, locator, dst, offset) +func (kvh *keepViaHTTP) BlockWrite(ctx context.Context, req arvados.BlockWriteOptions) (arvados.BlockWriteResponse, error) { + return kvh.httpBlockWrite(ctx, req) } -func (kvbc *keepViaBlockCache) BlockRead(ctx context.Context, opts arvados.BlockReadOptions) (int, error) { - rdr, _, _, _, err := kvbc.kc.getOrHead("GET", opts.Locator, nil) +func (kvh *keepViaHTTP) LocalLocator(locator string) (string, error) { + if !strings.Contains(locator, "+R") { + // Either it has +A, or it's unsigned and we assume + // it's a local locator on a site with signatures + // disabled. + return locator, nil + } + sighdr := fmt.Sprintf("local, time=%s", time.Now().UTC().Format(time.RFC3339)) + _, _, url, hdr, err := kvh.KeepClient.getOrHead("HEAD", locator, http.Header{"X-Keep-Signature": []string{sighdr}}) if err != nil { - return 0, err + return "", err } - defer rdr.Close() - n, err := io.Copy(opts.WriteTo, rdr) - return int(n), err + loc := hdr.Get("X-Keep-Locator") + if loc == "" { + return "", fmt.Errorf("missing X-Keep-Locator header in HEAD response from %s", url) + } + return loc, nil }