CORSの不思議

 今回の新型コロナウィルスの影響で、春季永代経法要は中止にしなかったものの、我が寺でできることはないだろうかと思い、法要のオンラインライブ配信を行いました。基本テーマはお金をかけず、持続可能なシステムを構築することです。

  さて、5月末の春季永代経法要では、初日に配信がダウンする事態に陥りました。思わぬ大量の視聴者があったことは事実なのですが、寺院内のWiFiでトラブルがあったのか、サイトにアクセスが集中してなのかは、どちらとも言いがたい面があります。安定していない5GHzのWiFiを使ったことが原因のような気がしますが、サーバーサイドも性能的に逼迫していたのも事実です。それで、WiFiのシステムを再構築するとともに、サーバーにアクセスが集中しても大丈夫なように、アマゾンウェッブサービス(AWS)のCloudFrontを利用するシステムにしました。本来であれば、利用サイトのウェブアクセラレーターというシステムを利用した方が安上がりなのですが、表記のCORSの関係で無理です。CORS(Cross-Origin Resource Sharing)、どこからアクセスしたのかを明かにして身元確認をせよ、という決まり事なのですが、これが動画配信の上ではネックとなります。

 今まではごまかしながら使っていたのですが、CloudFrontみたいなCDNでは設定が必要です。しかし、設定を指定通りにしても、チェッカーではOKとなっても、ネットワークエラーが発生します。それが、 AccessControlAllowOriginのエラーです。

 これを解決するまでには時間を要しました。使っているのは、FV PLAYERというWordpressのプラグインです。ここからは、分かる人にしか分からない言語で話します。

 当初はプラグインの問題かと思っていたのですが、mp4ではOKでm3u8ではNG。よく分かりません。そこで、BRADmax Playerなどを試してみると、Wordpressを置いたサーバーではなく、配信ソースを置いたサーバーの問題であることが分かりました。当サイトはApatchではなくnginxで運用していますので、ちょっと小手先では修正しにくいのですが、confファイルを自在に変更できます。そして、解決に至ったのが次の設定です。一度、設定したものを再度Amazon用に設定しています。詰めればもっとスッキリとするでしょうが、何故こうすると動作するのか、全くもって不思議です。同じ所ではまっている人はいないと思いますが、備忘録的に残しておきます。

検査サイト:https://www.webconfs.com/http-header-check.php

nginx.conf: https serverの中

location ~* ^.+.(jpg|png|mp4|ts|m3u8)$ {
        expires 1h;
        access_log off;
        if ($request_method = 'OPTIONS') {
            add_header 'Access-Control-Allow-Origin' '*';
            add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
#
# Custom headers and headers various browsers *should* be OK with but aren't
#
            add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-   Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';
#
# Tell client that this pre-flight info is valid for 20 days
#
            add_header 'Access-Control-Max-Age' 1728000;
            add_header 'Content-Type' 'text/plain; charset=utf-8';
            add_header 'Content-Length' 0;
            return 204;
        }
    
        if ($request_method = 'POST') {
            add_header 'Access-Control-Allow-Origin' ''; add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS'; add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range'; add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range'; } if ($request_method = 'GET') { add_header 'Access-Control-Allow-Origin' '';
            add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
            add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';
            add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range';
        }
        if ($http_user_agent != "Amazon CloudFront"){
            add_header 'Access-Control-Allow-Origin' '*';
            rewrite ^ https://cdn.xxxx.xxxx.comt$request_uri? last;
        }
  }


なぜ、if ($http_user_agent != “Amazon CloudFront”)の後に

add_header ‘Access-Control-Allow-Origin’

の記述が必要なのかよく分かりませんが、これで無事動作しました。

YouTubeが簡単なのですが、いつ仕様変更になるかも分からず、とりあえずやってみました。今回は2段階のサーバーを経由して、運用しています。最初のさくらのレンタルサーバーを介さなければ、上記の

if ($http_user_agent != “Amazon CloudFront”)の後のadd_header ‘Access-Control-Allow-Origin’

はなくても動作します。ここに至るまで色々と参考にさせて頂きましたが、整理がつきませんので、もし、勝手に引用された等ございましたらご連絡下さい。

P.S. AWSから$300のクレジットを頂きました。ただ、メディア関係はクレジットに入ってないんですよね。申請書にはその旨書いたつもりなんですが。Media LiveとかMedia Packetを利用すれば、今回の件は自分でnginx+rtmp環境を配置しないですむので簡単だと思います。貧乏性が働いたので意地でも使いませんが・・・IoTとかAIに利用しますかね。

KOUENJI,Hiroshima,Japan