AMP の
Update AMP Content | Google AMP Cache | Google Developers の
記事をapikey.pub
と
より
以下、
update-cache request に ついて
Update AMP Content | Google AMP Cache | Google Developers
の
更新キャッシュ要求
更新キャッシュ要求は、
追加の セキュリティ手段を 備えている ため、 より 高い 要求速度を 可能に します。
更新キャッシュ要求では、ドメイン所有者が RSAキーを 使用して 要求に 署名し、 一致する 公開鍵を 元の ドメインの 標準URLから 提供する 必要が あります。
署名された要求を AMPキャッシュに 発行する ことに よって、 現在キャッシュされている バージョンの ドキュメントを フラッシュする ことができます。
更新キャッシュ要求は、この アドレスで 呼び出されます。
公開鍵置いたほうが、
実施した こと
ドキュメントを
設定は
update-cache 要求を
送る ドメインの 選定 RASキーの
生成 update-cache 要求を
送る
1. update-cache 要求を 送る ドメインの 選定
https://cdn.ampproject.org/caches.json
に
URL に
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鍵、
- キーの
公開
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 キーの
これが
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
の404
エラーが
[2] r.text
だからか、
失敗時の
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.
の
URL指定して
引数のclick
を
AMP_BASE_URL = "https://{www-domain-com}.cdn.ampproject.org";
の{www-domain-com}
と、
秘密鍵の
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
を
amp の
うまく
そのうち試してみようかと
以上です。
コメント