You are here

class S3fsCorsPostObjectV4 in S3 File System CORS Upload 7

Encapsulates the logic for getting the data for an S3 object POST upload form

@link http://docs.aws.amazon.com/AmazonS3/latest/API/RESTObjectPOST.html @link http://docs.aws.amazon.com/AmazonS3/latest/API/sigv4-post-example.html

Hierarchy

Expanded class hierarchy of S3fsCorsPostObjectV4

File

./s3fs_cors.post_object_v4.class.inc, line 21
The code of classes was taken from the AWS SDK v3.180.3 and a bit modified. Next classes are used here:

View source
class S3fsCorsPostObjectV4 {
  use S3fsCorsSignatureTrait;
  private $client;
  private $bucket;
  private $formAttributes;
  private $formInputs;

  /**
   * Constructs the PostObject.
   *
   * The options array accepts the following keys:
   * @link http://docs.aws.amazon.com/AmazonS3/latest/API/sigv4-query-string-auth.html
   *
   * @param S3ClientInterface $client     Client used with the POST object
   * @param string            $bucket     Bucket to use
   * @param array             $formInputs Associative array of form input
   *                                      fields.
   * @param array             $options    Policy condition options
   * @param mixed             $expiration Upload expiration time value. By
   *                                      default: 1 hour valid period.
   */
  public function __construct(S3ClientInterface $client, $bucket, array $formInputs, array $options = [], $expiration = '+1 hours') {
    $this->client = $client;
    $this->bucket = $bucket;

    // setup form attributes
    $this->formAttributes = [
      'action' => $this
        ->generateUri(),
      'method' => 'POST',
      'enctype' => 'multipart/form-data',
    ];
    $credentials = $this->client
      ->getCredentials();
    if ($securityToken = $credentials
      ->getSecurityToken()) {
      $options[] = [
        'x-amz-security-token' => $securityToken,
      ];
      $formInputs['X-Amz-Security-Token'] = $securityToken;
    }

    // setup basic policy
    $policy = [
      'expiration' => gmdate('Y-m-d\\TH:i:s\\Z', strtotime($expiration)),
      'conditions' => $options,
    ];

    // setup basic formInputs
    $this->formInputs = $formInputs + [
      'key' => '${filename}',
    ];

    // finalize policy and signature
    $this->formInputs += $this
      ->getPolicyAndSignature($credentials, $policy);
  }

  /**
   * Gets the S3 client.
   *
   * @return S3ClientInterface
   */
  public function getClient() {
    return $this->client;
  }

  /**
   * Gets the bucket name.
   *
   * @return string
   */
  public function getBucket() {
    return $this->bucket;
  }

  /**
   * Gets the form attributes as an array.
   *
   * @return array
   */
  public function getFormAttributes() {
    return $this->formAttributes;
  }

  /**
   * Set a form attribute.
   *
   * @param string $attribute Form attribute to set.
   * @param string $value     Value to set.
   */
  public function setFormAttribute($attribute, $value) {
    $this->formAttributes[$attribute] = $value;
  }

  /**
   * Gets the form inputs as an array.
   *
   * @return array
   */
  public function getFormInputs() {
    return $this->formInputs;
  }

  /**
   * Set a form input.
   *
   * @param string $field Field name to set
   * @param string $value Value to set.
   */
  public function setFormInput($field, $value) {
    $this->formInputs[$field] = $value;
  }
  private function generateUri() {
    $url = Url::factory($this->client
      ->getBaseUrl());
    if ($url
      ->getScheme() === 'https' && strpos($this->bucket, '.') !== false) {

      // Use path-style URLs
      $url
        ->setPath($this->bucket);
    }
    else {

      // Use virtual-style URLs
      $url
        ->setHost($this->bucket . '.' . $url
        ->getHost());
    }
    return (string) $url;
  }
  protected function getPolicyAndSignature(CredentialsInterface $credentials, array $policy) {
    $ldt = gmdate('Ymd\\THis\\Z');

    // SignatureV4::ISO8601_BASIC
    $sdt = substr($ldt, 0, 8);
    $policy['conditions'][] = [
      'X-Amz-Date' => $ldt,
    ];
    $region = $this->client
      ->getRegion();
    $scope = $this
      ->createScope($sdt, $region, 's3');
    $creds = "{$credentials->getAccessKeyId()}/{$scope}";
    $policy['conditions'][] = [
      'X-Amz-Credential' => $creds,
    ];
    $policy['conditions'][] = [
      'X-Amz-Algorithm' => "AWS4-HMAC-SHA256",
    ];
    $jsonPolicy64 = base64_encode(json_encode($policy));
    $key = $this
      ->getSigningKey($sdt, $region, 's3', $credentials
      ->getSecretKey());
    return [
      'X-Amz-Credential' => $creds,
      'X-Amz-Algorithm' => "AWS4-HMAC-SHA256",
      'X-Amz-Date' => $ldt,
      'Policy' => $jsonPolicy64,
      'X-Amz-Signature' => bin2hex(hash_hmac('sha256', $jsonPolicy64, $key, true)),
    ];
  }

}

Members

Namesort descending Modifiers Type Description Overrides
S3fsCorsPostObjectV4::$bucket private property
S3fsCorsPostObjectV4::$client private property
S3fsCorsPostObjectV4::$formAttributes private property
S3fsCorsPostObjectV4::$formInputs private property
S3fsCorsPostObjectV4::generateUri private function
S3fsCorsPostObjectV4::getBucket public function Gets the bucket name.
S3fsCorsPostObjectV4::getClient public function Gets the S3 client.
S3fsCorsPostObjectV4::getFormAttributes public function Gets the form attributes as an array.
S3fsCorsPostObjectV4::getFormInputs public function Gets the form inputs as an array.
S3fsCorsPostObjectV4::getPolicyAndSignature protected function
S3fsCorsPostObjectV4::setFormAttribute public function Set a form attribute.
S3fsCorsPostObjectV4::setFormInput public function Set a form input.
S3fsCorsPostObjectV4::__construct public function Constructs the PostObject.
S3fsCorsSignatureTrait::$cache private property @var array Cache of previously signed values
S3fsCorsSignatureTrait::$cacheSize private property @var int Size of the hash cache
S3fsCorsSignatureTrait::createScope private function
S3fsCorsSignatureTrait::getSigningKey private function