Go请求者付费模式

请求者付费模式是指由请求者支付读取存储空间(Bucket)内数据时产生的流量费用和请求费用,而Bucket拥有者仅支付存储费用。当您希望共享数据,但又不希望产生流量费用和请求费用时,您可以开启此功能。

注意事项

  • 本文以华东1(杭州)外网Endpoint为例。如果您希望通过与OSS同地域的其他阿里云产品访问OSS,请使用内网Endpoint。关于OSS支持的Region与Endpoint的对应关系,请参见OSS访问域名、数据中心、开放端口

  • 本文以从环境变量读取访问凭证为例。如何配置访问凭证,请参见配置访问凭证

  • 本文以OSS域名新建OSSClient为例。如果您希望通过自定义域名、STS等方式新建OSSClient,请参见初始化

  • 要设置请求者付费模式,您必须有oss:PutBucketRequestPayment权限;要获取请求者付费模式,您必须有oss:GetBucketRequestPayment权限。具体操作,请参见为RAM用户授权自定义的权限策略

设置请求者付费模式

以下代码用于设置请求者付费模式。

package main

import (
	"fmt"
	"os"

	"github.com/aliyun/aliyun-oss-go-sdk/oss"
)

func main() {
	// 从环境变量中获取访问凭证。运行本代码示例之前,请确保已设置环境变量OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。
	provider, err := oss.NewEnvironmentVariableCredentialsProvider()
	if err != nil {
		fmt.Println("Error:", err)
		os.Exit(-1)
	}
	// 创建OSSClient实例。
	// yourEndpoint填写Bucket对应的Endpoint,以华东1(杭州)为例,填写为https://oss-cn-hangzhou.aliyuncs.com。其它Region请按实际情况填写。
	// yourRegion填写Bucket所在地域,以华东1(杭州)为例,填写为cn-hangzhou。其它Region请按实际情况填写。
	clientOptions := []oss.ClientOption{oss.SetCredentialsProvider(&provider)}
	clientOptions = append(clientOptions, oss.Region("yourRegion"))
	// 设置签名版本
	clientOptions = append(clientOptions, oss.AuthVersion(oss.AuthV4))
	client, err := oss.New("yourEndpoint", "", "", clientOptions...)
	if err != nil {
		fmt.Println("New Error:", err)
		os.Exit(-1)
	}

	// 初始化请求者付费模式。
	reqPayConf := oss.RequestPaymentConfiguration{
		Payer: "Requester",
	}

	// 设置请求者付费模式。
	err = client.SetBucketRequestPayment("<yourBucketName>", reqPayConf)
	if err != nil {
		fmt.Println("Error:", err)
		os.Exit(-1)
	}
}

获取请求者付费模式配置

以下代码用于获取请求者付费模式配置信息。

package main

import (
	"fmt"
	"os"

	"github.com/aliyun/aliyun-oss-go-sdk/oss"
)

func main() {
	// 从环境变量中获取访问凭证。运行本代码示例之前,请确保已设置环境变量OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。
	provider, err := oss.NewEnvironmentVariableCredentialsProvider()
	if err != nil {
		fmt.Println("Error:", err)
		os.Exit(-1)
	}

	// 创建OSSClient实例。
	// yourEndpoint填写Bucket对应的Endpoint,以华东1(杭州)为例,填写为https://oss-cn-hangzhou.aliyuncs.com。其它Region请按实际情况填写。
	// yourRegion填写Bucket所在地域,以华东1(杭州)为例,填写为cn-hangzhou。其它Region请按实际情况填写。
	clientOptions := []oss.ClientOption{oss.SetCredentialsProvider(&provider)}
	clientOptions = append(clientOptions, oss.Region("yourRegion"))
	// 设置签名版本
	clientOptions = append(clientOptions, oss.AuthVersion(oss.AuthV4))
	client, err := oss.New("yourEndpoint", "", "", clientOptions...)
	if err != nil {
		fmt.Println("Error:", err)
		os.Exit(-1)
	}

	// 获取请求者付费模式配置。
	ret, err := client.GetBucketRequestPayment("yourBucketName")
	if err != nil {
		fmt.Println("Error:", err)
		os.Exit(-1)
	}
	// 打印请求者付费模式配置信息。
	fmt.Println("Bucket request payer:", ret.Payer)
}

