Skip to content
This repository has been archived by the owner on Oct 22, 2019. It is now read-only.

Commit

Permalink
add AMP Cache URL converter
Browse files Browse the repository at this point in the history
  • Loading branch information
sebastianbenz committed Dec 3, 2016
1 parent b773bb9 commit ee7ba54
Show file tree
Hide file tree
Showing 6 changed files with 210 additions and 13 deletions.
1 change: 0 additions & 1 deletion api/.gitignore

This file was deleted.

3 changes: 3 additions & 0 deletions api/app.yaml
Expand Up @@ -22,6 +22,9 @@ handlers:
- url: /img
static_dir: img
secure: always
- url: /scripts
static_dir: scripts
secure: always
- url: /third_party
static_dir: third_party
secure: always
Expand Down
81 changes: 81 additions & 0 deletions api/iframe/amp-url-converter.html
@@ -0,0 +1,81 @@
<!doctype html>
<html>
<head>
<meta name="viewport" content="width=device-width,minimum-scale=1,initial-scale=1">
<style>
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
body {
font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Oxygen-Sans,Ubuntu,Cantarell,"Helvetica Neue",sans-serif;
}
pre {
font-family: Menlo,Monaco,Consolas,"Courier New",monospace;
font-size: 14px;
overflow: auto;
margin: 0;
padding: 8px;
background-color: #ECEFF1;
overflow-x: auto;
min-height: 32px;
}
-webkit-scrollbar, pre::-webkit-scrollbar {
height: 8px;
width: 4px;
}
pre::-webkit-scrollbar-thumb {
background: rgba(0,0,0,.26);
}
a {
color: #37474f;
text-decoration: none;
}
a:hover {
text-decoration: underline;
}
.error {
color: red;
}
.input-container {
display: flex;
}
.input-container .responsive {
flex: 1;
}
.input-container .fixed {
flex: 0;
margin: 0 0 0 16px;
}
.input-container div input {
font-size: 14px;
padding: 6px;
width: 100%;
}
.input-container div button {
font-size: 14px;
padding: 8px 16px;
white-space: nowrap;
}
.result-container {
padding: 16px 0 0 0;
}
</style>
</head>
<body>
<section class="input-container">
<div class="responsive">
<input id="input" type="text" />
</div>
<div class="fixed">
<button id="execute">Convert</button>
</div>
</section>
<section class="result-container">
<pre id="result"></pre>
</section>
<script src="https://cdn.ampproject.org/viewer/google/amp_url.js"></script>
<script src="/scripts/amp_url_converter.js"></script>
</body>
</html>
85 changes: 85 additions & 0 deletions api/scripts/amp_url_converter.js
@@ -0,0 +1,85 @@
/**
* Copyright 2016 Google Inc. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS-IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

const DEFAULT_URL = "https://www.example.com/amp?param=value";
const AMP_CACHE_PREFIX = "https://cdn.ampproject.org/c/";

class AmpUrlConverter {

constructor(root, ampUrlFactory) {
this.inputView = root.getElementById('input');
this.resultView = root.getElementById('result');
this.ampUrlFactory = ampUrlFactory;
root.getElementById('execute')
.addEventListener("click", this.onClick.bind(this));
}

setInput(urlString) {
this.inputView.value = urlString;
this.convert(urlString);
}

convert(urlString) {
urlString = urlString.trim();
if (!urlString) {
this.showError('Empty input');
return;
}
try {
const ampUrl = this.ampUrlFactory.createAmpUrl(urlString);
const proxyUrl = ampUrl.getProxyUrl();
this.showResult('<a href="' + proxyUrl + '" target="_parent">' + proxyUrl + '</a>');
}catch(e) {
this.showError('Invalid URL');
}
}

showError(message) {
this.resultView.className = 'error';
this.resultView.innerHTML = message;
}

showResult(result) {
this.resultView.className = '';
this.resultView.innerHTML = result;
}

onClick() {
this.convert(this.inputView.value);
}

}

function getParameterByName(name, defaultValue) {
const url = window.location.href;
name = name.replace(/[\[\]]/g, "\\$&");
const regex = new RegExp("[?&]" + name + "(=([^&#]*)|&|#|$)"),
results = regex.exec(url);
if (!results) { return defaultValue; }
if (!results[2]) { return defaultValue; }
return decodeURIComponent(results[2].replace(/\+/g, " "));
}

const proxyUrlPrefix = 'https://cdn.ampproject.org';
const javascriptVersion = '5';
const useCurlsEncoding = true;
const ampUrlFactory =
new AmpUrlFactory(proxyUrlPrefix, javascriptVersion, useCurlsEncoding);

const converter = new AmpUrlConverter(document, ampUrlFactory);
const initialUrl = getParameterByName('url', 'https://www.example.com/amp?param=1');

converter.setInput(initialUrl);
50 changes: 39 additions & 11 deletions src/30_Advanced/Using_the_Google_AMP_Cache.html
Expand Up @@ -5,31 +5,55 @@
<!--
#### Introduction
The Google AMP Cache stores valid AMPs and provides a consistently fast access to AMPs.
The [Google AMP Cache](https://developers.google.com/amp/cache/overview) stores valid AMPs and provides a consistently fast access to AMPs. It is available for anyone to use.
-->
<!-- -->
<!doctype html>
<html >
<head>
<meta charset="utf-8">
<script async src="https://cdn.ampproject.org/v0.js"></script>
<script async custom-element="amp-iframe" src="https://cdn.ampproject.org/v0/amp-iframe-0.1.js"></script>
<link rel="canonical" href="<%host%>/advanced/using_the_google_amp_cache/">
<meta name="viewport" content="width=device-width,minimum-scale=1,initial-scale=1">
<style amp-custom>
.amp-iframe-container {
margin: 0;
padding: 16px;
}
.doc pre {
margin: 16px;
padding: 16px;
}
.doc pre code {
font-size: 14px;
}
@media (max-width: 700px) {
.amp-iframe-container, .doc pre {
margin: 16px 0;
}
}
.doc pre, .doc pre>code, code {
background-color: #ECEFF1;
}
</style>
<style amp-boilerplate>body{-webkit-animation:-amp-start 8s steps(1,end) 0s 1 normal both;-moz-animation:-amp-start 8s steps(1,end) 0s 1 normal both;-ms-animation:-amp-start 8s steps(1,end) 0s 1 normal both;animation:-amp-start 8s steps(1,end) 0s 1 normal both}@-webkit-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@-moz-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@-ms-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@-o-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}</style><noscript><style amp-boilerplate>body{-webkit-animation:none;-moz-animation:none;-ms-animation:none;animation:none}</style></noscript>
</head>
<body>
<!--
#### AMP Cache URL Format
Loading your AMPs via the Google AMP Cache is easy. The AMP Cache URL is composed based on the source URL’s scheme (HTTP or HTTPS):
Loading your AMPs via the Google AMP Cache is easy. The AMP Cache URL is composed based on the source URL’s scheme (HTTP or HTTPS) + the source URL's domain. When possible, the Google AMP Cache will create a subdomain for each AMP document's domain by first converting it from IDN (punycode) to utf-8. The caches replaces every `-` (dash) with `--` (2 dashes) and replace every `.` (dot) with `-` (dash). For example, `pub.com` will map to `pub-com.cdn.ampproject.org`.
* for HTTP prepend `cdn.ampproject.org/c/`. Example:
[https://cdn.ampproject.org/c/www.bbc.co.uk/news/amp/35838735](https://cdn.ampproject.org/c/www.bbc.co.uk/news/amp/35838735)
* for HTTPS prepend `cdn.ampproject.org/c/s`. Example: [https://cdn.ampproject.org/c/s/ampbyexample.com](https://cdn.ampproject.org/c/s/ampbyexample.com)
Here is AMP Cache URL for `https://ampbyexample.com`:
<div class="amp-iframe-container"><amp-iframe height="88"
layout="fixed-height" sandbox="allow-scripts allow-same-origin allow-popups"
src="https://amp-by-example-api.appspot.com/iframe/amp-url-converter.html?url=https://ampbyexample.com"><amp-img layout="fixed-height" height="88" src="https://ampbyexample.comm/img/pixel-white.png" placeholder></amp-img></amp-iframe></div>
It is OK for URLs to include parameters in the query string, simply include these in the AMP Cache URL as well.
Example: [https://cdn.ampproject.org/c/s/ampbyexample.com/g?value=Hello%20World](https://cdn.ampproject.org/c/s/ampbyexample.com/g?value=Hello%20World)
Example: [https://ampbyexample-com.cdn.ampproject.org/ampbyexample.com/g?value=Hello%20World](https://ampbyexample-com.cdn.ampproject.org/ampbyexample.com/g?value=Hello%20World).
#### Redirect & Error Handling
Expand All @@ -41,33 +65,37 @@
```
$ curl -I https://ampbyexample.com/amp-img.html
HTTP/1.1 301 Moved Permanently
Location: https://ampbyexample.com/components/amp-img
Content-Type: text/html; charset=utf-8
Location: https://ampbyexample.com/components/amp-img/
...
```
Then the AMP Cache will return the content of the resolved redirect for the original URL.
Example: [https://cdn.ampproject.org/c/s/ampbyexample.com/amp-img.html](https://cdn.ampproject.org/c/s/ampbyexample.com/amp-img.html).
Example: [https://ampbyexample-com.cdn.ampproject.org/ampbyexample.com/amp-img.html](https://cdn.ampproject.org/c/s/ampbyexample.com/amp-img.html).
<p class="card important">**Important**: if you move the location of the AMP Files on your server, make sure to set up a redirect from the old location to the new one. </p>
**Not Found**
When a page is not found in the AMP Cache, it will show an error page and return a 404 status.
Example: [https://cdn.ampproject.org/c/s/ampbyexample.com/not-found](https://cdn.ampproject.org/c/s/ampbyexample.com/not-found).
Example: [https://ampbyexample-com.cdn.ampproject.org/ampbyexample.com/not-found](https://cdn.ampproject.org/c/s/ampbyexample.com/not-found)
**Invalid AMP**
When a page is invalid AMP, the AMP Cache will return a 404 status.
Example: [https://cdn.ampproject.org/c/s/ampbyexample.com/invalid_amp.html](https://cdn.ampproject.org/c/s/ampbyexample.com/invalid_amp.html).
Example: [https://ampbyexample-com.cdn.ampproject.org/ampbyexample.com/invalid_amp.html](https://cdn.ampproject.org/c/s/ampbyexample.com/invalid_amp.html)
**Server Errors**
If an URL returns a 5XX server errors, the AMP Cache will return a 404 status.
Example: [https://cdn.ampproject.org/c/s/ampbyexample.com/error](https://cdn.ampproject.org/c/s/ampbyexample.com/error).
Example: [https://ampbyexample-com.cdn.ampproject.org/ampbyexample.com/error](https://cdn.ampproject.org/c/s/ampbyexample.com/error)
<br>
-->
</body>
</html>
3 changes: 2 additions & 1 deletion templates/css/styles.css
Expand Up @@ -66,7 +66,8 @@ code, pre {
text-decoration: none;
}
.doc pre > code, .doc pre {
background-color: white;
padding: 0;
background-color: #f9f9f9;
}
.doc pre {
padding: 16px;
Expand Down

0 comments on commit ee7ba54

Please sign in to comment.