すべてのプロダクト
Search
ドキュメントセンター

CDN:EdgeScript のユースケース例

最終更新日:Apr 01, 2026

エッジスクリプトを使用すると、オリジンサーバーに触れることなく、Alibaba Cloud CDN のプレゼンスポイント (POP) で実行されるカスタムロジックを記述できます。エッジスクリプトを使用して、エッジで認証、ヘッダー、URL リライト、キャッシュの生存時間 (TTL) 値、速度制限、およびアクセスの制御をコントロールします。

このドキュメントで説明するシナリオの概要は、次の表をご参照ください。

シナリオ機能
認証.ts リクエストの URL 署名を検証し、失敗した場合は HTTP 403 を返します
リクエストヘッダーとレスポンスヘッダーContent-Disposition を設定して、名前付きファイルのダウンロードをトリガーします
書き換えとリダイレクトURI の書き換え、ファイル拡張子の変更、大文字と小文字の正規化、プレフィックスの追加、302 リダイレクトの実行を行います
キャッシュコントロールURL パターンまたは HTTP ステータスコードごとに TTL 値を設定します
速度制限URL パラメーターに基づいて転送レートを制限します
リージョンと ISP に基づくアクセスの制御特定のリージョンまたはインターネットサービスプロバイダー (ISP) からのリクエストをブロックします

認証ルールのカスタマイズ

エッジスクリプトの認証は、URL 署名の検証 (ホットリンク保護)、IP 許可リストの適用、User-Agent フィルタリングなど、さまざまなシナリオに対応できます。以下のスクリプトは、.ts リクエストに対して URL 署名ベースのホットリンク保護を実装します。

このスクリプトは、3 つのルールを順番に適用します。

  1. リクエストには t (有効期限) と key の両方のパラメーターが含まれている必要があります。含まれていない場合、POP は HTTP 403 を返します。

  2. t パラメーターは有効な数値であり、現在の POP の時間より前であってはなりません。そうでない場合、POP は HTTP 403 を返します。

  3. (秘密鍵 + パス + ファイル名.拡張子) の MD5 ハッシュは、URL 内の digest セグメントと一致する必要があります。一致しない場合、POP は HTTP 403 を返します。

リクエスト URL のフォーマット: /path/digest/?.ts?key=&t=

# .ts リクエストにのみ認証を適用
if eq(substr($uri, -3, -1), '.ts') {

  # ルール 1: t または key パラメーターがない場合は拒否
  if or(not($arg_t), not($arg_key)) {
    add_rsp_header('X-AUTH-MSG', 'auth failed - missing necessary arg')
    exit(403)
  }

  # ルール 2: t が有効な数値でない場合は拒否
  t = tonumber($arg_t)
  if not(t) {
    add_rsp_header('X-AUTH-MSG', 'auth failed - invalid time')
    exit(403)
  }

  # URL の有効期限が切れている場合は拒否
  # t はクライアントの時計ではなく、POP のローカル時計と比較されます。
  # クライアントの時計が POP の時計と大幅に異なる場合、有効なリクエストが拒否されることがあります。
  # 署名付き URL を生成する際に時間バッファーを追加してください。
  if gt(now(), t) {
    add_rsp_header('X-AUTH-MSG', 'auth failed - expired url')
    exit(403)
  }

  # ルール 3: 正規表現を使用してパスセグメントを抽出
  pcs = capture_re($request_uri,'^/([^/]+)/([^/]+)/([^?]+)%?(.*)')
  sec1 = get(pcs, 1)
  sec2 = get(pcs, 2)
  sec3 = get(pcs, 3)

  if or(not(sec1), not(sec2), not(sec3)) {
    add_rsp_header('X-AUTH-MSG', 'auth failed - malformed url')
    exit(403)
  }

  # MD5(秘密鍵 + パス + ファイル名) を計算し、ダイジェストと比較
  key = 'b98d643a-9170-4937-8524-6c33514bbc23'
  signstr = concat(key, sec1, sec3)
  digest = md5(signstr)

  if ne(digest, sec2) {
    add_rsp_header('X-AUTH-DEBUG', concat('signstr: ', signstr))
    add_rsp_header('X-AUTH-MSG', 'auth failed - invalid digest')
    exit(403)
  }
}

リクエストヘッダーとレスポンスヘッダーのカスタマイズ

以下のスクリプトは、Content-Disposition レスポンスヘッダーを設定し、指定したファイル名で自動的にファイルがダウンロードされるようにします。リクエストに filename URL パラメーターが含まれている場合、ブラウザはその名前でレスポンスボディを保存します。パラメーターがない場合、ブラウザはデフォルトのファイル名を使用します。

期待されるレスポンスヘッダー:

Content-Disposition: attachment;filename="monitor.apk"
説明

ファイル名の値は二重引用符で囲まれます。tochar(34) は、引用符を文字列に直接埋め込むことができないため、ASCII コード 34 を " 文字に変換します。

if $arg_filename {
  hn = 'Content-Disposition'
  hv = concat('attachment;filename=', tochar(34), $arg_filename, tochar(34))
  add_rsp_header(hn, hv)
}

書き換えとリダイレクトのカスタマイズ

URI の書き換え

/hello/index.html に書き換えます。オリジンへのリクエストは /index.html を使用し、すべての URL パラメーターは保持されます。

