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.
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.