Skip to content

Commit

Permalink
支持多种过期时间格式
Browse files Browse the repository at this point in the history
  • Loading branch information
overtrue committed Nov 15, 2023
1 parent 238ef94 commit 751ce50
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 8 deletions.
29 changes: 22 additions & 7 deletions src/Signature.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ public function __construct(public string $accessKey, public string $secretKey)
{
}

public function createAuthorizationHeader(RequestInterface $request, ?string $expires = null): string
public function createAuthorizationHeader(RequestInterface $request, int|string|\DateTimeInterface $expires = null): string
{
$signTime = self::getTimeSegments($expires);
$queryToBeSigned = self::getQueryToBeSigned($request);
Expand Down Expand Up @@ -68,10 +68,10 @@ protected static function getQueryToBeSigned(RequestInterface $request): array
$query = [];
foreach (explode('&', $request->getUri()->getQuery()) as $item) {
if (! empty($item)) {
$tmpquery = explode('=', $item);
$key = strtolower($tmpquery[0]);
if (count($tmpquery) >= 2) {
$value = $tmpquery[1];
$segments = explode('=', $item);
$key = strtolower($segments[0]);
if (count($segments) >= 2) {
$value = $segments[1];
} else {
$value = '';
}
Expand All @@ -83,13 +83,28 @@ protected static function getQueryToBeSigned(RequestInterface $request): array
return $query;
}

protected static function getTimeSegments(?string $expires): string
protected static function getTimeSegments(int|string|\DateTimeInterface $expires = '+60 minutes'): string
{
$timezone = \date_default_timezone_get();

date_default_timezone_set('PRC');

$signTime = \sprintf('%s;%s', time() - 60, strtotime($expires ?? '+60 minutes'));
// '900'/900
if (is_numeric($expires)) {
$expires = abs($expires);
}

$expires = match (true) {
// 900/1700001234
is_int($expires) => $expires >= time() ? $expires : time() + $expires,
// '+60 minutes'/'2023-01-01 00:00:00'
is_string($expires) => strtotime($expires),
// new \DateTime('2023-01-01 00:00:00')
$expires instanceof \DateTimeInterface => $expires->getTimestamp(),
default => time() + 60,
};

$signTime = \sprintf('%s;%s', time() - 60, $expires);

date_default_timezone_set($timezone);

Expand Down
2 changes: 1 addition & 1 deletion src/Support/XML.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ public static function fromArray(array $data): bool|string
if (empty($data)) {
return '';
}

return Transformer::toXml($data);
}
}
44 changes: 44 additions & 0 deletions tests/SignatureTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
<?php

namespace Overtrue\CosClient\Tests;

use GuzzleHttp\Psr7\Request;
use Overtrue\CosClient\Signature;

class SignatureTest extends TestCase
{
public function test_getTimeSegments()
{
$signature = new Signature('mock-access-key', 'mock-secret-key');

$request = new Request('GET', 'https://example.com');

$timezone = \date_default_timezone_get();

date_default_timezone_set('PRC');

$asserts = [
'900' => time() + 900,
60 => time() + 60,
time() + 3600 => time() + 3600,
'+ 1 hour' => strtotime('+ 1 hour'),
'+600 seconds' => strtotime('+600 seconds'),
'2021-01-01T00:00:00Z' => strtotime('2021-01-01T00:00:00Z'),
'2021-01-01' => strtotime('2021-01-01'),
'2021-01-01 00:00:00' => strtotime('2021-01-01 00:00:00'),
];

foreach ($asserts as $input => $output) {
$expect = sprintf('q-sign-time=%d;%d&q-key-time=%d;%d', time() - 60, $output, time() - 60, $output);
$this->assertStringContainsString($expect, $signature->createAuthorizationHeader($request, $input));
}

// date
$date = \DateTimeImmutable::createFromFormat('Y-m-d 00:00:00', '2023-11-15 00:00:00');
$expect = sprintf('q-sign-time=%d;%d&q-key-time=%d;%d', time() - 60, $date->getTimestamp(), time() - 60, $date->getTimestamp());

$this->assertStringContainsString($expect, $signature->createAuthorizationHeader($request, $date));

date_default_timezone_set($timezone);
}
}

0 comments on commit 751ce50

Please sign in to comment.