Created
April 2, 2015 23:53
-
-
Save charlie-s/89cb8b4d430c8e08d938 to your computer and use it in GitHub Desktop.
S3 PHP Example (without an SDK)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
class S3 { | |
private $key = 'ABC123'; | |
private $secret = 'lolftw'; | |
private $region = 'us-west-2'; | |
private $bucket = 'examplebucket'; | |
private $host = 's3.amazonaws.com'; | |
public function uploadFile($file_path) { | |
$default_timezone = date_default_timezone_get(); | |
date_default_timezone_set('UTC'); | |
$file_contents = file_get_contents($file_path); | |
$file_name = basename($file_path); | |
$hashed_payload = hash('sha256', $file_contents); | |
$date_full = date('D, d M Y H:i:s \G\M\T'); // @todo don't force GMT! | |
$date_time = date('Ymd\THisZ'); // @todo don't force Z! | |
$date = date('Ymd'); | |
// Set headers. | |
$headers = array( | |
'Host' => $this->bucket . '.' . $this->host, | |
'Content-Type' => mime_content_type($file_name), | |
'x-amz-content-sha256' => $hashed_payload, | |
'x-amz-date' => $date_full, | |
); | |
ksort($headers); | |
$signed_headers_string = strtolower(implode(';', array_keys($headers))); | |
// Build canonical request. | |
$canonical_request = "PUT\n"; // HTTP Method | |
$canonical_request .= '/' . urlencode($file_name) . "\n"; // Canonical URI | |
$canonical_request .= "\n"; // CanonicalQueryString | |
foreach ($headers as $header => $value) { | |
$canonical_request .= strtolower($header) . ':' . trim($value) . "\n"; | |
} | |
$canonical_request .= "\n"; | |
$canonical_request .= $signed_headers_string . "\n"; // SignedHeaders | |
$canonical_request .= $hashed_payload; // HashedPayload | |
print "\n\nCanonical Request:\n" . $canonical_request; | |
// Build string to sign. | |
$string_to_sign = "AWS4-HMAC-SHA256\n"; | |
$string_to_sign .= $date_full . "\n"; | |
$string_to_sign .= $date . '/' . $this->region . "/s3/aws4_request\n"; | |
$string_to_sign .= hash('sha256', $canonical_request); | |
print "\n\nString to Sign:\n" . $string_to_sign; | |
// Calculate signature. | |
$signature_date = hash_hmac('sha256', $date, 'AWS4' . $this->secret, true); | |
$signature_region = hash_hmac('sha256', $this->region, $signature_date, true); | |
$signature_service = hash_hmac('sha256', 's3', $signature_region, true); | |
$signature_request = hash_hmac('sha256', 'aws4_request', $signature_service, true); | |
$signature = hash_hmac('sha256', $string_to_sign, $signature_request); | |
// Calculate final `Authorization` header. | |
$headers['Authorization'] = 'AWS4-HMAC-SHA256 Credential=' . $this->key . '/' . $date . '/' . $this->region . '/s3/aws4_request,'; | |
$headers['Authorization'] .= 'SignedHeaders=' . $signed_headers_string . ','; | |
$headers['Authorization'] .= 'Signature=' . $signature; | |
print "\n\nAuthorization:\n" . $headers['Authorization']; | |
// Convert headers to key:value strings. | |
$curl_headers = array(); | |
foreach ($headers as $header => $value) { | |
$curl_headers[] = "{$header}:{$value}"; | |
} | |
// Init curl. | |
$curl = curl_init(); | |
$url = 'https://' . $this->bucket . '.' . $this->host . '/' bu. $file_name; | |
curl_setopt($curl, CURLOPT_URL, $url); | |
curl_setopt($curl, CURLOPT_VERBOSE, 1); | |
curl_setopt($curl, CURLOPT_CUSTOMREQUEST, 'PUT'); | |
curl_setopt($curl, CURLINFO_HEADER_OUT, true); | |
curl_setopt($curl, CURLOPT_HEADER, true); | |
curl_setopt($curl, CURLOPT_HTTPHEADER, $curl_headers); | |
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); | |
curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true); | |
curl_setopt($curl, CURLOPT_POSTFIELDS, $file_contents); | |
// Run request. | |
if ($result = curl_exec($curl)) { | |
print "\n\nSuccess!\n"; | |
$curl_info = curl_getinfo($curl, CURLINFO_HTTP_CODE); | |
print_r($curl_info); | |
print_r($result); | |
print "\n\nHeaders sent:\n"; | |
$headers_sent = curl_getinfo($curl, CURLINFO_HEADER_OUT); | |
print_r($headers_sent); | |
} | |
else { | |
print "\n\nError!\n"; | |
print_r(array( | |
'code' => curl_errno($curl), | |
'message' => curl_error($curl), | |
)); | |
} | |
@curl_close($curl); | |
date_default_timezone_set($default_timezone); | |
} | |
} | |
$foo = new S3(); | |
$foo->uploadFile(__DIR__ . '/test.txt'); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment