Skip to content

Commit 33b3fe9

Browse files
jkwluibshaffer
authored andcommitted
Add Storage v4 signed url samples (GoogleCloudPlatform#888)
1 parent fd30650 commit 33b3fe9

File tree

6 files changed

+213
-13
lines changed

6 files changed

+213
-13
lines changed

storage/README.md

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -32,16 +32,19 @@ This simple command-line application demonstrates how to invoke Google Cloud Sto
3232
5. Run `php storage.php`. The following commands are available:
3333

3434
```sh
35-
bucket-acl Manage the ACL for Cloud Storage buckets.
36-
bucket-default-acl Manage the default ACL for Cloud Storage buckets.
37-
bucket-labels Manage Cloud Storage bucket labels
38-
bucket-lock Manage Cloud Storage retention policies and holds
39-
buckets Manage Cloud Storage buckets
40-
encryption Upload and download Cloud Storage objects with encryption
41-
object-acl Manage the ACL for Cloud Storage objects
42-
objects Manage Cloud Storage objects
43-
requester-pays Manage Cloud Storage requester pays buckets and objects
44-
bucket-policy-only Manage Cloud Storage bucket policy only buckets
35+
bucket-acl Manage the ACL for Cloud Storage buckets.
36+
bucket-default-acl Manage the default ACL for Cloud Storage buckets.
37+
bucket-labels Manage Cloud Storage bucket labels
38+
bucket-lock Manage Cloud Storage retention policies and holds
39+
buckets Manage Cloud Storage buckets
40+
encryption Upload and download Cloud Storage objects with encryption
41+
object-acl Manage the ACL for Cloud Storage objects
42+
objects Manage Cloud Storage objects
43+
requester-pays Manage Cloud Storage requester pays buckets and objects
44+
bucket-policy-only Manage Cloud Storage bucket policy only buckets
45+
get-object-v2-signed-url Generate a v2 signed URL for downloading an object.
46+
get-object-v4-signed-url Generate a v4 signed URL for downloading an object.
47+
get-object-v4-upload-signed-url Generate a v4 signed URL for uploading an object.
4548
```
4649
6. Run `php storage.php COMMAND --help` to print information about the usage of each command.
4750

storage/composer.json

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@
3838
"src/get_object_acl.php",
3939
"src/get_object_acl_for_entity.php",
4040
"src/get_object_v2_signed_url.php",
41+
"src/get_object_v4_signed_url.php",
42+
"src/get_object_v4_upload_signed_url.php",
4143
"src/get_requester_pays_status.php",
4244
"src/get_retention_policy.php",
4345
"src/get_default_event_based_hold.php",
@@ -65,6 +67,7 @@
6567
},
6668
"require-dev": {
6769
"phpunit/phpunit": "^5",
68-
"google/cloud-tools": "^0.8.5"
70+
"google/cloud-tools": "^0.8.5",
71+
"guzzlehttp/guzzle": "^6.3"
6972
}
7073
}
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
2+
/**
3+
* Copyright 2019 Google LLC
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
/**
19+
* For instructions on how to run the full sample:
20+
*
21+
* @see https://github.com/GoogleCloudPlatform/php-docs-samples/tree/master/storage/README.md
22+
*/
23+
24+
namespace Google\Cloud\Samples\Storage;
25+
26+
# [START storage_generate_signed_url_v4]
27+
use Google\Cloud\Storage\StorageClient;
28+
29+
/**
30+
* Generate a v4 signed URL for downloading an object.
31+
*
32+
* @param string $bucketName the name of your Google Cloud bucket.
33+
* @param string $objectName the name of your Google Cloud object.
34+
*
35+
* @return void
36+
*/
37+
function get_object_v4_signed_url($bucketName, $objectName)
38+
{
39+
$storage = new StorageClient();
40+
$bucket = $storage->bucket($bucketName);
41+
$object = $bucket->object($objectName);
42+
$url = $object->signedUrl(
43+
# This URL is valid for 15 minutes
44+
new \DateTime('15 min'),
45+
[
46+
'version' => 'v4',
47+
]
48+
);
49+
50+
print('Generated GET signed URL:' . PHP_EOL);
51+
print($url . PHP_EOL);
52+
print('You can use this URL with any user agent, for example:' . PHP_EOL);
53+
print('curl ' . $url . PHP_EOL);
54+
}
55+
# [END storage_generate_signed_url_v4]
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
2+
/**
3+
* Copyright 2019 Google LLC
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
/**
19+
* For instructions on how to run the full sample:
20+
*
21+
* @see https://github.com/GoogleCloudPlatform/php-docs-samples/tree/master/storage/README.md
22+
*/
23+
24+
namespace Google\Cloud\Samples\Storage;
25+
26+
# [START storage_generate_upload_signed_url_v4]
27+
use Google\Cloud\Storage\StorageClient;
28+
29+
/**
30+
* Generate a v4 signed URL for uploading an object.
31+
*
32+
* @param string $bucketName the name of your Google Cloud bucket.
33+
* @param string $objectName the name of your Google Cloud object.
34+
*
35+
* @return void
36+
*/
37+
function get_object_v4_upload_signed_url($bucketName, $objectName)
38+
{
39+
$storage = new StorageClient();
40+
$bucket = $storage->bucket($bucketName);
41+
$object = $bucket->object($objectName);
42+
$url = $object->signedUrl(
43+
# This URL is valid for 15 minutes
44+
new \DateTime('15 min'),
45+
[
46+
'method' => 'PUT',
47+
'contentType' => 'application/octet-stream',
48+
'version' => 'v4',
49+
]
50+
);
51+
52+
print('Generated PUT signed URL:' . PHP_EOL);
53+
print($url . PHP_EOL);
54+
print('You can use this URL with any user agent, for example:' . PHP_EOL);
55+
print("curl -X PUT -H 'Content-Type: application/octet-stream' " .
56+
'--upload-file my-file ' . $url . PHP_EOL);
57+
}
58+
# [END storage_generate_upload_signed_url_v4]

