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

注意事项

  • 本文以华东1(杭州)外网Endpoint为例。如果您希望通过与OSS同地域的其他阿里云产品访问OSS,请使用内网Endpoint。关于OSS支持的Region与Endpoint的对应关系,请参见访问域名和数据中心
  • 本文以OSS域名新建OSSClient为例。如果您希望通过自定义域名、STS等方式新建OSSClient,请参见Go初始化
  • 要设置请求者付费模式,您必须有oss:PutBucketRequestPayment权限;要获取请求者付费模式,您必须有oss:GetBucketRequestPayment权限。具体操作,请参见为RAM用户授权自定义的权限策略

设置请求者付费模式

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

package main

import (
  "fmt"
  "os"

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

func main() {
  // 创建OSSClient实例。
  // yourEndpoint填写Bucket对应的Endpoint,以华东1(杭州)为例,填写为https://oss-cn-hangzhou.aliyuncs.com。其它Region请按实际情况填写。
  // 阿里云账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM用户进行API访问或日常运维,请登录RAM控制台创建RAM用户。
  client, err := oss.New("yourEndpoint", "yourAccessKeyId", "yourAccessKeySecret")
  if err != nil {
    fmt.Println("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() {
  // 创建OSSClient实例。
  // yourEndpoint填写Bucket对应的Endpoint,以华东1(杭州)为例,填写为https://oss-cn-hangzhou.aliyuncs.com。其它Region请按实际情况填写。
  // 阿里云账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM用户进行API访问或日常运维,请登录RAM控制台创建RAM用户。
  client, err := oss.New("yourEndpoint", "yourAccessKeyId", "yourAccessKeySecret")
  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"
  "os"
  "io/ioutil"
  "github.com/aliyun/aliyun-oss-go-sdk/oss"
  "strings"
)

func main() {
  // 创建OSSClient实例。
  // Endpoint填写Bucket对应的Endpoint,以华东1(杭州)为例,填写为https://oss-cn-hangzhou.aliyuncs.com。其它Region请按实际情况填写。
  // yourAccessKeyId与yourAccessKeySecret填写外部访问者账户密钥。
  payerClient, err := oss.New("yourEndpoint", "yourAccessKeyId", "yourAccessKeySecret")
  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 := ioutil.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)
  }
}

相关文档