AScript common scenarios

Updated at:
Copy as MD

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 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 requestRedirected to
http://www.test.com/path?a=1http://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 requestRedirected to
http://www.test.com/path?a=1http://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 requestRedirected to
http://www.test.com/path?a=1http://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 requestRedirected to
http://www.test.com/tmp/?a=bhttps://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.