storage/storage.php

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -487,6 +487,40 @@
487487
get_object_v2_signed_url($bucketName, $objectName);
488488
});
489489

490+
$application->add(new Command('get-object-v4-signed-url'))
491+
->setDescription('Generate a v4 signed URL for downloading an object.')
492+
->setHelp(<<
493+
The %command.name% command generates a v4 signed URL for downloading an object.
494+
495+
php %command.full_name% --help
496+
497+
EOF
498+
)
499+
->addArgument('bucket', InputArgument::REQUIRED, 'The Cloud Storage bucket name')
500+
->addArgument('object', InputArgument::REQUIRED, 'The Cloud Storage object name')
501+
->setCode(function ($input, $output) {
502+
$bucketName = $input->getArgument('bucket');
503+
$objectName = $input->getArgument('object');
504+
get_object_v4_signed_url($bucketName, $objectName);
505+
});
506+
507+
$application->add(new Command('get-object-v4-upload-signed-url'))
508+
->setDescription('Generate a v4 signed URL for uploading an object.')
509+
->setHelp(<<
510+
The %command.name% command generates a v4 signed URL for uploading an object.
511+
512+
php %command.full_name% --help
513+
514+
EOF
515+
)
516+
->addArgument('bucket', InputArgument::REQUIRED, 'The Cloud Storage bucket name')
517+
->addArgument('object', InputArgument::REQUIRED, 'The Cloud Storage object name')
518+
->setCode(function ($input, $output) {
519+
$bucketName = $input->getArgument('bucket');
520+
$objectName = $input->getArgument('object');
521+
get_object_v4_upload_signed_url($bucketName, $objectName);
522+
});
523+
490524
// for testing
491525
if (getenv('PHPUNIT_TESTS') === '1') {
492526
return $application;

storage/test/ObjectSignedUrlTest.php

Lines changed: 49 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
use Google\Cloud\TestUtils\TestTrait;
2121
use Google\Cloud\TestUtils\ExecuteCommandTrait;
2222
use Google\Cloud\Storage\StorageClient;
23+
use GuzzleHttp\Client;
2324
use PHPUnit\Framework\TestCase;
2425

2526
/**
@@ -30,17 +31,19 @@ class ObjectSignedUrlTest extends TestCase
3031
use TestTrait;
3132
use ExecuteCommandTrait;
3233

34+
private static $storage;
3335
private static $bucketName;
3436
private static $objectName;
3537
private static $commandFile = __DIR__ . '/../storage.php';
3638

3739
/** @beforeClass */
3840
public static function setUpObject()
3941
{
40-
$storage = new StorageClient();
42+
self::$storage = new StorageClient();
4143
self::$bucketName = self::requireEnv('GOOGLE_STORAGE_BUCKET');
4244
self::$objectName = sprintf('test-object-%s', time());
43-
$storage
45+
// Pre-upload an object for testing GET signed urls
46+
self::$storage
4447
->bucket(self::$bucketName)
4548
->upload("test file content", [
4649
'name' => self::$objectName
@@ -56,4 +59,48 @@ public function testGetV2SignedUrl()
5659

5760
$this->assertContains("The signed url for " . self::$objectName . " is", $output);
5861
}
62+
63+
public function testGetV4SignedUrl()
64+
{
65+
$output = $this->runCommand('get-object-v4-signed-url', [
66+
'bucket' => self::$bucketName,
67+
'object' => self::$objectName,
68+
]);
69+
70+
$this->assertContains('Generated GET signed URL:', $output);
71+
}
72+
73+
public function testGetV4UploadSignedUrl()
74+
{
75+
$uploadObjectName = sprintf('test-upload-object-%s', time());
76+
77+
$output = $this->runCommand('get-object-v4-upload-signed-url', [
78+
'bucket' => self::$bucketName,
79+
'object' => $uploadObjectName,
80+
]);
81+
82+
$this->assertContains('Generated PUT signed URL:', $output);
83+
84+
// Extract the signed URL from command output.
85+
preg_match_all('/URL:\n([^\s]+)/', $output, $matches);
86+
$url = $matches[1][0];
87+
88+
// Make a PUT request using the signed URL.
89+
$client = new Client();
90+
$res = $client->request('PUT', $url, [
91+
'headers' => [
92+
'Content-Type' => 'application/octet-stream',
93+
],
94+
'body' => 'upload content'
95+
]);
96+
97+
$this->assertEquals(200, $res->getStatusCode());
98+
99+
// Assert file is correctly uploaded to the bucket.
100+
$content = self::$storage
101+
->bucket(self::$bucketName)
102+
->object($uploadObjectName)
103+
->downloadAsString();
104+
$this->assertEquals('upload content', $content);
105+
}
59106
}

0 commit comments

Comments
 (0)