---
title: "MEL Quick Reference"
slug: "mel-quick-reference"
updated: 2025-02-26T14:54:58Z
published: 2025-02-26T14:54:58Z
stale: true
---

> ## Documentation Index
> Fetch the complete documentation index at: https://docs.qwilt.com/llms.txt
> Use this file to discover all available pages before exploring further.

# MEL Quick Reference

## Introduction

You can use the CDNI Metadata Expression Language (MEL) when configuring the following site configuration features:

- [Advanced Cache Key Management](/v1/docs/z-cache-key-management)
- [Modify Origin Request](/v1/docs/modify-origin-request)
- [Modify Client Response](/v1/docs/modify-client-response)
- [Origin Selection (Modifies Client Request)](/v1/docs/origin-selection-modify-client-request)

## Source Attribution

This article includes information copied from the document **CDNI Metadata Expression Language**, for your convenience when configuring a site for content delivery. It is meant to provide a quick reference to the MEL expression syntax. The full original document is publicly available at: [https://datatracker.ietf.org/doc/draft-power-metadata-expression-language/](https://datatracker.ietf.org/doc/draft-power-metadata-expression-language/).

*Copyright (c) 2023 IETF Trust and the persons identified as the document authors. All rights reserved*.

## Quick Reference

The following is a list of the SVA Open Caching Configuration - CDNI MEL components supported by Qwilt, with descriptions provided in the subsequent sections of this document.

| Variables | Operators | Keywords | Functions |
| --- | --- | --- | --- |
| req.h.<name> req.uri req.uri.path req.uri.pathquery req.uri.query req.uri.query.<key> req.uri.querykv.<key> req.method req.scheme resp.h.<name> resp.status req.clientip req.clientport var.<user-variable> | == Equality test != Inequality test ! Logical NOT operator > Greater than test < Less than test >= Greater than or equal test <= Less than or equal *= Glob style match ~= Regular expression match + Addition - Subtraction * Multiplication / Division % Modulus . Concatenation ( ) Grouping ? : Conditional operator: <e> ? <v1> : <v2> | and or not nil true false | string(e) upper(e) lower(e) match(string Input, string Match) match_replace(string Input, string Match, string Replace) add_query(string Input, string q, string v) add_query_multi(string Input, string qvs) remove_query(string Input, string q) remove_query_multi(string Input, string qs) keep_query_multi(string Input, string qs) path_element(string Input, integer n) path_element(string Input, integer n, integer m) |

## Expression Usage in CDNI Metadata Model

> [!WARNING]
> *Source Attribution*
> 
> *The information in this section is copied from section 3 of the document*[*CDNI Metadata Expression Language*](https://datatracker.ietf.org/doc/draft-power-metadata-expression-language/)*. Copyright (c) 2023 IETF Trust and the persons identified as the document authors. All rights reserved*.

The CDNI Metadata Expression Language (MEL) provides a syntax with a rich set of variables, operators, and built-in functions to facilitate two key use cases within the CDNI metadata model:

- **Match Expressions**: Expressions that evaluate to a Boolean value are used to dynamically determine if metadata should be applied based on the evaluation of aspects of an inbound HTTP request (matching to a header value, for example).
- **Value Expressions**: Enable the dynamic construction of a value to be used in scenarios such as constructing a cache key, setting an HTTP response header or status code, rewriting a request Uniform Resource Identifier (URI), or dynamically generating a response body.

Refer to the Processing Stages Metadata Specification [SVTA 2032] for example usage of both match expressions and value expressions within the Processing Stages Model.

Refer to the Cache Control Metadata Specification [SVTA2033] for example usage of value expressions to dynamically generate cache keys.

## Core Variables

> [!WARNING]
> *Source Attribution*
> 
> *The information in this section is copied from section 5 of the document*[*CDNI Metadata Expression Language*](https://datatracker.ietf.org/doc/draft-power-metadata-expression-language/)*. Copyright (c) 2023 IETF Trust and the persons identified as the document authors. All rights reserved*.

The expression language supports two namespaces of core variables, each with a distinct prefix:

- **req.**- A prefix for accessing attributes of the HTTP request object.
- **resp.******-****A prefix for accessing attributes of the HTTP response object.

| Variable | Meaning | Type |
| --- | --- | --- |
| req.h.<name> | Request header <name> | String |
| req.uri | Request URI (includes query string and fragment identifier, if any. | String |
| req.uri.path | Request URI path | String |
| req.uri.pathquery | Request path and query string. | String |
| req.uri.query | Request query string | String |
| req.uri.query.<key> | Request query string value associated with <key>. If the key is not present in the URI, nil is returned. If the key is present with no value, as in "a=", then an empty string is returned. | String |
| req.uri.querykv.<key> | Request query string key and value associated with <key>, returned as a single string exactly as-is from the request URL. For example, when used with a URI containing a query string "key=xxx", the expression would return the string "key=xxx". When used with a URI containing a query string "key=", the expression would return the string"key=". | String |
| req.method | Request HTTP method (GET, POST, etc.) | String |
| req.scheme | Request scheme (http or https) | String |
| req.clientip | IP address of the client that made the request. Note: IPv6 addresses MUST NOT be enclosed in square brackets [ ]. | String |
| req.clientport | Request port number | Unsigned |
| resp.h.<name> | Response header <name> | String |
| resp.status | Response status code | Unsigned |

## Operators and Keywords

> [!WARNING]
> *Source Attribution*
> 
> *The information in this section is copied from section 6 of the document*[*CDNI Metadata Expression Language*](https://datatracker.ietf.org/doc/draft-power-metadata-expression-language/)*. Copyright (c) 2023 IETF Trust and the persons identified as the document authors. All rights reserved*.

> [!NOTE]
> *Note that the *ipmatch*operator is not supported by Qwilt.

### Operators

| Operator | Type | Result Type | Meaning |
| --- | --- | --- | --- |
| == | infix | Boolean | Equality test |
| != | infix | Boolean | Inequality test |
| ! | infix | Boolean | Logical NOT operator |
| > | infix | Boolean | Greater than test |
| < | infix | Boolean | Less than test |
| >= | infix | Boolean | Greater than or equal test |
| <= | infix | Boolean | Less than or equal test |
| *= | infix | Boolean | Glob style match |
| ~= | infix | Boolean | Regular expression match (See [PCRE] for details on PCRE RegEx matching/) |
| ipmatch - Not supported by Qwilt. | infix | Boolean | Match against IP address or CIDR (IPv4 and IPv6). |
| + | infix | Numeric | Addition |
| - | infix | Numeric | Subtraction |
| * | infix | Numeric | Multiplication |
| / | infix | Numeric | Division |
| % | infix | Unsigned or Integer | Modulus |
| . | infix | String | Concatenation Note: There MUST be at least 1 space before/after the dot operator. |
| ? : | ternary | * | Conditional operator: <e> ? <v1> : <v2>Evaluates <v1> if <e> is true, <v2> otherwise. |
| ( ) | grouping |  | Used to override precedence and used for function calls. |

### Keywords

| Keyword | Meaning |
| --- | --- |
| and | Logical AND |
| or | Logical OR |
| not | Logical NOT (see also the "!" operator) |
| nil | No value (distinct from empty value) |
| true | Boolean constant: true |
| false | Boolean constant: false |

## Built-In Functions

> [!WARNING]
> *Source Attribution*
> 
> *The information in this section is copied from section 7 of the document*[*CDNI Metadata Expression Language*](https://datatracker.ietf.org/doc/draft-power-metadata-expression-language/)*. Copyright (c) 2023 IETF Trust and the persons identified as the document authors. All rights reserved*.

> [!NOTE]
> *Note that the *integer*, *real*, and *Boolean*functions are not supported by Qwilt.

To enable the types of expressions typically used in content delivery scenarios to evaluate and generate or modify HTTP headers, the following set of built-in functions are defined to facilitate format conversions, matching, and query string management. Any dCDN that advertises support for a metadata property that leverages MEL MUST provide implementations of these built-in functions.

### Type Conversions

| Function | Action | Argument(s) | Returns |
| --- | --- | --- | --- |
| integer(e) - Not supported by Qwilt. | Converts expression to integer. | 1 | integer |
| real (e) - Not supported by Qwilt. | Converts expression to real. | 1 | real |
| string (e) | Converts expression to string. | 1 | string |
| boolean (e) - Not supported by Qwilt. | Converts expression to Boolean. | 1 | Boolean |

### String Conversions

| Function | Action | Argument(s) | Returns |
| --- | --- | --- | --- |
| upper (e) | Converts a string to uppercase. Useful for case-insensitive comparisons. | 1 | string |
| lower (e) | Converts a string to lowercase. Useful for case-insensitive comparisons. | 1 | string |

### Convenience Functions

| Function | Action | Args | Returns |
| --- | --- | --- | --- |
| match (string Input, string Match) | Regular expression 'Match' is applied to Input and the matching element (if any) is returned. An empty string is returned if there is no match. See [[PCRE](https://www.pcre.org/)] for details on PCRE RegEx matching. | 2 | string |
| match_replace (string Input, string Match, string Replace) | Regular expression 'Match' is applied to the Input argument and replaced with the Replace argument upon successful match. It returns the updated (replaced) version of Input. | 3 | string |
| add_query (string Input, string q, string v) | Add query string element q with value v to the Input string. If v is nil, just add the query string element q. The query element q and value v MUST conform to the format defined in [[RFC3986](https://datatracker.ietf.org/doc/html/rfc3986)]. | 2 | string |
| add_query_multi (string input, string qvs) | Add all the query value elements from qvs to the input string. For example, if qvs = "k1=v1, k2=v2, k3=v3"), parameters k1, k2, k3 and associated values would be added to input. If a qvs element only has a key but no value, the existing value of that key will be kept. | 2 | string |
| remove_query (string Input,string q) | Remove all occurrences of query string element q from the Input string. | 2 | string |
| remove_query_multi (string input, string qs) | Remove all occurrences of the query string elements referenced in parameter qs from the input string. For example, if qs= "k1, k2, k3", all occurrences of k1, k2, k3 would be removed from input. | 2 | string |
| keep_query_multi (string input, string qs) | Remove all query string elements from input except for the elements referenced in parameter qs. For example, if qs = "k1, k2, k3", all query string elements would be removed from input except for k1, k2, k3. | 2 | string |
| path_element (string Input, integer n) | Return the path element n from Input. -1 returns the last element. | 2 | string |
| path_elements (string Input, integer n, integer m) | Return the path elements from position *n*to *m*. | 3 | string |

## User-Defined Variables

> [!WARNING]
> *Source Attribution*
> 
> *The information in this section is copied from section 8 of document*[*CDNI Metadata Expression Language*](https://datatracker.ietf.org/doc/draft-power-metadata-expression-language/)*. Copyright (c) 2023 IETF Trust and the persons identified as the document authors. All rights reserved*.

In addition to the core variable namespaces that address HTTP request and response objects (req. and resp.), MEL supports user-defined variables that can be referenced via the following prefix:

- `var.` Prefix for accessing user-defined variables set via `MI.SetVariable`

  

A user defined variable is available for access in MEL expressions from the moment it is assigned, throughout the duration of the transaction. If a user variable is accessed before it has been set, it returns the value of `nil`.

### MI.SetVariable

`MI.SetVariable` is a `GenericMetadata` object that allows one to set user-defined variables that can be accessed from MEL. Variables set via this mechanism can be accessed in matching and value construction expressions using a `var.`****prefix before the variable name. Note**:** Variable names MUST be string literals.

Property: `variable-name`

- Description: The name of the variable.
- Type: String. Alphanumeric with both uppercase and lowercase characters; the property MUST start with a letter.
- Mandatory-to-Specify: Yes

Property: `variable-value`

- Description: The string representation of the value to set for the user-defined variable.
- Type: String, either the static value or a MEL expression, determined by the `value-is-expression` property.
- Mandatory-to-Specify: Yes

Property: `value-is-expression`

- Description: A flag to signal whether the value is a static string literal or a MEL expression that needs to be dynamically evaluated.
- Type: Boolean
- Mandatory-to-Specify: No. The default is "False", indicating that the value is a string literal and does not need to be evaluated.

  

The following example illustrates the setting of a user-defined variable whose value is a MEL expression suffixed by a static literal string:

```json
{
  "generic-metadata-type": "MI.SetVariable",
  "generic-metadata-value": {
    "variable-name": "myvar",
    "variable-value": "req.h.host . 'is my host from player'"
    "value-is-expression": true
  }
}
```

The following example illustrates the setting of a user-defined variable whose value is another user-defined variable suffixed by a static literal string:

```json
{
  "generic-metadata-type": "MI.SetVariable",
  "generic-metadata-value": {
    "variable-name": "myvar1",
    "variable-value": "req.host . 'is my host from player'"
    "value-is-expression": true
  }
}
{
  "generic-metadata-type": "MI.SetVariable",
  "generic-metadata-value": {
    "variable-name": "myvar2",
    "variable-value": "var.myvar1 . 'and forwarded to Origin'"
    "value-is-expression": true
  }
}
```
