All Products
Search
Document Center

CDN:Manage EdgeScript with the CLI

Last Updated:Apr 01, 2026

Use the EdgeScript (ES) CLI to manage the full script lifecycle: write a script locally, deploy it to the staging environment, verify behavior, then promote it to production. This workflow lets you safely test EdgeScript (ES) logic before it affects live traffic.

For full ES CLI reference documentation, see Use the EdgeScript CLI to manage scripts.

Prerequisites

Before you begin, ensure that you have:

  • The es.py CLI tool downloaded and available in your working directory

  • An accelerated domain name configured in Alibaba Cloud CDN

  • An ES script file ready to deploy (the examples below use m3u8.es)

How it works

All commands use es.py with an action parameter to select the operation. The same domain is targeted across all steps; only the action value changes to move between environments.

Write script → Push to staging → Query staging → Test → Push to production → Query production

Step 1: Write the script

Save your ES logic as a local .es file. The following example uses m3u8.es to block all M3U8 requests by checking the URI suffix and returning a 400 Bad Request response.

$cat m3u8.es
if eq(substr($uri, -5, -1), '.m3u8') {
    add_rsp_header('X-DEBUG-DENY-REASON', 'block m3u8')
    exit(400)
}

Step 2: Push the script to the staging environment

Run push_test_env to deploy the script to staging before it reaches production.

$./es.py action=push_test_env domain=<your domain> rule='{"pos":"head","pri":"0","rule_path":"./m3u8.es","enable":"on"}'

Rule parameters

ParameterDescriptionExample value
posExecution position in the request pipelinehead
priPriority (lower number = higher priority)0
rule_pathPath to the local .es script file./m3u8.es
enableWhether the rule is activeon

Expected response

Response Code:
=============
200 OK

Response Info:
==============
{
    "RequestId": "FB98CC67-8FBA-44CF-A98A-BCE3B19FE510"
}

A 200 OK response with a RequestId confirms the script was pushed successfully.

Step 3: Query the staging environment

Run query_test_env to confirm the script is configured correctly before testing.

$./es.py action=query_test_env domain=<your domain>

Expected response

Response Code:
=============
200 OK

Response Info:
==============
{
    "DomainConfigs": [
        {
            "Status": "success",
            "ConfigId": 17432558,
            "FunctionArgs": [
                {
                    "ArgName": "enable",
                    "ArgValue": "on"
                },
                {
                    "ArgName": "pri",
                    "ArgValue": "0"
                },
                {
                    "ArgName": "pos",
                    "ArgValue": "head"
                },
                {
                    "ArgName": "rule",
                    "ArgValue": "if eq(substr($uri, -5, -1), '.m3u8') {\n    add_rsp_header('X-DEBUG-DENY-REASON', 'block m3u8')\n    exit(400)\n}\n"
                }
            ],
            "FunctionName": "dsl_ex"
        }
    ],
    "RequestId": "4DDBF3DB-BCAC-4074-AC1E-B6C1F1C6CBFB"
}
A "Status": "success" in the response confirms the script is configured in the staging environment.

Step 4: Test the script

Send a request through the staging environment to verify the script behaves as expected. Replace Staging environment IP with the actual IP address of your staging node.

$curl -x Staging environment IP:80 -o /dev/null -v 'http://www.archnote.net/test.m3u8'

Expected response headers

< HTTP/1.1 400 Bad Request
< Server: Tengine
< Date: Thu, 18 Jul 2019 09:40:41 GMT
< Content-Type: text/html
< Content-Length: 265
< Connection: close
< X-DEBUG-DENY-REASON: block m3u8
< Via: cache1.cn1191-1[,0]
< Timing-Allow-Origin: *
< EagleId: 2a7b771b15634428415537484e

A 400 Bad Request response with the X-DEBUG-DENY-REASON: block m3u8 header confirms the script is blocking M3U8 requests as intended.

Step 5: Push the script to the production environment

After verifying the script in staging, run push_product_env to promote it to production.

$./es.py action=push_product_env domain=<your domain>

Expected response

Response Code:
=============
200 OK

Response Info:
==============
{
    "RequestId": "F4B378F8-6AAE-457A-A70C-E856ED8341D8"
}

Step 6: Query the production environment

Run query_product_env to confirm the script is active in production.

$./es.py action=query_product_env domain=<your domain>

Expected response

Response Code:
=============
200 OK

Response Info:
==============
{
    "DomainConfigs": {
        "DomainConfig": [
            {
                "Status": "success",
                "ConfigId": 17432558,
                "FunctionArgs": {
                    "FunctionArg": [
                        {
                            "ArgName": "enable",
                            "ArgValue": "on"
                        },
                        {
                            "ArgName": "pri",
                            "ArgValue": "0"
                        },
                        {
                            "ArgName": "pos",
                            "ArgValue": "head"
                        },
                        {
                            "ArgName": "rule",
                            "ArgValue": "if eq(substr($uri, -5, -1), '.m3u8') {\n    add_rsp_header('X-DEBUG-DENY-REASON', 'block m3u8')\n    exit(400)\n}\n"
                        }
                    ]
                },
                "FunctionName": "dsl_ex"
            }
        ]
    },
    "RequestId": "36D57C1D-C820-43DA-8E70-DADC4B8BD4DD"
}
A "Status": "success" confirms the script is active in production. The production response uses a different JSON schema for FunctionArgs than the staging response: FunctionArgs is a JSON object containing a FunctionArg array, rather than a flat array.

What's next