第三方付费访问Object

第三方操作Object时需在HTTP Header中携带x-oss-request-payer:requester参数,否则会报错。

以下代码以PutObjectGetObjectDeleteObject为例,用于指定第三方付费访问Object。其他用于指定第三方付费的Object读写操作接口设置方法类似。

package main

import (
	"fmt"
	"io"
	"os"
	"strings"

	"github.com/aliyun/aliyun-oss-go-sdk/oss"
)

func main() {
	// 从环境变量中获取访问凭证。运行本代码示例之前,请确保已设置环境变量OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。
	provider, err := oss.NewEnvironmentVariableCredentialsProvider()
	if err != nil {
		fmt.Println("Error:", err)
		os.Exit(-1)
	}
	// 创建OSSClient实例。
	// yourEndpoint填写Bucket对应的Endpoint,以华东1(杭州)为例,填写为https://oss-cn-hangzhou.aliyuncs.com。其它Region请按实际情况填写。
	// yourRegion填写Bucket所在地域,以华东1(杭州)为例,填写为cn-hangzhou。其它Region请按实际情况填写。
	clientOptions := []oss.ClientOption{oss.SetCredentialsProvider(&provider)}
	clientOptions = append(clientOptions, oss.Region("yourRegion"))
	// 设置签名版本
	clientOptions = append(clientOptions, oss.AuthVersion(oss.AuthV4))
	payerClient, err := oss.New("yourEndpoint", "", "", clientOptions...)
	if err != nil {
		fmt.Println("New Error:", err)
		os.Exit(-1)
	}

	// 填写Bucket名称。
	payerBucket, err := payerClient.Bucket("examplebucket")
	if err != nil {
		fmt.Println("Error:", err)
		os.Exit(-1)
	}

	// 当Bucket拥有者开启请求者付费模式后,外部访问者必须设置oss.RequestPayer(oss.Requester)参数才可以访问授权的内容。
	// 当Bucket拥有者没有开启付费模式时,外部访问者可以不用携带oss.RequestPayer(oss.Requester)参数即可访问授权的内容。

	// 上传Object。
	// 填写Object完整路径,完整路径中不能包含Bucket名称,例如exampledir/exampleobject.txt。
	key := "exampledir/exampleobject.txt"
	err = payerBucket.PutObject(key, strings.NewReader("objectValue"), oss.RequestPayer("requester"))
	if err != nil {
		fmt.Println("put Error:", err)
		os.Exit(-1)
	}

	// 列举Bucket下的所有Object。
	lor, err := payerBucket.ListObjects(oss.RequestPayer(oss.Requester))
	if err != nil {
		fmt.Println("Error:", err)
		os.Exit(-1)
	}
	// 打印Object名称列表。
	for _, l := range lor.Objects {
		fmt.Println("the Key name is :", l.Key)
	}

	// 下载Object。
	body, err := payerBucket.GetObject(key, oss.RequestPayer(oss.Requester))
	if err != nil {
		fmt.Println("Get Error:", err)
		os.Exit(-1)
	}
	// 数据读取完成后,获取的流必须关闭,否则会造成连接泄漏,导致请求无连接可用,程序无法正常工作。
	defer body.Close()

	// 读取并打印获取的内容。
	data, err := io.ReadAll(body)
	if err != nil {
		fmt.Println("Error:", err)
		os.Exit(-1)
	}
	fmt.Println("data:", string(data))

	// 删除Object。
	err = payerBucket.DeleteObject(key, oss.RequestPayer(oss.Requester))
	if err != nil {
		fmt.Println("Error:", err)
		os.Exit(-1)
	}
}

相关文档