EdgeScript memungkinkan Anda menulis logika kustom yang dijalankan di titik keberadaan (POPs) Alibaba Cloud CDN—tanpa menyentuh server origin. Gunakan EdgeScript untuk mengontrol autentikasi, header, penulisan ulang URL, nilai TTL cache, pembatasan kecepatan, dan kontrol akses di tepi jaringan.
Tabel berikut merangkum skenario yang dibahas dalam dokumen ini:
| Skenario | Fungsinya |
|---|---|
| Autentikasi | Memvalidasi signature URL untuk permintaan .ts; mengembalikan HTTP 403 jika gagal |
| Header permintaan dan respons | Menetapkan Content-Disposition untuk memicu unduhan file dengan nama tertentu |
| Penulisan ulang dan pengalihan | Menulis ulang URI, mengubah ekstensi file, menormalisasi kapitalisasi, menambahkan awalan, serta melakukan pengalihan 302 |
| Kontrol cache | Menetapkan nilai TTL berdasarkan pola URL atau kode status HTTP |
| Pembatasan kecepatan | Membatasi laju transfer berdasarkan parameter URL |
| Kontrol akses berdasarkan Wilayah dan ISP | Memblokir permintaan dari Wilayah atau penyedia layanan Internet (ISP) tertentu |
Kustomisasi aturan autentikasi
Autentikasi EdgeScript dapat mencakup berbagai skenario, termasuk validasi signature URL (Perlindungan hotlink), penerapan daftar IP yang diizinkan, dan penyaringan User-Agent. Skrip berikut menerapkan Perlindungan hotlink berbasis signature URL untuk permintaan .ts.
Skrip ini menerapkan tiga aturan secara berurutan:
Permintaan harus menyertakan parameter
t(waktu kedaluwarsa) dankey—jika tidak, POP mengembalikan HTTP 403.Parameter
tharus berupa angka yang valid dan tidak boleh lebih awal dari waktu lokal POP saat ini—jika tidak, POP mengembalikan HTTP 403.Hash MD5 dari
(kunci privat + path + namafile.ekstensi)harus sesuai dengan segmendigestdalam URL—jika tidak, POP mengembalikan HTTP 403.
Format URL permintaan: /path/digest/?.ts?key=&t=
# Hanya terapkan autentikasi pada permintaan .ts
if eq(substr($uri, -3, -1), '.ts') {
# Aturan 1: Tolak jika parameter t atau key tidak ada
if or(not($arg_t), not($arg_key)) {
add_rsp_header('X-AUTH-MSG', 'auth failed - missing necessary arg')
exit(403)
}
# Aturan 2: Tolak jika t bukan angka yang valid
t = tonumber($arg_t)
if not(t) {
add_rsp_header('X-AUTH-MSG', 'auth failed - invalid time')
exit(403)
}
# Tolak jika URL telah kedaluwarsa.
# t dibandingkan dengan jam lokal POP, bukan jam client.
# Jika jam client berbeda signifikan dari jam POP, permintaan yang valid
# mungkin ditolak. Tambahkan buffer waktu saat membuat URL yang ditandatangani.
if gt(now(), t) {
add_rsp_header('X-AUTH-MSG', 'auth failed - expired url')
exit(403)
}
# Aturan 3: Ekstrak segmen path menggunakan ekspresi reguler
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)
}
# Hitung MD5(kunci_privat + path + namafile) dan bandingkan dengan digest
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)
}
}Kustomisasi header permintaan dan header respons
Skrip berikut menetapkan header respons Content-Disposition untuk memicu unduhan file otomatis dengan nama kustom. Saat permintaan menyertakan parameter URL filename, browser menyimpan badan respons dengan nama tersebut. Jika parameter tidak ada, browser menggunakan nama file default.
Header respons yang diharapkan:
Content-Disposition: attachment;filename="monitor.apk"Nilai filename dibungkus tanda kutip ganda. tochar(34) mengonversi kode ASCII 34 menjadi karakter ", karena tanda kutip tidak dapat disisipkan langsung dalam string.
if $arg_filename {
hn = 'Content-Disposition'
hv = concat('attachment;filename=', tochar(34), $arg_filename, tochar(34))
add_rsp_header(hn, hv)
}Kustomisasi penulisan ulang dan pengalihan
Menulis ulang URI
Tulis ulang /hello menjadi /index.html. Permintaan kembali-ke-asal menggunakan /index.html dan semua parameter URL dipertahankan.
if match_re($uri, '^/hello$') {
rewrite('/index.html', 'break')
}Menulis ulang ekstensi file
Ganti ekstensi file dalam URI dengan nilai parameter URL type. Misalnya, /1.txt?type=mp4 menjadi /1.mp4?type=mp4 sebelum permintaan diteruskan ke origin. Konten yang diambil kemudian di-cache di POP CDN.
if and(match_re($uri, '^/1.txt$'), $arg_type) {
rewrite(concat('/1.', $arg_type), 'break')
}Mengonversi ekstensi file menjadi huruf kecil
Normalisasi ekstensi file menjadi huruf kecil. Misalnya, /image/Photo.JPG menjadi /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')
}Menambahkan awalan URI
Tulis ulang URI apa pun yang sesuai dengan ^/nn_live/(.*) dengan menambahkan awalan /3rd. Misalnya, /nn_live/stream1 menjadi /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')
}Menjalankan pengalihan 302
Arahkan ulang permintaan ke path root / ke /app/movie/pages/index/index.html.
if eq($uri, '/') {
rewrite('/app/movie/pages/index/index.html', 'redirect')
}Mengarahkan ke URL HTTPS
Arahkan ulang permintaan ke path root—baik yang datang melalui HTTP maupun HTTPS—ke URL HTTPS tertentu. Ganti https://demo.aliyundoc.com/index.html dengan URL target Anda.
if eq($uri, '/') {
rewrite('https://demo.aliyundoc.com/index.html', 'redirect')
}Kustomisasi kontrol cache
Skrip berikut menetapkan TTL untuk sumber daya yang di-cache berdasarkan pola URL dan kode status HTTP.
# Untuk URL /image: cache respons 301 selama 10 dtk, respons 302 selama 5 dtk
if match_re($uri, '^/image') {
set_cache_ttl('code', '301=10,302=5')
}
# Untuk file .mp4: TTL = 5 dtk
if eq(substr($uri, -4, -1), '.mp4') {
set_cache_ttl('path', 5)
}
# Untuk path /201801/mp4/: TTL = 50 dtk
if match_re($uri, '^/201801/mp4/') {
set_cache_ttl('path', 50)
}
# Untuk path /201802/flv/: TTL = 10 dtk
if match_re($uri, '^/201802/flv/') {
set_cache_ttl('path', 10)
}set_cache_ttl mendukung dua mode:
'code'—menetapkan TTL per kode status HTTP, dengan format'<kode>=<detik>[,<kode>=<detik>]''path'—menetapkan TTL dalam detik untuk semua respons yang sesuai dengan pola URI
Kustomisasi kebijakan pembatasan kecepatan
Skrip berikut membaca parameter sp (batas kecepatan) dan unit dari URL permintaan dan menerapkan pembatasan kecepatan menggunakan limit_rate(). Kedua parameter harus ada agar pembatasan kecepatan diterapkan.
| Parameter | Deskripsi | Nilai yang valid |
|---|---|---|
sp | Laju transfer maksimum sebelum pembatasan kecepatan diterapkan | Bilangan bulat positif |
unit | Satuan laju | k (KB) atau m (MB) |
if and($arg_sp, $arg_unit) {
# Validasi bahwa sp adalah bilangan bulat positif
sp = tonumber($arg_sp)
if not(sp) {
add_rsp_header('X-LIMIT-DEBUG', 'invalid sp')
return false
}
# Validasi bahwa unit adalah k (KB) atau 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
}Kontrol akses berbasis Wilayah dan ISP
Skrip berikut membatasi akses berdasarkan Wilayah dan penyedia layanan Internet (ISP) dari alamat IP client. Permintaan dari Wilayah atau ISP yang tidak termasuk dalam daftar izin akan diblokir dengan HTTP 403.
client_region() mengembalikan kode Wilayah dari IP client. client_isp() mengembalikan kode ISP. Untuk daftar lengkap kode Wilayah dan ISP, lihat Fungsi logika permintaan.
# Blokir permintaan dari Wilayah yang tidak termasuk dalam daftar izin
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)
}
# Blokir permintaan dari ISP yang tidak termasuk dalam daftar izin
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)
}Ganti '440000|370000' dan '100017|100025' dengan kode Wilayah dan ISP yang sesuai dengan kebijakan akses Anda.