AMP の Cache 更新について調べていたところ、
Update AMP Content | Google AMP Cache | Google Developers の記載を見つけました。
記事を読む限り、自サイトに、apikey.pub
という公開鍵を置くと、
より早く Cache 更新をしてくれそうなので、試してみました。
以下、試してみた結果を記載します。
update-cache request について
Update AMP Content | Google AMP Cache | Google Developers
の冒頭の文章をGoogle 翻訳に突っ込んだ結果になります。
更新キャッシュ要求
更新キャッシュ要求は、追加のセキュリティ手段を備えているため、より高い要求速度を可能にします。
更新キャッシュ要求では、ドメイン所有者がRSAキーを使用して要求に署名し、一致する公開鍵を元のドメインの標準URLから提供する必要があります。
署名された要求をAMPキャッシュに発行することによって、現在キャッシュされているバージョンのドキュメントをフラッシュすることができます。
更新キャッシュ要求は、このアドレスで呼び出されます。
公開鍵置いたほうが、より早くCacheを更新してくれるようです。
実施したこと
ドキュメントを読む限り、以下の手順を踏めば、
設定はできそうですので順に実施していきます。
-
update-cache 要求を送るドメインの選定
-
RASキーの生成
-
update-cache 要求を送る
1. update-cache 要求を送るドメインの選定
https://cdn.ampproject.org/caches.json
に AMP の Cache を保持しているドメインが記載されているようです。
URL にアクセスすると、以下のJSONファイルが取得できました。
-
caches.json
おそらくこれが、今後増えていくのではないかと思いましたので、{ "caches": [ { "id": "google", "name": "Google AMP Cache", "docs": "https://developers.google.com/amp/cache/", "updateCacheApiDomainSuffix": "cdn.ampproject.org" } ] }
以下のような、updateCacheApiDomainSuffix
に記載されているdomain を取得するpython スクリプトを作成しました。 -
get_domain_suffix.py
# -*- coding: utf-8 - import requests CACHES_JSON_URL = "https://cdn.ampproject.org/caches.json" def main(): print("### " + __file__ + " START ") json_o = requests.get(CACHES_JSON_URL).json() for cache in json_o.get("caches"): print(cache.get("updateCacheApiDomainSuffix")) print("### " + __file__ + " END ") if __name__ == '__main__': main()
2. RSAキーの生成、公開
- キーの生成
公開鍵と、秘密鍵のキーペアを生成します。
ドキュメント記載のコマンドをそのまま実行します。
openssl genrsa 2048 > private-key.pem
openssl rsa -in private-key.pem -pubout >public-key.pem
以下の秘密鍵と、公開鍵が生成されました。
ls
------------------------------
private-key.pem public-key.pem
------------------------------
RSA鍵、証明書のファイルフォーマットについて - Qiitaが勉強になりました。
- キーの公開
HTTPサーバーの設定を変更して、https://example.com/.well-known/amphtml/apikey.pub
と、生成したpublic-key.pem
の紐付けをし、
外部公開します。
このキーは、content-type "text/plain"
になるように、設定します。1
[1]. 私は、content-type "text/html"
で配信しており、最初エラーになりました。
3. update-cache 要求を送る
RSA キーの生成が済んだら、実際に、update-cache 要求を送ります。
これがなかなか大変で、以下の手順を踏む必要があります。
-
AMP Cache の URL のドメイン部を除去した文字列をダイジェスト値として、電子署名を生成
-
1.
で生成した電子署名をbase64エンコードし、amp_url_signature
として使う。 -
update-cache の要求URLを生成し、リクエスト送付。
とりあえず、更新通知が送れるか試してみるのに、
以下のようなスクリプトを作成してみました。
{www-domain-com}
、{www.domain.com}
、{page_url}
、{your_private-key_path}
を読み替えてもらえれば、動作するかと思います。
-
update_amp_cache.py
# -*- coding: utf-8 - from OpenSSL import crypto from OpenSSL.crypto import FILETYPE_PEM, load_privatekey import requests import datetime import time import base64 AMP_BASE_URL = "https://{www-domain-com}.cdn.ampproject.org"; SIGNATURE_URL = "/update-cache/c/s/{www.domain.com}/{page_url}?amp_action=flush&_ts=" def main(): try key = open("{your_private-key_path}") # UNIXタイムスタンプを取得 ts = time.mktime(datetime.datetime.now().utctimetuple()) ts = int(ts) # 1. AMP Cache の URL のドメイン部を除去した文字列をダイジェスト値として、電子署名を生成 url = SIGNATURE_URL + str(ts) p_key = load_privatekey(FILETYPE_PEM, key.read()) sign = crypto.sign(p_key, url ,"sha256") # 2. `1.`で生成した電子署名をbase64エンコードし、`amp_url_signature` として使う。 enc_sign = base64.urlsafe_b64encode(sign) # 3. update-cache の要求URLを生成し、リクエスト送付 amp_url = AMP_BASE_URL + url + "&_url_signature=" + enc_sign print(amp_url) r = requests.get(amp_url) print(r.text) finally: key.close() if __name__ == '__main__': main()
-
補足 ライブラリのインストール
スクリプトの実行には、requests
と、pyopenssl
のインストールが必要になります。
pip install requests pip install pyopenssl
-
実行結果
上記スクリプトを実行すると、うまくいくと以下出力されます。
レスポンスのコンテンツBody は、OK
になるようです。
https://{www-domain-com}.cdn.ampproject.org/update-cache/c/s/{www.domain.com}/{page_url}?amp_action=flush&_ts=1501070789&_url_signature=leYSwvcTxiT... OK
ちなみに、amp_ts=1501070789
のUnix タイムスタンプの指定を忘れて実行すると、以下404
エラーが返ります。2
[2] r.text
だからか、途中でHTMLが千切れてます。
-
失敗時の
r.text
の中身
<!DOCTYPE html> <html lang=en> <meta charset=utf-8> <meta name=viewport content="initial-scale=1, minimum-scale=1, width=device-width"> <title>Error 404 (Not Found)!!1</title> <style> *{margin:0;padding:0}html,code{font:15px/22px arial,sans-serif}html{background:#fff;color:#222;padding:15px}body{margin:7% auto 0;max-width:390px;min-height:180px;padding:30px 0 15px}* > body{background:url(//www.google.com/images/errors/robot.png) 100% 5px no-repeat;padding-right:205px}p{margin:11px 0 22px;overflow:hidden}ins{color:#777;text-decoration:none}a img{border:0}@media screen and (max-width:772px){body{background:none;margin-top:0;max-width:none;padding-right:0}}#logo{background:url(//www.google.com/images/branding/googlelogo/1x/googlelogo_color_150x54dp.png) no-repeat;margin-left:-5px}@media only screen and (min-resolution:192dpi){#logo{background:url(//www.google.com/images/branding/googlelogo/2x/googlelogo_color_150x54dp.png) no-repeat 0% 0%/100% 100%;-moz-border-image:url(//www.google.com/images/branding/googlelogo/2x/googlelogo_color_150x54dp.png) 0}}@media only screen and (-webkit-min-device-pixel-ratio:2){#logo{background:url(//www.google.com/images/branding/googlelogo/2x/googlelogo_color_150x54dp.png) no-repeat;-webkit-background-size:100% 100%}}#logo{display:inline-block;height:54px;width:150px} </style> <a href=//www.google.com/><span id=logo aria-label=Google></span></a> <p><b>404.</b> <ins>That’s an error.</ins> <p>The requested URL <code>/update-cache/c/s/{www.domain.com}/{page_url}?amp_action=flush&amp_ts=&amp_url_signature=pKqqgI....</code> was not found on this server. <ins>That’s all we know.</ins>
-
参考にしたもの
php - Using /update-cache requests to update AMP pages - Stack Overflow に、
php で、update-cache URLを生成する gist にリンクがあり、その実装が参考になりました。
4. 更新対象の URL を外部から指定可能にする
後日、3.
のpython を実行する記載があり、
URL指定して更新できないのが不便だったので、以下のように、実装しなおしました。
引数の処理にclick
を使うようにしたので、別途インストールが必要です。
AMP_BASE_URL = "https://{www-domain-com}.cdn.ampproject.org";
の {www-domain-com}
と、
秘密鍵のpath は変更する前提ですが、更新対象 URL を外部から指定できるようにしました。
-
update_amp_cache.py
# -*- coding: utf-8 - from OpenSSL import crypto from OpenSSL.crypto import FILETYPE_PEM, load_privatekey import requests import datetime import time import base64 import click from urlparse import urlparse AMP_BASE_URL = "https://www-monotalk-xyz.cdn.ampproject.org"; @click.command() @click.option('-url', help='update-cache target url', required=1) def main(url): try: key = open("{your_private-key_path}") # UNIXタイムスタンプを取得 ts = time.mktime(datetime.datetime.now().utctimetuple()) ts = int(ts) # 1. AMP Cache の URL のドメイン部を除去した文字列をダイジェスト値として、電子署名を生成 parsed_url = urlparse(url) signature_url = "/update-cache/c/" if "https" == parsed_url.scheme: signature_url = signature_url + "s/" signature_url = signature_url + parsed_url.netloc + parsed_url.path + "?amp_action=flush&_ts=" url = signature_url + str(ts) # 秘密鍵の読み出し、電子署名の作成 p_key = load_privatekey(FILETYPE_PEM, key.read()) sign = crypto.sign(p_key, url ,"sha256") # 2. `1.`で生成した電子署名をbase64エンコードし、`amp_url_signature` として使う。 enc_sign = base64.urlsafe_b64encode(sign) # 3. update-cache の要求URLを生成し、リクエスト送付 amp_url = AMP_BASE_URL + url + "&_url_signature=" + enc_sign print("####################") print("REQUEST URL:" + amp_url) print("####################") r = requests.get(amp_url) print("####################") print("RESULT:" + r.text) print("####################") finally: key.close() if __name__ == '__main__': main()
-
参考にしたもの
urlparse – URL を部分文字列に分割する - Python Module of the Week
urlparse を使用して、URLを分割する。
Python: コマンドラインパーサの Click が便利すぎた - CUBE SUGAR CONTAINER -
実行する
以下コマンドで、実行可能です。
python2.7 update_amp_cache.py -url https://www.monotalk.xyz/
感想
公開鍵と、秘密鍵の発行とか、中々敷居高いですが、なんとかupdate-cache
を実行することができました。
スクリプトが汚かったり、1件実行しかできなかったりします。
amp の validation api や、amp url api と組み合わせて、
うまく batch 処理化して、スケジュール実行できるといい感じになりそうなので、
そのうち試してみようかと思います。
以上です。
コメント