AScript common scenarios
AScript lets you write custom forwarding rules directly on Application Load Balancer (ALB). This page provides ready-to-use scripts for common scenarios: hotlink protection, IP blacklists, request and response header manipulation, URI rewrites, redirects, and request tracking.
The AScript feature is in whitelist release. To add or modify scripts, contact your account manager.
Hotlink protection
Custom authentication for .ts files
Requirement: Validate .ts requests using a time-based digest scheme. The request URL format is /path/digest/?.tskey=&t=.
The validation applies three rules:
-
Rule 1: If the request is missing the
torkeyparameter, return HTTP 403 and add theX-AUTH-MSGresponse header with the failure reason. -
Rule 2: The
tparameter is the absolute expiration time. Iftis earlier than the current time, return HTTP 403 and addX-AUTH-MSG. -
Rule 3: Compare the computed MD5 digest with the
digestvalue in the URL. If they do not match, return HTTP 403.
MD5 value format: Private key + Path + File name.extension
Sample script:
if eq(substr($uri, -3, -1), '.ts') {
if or(not($arg_t), not($arg_key)) {
add_rsp_header('X-AUTH-MSG', 'auth failed - missing necessary arg')
exit(403)
}
t = tonumber($arg_t)
if not(t) {
add_rsp_header('X-AUTH-MSG', 'auth failed - invalid time')
exit(403)
}
if gt(now(), t) {
add_rsp_header('X-AUTH-MSG', 'auth failed - expired url')
exit(403)
}
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)
}
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)
}
}
The key value ('b98d643a-9170-4937-8524-6c33514bbc23') is a placeholder. Replace it with your actual private key before deploying to production. Using the example key in production is a security risk.
User-Agent blacklist
Requirement: Return HTTP 403 for requests whose User-Agent header starts with ijkplayer or Ysten.
Sample script:
if and($http_user_agent, match_re($http_user_agent, '^(ijkplayer|Ysten).*$')) {
add_rsp_header('X-BLOCKLIST-DEBUG', 'deny')
exit(403)
}
Referer whitelist
Requirement: Return HTTP 403 for requests whose Referer header does not match http[s]://*alibaba.com*.
Sample script:
if and($http_referer, match_re($http_referer, '^(http|https)://(.)+\.alibaba\.com.*$')) {
return true
}
add_rsp_header('X-WHITELIST-DEBUG', 'missing')
exit(403)
IP blacklist
Requirement: Return HTTP 403 for requests from 127.0.0.1 or 10.0.0.1.
Sample script:
if match_re($remote_addr, '127.0.0.1|10.0.0.1') {
add_rsp_header('X-IPBLOCK-DEBUG', 'hit')
exit(403)
}
Custom request and response headers
Set Content-Disposition for file downloads
Requirement: If the filename query parameter is present, set Content-Disposition so the browser downloads the file under that name. If filename is absent, the default filename is used.
Sample script:
if $arg_filename {
hn = 'Content-Disposition'
hv = concat('attachment;filename=', $arg_filename)
add_rsp_header(hn, hv)
}
Example with quoted filename:
add_rsp_header('Content-Disposition', concat('attachment;filename=', tochar(34), filename, tochar(34)))
AddingContent-Disposition: attachmentto a response causes the browser to download the message body automatically. Thetochar(34)call produces a double quotation mark ("), whose ASCII code is 34.
Output:
Content-Disposition: attachment;filename="monitor.apk"
Overwrite a response header
Requirement: Overwrite the Content-Type response header.
Sample script:
add_rsp_header('Content-Type', 'audio/mpeg')
URI rewrites
All rewrite examples in this section use 'break' mode, which rewrites the URI for the back-to-origin request and the cache key without issuing a new HTTP redirect to the client.
Rewrite a URI path
Requirement: Rewrite /hello to /index.html. The URI of the back-to-origin request and the cached URI change to /index.html; other parameters remain unchanged.
Sample script:
if match_re($uri, '^/hello$') {
rewrite('/index.html', 'break')
}
Rewrite a file extension
Requirement: Rewrite /1.txt to /1.<type>, where type comes from the type URL parameter. For example, /1.txt?type=mp4 becomes /1.mp4?type=mp4.
Sample script:
if and(match_re($uri, '^/1.txt$'), $arg_type) {
rewrite(concat('/1.', $arg_type), 'break')
}
Normalize file extensions to lowercase
Requirement: Convert file extensions in URI strings to lowercase letters.
Sample script:
pcs = capture_re($uri, '^(.+\.)([^.]+)')
section = get(pcs, 1)
postfix = get(pcs, 2)
if and(section, postfix) {
rewrite(concat(section, lower(postfix)), 'break')
}
Add a URI prefix
Requirement: Rewrite paths matching ^/nn_live/(.*) by prepending /3rd, so /nn_live/foo becomes /3rd/nn_live/foo.
Sample script:
pcs = capture_re($uri, '^/nn_live/(.*)')
sec = get(pcs, 1)
if sec {
dst = concat('/3rd/nn_live/', sec)
rewrite(dst, 'break')
}
Redirects
All redirect examples in this section issue an HTTP 302 response to the client.
Redirect the root path to a specific page
Requirement: Redirect requests for / to /app/movie/pages/index/index.html.
Sample script:
if eq($uri, '/') {
rewrite('/app/movie/pages/index/index.html', 'redirect')
}
Redirect the root path to an HTTPS URL
Requirement: Redirect requests matching the ^/$ root path to https://aliyun.com. This applies to both http://rtmp.cdnpe.com and https://rtmp.cdnpe.com. Replace the target URL with your own as needed.
Sample script:
if eq($uri, '/') {
rewrite('https://aliyun.com', 'redirect')
}
Redirect a domain, dropping query parameters
Requirement: Redirect requests for www.test.com to www.example.com, removing all query parameters.
Sample script:
if and(eq(req_header('Host'), 'www.test.com')) {
rewrite('www.example.com', 'redirect')
}
Result: The original query parameters are removed. However, the redirected URL ends with a trailing ?.
| Original request | Redirected to |
|---|---|
http://www.test.com/path?a=1 |
http://www.example.com/path? |
To remove the trailing ?, use enhance_redirect instead:
if and(eq(req_header('Host'), 'www.test.com')) {
rewrite('www.example.com', 'enhance_redirect')
}
| Original request | Redirected to |
|---|---|
http://www.test.com/path?a=1 |
http://www.example.com/path |
Redirect a domain, retaining query parameters
Requirement: Redirect requests for www.test.com to www.example.com, preserving the original query parameters.
Sample script:
if and(eq(req_header('Host'), 'www.test.com')) {
rewrite(concat('www.example.com', $uri), 'enhance_redirect')
}
| Original request | Redirected to |
|---|---|
http://www.test.com/path?a=1 |
http://www.example.com/path?a=1 |
Wildcard domain matching with URI suffix
Requirement: Match requests to any subdomain of test.com where the URI does not already contain index.php, and append /index.php?s=<uri> to the host.
Sample script:
host_re = match_re(req_header('Host'), '.*.test.com')
url_match = null(find($uri, 'index.php'))
if and(host_re, url_match) {
rewrite(concat($host, '/index.php?s=', $uri), 'enhance_redirect')
}
HTTP to HTTPS redirect, removing query parameters
Requirement: Redirect http://www.test.com/tmp/?a=b to https://www.test.com, stripping all query parameters.
Sample script:
host_re = match_re(req_header('Host'), 'www.test.com')
url_match = not(null(find($request_uri, '?'))) # Prevent a redirect loop
if req_scheme('http') {
if and(host_re, url_match) {
rewrite('https://www.test.com', 'enhance_redirect') # Status code 302
}
}
Theurl_matchcondition checks for the presence of?in the request URI to prevent a redirect loop. Requests that have already been redirected to HTTPS will not matchreq_scheme('http')and are passed through.
| Original request | Redirected to |
|---|---|
http://www.test.com/tmp/?a=b |
https://www.test.com |
https://www.test.com/tmp/?a=b |
(not redirected) |
Troubleshooting
Add x-request-id for request tracking
Requirement: Generate a unique x-request-id header and attach it to both the request and the response to simplify request tracking and error locating.
Sample script:
requestid=md5(concat(rand(1, 10000), now()))
add_req_header('x-request-id', requestid)
add_rsp_header('x-request-id', requestid)
The x-request-id value is derived from md5(concat(rand(1, 10000), now())), combining a random number and the current timestamp.