EdgeScript le permite escribir lógica personalizada que se ejecuta en los puntos de presencia (POP) de Alibaba Cloud CDN sin modificar su servidor de origen. Utilice EdgeScript para gestionar la autenticación, los encabezados, las reescrituras de URL, los valores de tiempo de vida (TTL) de la caché, la limitación de ancho de banda y el control de acceso directamente en el borde de la red.
A continuación se presenta un resumen de los escenarios que abarca este documento:
|
Scenario |
What it does |
|
Valida firmas de URL para solicitudes |
|
|
Establece |
|
|
Reescribe URI, cambia extensiones de archivo, normaliza mayúsculas y minúsculas, agrega prefijos y realiza redireccionamientos 302 |
|
|
Establece valores de TTL según patrones de URL o códigos de estado HTTP |
|
|
Limita la tasa de transferencia según parámetros de URL |
|
|
Bloquea solicitudes provenientes de regiones o proveedores de servicios de Internet (ISP) específicos |
Personalización de reglas de autenticación
La autenticación con EdgeScript abarca diversos escenarios, como la validación de firmas de URL (protección contra hotlinking), la aplicación de listas de permitidos de IP y el filtrado por User-Agent. El siguiente script implementa protección contra hotlinking basada en firmas de URL para solicitudes .ts.
El script aplica tres reglas de forma secuencial:
La solicitud debe incluir tanto el parámetro
t(tiempo de expiración) comokey; de lo contrario, el POP devuelve HTTP 403.El parámetro
tdebe ser un número válido y no puede ser anterior a la hora actual del POP; en caso contrario, el POP devuelve HTTP 403.El hash MD5 de
(clave privada + ruta + nombre_archivo.extensión)debe coincidir con el segmentodigestde la URL; si no coincide, el POP devuelve HTTP 403.
Formato de la URL de solicitud: /path/digest/?.ts?key=&t=
# Only apply authentication to .ts requests
if eq(substr($uri, -3, -1), '.ts') {
# Rule 1: Reject if t or key parameters are missing
if or(not($arg_t), not($arg_key)) {
add_rsp_header('X-AUTH-MSG', 'auth failed - missing necessary arg')
exit(403)
}
# Rule 2: Reject if t is not a valid number
t = tonumber($arg_t)
if not(t) {
add_rsp_header('X-AUTH-MSG', 'auth failed - invalid time')
exit(403)
}
# Reject if the URL has expired.
# t is compared against the POP's local clock, not the client clock.
# If the client clock differs significantly from the POP clock, valid
# requests may be rejected. Add a time buffer when generating signed URLs.
if gt(now(), t) {
add_rsp_header('X-AUTH-MSG', 'auth failed - expired url')
exit(403)
}
# Rule 3: Extract path segments using a regular expression
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)
}
# Compute MD5(private_key + path + filename) and compare with 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)
}
}
Personalización de encabezados de solicitud y respuesta
El siguiente script establece el encabezado de respuesta Content-Disposition para iniciar automáticamente la descarga de un archivo con un nombre personalizado. Cuando la solicitud incluye el parámetro de URL filename, el navegador guarda el cuerpo de la respuesta con ese nombre. Si el parámetro está ausente, el navegador utiliza el nombre de archivo predeterminado.
Encabezado de respuesta esperado:
Content-Disposition: attachment;filename="monitor.apk"
El valor del nombre de archivo va entre comillas dobles. tochar(34) convierte el código ASCII 34 al carácter ", ya que las comillas no pueden insertarse directamente en la cadena.
if $arg_filename {
hn = 'Content-Disposition'
hv = concat('attachment;filename=', tochar(34), $arg_filename, tochar(34))
add_rsp_header(hn, hv)
}
Personalización de reescrituras y redireccionamientos
Reescritura de una URI
Reescriba /hello como /index.html. La solicitud al origen utiliza /index.html y se conservan todos los parámetros de la URL.
if match_re($uri, '^/hello$') {
rewrite('/index.html', 'break')
}
Reescritura de una extensión de archivo
Sustituya la extensión de archivo en la URI por el valor del parámetro de URL type. Por ejemplo, /1.txt?type=mp4 se convierte en /1.mp4?type=mp4 antes de reenviar la solicitud al origen. Posteriormente, el contenido recuperado se almacena en la caché de los POP de CDN.
if and(match_re($uri, '^/1.txt$'), $arg_type) {
rewrite(concat('/1.', $arg_type), 'break')
}
Conversión de una extensión de archivo a minúsculas
Normalice la extensión del archivo a minúsculas. Por ejemplo, /image/Photo.JPG se convierte en /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')
}
Adición de un prefijo a la URI
Reescriba cualquier URI que coincida con ^/nn_live/(.*) anteponiendo /3rd. Por ejemplo, /nn_live/stream1 se convierte en /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')
}
Realización de un redireccionamiento 302
Redirija las solicitudes a la ruta raíz / hacia /app/movie/pages/index/index.html.
if eq($uri, '/') {
rewrite('/app/movie/pages/index/index.html', 'redirect')
}
Redireccionamiento a una URL HTTPS
Redirija las solicitudes a la ruta raíz —ya sea que lleguen por HTTP o HTTPS— a una URL HTTPS específica. Sustituya https://demo.aliyundoc.com/index.html por su URL de destino.
if eq($uri, '/') {
rewrite('https://demo.aliyundoc.com/index.html', 'redirect')
}
Personalización del control de caché
El siguiente script establece el TTL de los recursos en caché según patrones de URL y códigos de estado HTTP.
# For /image URLs: cache 301 responses for 10 s, 302 responses for 5 s
if match_re($uri, '^/image') {
set_cache_ttl('code', '301=10,302=5')
}
# For .mp4 files: TTL = 5 s
if eq(substr($uri, -4, -1), '.mp4') {
set_cache_ttl('path', 5)
}
# For /201801/mp4/ paths: TTL = 50 s
if match_re($uri, '^/201801/mp4/') {
set_cache_ttl('path', 50)
}
# For /201802/flv/ paths: TTL = 10 s
if match_re($uri, '^/201802/flv/') {
set_cache_ttl('path', 10)
}
set_cache_ttl admite dos modos:
'code'— establece el TTL por código de estado HTTP mediante el formato'<código>=<segundos>[,<código>=<segundos>]''path'— establece el TTL en segundos para todas las respuestas que coinciden con el patrón de URI
Personalización de políticas de limitación de ancho de banda
El siguiente script lee los parámetros sp (límite de velocidad) y unit de la URL de solicitud, y aplica la limitación mediante limit_rate(). Ambos parámetros deben estar presentes para que la limitación surta efecto.
|
Parameter |
Description |
Valid values |
|
|
Tasa máxima de transferencia antes de que se aplique la limitación |
Entero positivo |
|
|
Unidad de la tasa |
|
if and($arg_sp, $arg_unit) {
# Validate that sp is a positive integer
sp = tonumber($arg_sp)
if not(sp) {
add_rsp_header('X-LIMIT-DEBUG', 'invalid sp')
return false
}
# Validate that unit is k (KB) or 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
}
Control de acceso por región e ISP
El siguiente script restringe el acceso según la región y el proveedor de servicios de Internet (ISP) asociados a la dirección IP del cliente. Las solicitudes provenientes de cualquier región o ISP que no figure en la lista de permitidos se bloquean con HTTP 403.
client_region() devuelve el código de región de la IP del cliente. client_isp() devuelve el código del ISP. Para consultar la lista completa de códigos de región e ISP, consulte Request logic functions.
# Block requests from regions not in the allowlist
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)
}
# Block requests from ISPs not in the allowlist
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)
}
Sustituya '440000|370000' y '100017|100025' por los códigos de región e ISP correspondientes a su política de acceso.