Rules Engine for Edge Application
Rules Engine is an Edge Application feature that handles the conditional execution of behaviors through logical operators. By using Rules Engine, you can build an architecture that provides better performance to your users while consuming fewer resources by processing at the edge.
Each request made to an application built with Azion Real-Time Manager (RTM) is processed in a fixed sequence of two phases:
- Request Phase: takes place when a user submits a request to the edge application.
- Response Phase: occurs when a user receives a response from the edge application.
At each processing phase, you can define a set of rules to handle the request according to the needs of your application. Once you’ve selected in which of the two phases your rule will be executed, you’ll be able to create a new rule.
Rules are designed to follow a conditional if-then logic. Every rule is composed of Criteria (if) that will define the set of conditions that must be met for the execution of Behaviors (then).
To trigger the intended behaviors for your application, you may employ variables, comparison operators, and logical operators. If the given conditions are met, the behaviors associated with each rule are executed sequentially until all the rules have been processed.
Implementation
Section titled ImplementationScope | Resource |
---|---|
Edge Application first steps | First steps |
Creating a rule | Creating rules using Rules Engine for Edge Application |
Creating a cache setting | How to configure cache policies for Edge Application |
Mitigating HTTPoxy using rules | How to mitigate the HTTPOxy vulnerability |
Processing phases
Section titled Processing phasesWhen creating a rule, you’ll be prompted to select one of the two available processing phases: Request Phase or Response Phase.
Request Phase
Section titled Request PhaseDuring the Request Phase, the edge handles end-user requests. For Request Phase rules, any variables associated with the data provided by the user in the request can be utilized. However, variables related to the content that will be delivered to the user in this phase aren’t accessible, as the response hasn’t been processed by the application yet.
Additionally, it’s in the Request Phase that you determine how your application will cache the content. If your application doesn’t permit any form of caching, you have the option to define the conditions under which caching should be disregarded.
Response Phase
Section titled Response PhaseDuring the Response Phase, your application delivers data to end-users. All handling processes in this phase are dynamic, and each user’s delivery is performed independently based on their specific requirements.
Description
Section titled DescriptionAside from the name of the rule, you can add a description to your rule using the Description field. Your description will be visible from the rule list and can be used to help you identify what the rule does.
Criteria
Section titled CriteriaThe Criteria section of Rules Engine is where you define the conditions for executing the rule. Criteria are composed of:
- variables
- comparison operators
- arguments, when applicable
The inclusion of arguments in a criteria depends on the comparison operators chosen. The format of the arguments is described in the variables and comparison operators sections below. You can also add logical operators to increase the amount of comparisons that the rule will execute.
For example, this criteria identifies whether a user is accessing your application via a desktop web browser using a regular expression as an argument:
Variable | Comparison operator | Argument | |
---|---|---|---|
If | ${http_user_agent} | matches | (Chrome|Mozilla) |
Variables
Section titled VariablesCheck the full list of variables available and their processing phase:
Variable | Description | Available for |
---|---|---|
${arg_name} | The name argument sent by the user on the request line (query string). For example: for the GET /path?Search=test request, the variable will assume the value test . | Request Phase Response Phase |
${args} | All arguments sent by the user in the request string (query string). For example: for the GET /path?Search=test request, the variable will assume the value Search=test . | Request Phase Response Phase |
${cookie_name} | Value of the cookie name. For example, for cookie_icl_current_language = pt-br , the variable ${cookie_icl_current_language} will assume the value pt-br . | Request Phase Response Phase |
${device_group} | Device group name. You can customize your device groups in the Device Groups tab of your application in Real-Time Manager. | Request Phase Response Phase |
${domain} | Similar to the ${host} variable. Stores the host name or the Host header from the request, excluding the last subdomain after the second-level domain. For example, for a domain az.blog.domain.com , this variable carries the value blog.domain.com . | Request Phase Response Phase |
${geoip_city} | Name of the city, using the geolocation base geoip_city . For example: Sao Paulo , London . | Request Phase Response Phase |
${geoip_city_continent_code} | 2-letter continent code, using the geolocation base geoip_city . For example: EU for Europe, NA for North America. | Request Phase Response Phase |
${geoip_city_country_code} | 2-letter country code, using the geolocation base geoip_city . For example: RU for Russia, BR for Brazil. | Request Phase Response Phase |
${geoip_city_country_name} | Name of the country, using the geolocation base geoip_city . For example: United States , Brazil . | Request Phase Response Phase |
${geoip_continent_code} | 2-letter continent code. For example: EU for Europe, NA for North America. | Request Phase Response Phase |
${geoip_country_code} | 2-letter country code, using the geolocation base geoip_country . For example: RU for Russia, BR for Brazil. | Request Phase Response Phase |
${geoip_country_name} | Name of the country, using the geolocation base geoip_country . For example: United States , Brazil . | Request Phase Response Phase |
${geoip_region} | 2-letter region code. For example: RS for Rio Grande do Sul, ON for Toronto. | Request Phase Response Phase |
${geoip_region_name} | Name of the country, using the geolocation base geoip_region . For example: Ontario , Sao Paulo . | Request Phase Response Phase |
${host} | In order of precedence: the host name of the request line, or the value of the Host header field of the request, or the name of the server serving the request. For example: blog.domain.com . | Request Phase Response Phase |
${http_name} | The value of a request header. name must be a valid HTTP request header converted to lowercase; hyphens must be converted to underscore. For example: ${http_accept} will take the value of the Accept header of the HTTP request field. | Request Phase Response Phase |
${remote_addr} | The IP address of the client performing the HTTP request. | Request Phase Response Phase |
${remote_port} | The HTTP port being used in the request URL of the client. | Request Phase Response Phase |
${remote_user} | The username provided by basic authentication, if any. | Request Phase Response Phase |
${request} | Original first request line of the client request. It’s composed of the request method, the request URI, and the HTTP version. For example: GET /path HTTP/2.0 . | Request Phase Response Phase |
${request_method} | The HTTP method of the request. For example: GET . | Request Phase Response Phase |
${request_uri} | The complete URI of the request, with arguments (query string). Special UTF-8 characters are URL encoded. For example: /path?var=value%20of%20var . | Request Phase Response Phase |
${scheme} | The scheme of the request. For example: http or https . | Request Phase Response Phase |
${sent_http_name} | The value of the response header field name. The name argument must be converted to lowercase and the hyphens must be converted to underscore. For example: for a header Content-Length: 9593 , the variable ${sent_http_content_length} will assume the value 9593 . | Response Phase |
${server_addr} | The IP address of the server that’ll be receiving the HTTP request. For example: 200.0.0.0 | Request Phase |
${server_port} | The HTTP port of the server that’ll be receiving the request. For example: 8080 . | Request Phase |
${status} | Status code of the response. For example: 200 . | Response Phase |
${tcpinfo_rtt} | Round-Trip Time (RTT) of the client’s TCP connection, in microseconds. For example: 24763 . | Response Phase |
${upstream_addr} | The IP address and port of the queried origin for obtaining the response. If many origins are consulted during the processing of the request, the addresses will be separated by a comma (, ). For example: 192.168.1.1:80, 192.168.1.2:80 . If an internal redirect from one group of servers to another occurs, initiated by an X-Accel-Redirect or an error page, the addresses of the different groups will be separated by a colon (: ). For example: 192.168.1.1:80, 192.168.1.2:80 : 192.168.10.1:80, 192.168.10.2:80 . | Response Phase |
${upstream_cookie_name} | Value of cookie name sent by the origin using the Set-Cookie header field. If many origins are consulted while the request is processed, only cookies from the last origin are stored. | Response Phase |
${upstream_http_name} | Value of the name header field sent by the origin. The name argument must be converted to lowercase and the hyphens must be converted to underscore. If many origins are consulted while the request is processed, only headers from the last origin are stored. For example: ${upstream_http_server} will assume the value of the Server header field sent by the last queried origin. | Response Phase |
${upstream_status} | Status code of the origin response sent to RTM. If many origins are consulted while the request is processed, the status codes will be separated by a comma (, ). If an internal redirect from one group of servers to another is initiated by an X-Accel-Redirect or an error page, the status codes of the different groups will be separated by a colon (: ). | Response Phase |
${uri} | The normalized (URL decoded) URI of the request. For example: /path/my file.txt The value of ${uri} can change during the processing of a request, for example, when an internal redirect occurs or when index files are used. For query string parameters and URL encoded characters, use ${request_uri} . | Request Phase Response Phase |
Mutual Transport Layer Security (mTLS) variables
Section titled Mutual Transport Layer Security (mTLS) variablesAdd these variables inside the Rules Engine of your edge application to configure Mutual Transport Layer Security (mTLS). mTLS variables are only available for the Request Phase.
Variable | Description |
---|---|
${ssl_client_fingerprint} | Returns the Secure Hash Algorithm 1 (SHA-1) of the client certificate. |
${ssl_client_escaped_cert} | Returns the client certificate in Private Enhanced Mail (PEM) format as URL encoded string. |
${ssl_client_s_dn} | Returns the “subject DN” string of the client certificate. |
${ssl_client_s_dn_parsed} | Returns the extracted “subject CN” value of the client certificate. |
${ssl_client_cert} | Returns the client certificate (PEM format). This variable is deprecated. Use $ssl_client_escaped_cert instead. |
${ssl_client_i_dn} | Returns the “issuer DN” string of the client certificate. |
${ssl_client_serial} | Returns the serial number of the client certificate. |
${ssl_client_v_end} | Returns the end date (expiration date) of the client certificate. |
${ssl_client_v_remain} | Returns the number of days until the client certificate expires. |
${ssl_client_v_start} | Returns the start date of the client certificate. |
${ssl_client_verify} | Returns the result of the client certificate verification. It can be SUCCESS , FAILED:reason , or NONE . |
Variables as arguments
Section titled Variables as argumentsFor behaviors that require an argument, you can use the same variables available for the processing phase in which they’re available. This way, you can, for example, compose cookies or HTTP headers using data collected during the request phase, such as the user’s device group or their geolocation.
For example, for the following rule in the Response Phase:
If
${host}
is equalmyhost.com
Then Add Response Cookiecookie-host-value=${host}
When this rule is active, if the request is made from the host determined in the criteria, the response will return the following header: Set-Cookie: cookie-host-value=myhost.com
.
Azion also provides special variables that act as functions and take arguments. The following variables can be used to compose Behavior arguments:
Variable | Description |
---|---|
${cookie_time_offset(number)} | Returns the current date plus an offset in seconds, entered as an argument, to be used to define the expiration time of a cookie. For example, if you want the cookie to expire in 1 hour from the time it’s created, use the Add Response Cookie behavior with the argument: cookie-name=cookie-value; Expires=${cookie_time_offset(3600)} |
${encode_base64(string)} | Returns the arguments coded in base64. For example: ${encode_base64(http://www.yourdomain.com/)} will return the value d3d3LmRvbWFpbi5jb20K |
Comparison Operators
Section titled Comparison OperatorsOperator | Description | Argument type |
---|---|---|
is equal | The value of the variable is exactly the same as the argument. | string |
is not equal | The value of the variable isn’t the same as the argument. | string |
starts with | The value of the variable starts with the argument. | string |
does not start with | The value of the variable doesn’t start with the argument. | string |
matches | The value of the variable matches the regular expression entered as an argument. | regular expression |
does not match | The value of the variable doesn’t match the regular expression entered as an argument. | regular expression |
exists | The variable has a defined value. For example: ${arg_search} exists if a search argument was sent in the request query string. | - |
does not exist | The variable doesn’t have a defined value. For example: ${arg_search} doesn’t exist if a search argument wasn’t sent in the request query string. | - |
Logical operators
Section titled Logical operatorsMultiple criteria can be defined using the logical operators AND and OR. Each rule can have up to 10 criteria.
The operator AND has implicit precedence over the operator OR. If explicit precedence is required, you can add more criteria groups using the AND operator only.
Behaviors
Section titled BehaviorsIn the Behaviors section of the Rules Engine, you must add the behaviors you want your rule to perform if the conditions defined in the criteria are met.
For example, this behavior redirects the user to an English version of an FAQ location:
Behavior | Argument |
---|---|
Redirect To (302 Found) | /en-us/faq |
Each rule can perform up to 10 behaviors.
Add Cookie
Section titled Add CookieRequest Phase Response Phase Requires Application Acceleration
Allows you to add a cookie in the Set-Cookie
HTTP header. The cookie must be inputted as an argument in the format cookie-name=cookie-value
. You may use a variable as a cookie value in the format cookie-name=${arg_cookie}
.
For cookies in the Response Phase, the following Set-Cookie policies can be added to the argument, after the cookie value and separated by a semicolon (;
):
Expires=date
(EEE, d MMM yyyy HH:mm Z)Domain=domain-value
Path=path-value
Max-age=number
(TTL in seconds, takes precedence overExpires
)SameSite=value; Secure
HttpOnly
Multiple policies for the same cookie can be separated by semicolons (;
). For example: cookie-name=cookie-value; Domain=domain-value; Path=path-value; SameSite=value
.
You may also use variables as a cookie or policy value, for example: Path=${uri}; Domain=${host}
.
Add Header
Section titled Add HeaderAdds a header field to the request that will be sent to the origin or to the response that will be sent to the user.
The header field must be informed as an argument in the format Field: value
.
Bypass Cache
Section titled Bypass CacheRequest Phase Requires Application Acceleration
Defines that Azion shouldn’t cache the response from its origin. The execution of this rule has no impact on the cache in the users’ browser, which must be defined using the Set Cache Policy behavior.
By using Bypass Cache, you’ll configure Azion’s service to forward all requests to a path directly to their origin. However, you’ll count on important protocol optimizations to speed up your application and a keepalive connection between Azion edge nodes and their origin whenever possible.
See the guide on How to configure cache policies for Edge Application for more information on Bypass Cache.
Difference between Bypass Cache and TTL 0
Section titled Difference between Bypass Cache and TTL 0While both the Bypass Cache behavior and Maximum TTL at zero seconds allow you to optimize content delivery and reduce load times at the origin, their effects are a bit different.
By using the Bypass Cache behavior, all HTTP and HTTPS requests received by Azion’s edge nodes will be sent to the origin, without caching any content. Use Bypass Cache if you want to deliver different content for each user request.
However, when setting TTL to 0 (zero) seconds, multiple requests in parallel to Azion’s edge nodes will be sent as a single request to their origin. In this case, Azion’s edge nodes also validate changes to the content with its origin by using the If-Modified-Since parameter. If the object hasn’t changed since the last request, the content won’t need to be transferred again, which could result in a much faster 304 Not Modified response. Also, setting maximum cache TTL to 0 will still generate a cache object that lives for 999 milliseconds.
Capture Match Groups
Section titled Capture Match GroupsRequest Phase Requires Application Acceleration
Support behavior for handling strings. Stores in a temporary variable the result of capturing correspondence groups defined by a regex applied to one of the available HTTP request fields. This temporary variable can be referenced later in the behavior Rewrite Request to assemble the rewrite string.
This behavior requires three arguments:
- captured array name: the name you want to give to the temporary variable where the array of captured strings will be stored.
- subject: the HTTP request field where you want to capture a string.
- regex: the regular expression used to capture the strings. Each captured group must be represented in parentheses.
For example, to capture the path and name of a file in an HTTP request, you could use:
- captured array name:
capture
- subject:
${uri}
- regex:
^(./)([^/])$
You may reference the capture variable as an array by using the notation %{variable[index]}
. Because it’s a local variable, you can only use it within the same rule you are setting up. In this example, if the URI is /path/image.jpg
, the capture variable will have the following values:
%{capture[0]} = "/path/image.jpg"
%{capture[1]} = "/path/"
%{capture[2]} = "image.jpg"
You can also name the indexes to reference them using names instead of a numeric index. To do so, use the ?<name>
notation as in the example:
- captured array name:
capture
- subject:
${uri}
- regex:
^(?<path>.*/)(?<filename>[^/]*)$
Deliver
Section titled DeliverFinishes processing the request and delivers the content to the user, without executing any of the rules added later. You’re forcing the processing to end immediately.
Deny (403 Forbidden)
Section titled Deny (403 Forbidden)Delivers a 403 Forbidden page to the user. Ends the request processing.
Enable Gzip
Section titled Enable GzipEnables Gzip data compression, if supported by the user’s browser. See the guide on How to enable gzip compression for more information.
Enable Sliced Files
Section titled Enable Sliced FilesRequest Phase Requires Edge Caching
Enables segmentation of large objects into 1MB slices, if their origin supports HTTP range requests. You can use this behavior to optimize the performance of your website or application. If you deliver media larger than 1MB sliced through Azion, the content reaches users before the edge has received the entire object from its origin.
When activating this functionality, Azion will request the objects for their origin via range requests and they’ll be cached in Azion with Advanced Cache Key.
If your origin doesn’t support range requests, Azion will only be able to start delivering your content to its users after your origin has finished the complete sending of the object.
Enforce HLS cache
Section titled Enforce HLS cacheThis behavior is automatically included by Azion every time you select a Live Ingest source. Two actions are performed in this situation: the bypass of all your Cache Phase rules and the imposition of the cache policy defined by Azion for live transmissions in HLS.
Azion’s cache policy for live HLS streams is 5 seconds of cache for playlists (.m3u8
) and 60 seconds of cache for chunks (.ts
).
Filter Cookie
Section titled Filter CookieRequest Phase Response Phase Requires Application Acceleration
Removes a cookie from the request header that would be sent to the origin or from the response header that would be sent to the user. As an argument, add the name of the cookie you want to remove as cookie-name
.
To remove only specific values, you must inform the name and value of the cookie as cookie-name=cookie-value
.
Filter Header
Section titled Filter HeaderRemoves a request header that would be sent to the origin or a response header that would be sent to the user. The name of the header field must be entered as an argument, for example: Header-Name
.
Finish Request Phase
Section titled Finish Request PhaseFinishes the request phase. Any behavior or other rules under this behavior won’t be executed.
Forward Cookies
Section titled Forward CookiesRequest Phase Requires Application Acceleration
By using the Forward Cookies behavior, you’re determining that Azion forwards to its users the Set-Cookie
header received from its origin, even when cached content is identified (HIT).
To prevent a user from receiving the Set-Cookie
header from another user’s session, see the guide on cache policies.
JavaScript Cookies
Section titled JavaScript CookiesAn alternative to sending the response header Set-Cookie
is to create cookies using JavaScript, which allows you to create, read, and expire cookies through the document.cookie
property.
A JavaScript cookie should have the following format:
document.cookie = "username=John Doe; expires=Thu, 18 Dec 2020 12:00:00 UTC; path=/";
By default, Azion won’t filter the request header Cookie
regardless of its Forward Cookies configuration and therefore JavaScript Cookies may be sent to the origin to enable the management of your application.
No Content (204)
Section titled No Content (204)Returns a 204
code when accessing the edge application instead of the code received from the origin.
Optimize Images
Section titled Optimize ImagesRequest Phase Requires Image Processor
Enables Image Processor.
Redirect HTTP to HTTPS
Section titled Redirect HTTP to HTTPSRequest Phase Requires HTTPS application
Redirects the HTTP request to HTTPS. If the request is already made through HTTPS, the behavior isn’t executed.
Redirect To
Section titled Redirect ToRedirect to (301 Moved Permanently) and Redirect To (302 Found) redirect the user to the URL or URI entered as an argument, returning the corresponding status code.
It’s recommended using these behaviors for path changes; 301 Moved Permanently for permanent changes and 302 Found for temporary changes.
Both behaviors end the request processing phase.
Rewrite Request
Section titled Rewrite RequestRequest Phase Requires Application Acceleration
Modifies the resource path that will be requested for the origin. You can rewrite the resource path using:
- A string.
- The requisition variables (which can also be used in Criteria).
- The local variables, in the format
%{name [index]}
, with the result of capturing strings, when using the auxiliary behavior Capture Match Groups.
For example, to rewrite a user request for the /original/image.jpg
resource to be sent to its origin as /new/image.jpg
:
- Use the Capture Match Groups behavior with the arguments:
- captured array name:
capture
- subject:
${uri}
- regex:
/original/(.)
- Use the Rewrite Request behavior with the argument
/new/%{capture[1]}
.
Run Function
Section titled Run FunctionRequest Phase Response Phase Requires Application Acceleration Requires Edge Functions
Runs a function created using Edge Functions and instantiated in the Edge Functions tab for the edge application. See the guide on How to run serverless functions for more information.
Set Cache Policy
Section titled Set Cache PolicyAssigns the cache policy that should be used for the request. You must first set up the cache policies in Cache Settings.
You can set up the time that an object will be stored in cache and the rules for the variation of objects in cache with the Advanced Cache Key.
Set Origin
Section titled Set OriginAssigns an origin that must be consulted by the edge node for the request.
Before configuring this behavior, you must set up your origins using Origins.
Debugging rules
Section titled Debugging rulesYou can debug rules created with Rules Engine created in Rules Engine for Edge Application through the GraphQL API, Data Streaming, or Real-Time Events.
Contributors