EdgeScript memungkinkan Anda menulis logika kustom yang dijalankan di titik keberadaan (POPs) Alibaba Cloud CDN—tanpa menyentuh server origin. Gunakan EdgeScript untuk mengontrol otentikasi, header, penulisan ulang URL, nilai waktu hidup cache (TTL), pembatasan kecepatan, dan kontrol akses di tepi jaringan.
Tabel berikut merangkum skenario yang dibahas dalam dokumen ini:
Skenario | Fungsinya |
Memvalidasi signature URL untuk permintaan | |
Menetapkan | |
Menulis ulang URI, mengubah ekstensi file, menormalisasi huruf kapital/kecil, menambahkan awalan, serta melakukan pengalihan 302 | |
Menetapkan nilai TTL berdasarkan pola URL atau kode status HTTP | |
Membatasi laju transfer berdasarkan parameter URL | |
Memblokir permintaan dari wilayah atau penyedia layanan Internet (ISP) tertentu |
Menyesuaikan aturan otentikasi
Otentikasi EdgeScript 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
(private key + path + filename.extension)harus sesuai dengan segmendigestdalam URL—jika tidak, POP mengembalikan HTTP 403.
Format URL permintaan: /path/digest/?.ts?key=&t=
# Hanya terapkan otentikasi untuk 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 klien.
# Jika jam klien 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(private_key + path + filename) 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)
}
}Menyesuaikan header permintaan dan header respons
Skrip berikut menetapkan header respons Content-Disposition untuk memicu unduhan file otomatis dengan nama kustom. Jika 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 dengan 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)
}Menyesuaikan penulisan ulang dan pengalihan
Menulis ulang URI
Tulis ulang /hello menjadi /index.html. Permintaan 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 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 permintaan ke path root—baik 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')
}Menyesuaikan 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 detik, respons 302 selama 5 detik
if match_re($uri, '^/image') {
set_cache_ttl('code', '301=10,302=5')
}
# Untuk file .mp4: TTL = 5 detik
if eq(substr($uri, -4, -1), '.mp4') {
set_cache_ttl('path', 5)
}
# Untuk path /201801/mp4/: TTL = 50 detik
if match_re($uri, '^/201801/mp4/') {
set_cache_ttl('path', 50)
}
# Untuk path /201802/flv/: TTL = 10 detik
if match_re($uri, '^/201802/flv/') {
set_cache_ttl('path', 10)
}set_cache_ttl menerima 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
Menyesuaikan 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 berlaku.
Parameter | Deskripsi | Nilai yang valid |
| Laju transfer maksimum sebelum pembatasan kecepatan diterapkan | Bilangan bulat positif |
| Unit laju |
|
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 klien. Permintaan dari wilayah atau ISP yang tidak termasuk dalam daftar izin akan diblokir dengan HTTP 403.
client_region() mengembalikan kode wilayah dari IP klien. 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.