如何在Go中使用带有自定义标头的GCP签名URL?

huangapple go评论89阅读模式
英文:

How to use gcp signed url with custom headers in Go

问题

我正在尝试动态设置头部中的 x-goog-meta-reference,所以我想在函数签名中传递一个名为 reference 的参数,并将其赋值给头部中的 x-goog-meta-reference。请参考下面代码示例中的 x-goog-meta-reference。我按照这个链接中关于规范请求的说明进行操作。

我的示例代码来自这里,但这是我生产代码的编辑版本。

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", // << 我希望 xxx 的值是我作为参数传递给该函数的任意值
		},
		Expires:     expiration,
	}

	url, err := gcsClient.Bucket(bucket).SignedURL(key, opts)
	if err != nil {
		log.WithContext(ctx).Warn("生成 GCS 签名 URL 失败")
		return "", err
	}

	return url, nil
}

我尝试查看了一些示例,但它们都是关于 S3 的,我没有找到任何关于 GCP 的示例代码。不过,我找到了这个问题,但我自己无法解决。

英文:

I am trying to set the x-goog-meta-reference in the header section dynamically so i want to pass an argument called reference in the function signature and assign that to the x-goog-meta-reference in the header. See x-goog-meta-reference in my code sample below. I followed this link regarding canonical requests.

My sample code is from here but it is the edited version of my prod code.

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

	storage.SignedURL()
	opts := &amp;storage.SignedURLOptions{
		Scheme:      storage.SigningSchemeV4,
		Method:      &quot;PUT&quot;,
		ContentType: &quot;text/csv&quot;,
		Headers:     []string{
			&quot;x-goog-meta-reference: xxx&quot;, // &lt;&lt; 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(&quot;Failed to generate a GCS signed URL&quot;)
		return &quot;&quot;, err
	}

	return url, nil
}

I tried looking at some examples but all of them are s3 and I did not run into any gcp sample code. However, I did find this issue but i was not able to figure it out myself.

答案1

得分: 0

如@dazwilkin所提到的,fmt.Sprintf对于这种情况已经足够好了,但你也可以使用我从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
}
英文:

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

import (
	&quot;context&quot;
	&quot;fmt&quot;
	&quot;time&quot;

	&quot;cloud.google.com/go/storage&quot;
	&quot;github.com/dkbyo/go-stringhttpheader&quot;
)

type Headers struct {
	GoogleMetaReference string `header:&quot;x-goog-meta-reference&quot;`
}

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

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

	return url, nil
}

huangapple
  • 本文由 发表于 2022年2月14日 08:01:21
  • 转载请务必保留本文链接:https://go.coder-hub.com/71105918.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定