Created
June 29, 2015 17:16
-
-
Save efreed/5bcbf2f2ab85575a23f5 to your computer and use it in GitHub Desktop.
S3 REST
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
class OdysysCache { | |
protected $_key = 'abc'; | |
protected $_secret = 'abc123xyz'; | |
protected $_bucket = 'odysyscache'; | |
/** | |
* Write a file to the S3 Bucket | |
* @param String $file_name | |
* @param mixed $file_data | |
* @param String $file_type Optional MIME type, or will be auto set from the file extention | |
* @return boolean | |
*/ | |
function put($file_name, $file_data, $file_type = null) { | |
$file_name = strtolower($file_name); | |
if(empty($file_type)) { | |
if (strpos($file_name, '.css')) | |
$file_type = 'text/css'; | |
if (strpos($file_name, '.js')) | |
$file_type = 'application/javascript'; | |
} | |
if(empty($file_type)) { | |
$file_type = 'application/octet-stream'; // the most generic so we at least have something | |
} | |
// opening HTTP connection to Amazon S3 | |
$fp = fsockopen("$this->_bucket.s3.amazonaws.com", 80, $errno, $errstr, 30); | |
if (!$fp) { | |
die("$errstr ($errno)\n"); | |
} | |
// Uploading object | |
$file_length = strlen($file_data); // for Content-Length HTTP field | |
$dt = gmdate('r'); // GMT based timestamp | |
// preparing String to Sign (see AWS S3 Developer Guide) | |
$string2sign = "PUT | |
$file_type | |
$dt | |
x-amz-acl:public-read | |
/$this->_bucket/$file_name"; | |
// preparing HTTP PUT query | |
$query = "PUT /$this->_bucket/$file_name HTTP/1.1 | |
Host: s3.amazonaws.com | |
x-amz-acl: public-read | |
Connection: keep-alive | |
Content-Type: $file_type | |
Content-Length: $file_length | |
Date: $dt | |
Authorization: AWS {$this->_key}:" . $this->amazon_hmac($string2sign)."\n\n"; | |
$query .= $file_data; | |
$resp = $this->send($fp, $query); | |
fclose($fp); | |
if (strpos($resp, '<Error>') !== false) { | |
report_error('failed upload to S3', array('resp'=>$resp)); | |
return false; | |
} | |
echo "Your file's URL is: http://s3.amazonaws.com/{$this->_bucket}/{$file_name}\n"; | |
return true; | |
} | |
// Sending HTTP query and receiving, with trivial keep-alive support | |
private function send($fp, $q, $debug = false) { | |
if ($debug) echo "\nQUERY<<{$q}>>\n"; | |
fwrite($fp, $q); | |
$r = ''; | |
$check_header = true; | |
while (!feof($fp)) { | |
$tr = fgets($fp, 256); | |
if ($debug) echo "\nRESPONSE<<{$tr}>>"; | |
$r .= $tr; | |
if (($check_header)&&(strpos($r, "\r\n\r\n") !== false)) | |
{ | |
// if content-length == 0, return query result | |
if (strpos($r, 'Content-Length: 0') !== false) | |
return $r; | |
} | |
// Keep-alive responses does not return EOF | |
// they end with \r\n0\r\n\r\n string | |
if (substr($r, -7) == "\r\n0\r\n\r\n") | |
return $r; | |
} | |
return $r; | |
} | |
// hmac-sha1 code START | |
// hmac-sha1 function: assuming key is global $aws_secret 40 bytes long | |
// read more at http://en.wikipedia.org/wiki/HMAC | |
// warning: key($aws_secret) is padded to 64 bytes with 0x0 after first function call | |
private function amazon_hmac($stringToSign) { | |
// helper function binsha1 for amazon_hmac (returns binary value of sha1 hash) | |
if (!function_exists('binsha1')) | |
{ | |
if (version_compare(phpversion(), "5.0.0", ">=")) { | |
function binsha1($d) { return sha1($d, true); } | |
} else { | |
function binsha1($d) { return pack('H*', sha1($d)); } | |
} | |
} | |
if (strlen($this->_secret) == 40) | |
$this->_secret = $this->_secret . str_repeat(chr(0), 24); | |
$ipad = str_repeat(chr(0x36), 64); | |
$opad = str_repeat(chr(0x5c), 64); | |
$hmac = binsha1(($this->_secret^$opad) . binsha1(($this->_secret^$ipad).$stringToSign)); | |
return base64_encode($hmac); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment