Skip to content

Commit a5c6f98

Browse files
committed
Add setTimeCorrectionOffset() to use the AWS server time to calculate an offset to apply to incorrect system times (fixes issues #23 and #25)
1 parent 2cf80b2 commit a5c6f98

File tree

1 file changed

+48
-5
lines changed

1 file changed

+48
-5
lines changed

S3.php

Lines changed: 48 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -120,8 +120,13 @@ class S3
120120
*/
121121
public static $useExceptions = false;
122122

123-
// SSL CURL SSL options - only needed if you are experiencing problems with your OpenSSL configuration
124-
123+
/**
124+
* Time offset applied to time()
125+
* @access private
126+
* @static
127+
*/
128+
private static $__timeOffset = 0;
129+
125130
/**
126131
* SSL client key
127132
*
@@ -278,6 +283,30 @@ public static function setExceptions($enabled = true)
278283
}
279284

280285

286+
/**
287+
* Set AWS time correction offset (use carefully)
288+
*
289+
* This can be used when an inaccurate system time is generating
290+
* invalid request signatures. It should only be used as a last
291+
* resort when the system time cannot be changed.
292+
*
293+
* @param string $offset Time offset (set to zero to use AWS server time)
294+
* @return void
295+
*/
296+
public static function setTimeCorrectionOffset($offset = 0)
297+
{
298+
if ($offset == 0)
299+
{
300+
$rest = new S3Request('HEAD');
301+
$rest = $rest->getResponse();
302+
$awstime = $rest->headers['date'];
303+
$systime = time();
304+
$offset = $systime > $awstime ? -($systime - $awstime) : ($awstime - $systime);
305+
}
306+
self::$__timeOffset = $offset;
307+
}
308+
309+
281310
/**
282311
* Set signing key
283312
*
@@ -1125,7 +1154,7 @@ public static function deleteObject($bucket, $uri)
11251154
*/
11261155
public static function getAuthenticatedURL($bucket, $uri, $lifetime, $hostBucket = false, $https = false)
11271156
{
1128-
$expires = time() + $lifetime;
1157+
$expires = self::__getTime() + $lifetime;
11291158
$uri = str_replace(array('%2F', '%2B'), array('/', '+'), rawurlencode($uri));
11301159
return sprintf(($https ? 'https' : 'http').'://%s/%s?AWSAccessKeyId=%s&Expires=%u&Signature=%s',
11311160
// $hostBucket ? $bucket : $bucket.'.s3.amazonaws.com', $uri, self::$__accessKey, $expires,
@@ -1168,7 +1197,7 @@ public static function getSignedCannedURL($url, $lifetime)
11681197
return self::getSignedPolicyURL(array(
11691198
'Statement' => array(
11701199
array('Resource' => $url, 'Condition' => array(
1171-
'DateLessThan' => array('AWS:EpochTime' => time() + $lifetime)
1200+
'DateLessThan' => array('AWS:EpochTime' => self::__getTime() + $lifetime)
11721201
))
11731202
)
11741203
));
@@ -1194,7 +1223,7 @@ public static function getHttpUploadPostParams($bucket, $uriPrefix = '', $acl =
11941223
{
11951224
// Create policy object
11961225
$policy = new stdClass;
1197-
$policy->expiration = gmdate('Y-m-d\TH:i:s\Z', (time() + $lifetime));
1226+
$policy->expiration = gmdate('Y-m-d\TH:i:s\Z', (self::__getTime() + $lifetime));
11981227
$policy->conditions = array();
11991228
$obj = new stdClass; $obj->bucket = $bucket; array_push($policy->conditions, $obj);
12001229
$obj = new stdClass; $obj->acl = $acl; array_push($policy->conditions, $obj);
@@ -1810,6 +1839,18 @@ private static function __getMIMEType(&$file)
18101839
}
18111840

18121841

1842+
/**
1843+
* Get the current time
1844+
*
1845+
* @internal Used to apply offsets to sytem time
1846+
* @return integer
1847+
*/
1848+
public static function __getTime()
1849+
{
1850+
return time() + self::$__timeOffset;
1851+
}
1852+
1853+
18131854
/**
18141855
* Generate the auth string: "AWS AccessKey:Signature"
18151856
*
@@ -2278,6 +2319,8 @@ private function __responseHeaderCallback(&$curl, &$data)
22782319
list($header, $value) = explode(': ', $data, 2);
22792320
if ($header == 'Last-Modified')
22802321
$this->response->headers['time'] = strtotime($value);
2322+
elseif ($header == 'Date')
2323+
$this->response->headers['date'] = strtotime($value);
22812324
elseif ($header == 'Content-Length')
22822325
$this->response->headers['size'] = (int)$value;
22832326
elseif ($header == 'Content-Type')

0 commit comments

Comments
 (0)