From a5c6f98351ddadeafe17cb6c33f6fa48d146e5d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Donovan=20Scho=CC=88nknecht?= Date: Sat, 5 Oct 2013 16:45:53 +0200 Subject: [PATCH] Add setTimeCorrectionOffset() to use the AWS server time to calculate an offset to apply to incorrect system times (fixes issues #23 and #25) --- S3.php | 53 ++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 48 insertions(+), 5 deletions(-) diff --git a/S3.php b/S3.php index 6be5fc85..1ef7391b 100644 --- a/S3.php +++ b/S3.php @@ -120,8 +120,13 @@ class S3 */ public static $useExceptions = false; - // SSL CURL SSL options - only needed if you are experiencing problems with your OpenSSL configuration - + /** + * Time offset applied to time() + * @access private + * @static + */ + private static $__timeOffset = 0; + /** * SSL client key * @@ -278,6 +283,30 @@ public static function setExceptions($enabled = true) } + /** + * Set AWS time correction offset (use carefully) + * + * This can be used when an inaccurate system time is generating + * invalid request signatures. It should only be used as a last + * resort when the system time cannot be changed. + * + * @param string $offset Time offset (set to zero to use AWS server time) + * @return void + */ + public static function setTimeCorrectionOffset($offset = 0) + { + if ($offset == 0) + { + $rest = new S3Request('HEAD'); + $rest = $rest->getResponse(); + $awstime = $rest->headers['date']; + $systime = time(); + $offset = $systime > $awstime ? -($systime - $awstime) : ($awstime - $systime); + } + self::$__timeOffset = $offset; + } + + /** * Set signing key * @@ -1125,7 +1154,7 @@ public static function deleteObject($bucket, $uri) */ public static function getAuthenticatedURL($bucket, $uri, $lifetime, $hostBucket = false, $https = false) { - $expires = time() + $lifetime; + $expires = self::__getTime() + $lifetime; $uri = str_replace(array('%2F', '%2B'), array('/', '+'), rawurlencode($uri)); return sprintf(($https ? 'https' : 'http').'://%s/%s?AWSAccessKeyId=%s&Expires=%u&Signature=%s', // $hostBucket ? $bucket : $bucket.'.s3.amazonaws.com', $uri, self::$__accessKey, $expires, @@ -1168,7 +1197,7 @@ public static function getSignedCannedURL($url, $lifetime) return self::getSignedPolicyURL(array( 'Statement' => array( array('Resource' => $url, 'Condition' => array( - 'DateLessThan' => array('AWS:EpochTime' => time() + $lifetime) + 'DateLessThan' => array('AWS:EpochTime' => self::__getTime() + $lifetime) )) ) )); @@ -1194,7 +1223,7 @@ public static function getHttpUploadPostParams($bucket, $uriPrefix = '', $acl = { // Create policy object $policy = new stdClass; - $policy->expiration = gmdate('Y-m-d\TH:i:s\Z', (time() + $lifetime)); + $policy->expiration = gmdate('Y-m-d\TH:i:s\Z', (self::__getTime() + $lifetime)); $policy->conditions = array(); $obj = new stdClass; $obj->bucket = $bucket; array_push($policy->conditions, $obj); $obj = new stdClass; $obj->acl = $acl; array_push($policy->conditions, $obj); @@ -1810,6 +1839,18 @@ private static function __getMIMEType(&$file) } + /** + * Get the current time + * + * @internal Used to apply offsets to sytem time + * @return integer + */ + public static function __getTime() + { + return time() + self::$__timeOffset; + } + + /** * Generate the auth string: "AWS AccessKey:Signature" * @@ -2278,6 +2319,8 @@ private function __responseHeaderCallback(&$curl, &$data) list($header, $value) = explode(': ', $data, 2); if ($header == 'Last-Modified') $this->response->headers['time'] = strtotime($value); + elseif ($header == 'Date') + $this->response->headers['date'] = strtotime($value); elseif ($header == 'Content-Length') $this->response->headers['size'] = (int)$value; elseif ($header == 'Content-Type')