Example #1
0
 /**
  * Get the S3 response
  *
  * @return  Response
  */
 public function getResponse()
 {
     $this->processParametersIntoResource();
     $schema = 'http://';
     if ($this->configuration->isSSL()) {
         $schema = 'https://';
     }
     $url = $schema . $this->headers['Host'] . $this->uri;
     // Basic setup
     $curl = curl_init();
     curl_setopt($curl, CURLOPT_USERAGENT, 'keek/s3-client');
     curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 1);
     curl_setopt($curl, CURLOPT_TIMEOUT, 5);
     if ($this->configuration->isSSL()) {
         // Set the CA certificate cache location
         $caCert = $this->getCaCertLocation();
         if (!empty($caCert)) {
             if (is_dir($caCert)) {
                 @curl_setopt($curl, CURLOPT_CAPATH, $caCert);
             } else {
                 @curl_setopt($curl, CURLOPT_CAINFO, $caCert);
             }
         }
         // Verify the host name in the certificate and the certificate itself. However, if your bucket contains dots
         // we have to turn off host verification. Sorry, that's a limitation of Amazon S3. Since they recommend
         // always using virtual hosting style hostnames while their SSL certificate is set up to only allow
         // subdomains (bucket names) without dots the direct implication is that if you want to use SSL you MUST NOT
         // use dots in your bucket name. Of course this contradicts another part of their documentation which
         // suggests using bucket names with dots (same as your domain name) but YOU CAN'T MAKE SENSE OF THEIR BLOODY
         // DOCS, CAN YOU? For what is worth their own SDK uses path-style access which they tell everyone else to
         // not use.
         //
         // TL;DR: Amazon is a bunch of jerks.
         $isAmazonS3 = substr($this->headers['Host'], -14) == '.amazonaws.com';
         $tooManyDots = substr_count($this->headers['Host'], '.') > 3;
         $verifyHost = $isAmazonS3 && $tooManyDots ? 0 : 2;
         curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, $verifyHost);
         curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, true);
     }
     curl_setopt($curl, CURLOPT_URL, $url);
     $signer = Signature::getSignatureObject($this, $this->configuration->getSignatureMethod());
     $signer->preProcessHeaders($this->headers, $this->amzHeaders);
     // Headers
     $headers = array();
     foreach ($this->amzHeaders as $header => $value) {
         if (strlen($value) > 0) {
             $headers[] = $header . ': ' . $value;
         }
     }
     foreach ($this->headers as $header => $value) {
         if (strlen($value) > 0) {
             $headers[] = $header . ': ' . $value;
         }
     }
     $headers[] = 'Authorization: ' . $signer->getAuthorizationHeader();
     curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
     curl_setopt($curl, CURLOPT_HEADER, false);
     curl_setopt($curl, CURLOPT_RETURNTRANSFER, false);
     curl_setopt($curl, CURLOPT_WRITEFUNCTION, array($this, '__responseWriteCallback'));
     curl_setopt($curl, CURLOPT_HEADERFUNCTION, array($this, '__responseHeaderCallback'));
     curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true);
     // Optimize the Object Store Request Caching
     if (!in_array($this->verb, ['PUT', 'POST'])) {
         curl_setopt($curl, CURLOPT_FRESH_CONNECT, false);
         curl_setopt($curl, CURLOPT_CONNECTTIMEOUT_MS, 1000);
         // Disabled execution timeout to allow streaming to complete
         //curl_setopt($curl, CURLOPT_TIMEOUT_MS, 8000);
         curl_setopt($curl, CURLOPT_DNS_CACHE_TIMEOUT, 604800);
     }
     // Request types
     switch ($this->verb) {
         case 'GET':
             break;
         case 'PUT':
         case 'POST':
             if (!is_object($this->input) || !$this->input instanceof Input) {
                 $this->input = new Input();
             }
             $size = $this->input->getSize();
             $type = $this->input->getInputType();
             if ($type == Input::INPUT_DATA) {
                 curl_setopt($curl, CURLOPT_CUSTOMREQUEST, $this->verb);
                 $data = $this->input->getDataReference();
                 if (strlen($data)) {
                     curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
                 }
                 if ($size > 0) {
                     curl_setopt($curl, CURLOPT_BUFFERSIZE, $size);
                 }
             } else {
                 curl_setopt($curl, CURLOPT_PUT, true);
                 curl_setopt($curl, CURLOPT_INFILE, $this->input->getFp());
                 if ($size > 0) {
                     curl_setopt($curl, CURLOPT_INFILESIZE, $size);
                 }
             }
             break;
         case 'HEAD':
             curl_setopt($curl, CURLOPT_CUSTOMREQUEST, 'HEAD');
             curl_setopt($curl, CURLOPT_NOBODY, true);
             break;
         case 'DELETE':
             curl_setopt($curl, CURLOPT_CUSTOMREQUEST, 'DELETE');
             break;
         default:
             break;
     }
     // Execute, grab errors
     $this->response->resetBody();
     if (curl_exec($curl)) {
         $this->response->code = curl_getinfo($curl, CURLINFO_HTTP_CODE);
     } else {
         $this->response->error = new Error(curl_errno($curl), curl_error($curl), $this->resource);
     }
     @curl_close($curl);
     // Set the body data
     $this->response->finaliseBody();
     // Clean up file resources
     if (!is_null($this->fp) && is_resource($this->fp)) {
         fclose($this->fp);
     }
     return $this->response;
 }