if match_re($uri, '^/hello$') {
    rewrite('/index.html', 'break')
}

ファイル拡張子の書き換え

URI のファイル拡張子を type URL パラメーターの値に置き換えます。たとえば、/1.txt?type=mp4 は、リクエストがオリジンに転送される前に /1.mp4?type=mp4 になります。取得されたコンテンツは CDN POP にキャッシュされます。

if and(match_re($uri, '^/1.txt$'), $arg_type) {
    rewrite(concat('/1.', $arg_type), 'break')
}

ファイル拡張子の小文字への変換

ファイル拡張子を小文字に正規化します。たとえば、/image/Photo.JPG/image/Photo.jpg になります。

pcs = capture_re($uri, '^(.+%.)([^.]+)')
section = get(pcs, 1)
postfix = get(pcs, 2)

if and(section, postfix) {
    rewrite(concat(section, lower(postfix)), 'break')
}

URI プレフィックスの追加

^/nn_live/(.*) に一致する URI の先頭に /3rd を追加して書き換えます。たとえば、/nn_live/stream1/3rd/nn_live/stream1 になります。

pcs = capture_re($uri, '^/nn_live/(.*)')
sec = get(pcs, 1)

if sec {
    dst = concat('/3rd/nn_live/', sec)
    rewrite(dst, 'break')
}

302 リダイレクトの実行

ルートパス / へのリクエストを /app/movie/pages/index/index.html にリダイレクトします。

if eq($uri, '/') {
    rewrite('/app/movie/pages/index/index.html', 'redirect')
}

HTTPS URL へのリダイレクト

HTTP または HTTPS でルートパスに到達したリクエストを、特定の HTTPS URL にリダイレクトします。https://demo.aliyundoc.com/index.html をターゲット URL に置き換えてください。

if eq($uri, '/') {
    rewrite('https://demo.aliyundoc.com/index.html', 'redirect')
}

キャッシュ制御のカスタマイズ

以下のスクリプトは、URL パターンと HTTP ステータスコードに基づいて、キャッシュされたリソースの TTL を設定します。

# /image URL の場合:301 応答を 10 秒、302 応答を 5 秒キャッシュ
if match_re($uri, '^/image') {
    set_cache_ttl('code', '301=10,302=5')
}

# .mp4 ファイルの場合:TTL = 5 秒
if eq(substr($uri, -4, -1), '.mp4') {
    set_cache_ttl('path', 5)
}

# /201801/mp4/ パスの場合:TTL = 50 秒
if match_re($uri, '^/201801/mp4/') {
    set_cache_ttl('path', 50)
}

# /201802/flv/ パスの場合:TTL = 10 秒
if match_re($uri, '^/201802/flv/') {
    set_cache_ttl('path', 10)
}

set_cache_ttl は 2 つのモードを受け入れます。

  • 'code''<code>=<seconds>[,<code>=<seconds>]' のフォーマットを使用して、HTTP ステータスコードごとに TTL を設定します

  • 'path' — URI パターンに一致するすべての応答に対して TTL を秒単位で設定します

スロットリングポリシーのカスタマイズ

以下のスクリプトは、リクエスト URL から sp (速度制限) と unit パラメーターを読み取り、limit_rate() を使用して速度制限を適用します。速度制限を有効にするには、両方のパラメーターが存在する必要があります。

パラメーター説明有効値
sp速度制限が有効になる前の最大転送レート正の整数
unitレートの単位k (KB) または m (MB)
if and($arg_sp, $arg_unit) {

  # sp が正の整数であることを検証
  sp = tonumber($arg_sp)
  if not(sp) {
    add_rsp_header('X-LIMIT-DEBUG', 'invalid sp')
    return false
  }

  # unit が k (KB) または m (MB) であることを検証
  if and(ne($arg_unit, 'k'), ne($arg_unit, 'm')) {
    add_rsp_header('X-LIMIT-DEBUG', 'invalid unit')
    return false
  }

  add_rsp_header('X-LIMIT-DEBUG', concat('set on: ', sp, $arg_unit))
  limit_rate(sp, $arg_unit)
  return true
}

リージョンと ISP に基づくアクセスの制御

以下のスクリプトは、クライアント IP アドレスのリージョンとインターネットサービスプロバイダー (ISP) に基づいてアクセスを制限します。許可リストにないリージョンまたは ISP からのリクエストは、HTTP 403 でブロックされます。

client_region() はクライアント IP のリージョンコードを返します。client_isp() は ISP コードを返します。リージョンコードと ISP コードの完全なリストについては、「リクエストロジック関数」をご参照ください。

# 許可リストにないリージョンからのリクエストをブロック
ip_region_id = client_region()
if not(match_re(ip_region_id, '440000|370000')) {
    add_rsp_header('X-REGION-BLOCK-DEBUG', concat('hit ip_region_id:', ip_region_id))
    exit(403)
}

# 許可リストにない ISP からのリクエストをブロック
ip_isp_id = client_isp()
if not(match_re(ip_isp_id, '100017|100025')) {
    add_rsp_header('X-REGION-BLOCK-DEBUG', concat('hit ip_isp_id:', ip_isp_id))
    exit(403)
}

'440000|370000''100017|100025' を、ご利用のアクセスポリシーに一致するリージョンコードと ISP コードに置き換えてください。