After pay-by-requester mode is enabled for a bucket in Alibaba Cloud OSS, the requester instead of the bucket owner pays the cost of requests and traffic. The bucket owner always pays the cost of storing data. You can enable this feature to share data without paying for all requests and traffic by yourself.

Request methods

  • Access from anonymous users is not allowed

    If you enable pay-by-requester mode for a bucket, anonymous users are not allowed to access the bucket. Requesters must provide authentication information so that OSS can identify and charge them, but not the bucket owner, for requests and traffic.

    If requesters assume the RAM role of an Alibaba Cloud account to request data, OSS charges this Alibaba Cloud account for such requests and traffic.

  • Requesters must include the x-oss-request-payer request header

    If you enable pay-by-requester mode for a bucket, requesters must include the x-oss-request-payer:requester request header in a PUT, POST, GET, or HEAD request. This field indicates that requesters understand that their requests and data downloads incur fees. Otherwise, requests cannot pass authentication.

    Bucket owners do not need to include the x-oss-request-payer request header when accessing their own buckets. In this case, bucket owners are requesters who pay for such requests and traffic.

For more information about pay-by-requester mode, see Enable the pay-by-requester mode in the OSS Developer Guide.

Enable pay-by-requester mode

The following code provides an example of how to enable pay-by-requester mode:
package main

import (
  "fmt"
  "os"

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

func main() {
  // Create an OSSClient instance.
  client, err := oss.New("<yourEndpoint>", "<yourAccessKeyId>", "<yourAccessKeySecret>")
  if err ! = nil {
    fmt.Println("Error:", err)
    os.Exit(-1)
  }

  // Initialize pay-by-requester mode.
  reqPayConf := oss.RequestPaymentConfiguration{
    Payer: "Requester",
  }

  // Enable pay-by-requester mode for the bucket.
  err = client.SetBucketRequestPayment("<yourBucketName>", reqPayConf)
  if err ! = nil {
    fmt.Println("Error:", err)
    os.Exit(-1)
  }
}

Obtain pay-by-requester configurations

The following code provides an example of how to obtain pay-by-requester configurations:
package main

import (
  "fmt"
  "os"

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

func main() {
  // Create an OSSClient instance.
  client, err := oss.New("<yourEndpoint>", "<yourAccessKeyId>", "<yourAccessKeySecret>")
  if err ! = nil {
    fmt.Println("Error:", err)
    os.Exit(-1)
    }

  // Obtain pay-by-requester configurations for the bucket.
  ret, err := client.GetBucketRequestPayment("<yourBucketName>")
  if err ! = nil {
    fmt.Println("Error:", err)
    os.Exit(-1)
  }
  // Display pay-by-requester configurations for the bucket.
  fmt.Println("Bucket request payer:", ret.Payer)
}

Specify a third party to pay for access to objects

The following code provides an example of how to specify a third party to pay for access to objects when you use PutObject, ListObjects, GetObject, and DeleteObject:

package main

import (
  "fmt"
  "os"
  "io/ioutil"
  "github.com/aliyun/aliyun-oss-go-sdk/oss"
  "strings"
)

func main() {
  // Create an OSSClient instance.
  // <Endpoint>: specifies the domain name that is used to access the bucket.
  // <yourAccessKeyId>  <yourAccessKeySecret>: specify the AccessKey ID and AccessKey secret that are assigned to third parties to access resources in OSS.
  payerClient, err := oss.New("<Endpoint>", "<yourAccessKeyId>", "<yourAccessKeySecret>")
  if err ! = nil {
    fmt.Println("New Error:", err)
    os.Exit(-1)
  }

  // Obtain pay-by-requester configurations for the bucket.
    //The bucket has enabled pay-by-requester mode and permissions have been assigned to a third party.
  payerBucket, err := payerClient.Bucket("<bucketName>")
  if err ! = nil {
    fmt.Println("Error:", err)
    os.Exit(-1)
  }

    // If the bucket owner enables pay-by-requester mode, requesters must include the oss.RequestPayer(oss.Requester) field in the request. This field indicates that requesters understand that their requests and data downloads incur fees.
    // If the bucket owner does not enable pay-by-requester mode, requesters do not need to include the oss.RequestPayer(oss.Requester) field in the request.
    // For more information about request payment modes of buckets, see SetBucketRequestPayment.

  // Upload an object. The third party has been authorized to perform corresponding operations on the bucket.
  key := "youObjectName"
  err = payerBucket.PutObject(key, strings.NewReader("<objectValue>"), oss.RequestPayer("requester"))
  if err ! = nil {
    fmt.Println("put Error:", err)
    os.Exit(-1)
  }

  // List all objects in the bucket. The third party has been authorized to perform corresponding operations on the bucket.
  // The third party must include the oss.RequestPayer(oss.Requester) field in the request header.
  lor, err := payerBucket.ListObjects(oss.RequestPayer(oss.Requester))
  if err ! = nil {
    fmt.Println("Error:", err)
    os.Exit(-1)
  }
  // Display object names.
  for _, l := range lor.Objects {
    fmt.Println("the Key name is :", l.Key)
  }

  // Download an object. The third party has been authorized to perform corresponding operations on the bucket.
  body, err := payerBucket.GetObject(key, oss.RequestPayer(oss.Requester))
  if err ! = nil {
    fmt.Println("Get Error:", err)
    os.Exit(-1)
  }
  // If you do not close the connection after it is used, connection leaks may occur. Consequently, no connections are available and the program cannot run properly.
  defer body.Close()

  // Read and display the obtained content.
  data, err := ioutil.ReadAll(body)
  if err ! = nil {
    fmt.Println("Error:", err)
    os.Exit(-1)
  }
  fmt.Println("data:", string(data))

  // Delete an object. The third party has been authorized to perform corresponding operations on the bucket.
  err = payerBucket.DeleteObject(key, oss.RequestPayer(oss.Requester))
  if err ! = nil {
    fmt.Println("Error:", err)
    os.Exit(-1)
  }
}