Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit ee0ee22

Browse filesBrowse files
djmailhotJon Wayne Parrott
authored andcommitted
CDN samples dir with snippet for signing urls (GoogleCloudPlatform#1383)
1 parent 9ed5364 commit ee0ee22
Copy full SHA for ee0ee22

File tree

Expand file treeCollapse file tree

5 files changed

+225
-0
lines changed
Filter options
Expand file treeCollapse file tree

5 files changed

+225
-0
lines changed

‎cdn/README.rst

Copy file name to clipboard
+55Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
.. This file is automatically generated. Do not edit this file directly.
2+
3+
Google Cloud CDN Python Samples
4+
===============================================================================
5+
6+
.. image:: https://gstatic.com/cloudssh/images/open-btn.png
7+
:target: https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/GoogleCloudPlatform/python-docs-samples&page=editor&open_in_editor=cdn/README.rst
8+
9+
10+
This directory contains samples for Google Cloud CDN. 'Google Cloud CDN'_ enables low-latency, low-cost content delivery using Google's global network
11+
12+
13+
14+
15+
.. _Google Cloud CDN: https://cloud.google.com/cdn/docs
16+
17+
18+
Samples
19+
-------------------------------------------------------------------------------
20+
21+
Snippets
22+
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
23+
24+
.. image:: https://gstatic.com/cloudssh/images/open-btn.png
25+
:target: https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/GoogleCloudPlatform/python-docs-samples&page=editor&open_in_editor=cdn/snippets.py;cdn/README.rst
26+
27+
28+
29+
30+
To run this sample:
31+
32+
.. code-block:: bash
33+
34+
$ python snippets.py
35+
36+
usage: snippets.py [-h] {sign-url} ...
37+
38+
This application demonstrates how to perform operations on data (content)
39+
when using Google Cloud CDN (Content Delivery Network).
40+
41+
For more information, see the README.md under /cdn and the documentation
42+
at https://cloud.google.com/cdn/docs.
43+
44+
positional arguments:
45+
{sign-url}
46+
sign-url Sign a URL to grant temporary authorized access.
47+
48+
optional arguments:
49+
-h, --help show this help message and exit
50+
51+
52+
53+
54+
55+
.. _Google Cloud SDK: https://cloud.google.com/sdk/

‎cdn/README.rst.in

Copy file name to clipboard
+16Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
# Used to generate README.rst
2+
3+
product:
4+
name: Google Cloud CDN
5+
short_name: Cloud CDN
6+
url: https://cloud.google.com/cdn/docs
7+
description: >
8+
'Google Cloud CDN'_ enables low-latency, low-cost content delivery using
9+
Google's global network
10+
11+
samples:
12+
- name: Snippets
13+
file: snippets.py
14+
show_help: true
15+
16+
folder: cdn

‎cdn/requirements.txt

Copy file name to clipboard
+1Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
six

‎cdn/snippets.py

Copy file name to clipboard
+101Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
#!/usr/bin/env python
2+
#
3+
# Copyright 2017 Google, Inc.
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+
"""This application demonstrates how to perform operations on data (content)
18+
when using Google Cloud CDN (Content Delivery Network).
19+
20+
For more information, see the README.md under /cdn and the documentation
21+
at https://cloud.google.com/cdn/docs.
22+
"""
23+
24+
import argparse
25+
import base64
26+
import datetime
27+
import hashlib
28+
import hmac
29+
30+
from six.moves import urllib
31+
32+
33+
# [BEGIN sign_url]
34+
def sign_url(url, key_name, base64_key, expiration_time):
35+
"""Gets the Signed URL string for the specified URL and configuration.
36+
37+
Args:
38+
url: URL to sign as a string.
39+
key_name: name of the signing key as a string.
40+
base64_key: signing key as a base64 encoded string.
41+
expiration_time: expiration time as a UTC datetime object.
42+
43+
Returns:
44+
Returns the Signed URL appended with the query parameters based on the
45+
specified configuration.
46+
"""
47+
stripped_url = url.strip()
48+
parsed_url = urllib.parse.urlsplit(stripped_url)
49+
query_params = urllib.parse.parse_qs(
50+
parsed_url.query, keep_blank_values=True)
51+
epoch = datetime.datetime.utcfromtimestamp(0)
52+
expiration_timestamp = int((expiration_time - epoch).total_seconds())
53+
decoded_key = base64.urlsafe_b64decode(base64_key)
54+
55+
url_pattern = u'{url}{separator}Expires={expires}&KeyName={key_name}'
56+
57+
url_to_sign = url_pattern.format(
58+
url=stripped_url,
59+
separator='&' if query_params else '?',
60+
expires=expiration_timestamp,
61+
key_name=key_name)
62+
63+
digest = hmac.new(
64+
decoded_key, url_to_sign.encode('utf-8'), hashlib.sha1).digest()
65+
signature = base64.urlsafe_b64encode(digest).decode('utf-8')
66+
67+
signed_url = u'{url}&Signature={signature}'.format(
68+
url=url_to_sign, signature=signature)
69+
70+
print(signed_url)
71+
# [END sign_url]
72+
73+
74+
if __name__ == '__main__':
75+
parser = argparse.ArgumentParser(
76+
description=__doc__,
77+
formatter_class=argparse.RawDescriptionHelpFormatter)
78+
79+
subparsers = parser.add_subparsers(dest='command')
80+
81+
sign_url_parser = subparsers.add_parser(
82+
'sign-url',
83+
help="Sign a URL to grant temporary authorized access.")
84+
sign_url_parser.add_argument(
85+
'url', help='The URL to sign.')
86+
sign_url_parser.add_argument(
87+
'key_name',
88+
help='Key name for the signing key.')
89+
sign_url_parser.add_argument(
90+
'base64_key',
91+
help='The base64 encoded signing key.')
92+
sign_url_parser.add_argument(
93+
'expiration_time',
94+
type=lambda d: datetime.datetime.utcfromtimestamp(float(d)),
95+
help='Expiration time expessed as seconds since the epoch.')
96+
97+
args = parser.parse_args()
98+
99+
if args.command == 'sign-url':
100+
sign_url(
101+
args.url, args.key_name, args.base64_key, args.expiration_time)

‎cdn/snippets_test.py

Copy file name to clipboard
+52Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
#!/usr/bin/env python
2+
#
3+
# Copyright 2017 Google, Inc.
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+
"""Tests for snippets."""
18+
19+
import datetime
20+
21+
import snippets
22+
23+
24+
def test_sign_url(capsys):
25+
snippets.sign_url(
26+
'http://35.186.234.33/index.html',
27+
'my-key',
28+
'nZtRohdNF9m3cKM24IcK4w==',
29+
datetime.datetime.utcfromtimestamp(1549751401))
30+
snippets.sign_url(
31+
'http://www.example.com/',
32+
'my-key',
33+
'nZtRohdNF9m3cKM24IcK4w==',
34+
datetime.datetime.utcfromtimestamp(1549751401))
35+
snippets.sign_url(
36+
'http://www.example.com/some/path?some=query&another=param',
37+
'my-key',
38+
'nZtRohdNF9m3cKM24IcK4w==',
39+
datetime.datetime.utcfromtimestamp(1549751401))
40+
41+
out, _ = capsys.readouterr()
42+
43+
results = out.splitlines()
44+
assert results[0] == (
45+
'http://35.186.234.33/index.html?Expires=1549751401&KeyName=my-key&'
46+
'Signature=CRFqQnVfFyiUyR63OQf-HRUpIwc=')
47+
assert results[1] == (
48+
'http://www.example.com/?Expires=1549751401&KeyName=my-key&'
49+
'Signature=OqDUFfHpN5Vxga6r80bhsgxKves=')
50+
assert results[2] == (
51+
'http://www.example.com/some/path?some=query&another=param&Expires='
52+
'1549751401&KeyName=my-key&Signature=9Q9TCxSju8-W5nUkk5CuTrun2_o=')

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.