如何在 Go 中使用带有自定义 headers 的 gcp signed url

How to use gcp signed url with custom headers in Go

我正在尝试动态设置 header 部分中的 x-goog-meta-reference,因此我想在函数签名中传递一个名为 reference 的参数,并将其分配给 x-goog-meta-reference header。请参阅下面我的代码示例中的 x-goog-meta-reference。我关注 this link 关于规范请求。

我的示例代码来自 here 但它是我的产品代码的编辑版本。

func GenerateSignedURL(ctx context.Context, bucket string, key string, expiration time.Time,
) (string, error) {
    gcsClient, err := storage.NewClient(ctx)
    if err != nil {
        return "", fmt.Errorf("storage.NewClient: %v", err)
    }
    defer gcsClient.Close()

    storage.SignedURL()
    opts := &storage.SignedURLOptions{
        Scheme:      storage.SigningSchemeV4,
        Method:      "PUT",
        ContentType: "text/csv",
        Headers:     []string{
            "x-goog-meta-reference: xxx", // << I want xxx value to be whatever I pass to this function as an arg
        },
        Expires:     expiration,
    }

    url, err := gcsClient.Bucket(bucket).SignedURL(key, opts)
    if err != nil {
        log.WithContext(ctx).Warn("Failed to generate a GCS signed URL")
        return "", err
    }

    return url, nil
}

我尝试查看一些示例,但它们都是 s3,我没有 运行 进入任何 gcp 示例代码。但是,我确实发现了 this 问题,但我自己无法解决。

作为@dazwilkin , fmt.Sprintf is good enough for this case, but you can also use this library that I ported from mozilla

import (
    "context"
    "fmt"
    "time"

    "cloud.google.com/go/storage"
    "github.com/dkbyo/go-stringhttpheader"
)

type Headers struct {
    GoogleMetaReference string `header:"x-goog-meta-reference"`
}

func GenerateSignedURL(bucket string, key string, expiration time.Time,
) (string, error) {
    ctx := context.Background()
    gcsClient, err := storage.NewClient(ctx)
    if err != nil {
        return "", fmt.Errorf("storage.NewClient: %v", err)
    }
    defer gcsClient.Close()
    headers := Headers{
        GoogleMetaReference: "xxx",
    }
    fmt.Print(stringhttpheader.Encode(headers))
    stringheaders, _ := stringhttpheader.Encode(headers)
    //storage.SignedURL()
    opts := &storage.SignedURLOptions{
        Scheme:      storage.SigningSchemeV4,
        Method:      "PUT",
        ContentType: "text/csv",
        Headers:     stringheaders,
        Expires:     expiration,
    }

    url, err := gcsClient.Bucket(bucket).SignedURL(key, opts)
    if err != nil {
        log.WithContext(ctx).Warn("Failed to generate a GCS signed URL")
        return "", err
    }

    return url, nil
}