AScript common scenarios

Updated at:

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.

Note

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 t or key parameter, return HTTP 403 and add the X-AUTH-MSG response header with the failure reason.

  • Rule 2: The t parameter is the absolute expiration time. If t is earlier than the current time, return HTTP 403 and add X-AUTH-MSG.

  • Rule 3: Compare the computed MD5 digest with the digest value 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)
    }

}
Important

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)))
Adding Content-Disposition: attachment to a response causes the browser to download the message body automatically. The tochar(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
    }
}
The url_match condition checks for the presence of ? in the request URI to prevent a redirect loop. Requests that have already been redirected to HTTPS will not match req_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.