EdgeScript provides built-in functions for manipulating HTTP request and response headers, rewriting or redirecting URIs, outputting response bodies, and setting cookies. This reference covers each function's syntax, parameters, return values, and examples.
Jump to:
Request headers:
add_req_header,del_req_headerResponse headers:
add_rsp_header,del_rsp_header,get_rsp_headerURL rewrite and redirect:
rewriteResponse body:
say,print,exitCookies:
add_rsp_cookieEncoding:
encode_args,decode_args
Request headers
add_req_header
Adds a request header before the request is forwarded to the origin server.
Syntax
add_req_header(name, value [, append])Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
name | string | Yes | Name of the request header to add. |
value | string | Yes | Value of the request header to add. |
append | Boolean | No | Whether to append the header if a header with the same name already exists. Default: false. If false, the new value overwrites the existing value. |
Return value
Returns true by default. Returns false if the header name is invalid.
Example
add_req_header('USER-DEFINED-REQ-1', '1')
add_req_header('USER-DEFINED-REQ-1', 'x', true)
add_req_header('USER-DEFINED-REQ-2', '2')
del_req_header('USER-DEFINED-REQ-2')Result: the origin server receives the following headers:
USER-DEFINED-REQ-1: 1
USER-DEFINED-REQ-1: xUSER-DEFINED-REQ-2 is added and then deleted, so it is not forwarded to the origin server.
del_req_header
Deletes a request header before the request is forwarded to the origin server.
Syntax
del_req_header(name)Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
name | string | Yes | Name of the request header to delete. |
Return value
Returns true by default. Returns false if the header name is invalid.
Example
add_req_header('USER-DEFINED-REQ-1', '1')
add_req_header('USER-DEFINED-REQ-1', 'x', true)
add_req_header('USER-DEFINED-REQ-2', '2')
del_req_header('USER-DEFINED-REQ-2')Result: the origin server receives the following headers:
USER-DEFINED-REQ-1: 1
USER-DEFINED-REQ-1: xUSER-DEFINED-REQ-2 is added and then deleted, so it is not forwarded to the origin server.
Response headers
add_rsp_header
Adds a response header.
Syntax
add_rsp_header(name, value [, append])Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
name | string | Yes | Name of the response header to add. |
value | string | Yes | Value of the response header to add. Supports dynamic expressions: ${x} is replaced with the value of ngx.var.x; @{y} is replaced with the value of response header y. |
append | Boolean | No | Whether to append the header if a header with the same name already exists. Default: false. If false, the new value overwrites the existing value. |
Return value
Returns true by default. Returns false if the header name is invalid.
Example
add_rsp_header('USER-DEFINED-RSP-1', '1')
add_rsp_header('USER-DEFINED-RSP-1', 'x', true)
add_rsp_header('USER-DEFINED-RSP-2', '2')
del_rsp_header('USER-DEFINED-RSP-2')Result: the response includes the following headers:
USER-DEFINED-RSP-1: 1
USER-DEFINED-RSP-1: xUSER-DEFINED-RSP-2 is added and then deleted, so it is not included in the response.
del_rsp_header
Deletes a response header.
Syntax
del_rsp_header(name)Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
name | string | Yes | Name of the response header to delete. |
Return value
Returns true by default. Returns false if the header name is invalid.
Example
add_rsp_header('USER-DEFINED-RSP-1', '1')
add_rsp_header('USER-DEFINED-RSP-1', 'x', true)
add_rsp_header('USER-DEFINED-RSP-2', '2')
del_rsp_header('USER-DEFINED-RSP-2')Result: the response includes the following headers:
USER-DEFINED-RSP-1: 1
USER-DEFINED-RSP-1: xUSER-DEFINED-RSP-2 is added and then deleted, so it is not included in the response.
get_rsp_header
Retrieves a response header value.
Syntax
get_rsp_header(str)Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
str | string | Yes | Name of the response header to retrieve. |
Return value
If the header exists: returns the header value as a string, number, dictionary, or Boolean.
If the header does not exist: returns
false.
Example
ct = get_rsp_header('content-type')
if ct {
add_rsp_header('origin-content-type', 'is')
} else {
add_rsp_header('origin-content-type', 'no')
}URL rewrite and redirect
rewrite
Rewrites the URI or redirects the request.
Syntax
rewrite(url, flag, code)Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
url | string | Yes | Target URI or URL after the rewrite or redirect. |
flag | string | Yes | Rewrite mode. See the flag reference table below. |
code | numeric | No | HTTP status code for the redirect. Applies only when flag is redirect or enhance_redirect. Valid values: 301, 302, 303, 307, 308. Default: 302. |
Flag reference
Use this table to choose the right flag for your use case:
| URI only | URI + query parameters | |
|---|---|---|
| Server-side rewrite (no redirect, URL in browser unchanged) | break | enhance_break |
| Client-side redirect (browser makes a new request, URL changes) | redirect | enhance_redirect |
Return value
Rewrite operation (
break,enhance_break): returnstrue.Redirect operation (
redirect,enhance_redirect): no return value.
Examples
Server-side rewrite (URI + parameters)
if and($arg_mode, eq($arg_mode, 'rewrite:enhance_break')) {
rewrite('/example/examplefile.txt?k=v', 'enhance_break')
}The origin server receives the request with the URI and query parameters rewritten to /example/examplefile.txt?k=v.
Client-side redirect (URI + parameters)
if and($arg_mode, eq($arg_mode, 'rewrite:enhance_redirect')) {
rewrite('/example/examplefile.txt?k=v', 'enhance_redirect')
}
if and($arg_mode, eq($arg_mode, 'rewrite:enhance_redirect_301')) {
rewrite('/example/examplefile.txt?k=v', 'enhance_redirect', 301)
}The client receives a 302 or 301 redirect to /example/examplefile.txt?k=v.
Server-side rewrite (URI only)
if and($arg_mode, eq($arg_mode, 'rewrite:break')) {
rewrite('/example/examplefile.txt', 'break')
}The origin server receives the request with the URI rewritten to /example/examplefile.txt. The original query parameters are preserved.
Client-side redirect (URI only)
if and($arg_mode, eq($arg_mode, 'rewrite:redirect')) {
rewrite('/example/examplefile.txt', 'redirect')
}
if and($arg_mode, eq($arg_mode, 'rewrite:redirect_301')) {
rewrite('/example/examplefile.txt', 'redirect', 301)
}The client receives a 302 or 301 redirect to /example/examplefile.txt. The original query parameters are preserved.
Response body
say
Prints content to the response body and appends a newline character.
Syntax
say(arg)Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
arg | any | Yes | Content to write to the response body. |
Return value
None.
Example
say('hello')
print('byebye')
print('byebye')Output:
hello
byebyebyebyePrints content to the response body without appending a newline character.
Syntax
print(arg)Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
arg | any | Yes | Content to write to the response body. |
Return value
None.
Example
say('hello')
print('byebye')
print('byebye')Output:
hello
byebyebyebyeexit
Terminates the current request with the specified HTTP status code and an optional response body.
Syntax
exit(code [, body])Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
code | numeric | Yes | HTTP status code to return. |
body | any | No | Response body to include in the response. |
Return value
None.
Examples
Example 1: block requests based on query parameters and cookies
if not($arg_key) {
exit(403)
}If the request does not include the key query parameter, the CDN node returns HTTP 403.
if not($cookie_user) {
exit(403, 'not cookie user')
}If the request does not include the user cookie, the CDN node returns HTTP 403 with the response body not cookie user.
if not(0) {
exit(403)
}not(0) evaluates to false, so this block does not execute.
if not(false) {
exit(403)
}not(false) evaluates to true, so the CDN node returns HTTP 403.
Example 2: URI-based authentication
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-TENGINE-ERROR', 'auth failed - missing necessary uri set')
exit(403)
}
digest = md5(concat(sec1, sec3))
if ne(digest, sec2) {
add_rsp_header('X-TENGINE-ERROR', 'auth failed - invalid digest')
exit(403)
}This example extracts segments from the request URI, computes an MD5 digest, and validates it against an embedded signature. If the URI is malformed or the digest does not match, the CDN node returns HTTP 403 with an error header.
Cookies
add_rsp_cookie
Sets a cookie in the response. Each call generates a new Set-Cookie response header.
Syntax
add_rsp_cookie(k, v [, properties])Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
k | string | Yes | Name of the cookie. |
v | string | Yes | Value of the cookie. |
properties | dictionary | No | Cookie attributes such as path, domain, secure, httponly, expires, max_age, samesite, and extension. For the full attribute reference, see Set-Cookie. |
Return value
Returns true if the cookie is set. Returns false if the cookie could not be set.
Example
add_rsp_cookie('user', 'edgescript')
add_rsp_cookie('login_time', tostring(now()), [
'path' = '/'
])
expires = cookie_time(time())
add_rsp_cookie('psid', 'SDF93745HFSDF2934JKHG', [
'path' = '/play',
'domain' = 'foo.com',
'secure' = true,
'httponly' = true,
'expires' = expires,
'max_age' = 100,
'samesite' = 'Strict',
'extension' = 'xxt3s'
])The response includes the following Set-Cookie headers:
Set-Cookie: user=edgescript
Set-Cookie: login_time=1582538968.912; Path=/
Set-Cookie: psid=SDF93745HFSDF2934JKHG; Expires=Mon, 24-Feb-20 10:09:28 GMT; Max-Age=100; Domain=foo.com; Path=/play; Secure; HttpOnly; SameSite=Strict; xxt3sEncoding
encode_args
Converts key-value pairs in a dictionary to a URI-encoded string in k1=v1&k2=v2 format.
Syntax
encode_args(d)Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
d | dictionary | Yes | Dictionary to encode. |
Return value
Returns a URI-encoded string.
Example
encode_args and decode_args are typically used together. The following example encodes a dictionary, sets it as a response header, then decodes it and reads individual values:
my_args = []
set(my_args, 'signature', 'da9dc4b7-87ae-4330-aaaf-e5454e2c2af1')
set(my_args, 'algo', 'private sign1')
my_args_str = encode_args(my_args)
add_rsp_header('X-DSL-ENCODE-ARGS', my_args_str)
to_args = decode_args(my_args_str)
if get(to_args, 'algo') {
add_rsp_header('X-DSL-DECODE-ARGS-ALGO', get(to_args, 'algo'))
}
if get(to_args, 'signature') {
add_rsp_header('X-DSL-DECODE-ARGS-SIGN', get(to_args, 'signature'))
}The response includes the following headers:
X-DSL-ENCODE-ARGS: signature=da9dc4b7-87ae-4330-aaaf-e5454e2c2af1&algo=private%20sign1
X-DSL-DECODE-ARGS-ALGO: private sign1
X-DSL-DECODE-ARGS-SIGN: da9dc4b7-87ae-4330-aaaf-e5454e2c2af1decode_args
Converts a URI-encoded string in k1=v1&k2=v2 format to a dictionary.
Syntax
decode_args(s)Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
s | string | Yes | URI-encoded string to decode. |
Return value
Returns a dictionary converted from the string.
Example
See the encode_args example above. decode_args is the inverse operation and is used together with encode_args.