DataScripts can be used to inspect client HTTP requests or server HTTP responses and perform content switching, redirection, header manipulation, logging, and more. The below table lists the available HTTP DataScripts on NSX Advanced Load Balancer.
String |
Description |
---|---|
Insert a new cookie. |
|
Insert a new header and value. |
|
Close or reset a TCP connection. |
|
Validate if a cookie already exists. |
|
Upgrade (disable) HTTP processing for the current connection, which will subsequently be treated as layer 4 TCP. |
|
Return the values of a cookie. |
|
Return the names of cookies. |
|
Return header names or their values. |
|
Return a subsection of the host. |
|
Returns the URI's path /path.index.htm. |
|
Return a subsection of the path. |
|
avi.http.get_query( [arg_name | avi.QUERY_TABLE] [, decode] ) |
Return the URI's query |
Returns part or the entire portion of the client request body. |
|
Returns the request ID. |
|
Gets (reads) data stored in a variable through the |
|
Gets (reads) a specified number of kilobytes from the buffered response body starting at the specified kilobyte offset. |
|
Returns the URI (path plus query). |
|
Returns the user ID for the session. |
|
Return the hostname requested by client. |
|
Returns HTTP status as a string. |
|
Return the client's request method. |
|
Returns the session protocol, http or https. |
|
Extracts the token of TOKEN_TYPE from the user’s OAuth session. |
|
Redirect a request. |
|
Remove an existing cookie. |
|
Remove all instances of a header. |
|
Replace value of an existing cookie. |
|
Replace an existing header's value. |
|
Sends a defined HTTP response page. |
|
Returns a string of the decrypted SAML session cookie if it exists; else nil. |
|
Returns |
|
Returns |
|
Modifies the path of a request. |
|
Modifies the query of a request. |
|
Sets (write) arbitrary data from an HTTP request event into a variable. These variables have scope across the |
|
Sets the maximum response body to be buffered. |
|
Sets a custom timeout value for a particular request. |
|
Changes the URI. |
|
Sets the user ID for the session. |
|
Returns status code to be sent to the client. |
|
Modifies the existing cookie attributes value in the HTTP response. |
|
Disables the client authentication. |
avi.http.add_cookie
Function |
avi.http.add_cookie( table ) |
Description |
Insert a new cookie or cookies into the HTTP request or response. If the cookie already exists, the VMware NSX Advanced Load Balancer appends the specified value or flags to the existing cookie. |
Events |
|
|
|
Parameter |
A table of cookie name-value pairs for HTTP request context and optionally additional cookie attribute value pairs such as path, domain, etc. for HTTP response. |
Request Parameter |
HTTP Request event: The cookie name-value pairs are added to the cookie header of the HTTP request, and if no such header exists, the cookie header is added.
name is the name of the new cookie. value is the value or data field of the new cookie. In the HTTP request context, all arguments are treated as cookie name-value pairs, i.e. the function ignores cookie attributes such as "Domain", "Path", etc. and treats them as another cookie to be added. |
Response Parameter |
HTTP Response event: When called in an HTTP response context, the cookie name-value pairs are added in the Set-Cookie header of the HTTP response. If no such header exists, the Set-Cookie header is created. In the HTTP response context, only the first two arguments are treated as cookie name-value pairs and the subsequent arguments are interpreted as cookie attributes such as Domain, Path, etc. and their corresponding values.
name is the name of the new cookie. value is the value or data field of the new cookie. path is the value (a string) of the path attribute. domain is the value (a string) of the domain attribute. expires is the value (an integer) of the expires attribute. maxage is the value (an integer) of the maxage attribute. httponly is the value (a boolean) of the httponly attribute. secure is the value (a boolean) of the secure attribute. |
Returns |
None. |
HTTP Request Example |
Example method 1: Add two cookies: jsessionid=123 and lang=en cookie_table = {jsessionid="123", lang="en"}avi.http.add_cookie( cookie_table ) Example method 2: Add two cookies: jsessionid=123 and lang=en avi.http.add_cookie( "jsessionid", "123", "lang", "en" ) |
HTTP Response Example |
Example 1: Add the cookie jsessionid with value 123, and attributes of path=/ and domain=www.avinetworks.com to produce the following header in the HTTP response: Set-Cookie: jsessionid=123; path=/;domain=www.avinetworks.com cookie_table = {jsessionid="123", path="/", domain="www.avinetworks.com"} avi.http.add_cookie( cookie_table ) Example 2: In this format, the order matters. The third, fourth, fifth, sixth, seventh and eighth arguments must be path, domain, expires, maxage, httponly flag and secure flag , respectively. avi.http.add_cookie( "jsessionid", "123", "/", "www.avinetworks.com" ) If expires and maxage attributes are not needed, values 0 are passed as an argument. avi.http.add_cookie( "jsessionid", "123", "/", "a.b.c", 0, 0, true, true) |
avi.http.add_header
Function |
avi.http.add_header( name, value ) |
Description |
Adds a header with a specified name and value into the client HTTP request headers or the server HTTP response headers. If a header already exists with the same name, a new header with the name will be appended to the end of the list of existing headers. |
Events |
HTTP_REQ HTTP_RESP LB_DONE |
Parameter |
name is a string specifying the new header’s name. |
value is a string specifying the new header’s value. |
|
Returns |
No return value. |
Example |
Add a header named X-Foo with the value Bar in the HTTP request if the user agent contains Mozilla. ua = avi.http.get_header("user-agent") i,j = string.find(ua, "Mozilla") if i then avi.http.add_header("X-Foo", "Bar") end |
avi.http.close_conn
Function |
avi.http.close_conn( [reset] ) |
Description |
Closes the current TCP connection. |
Events |
HTTP_REQ HTTP_RESP |
Parameter |
The |
Returns |
No return value. |
Example |
if avi.vs.client_ip() == "10.1.1.1" then avi.http.close_conn() end |
avi.http.cookie_exists
Function |
avi.http.cookie_exists( name, [context] ) |
Description |
Returns |
Events |
HTTP_REQ HTTP_REQ_BODY HTTP_RESP |
Parameter |
name: It is a string specifying the cookie name. context : Rather than inspecting the cookie from the current event context, specify the context of either For example, during an HTTP response event, check for a cookie sent by the client during the request event.
Note:
You cannot provide |
Returns |
Boolean |
Example |
If the ServerIP cookie exists, send the request to the server IP address defined within the cookie. if avi.http.cookie_exists("ServerIP") then avi.pool.select("Pool1", avi.http.get_cookie("ServerIP")) end |
avi.http.disable
Function |
avi.http.disable() |
Description |
Protocols such as WebSockets can be embedded within the HTTP. The initial connection and handshake begins as HTTP, and then switches to a non-HTTP, non-HTML protocol. Some Microsoft applications, Java, and binary protocols use this method to tunnel through HTTP. With the Note that Websocket support can be enabled natively through an HTTP profile. Some application protocols use slightly different variations of the names of the headers, which is when the DataScript becomes necessary. The |
Events |
|
Parameter |
None |
Returns |
None |
Example |
HTTP Request Event if string.lower(avi.http.get_header("Upgrade")) == "websocket" and string.lower(avi.http.get_header("Connection") == "upgrade" then avi.http.set_reqvar("var", 1) end HTTP Response Event if avi.http.get_reqvar("var") == 1 then avi.http.disable() end |
avi.http.get_cookie
Function |
avi.http.get_cookie( name [, context] ) |
Description |
Returns the value of a specific cookie from the client request or server response header. |
Events |
HTTP_REQ HTTP_REQ_BODY HTTP_RESP |
Parameter |
Name: The name of the cookie to inspect. Context: Rather than inspecting the cookie from the current event context, specify the context of either For example, during an
Note:
You cannot provide |
Return Value |
If a name is provided:
If Set-Cookie: A1=foobar; path=/path/to/file/; Domain=avinetworks.com; secure; HTTPOnly then the table is: {path = '/path/to/file/', Domain = 'avinetworks.com', secure = true, HTTPOnly = true} If a name is not provided:
{name1 = 'value1', name2 = 'value2', name3 = 'value3'} |
Example |
Check the value of cookie named foo. If the value is not bar , then do something. if avi.http.get_cookie("foo") ~= "bar" then -- do something with the cookie header end |
Additional Examples
Example 1: get_cookie
in the HTTP_RESP
event and shows the attributes table.
value, attr_tbl = avi.vs.get_cookie("A1") local k, v = next(attr_tbl, nil) output = "" while k do if type(v) ~= "boolean" then output = output .. ", " .. k .. ": " .. v else output = output .. ", " .. k .. ": " .. tostring(v) end k, v = next(attr_tbl, k) end if v then output = output .. ", " .. k .. ": " .. v end avi.vs.log("value= " .. value .. "; attributes= " .. output)
If the response has the header Set-Cookie: A1=foobar; path=/path/to/file/; Domain=avinetworks.com; secure; HTTPOnly
, the DataScript log will be "value= foobar; attributes= , path: /path/to/file/, Domain: avinetworks.com, secure: true, HTTPOnly: true"
.
Example 2: get_cookie
without the name argument.
cookies = avi.vs.get_cookie() local k, v = next(cookies, nil) output = "" while k do output = output .. ", " .. k .. "=" .. v k, v = next(attr_tbl, k) end if v then output = output .. ", " .. k .. "=" .. v end avi.vs.log("cookies: " .. output)
The format for DataScript log is: "cookies: , name1=value1, name2=value=2, name3=value3, ..."
avi.http.get_cookie_names
Function |
avi.http.get_cookie_names ( [context] ) |
Description |
Returns all the cookies present in the HTTP request or response, determined by the context flag. When context is not specified, it is chosen based on the event which executed the DataScript. |
Events |
HTTP_REQ HTTP_REQ_BODY HTTP_RESP |
Parameter |
Context: Instead of inspecting the cookie from the current event context, specify the context of either For example, during an HTTP response event, check for a cookie sent by the client during the request event by passing |
Returns |
A table containing the cookie names and a number to indicate the number of cookies present. |
Example |
cookies, count = avi.http.get_cookie_names() if count == 0 then -- No cookies found, do something end |
avi.http.get_header
Function |
avi.http.get_header( [[name] [context]] ) |
Description |
Returns a table holding all the headers and their values as a key-value pair in a table. By default, the command is executed against server response headers for an |
Events |
HTTP_REQ HTTP_RESP LB_DONE |
Parameter |
If a name is not specified, a keyed table of all headers and corresponding values is returned. When a header is explicitly repeated, for example, if there are multiple Set-Cookie headers, the table contains a single key for the header with a value that is a table array. If a name is specified, only the value of the specified header is returned as a string. If the specified header is repeated, only the first header value is returned. The context flag allows inspecting of header values from the |
Returns |
A table of headers and their values or a string for a specific header value. |
Example |
The following example can be used to prevent a Shell Shock attack. This attack embeds a client header which starts with () characters. headers = avi.http.get_header() -- get all the HTTP headers for key,val in pairs(headers) do -- iterate through all headers if #val > 2 and string.sub(val, 1, 2) == "()" then avi.http.close_conn() -- reset the TCP connection end end |
avi.http.get_host_tokens
Function |
avi.http.get_host_tokens("MODIFIED" [,start [, end]]) or avi.http.get_host_tokens( [start [, end]] ) |
Description |
|
Events |
HTTP_REQ HTTP_RESP |
Parameter |
|
Returns |
If no If either |
Example |
Example host header:http://www.avinetworks.com/a/b/index.htm?avi=true. If we have HTTP Request Policies with Redirect action to www.vmware.com. avi.http.get_host_tokens("MODIFIED", 1) Returns ‘www.vmware.com’ avi.http.get_host_tokens(1) Returns ‘www.avinetworks.com' avi.http.get_host_tokens("MODIFIED",2,2) Returns ‘vmware’ avi.http.get_host_tokens(2,2) Returns ‘avinetworks’ avi.http.get_host_tokens(6) Returns 'nil' avi.http.get_host_tokens("MODIFIED", 6) Returns ‘nil’ domain = avi.http.get_host_tokens(2, 3) if domain ~= "avinetworks.com" then avi.http.redirect("new.avinetworks.com") end |
This API is not supported in the events SSL_PRECONNECT
, SSL_CLIENTHELLO
, and SSL_HANDSHAKE_DONE
.
avi.http.get_path
Function |
avi.http.get_path( [false] ) |
Description |
Returns the client request’s parsed URI path, i.e. the part of the URI without the query which starts with the first ‘/’ and up to but excluding the ‘?’. The highlighted portion of the request is included in the path:http://www.avinetworks.com/path1/path2/index.html?a=b&c=d |
Events |
HTTP_REQ HTTP_RESP |
Parameter |
When the optional flag is set to false, the returned URI path is unparsed, i.e. is not URI decoded. |
Returns |
A string value of the URI path |
Example |
For an IIS shop, drop bots searching for PHP backdoors if string.endswith(avi.http.get_path(), ".php") then avi.http.close_conn(true) end |
avi.http.get_path_tokens
Function |
avi.http.get_path_tokens( [start [, end]] ) |
Description |
Retrieve individual path sections, or tokens, from the URI’s path (strings separated by the delimiter ‘/’). The command provides the flexibility to get a section of path tokens (see examples below) when start or end indices are provided. |
Events |
HTTP_REQ HTTP_RESP |
Parameter |
|
Returns |
If no |
Example |
Example: https://www.avinetworks.com/a/b/c/d/e.htm. Returns a table which is an array with values ‘a’, ‘b’, ‘c’, ‘d’, ‘e.htm’. All tokens are returned. avi.http.get_path_tokens() Returns ‘a/b/c/d/e.htm’ avi.http.get_path_tokens(1) Returns ‘c/d/e.htm’ avi.http.get_path_tokens(3) Returns ‘b/c’ avi.http.get_path_tokens(2,3) Returns ‘nil’ avi.http.get_path_tokens(7) |
This API is not supported in the events SSL_PRECONNECT
, SSL_CLIENTHELLO
, and SSL_HANDSHAKE_DONE
.
avi.http.get_query
Function |
avi.http.get_query( [arg_name | avi.QUERY_TABLE] [, decode] ) |
Description |
Returns the query from the URI or an individual query value. The highlighted portion of the request is included in the query: http://www.avinetworks.com/path1/path2/index.html? From the example , a=b, a is the argument and b is the value. |
Events |
HTTP_REQ HTTP_RESP |
Parameter |
When no parameter is specified, the full query is returned. If an arg_name is specified and if that argument is present in the query, then its value is returned. When the flag avi.QUERY_TABLE is specified, a table is returned with all the arguments.
By default, the query is returned as URI decoded. For instance, ‘/’ rather than %2F. The decode parameter will URI decode the returned value. The default value of the decode parameter is
Note:
The decode parameter does not have an effect if the format arg provided is |
Returns |
A string for the returned query, an individual argument and value, or a table holding all arguments and values where the argument names are the keys. |
Example 1 |
if avi.http.get_query("intro", false) == "hello%20world" then avi.http.add_header("intro", false) end |
Example 2 |
Return all URI query arguments to the client via local response page. local qa = avi.http.get_query(avi.QUERY_TABLE) local resp = "" for k, v in pairs(qa) do if type(v) == table then resp = resp .. k .. ":" .. table.concat(v, ",") .. ", " else resp = resp .. k .. ":" .. tostring(v) .. ", " -- when v is bool tostring() converts to string end end avi.http.response(200, {}, resp) For request: https://demo.avinetworks.com/path1/index.html?a=b&c=&d=e. The following is returned: a:b, d:e, c:, |
This API is not supported in the events SSL_PRECONNECT
, SSL_CLIENTHELLO
, and SSL_HANDSHAKE_DONE
.
avi.http.get_req_body
Function |
avi.http.get_req_body([size_in_kb]) |
Description |
Returns the client request body. If no data exists within the request body - for example, if the request is not a POST - the function returns nil.
Note:
|
Events |
HTTP_REQ_DATA |
Parameter |
size_in_kb: An optional parameter indicating the maximum payload in kilobytes to be returned. If not specified, the entire request payload is returned.
Note:
The maximum payload size that can be accepted by the virtual service can be limited by the HTTP profile's DDoS settings. |
Returns |
If data exists, returns the data stored in the variable, else returns |
Example |
body = avi.http.get_req_body(4) if string.match(body, "RandomString") then avi.http.response(404) end |
avi.http.get_request_id
Function |
avi.http.get_request_id() |
Description |
To get the request ID for a request. |
Events |
HTTP_REQ HTTP_RESP |
Parameter |
No parameter. |
Returns |
A string value of the request ID (XXXX-XXXX-XXXX, the length is not fixed). |
Example |
1. Add request ID to application log: id=avi.http.get_request_id() avi.vs.log(id) After sending a request, the request ID can be found in the application log: DataScript Log: 2. Add request id to header: id=avi.http.get_request_id() avi.http.add_header("Request ID", id) After sending a request, the request ID can be found in the header:
|
This API is not supported in the events SSL_PRECONNECT
, SSL_CLIENTHELLO
, and SSL_HANDSHAKE_DONE
.
avi.http.get_reqvar
Function |
avi.http.get_reqvar() |
Description |
Gets (reads) data stored in a variable through the After the response completes, the variable is automatically unset. Any Lua value can be stored within this variable. This variable type can be used by other components within the VMware NSX Advanced Load Balancer and not only DataScripts. The VMware NSX Advanced Load Balancer supports three levels of storing data in variables.
var = 1 if var == 2 then ... 2. For variables that must remain persistent across the HTTP request and response events (a complete flow), use the 3. For variable data that needs to be saved across connections or mirrored to other Service Engines supporting the virtual service, use |
Events |
HTTP_REQ HTTP_RESP |
Parameter |
Name: Specify the name of the variable to be declared. The name is a string and must be in quotation marks. |
Returns |
If data exists, returns the data stored in the variable. Else returns nil. |
Related |
|
Example |
avi.http.set_reqvar("foo", 10)
if avi.http.get_reqvar("foo") > 5 then avi.vs.log("Foo=" .. avi.http.get_reqvar("foo")) end |
This API is not supported in the eventsSSL_PRECONNECT
, SSL_CLIENTHELLO
, and SSL_HANDSHAKE_DONE
.
avi.http.get_response_body
Function |
avi.http.get_response_body(size [,offset]) |
Description |
Reads a specified number of kilobytes — not to exceed 32,768 kB (32 MB) — from the buffered body starting at the specified kilobyte offset. If the offset is not specified, reads from the beginning of the buffer. The buffered body will only be processed once by the LUA script. |
Events |
HTTP_RESP_DATA |
Parameter |
size is the number of kilobytes to be read. If specified, the minimum value is 1. The optional offset parameter determines the kilobyte offset at which the first byte is to be read. If specified, the minimum is 1. If not specified, 0 is assumed, i.e., bytes are read from the beginning of the buffer. |
Returns |
If data exists, returns the data stored in the variable. Else returns nil. |
Related |
avi.http.set_response_body_buffer_size() sets the maximum response body to be buffered. |
Example |
Response Data Event Script: local body = avi.http.get_response_body(50) if (body ~= nil) then local uuid = string.match(body, "uuid:(%w+)") if (uuid ~= nil) then local srv = avi.pool.server_ip() avi.vs.table_insert(uuid, srv) end end Request Event Script: uuid = avi.http.get_cookie("uuid") if ( uuid ~= nil) then local srvr = avi.vs.table_lookup(uuid) if (srvr ~= nil) then avi.pool.select("pool-3", srvr) end end |
avi.http.get_uri
Function |
avi.http.get_uri( [false] ) |
Description |
Returns the full, original client requested URI (including the path and query). The highlighted portion of the request is included in the URI: http://www.avinetworks.com |
Events |
HTTP_REQ HTTP_RESP |
Parameter |
When the optional flag is set to |
Returns |
A string value of the URI. |
Example |
Check for layered URI double encoding attack embedded in the request. if string.contains(avi.http.get_uri(), "%") then avi.vs.log("Probable Double Encoding attack, conn closed.") avi.http.close_conn() end |
This API is not supported in the events SSL_PRECONNECT
, SSL_CLIENTHELLO
, and SSL_HANDSHAKE_DONE
.
avi.http.get_user
Function |
avi.http.get_userid() |
Description |
Returns the user ID associated with a connection. The user ID can be used by the DataScript in a number of ways, such as evaluating a user against a white or blacklist. This field is also used in the client logs to populate the searchable userid field. This field is populated through the following methods, prioritized in the following order: Custom: The userid can be explicitly set by a DataScript through the avi.http.set_userid() command. For example, DataScript can parse through a cookie to grab a user name or session ID, and insert the value into the userid field. Basic Auth: If HTTP Basic Auth is enabled on the Virtual Service and a client authenticates, the username field will be used to populate the userid. Client Certificate: If client certificate authentication has been enabled, the userid is populated with the user name field from the client certificate received during the SSL/TLS handshake. |
Events |
HTTP_REQ HTTP_RESP |
Parameter |
None |
Returns |
String of the user ID, nilif empty. |
Example |
If HTTP header username exists, insert its value into the userid field, else set the field to if not avi.http.get_userid() then avi.http.redirect("http://login.foo.com") end |
avi.http.hostname
Function |
avi.http.hostname() |
Description |
Returns the host name from the request. This field could be learned from the following sources, in the following order of precedence:
Note:
Host name does not include the port, even in case of a request line or host header of the form hostname:port. |
Events |
HTTP_REQ HTTP_RESP |
Parameter |
None |
Returns |
String of the hostname requested by the client. It does not include the port. |
Example 1 |
If there is no host name, close the TCP connection. host = avi.http.hostname() if not host then avi.http.close_conn() end |
Example 2 |
Rewrite the location header for relative redirects to absolute, while changing them to HTTPS. This DataScript must be applied to the The rewritten headers must look as follows: https://www.test.com/index.htm loc = avi.http.get_header("Location") if loc and string.beginswith(loc, "/") then loc = "https://" .. avi.http.hostname() .. loc avi.http.replace_header("Location", loc) end |
SSL_PRECONNECT
,
SSL_CLIENTHELLO
, and
SSL_HANDSHAKE_DONE
.
avi.http.internal_status
Function |
avi.http.internal_status() |
Description |
Returns a string stating the reason why a request to a back-end server has failed. The user can use this to customize the response for the different types of failures, log the reason in VMware NSX Advanced Load Balancer logs, etc. |
Events |
RESP_FAILED |
Returns |
Reason for failure |
avi.http.method
Function |
avi.http.method() |
Description |
Returns the client’s request method, such as |
Events |
HTTP_REQ HTTP_RESP |
Parameter |
None |
Returns |
String of the method |
Example |
method = avi.http.method() if method ~= "GET" or method ~= "POST" then avi.http.response("403") end |
This API is not supported in the events SSL_PRECONNECT
, SSL_CLIENTHELLO
, and SSL_HANDSHAKE_DONE
.
avi.http.protocol
Function |
avi.http.protocol() |
Description |
Returns the HTTP protocol of the connection as a string, http for plain HTTP or https for HTTPS. |
Events |
HTTP_REQ HTTP_RESP |
Parameter |
None |
Returns |
Returns http or https |
Example |
If the HTTP request is not SSL then redirect it to secure HTTPS. if avi.http.protocol() ~= "https" then avi.http.redirect("https://" .. avi.http.hostname() .. avi.http.get_uri()) end |
This API is not supported in the events SSL_PRECONNECT
, SSL_CLIENTHELLO
, SSL_HANDSHAKE_DONE
.
avi.http.oauth_get_token
Function |
avi.http.oauth_get_token(TOKEN_TYPE) |
Description |
Extracts the token of TOKEN_TYPEfrom the user’s OAuth session after the session is established. The token (OAUTH_ACCESS_TOKEN or OAUTH_ID_TOKEN) can further be sent to the backend application. |
Events |
HTTP_REQ HTTP_RESP HTTP_RESP_DATA HTTP_POST_AUTH RESP_FAILED HTTP_REQ_DATA LB_DONE |
Parameter |
The function takes a single parameter TOKEN_TYPE. TOKEN_TYPE can be one of the two types of OAuth tokens:
|
Returns |
Requested token is returned as a string, if a token is present. Else, nil is returned. |
Example |
Extracts token of TOKEN_TYPE (avi.OAUTH_ACCESS_TOKEN). If the token is found, it is sent to the backend under the authorization header. token = avi.http.oauth_get_token(avi.OAUTH_ACCESS_TOKEN) if token == nil then avi.vs.log("Token not found") else avi.http.add_header("Authorization", token) end |
avi.http.redirect
Function |
avi.http.redirect( uri [,status] ) |
Description |
Issues an HTTP redirect to a specified URI with a specified status code. This command is available only in the |
Events |
HTTP_REQ |
Parameter |
uri is a string which will be the new URI to redirect the current request to. Optional status code is a number for the redirect status code. Use either the status code number or the constant string. Supported status codes are:
When no status code is provided, the default is 302. |
Returns |
No return value. |
Example |
Redirect an HTTP request received on service port 80 to port 443. if avi.vs.port() ~= "443" then avi.http.redirect("https://" .. avi.http.hostname() .. avi.http.get_uri()) end |
avi.http.remove_cookie
Function |
avi.http.remove_cookie( name1, [name2, ...] ) |
Description |
Removes the given cookie(s) from either the HTTP request or response based on the current context the function was executed from within |
Events |
HTTP_REQ HTTP_REQ_BODY HTTP_RESP |
Parameter |
Removes the given cookie(s) from either the HTTP request or response based on the current context the function was executed from within. If no cookie names are provided, then all the cookies in that context are removed. |
Returns |
None |
Example |
Remove two cookies from the request or response. avi.http.remove_cookie( "jsessionid", "lang" ) Remove all the cookies from the request or response: avi.http.remove_cookie() |
avi.http.remove_header
Function |
avi.http.remove_header( name ) |
Description |
Removes all the instances of a specified HTTP header from the current request or response, depending on the event the script is executed within. |
Events |
HTTP_REQ HTTP_RESP LB_DONE |
Parameter |
name is a string specifying the header name. The name is treated as case insensitive. |
Returns |
No return value. |
Example |
Remove a server response header that can identify potential server vulnerabilities. avi.http.remove_header("Server") |
SSL_PRECONNECT
,
SSL_CLIENTHELLO
, and
SSL_HANDSHAKE_DONE
.
avi.http.replace_cookie
Function |
avi.http.replace_cookie( table ) |
Description |
Replaces a cookie from either the HTTP request or response, based on the current context the function is executed from. Supplied parameters allow for modifying existing cookie attributes. If the specified cookie already exists, the function first removes all the existing instances of the cookie and adds the new cookie with the specified value. If the cookie does not already exist, the command behaves the same as |
Events |
HTTP_REQ HTTP_RESP |
Parameter |
A table of cookie name-value pairs (for HTTP request context) and optionally other cookie attribute-value pairs such as path, domain, etc (for HTTP response). |
Request Parameter |
HTTP Request event: The cookie values are replaced in the Cookie header of the HTTP request, and if no such header exists, the Cookie header is added. avi.http.replace_cookie( name1, value1 [, name2, value2] ) name is the name of the cookie to be modified. value is the new value for the cookie. In the HTTP request context, all arguments are treated as cookie name value pairs, i.e. the function ignores cookie attributes such as "Domain", "Path", etc. and treats them as another cookie to be replaced. |
Response Parameter |
HTTP Response event: When called in an HTTP response context, the cookie values are replaced in the Set-Cookie header of the HTTP response. If no such header exists, the Set-Cookie header is created. In the HTTP response context, only the first two arguments are treated as cookie name-value pairs and the subsequent arguments are interpreted as cookie attributes such as Domain, Path, etc. and their corresponding values. avi.http.replace_cookie( name, value, path, domain, expires, maxage, secure, httponly ) name is the name of the cookie to be modified. value is the new value or data field of the cookie. path is the value (a string) of the path attribute. domain is the value (a string) of the domain attribute. expires is the value (an integer) of the expires attribute. maxage is the value (an integer) of the maxage attribute. secure is the value (a boolean) of the secure attribute. httponly is the value (a boolean) of the httponly attribute. |
Returns |
None |
HTTP Request Example |
Example method 1: Replace the values of two cookies: jsessionid=123 and lang=en cookie_table = {jsessionid="123", lang="en"} avi.http.replace_cookie( cookie_table ) Example method 2: Replace two cookies: jsessionid=123 and lang=en avi.http.replace_cookie( "jsessionid", "123", "lang", "en" ) |
HTTP Response Example |
Example 1: Replace the cookie jsessionid with value
cookie_table = {jsessionid="123", path="/", domain="www.avinetworks.com"} avi.http.replace_cookie( cookie_table ) Example 2: In this format, the order matters. The third argument must be path, fourth must be domain, fifth must be expires, sixth must be maxage, seventh must be httponly flag and the eighth must be secure flag. avi.http.replace_cookie( "jsessionid", "123", "/", "www.avinetworks.com" ) If expires and maxage attributes are not desired, value 0 is passed for each argument. avi.http.replace_cookie( "jsessionid", "123", "/", "a.b.c", 0, 0, true, true) |
avi.http.replace_header
Function |
avi.http.replace_header( name, value ) |
Description |
Set an existing HTTP header to a specified value, overriding all existing headers of the same name. If the header does not already exist, it will be added. The header name is treated case insensitively for matching with existing headers. |
Events |
HTTP_REQ HTTP_RESP LB_DONE |
Parameter |
name is a string specifying the header name. value is a string specifying the new header value. |
Returns |
No return value. |
Example |
Modify the header named “X-Forwarded-For” in the HTTP request to append the virtual service IP. ff = avi.http.get_header("x_forwarded_for") if xff then avi.http.replace_header("X-Forwarded-For", xff ..", ".. avi.vs_ip()) end |
This API is not supported in the events SSL_PRECONNECT
, SSL_CLIENTHELLO
, and SSL_HANDSHAKE_DONE
.
avi.http.response
Function |
avi.http.response (status, {headers}, body) |
Description |
Responds to the HTTP request with a custom HTTP response. |
Events |
HTTP_REQ HTTP_RESP LB_DONE |
Parameter |
status is used to specify the HTTP status code. See list for supported status codes below. Optional headers are used to specify a table to add headers in the response. The default content-type used is “text/plain”. Hence if the body is some other mime-type such as “text/html”, the headers parameter must be used to specify the corresponding content-type. Optional body flag is a string used to specify a custom HTTP response body. To learn how to insert a graphic in a returned page, see Returning an Image from a DataScript. |
Supported Status Codes |
|
Returns |
No return value. |
Example |
Prevent Shellshock attack and notify the attacker with a friendly message. local h = avi.http.get_headers() for k, v in pairs(h) do if string.sub(v, 1, 2) == "()" and #v > 2 then avi.http.response(404, {content_type="text/html"}, "Blocking Shellshock Attack!") end end |
avi.http.saml_session_decrypt
Function |
avi.http.saml_session_decrypt() |
Description |
Returns the decrypted SAML session cookie value found in the client request. |
Events |
HTTP_REQ. |
Parameter |
None. |
Returns |
A string of the decrypted SAML session cookie if it exists; else nil. |
Example |
If the SAML session cookie is present, do something: cookie_val = avi.http.saml_session_decrypt() if (cookie_val) – action to be executed |
avi.http.scheme
Function |
avi.http.scheme() |
Description |
Returns the HTTP protocol as a string concatenated with ‘://’. For plain HTTP ‘http://’ is returned and ‘https://’ for secure HTTPS. |
Events |
HTTP_REQ HTTP_RESP |
Parameter |
None |
Returns |
Returns ‘http://’ or ‘https://’ |
Example |
Redirect clients to test.com on the same protocol the were received on. if avi.http.hostname() ~= "test.com" then avi.http.redirect(avi.http.scheme() .. "test.com" .. avi.http.get_uri()) end |
avi.http.secure
Function |
avi.http.secure() |
Description |
Returns the string ‘ |
Events |
HTTP_REQ. HTTP_RESP. |
Parameter |
None. |
Returns |
String, ‘on’ if true, ‘nil’ if false. |
Example |
If the HTTP request is not SSL then redirect it to secure HTTPS. if avi.http.secure() ~= "on" then avi.http.redirect("https://" .. avi.http.hostname() .. avi.http.get_uri()) end |
avi.http.set_path
Function |
avi.http.set_path( new_uri ) |
Description |
Rewrites the current HTTP request’s URI path to the new_path before the request is sent to a server. This action is generally transparent to the client, as opposed to a redirect, which forces a client to send a new request and incurs a round trip time cost. The highlighted portion of the request is included in the path: http://www.avinetworks.com |
Events |
HTTP_REQ. |
Parameter |
The new URI path must be specified. |
Returns |
No return value. |
Example |
Save a redirect RTT by appending a '/' to a blank URL prior to sending request to the server. if avi.http.get_path() == nil then avi.http.set_path("/") end |
avi.http.set_query
Function |
avi.http.set_query( integer | string | table ) |
Description |
Sets the request’s URI query. The highlighted portion of the request is included in the query: http://www.avinetworks.com/path1/path2/index.html? From the example a=b, a is the argument, b is the value. |
Events |
HTTP_REQ |
Parameter |
The new query can be an |
Returns |
No value returned. |
Example |
if avi.http.get_path() == "/sales" then avi.http.set_path("/") avi.http.set_query("sales=true") end |
avi.http.set_reqvar
Function |
avi.http.set_reqvar() |
Description |
Sets (writes) arbitrary data from an HTTP request event into a variable. These variables have scope across the 1. For variable data that is only required during the current event, map the variable to the data. var = 1 if var == 2 then ... 2. For variables that must remain persistent across the HTTP request and response events (a complete flow), use the avi.http.set_reqvar() and avi.http.get_reqvar() functions. 3. For variable data that needs to be saved across connections or mirrored to other Service Engines supporting the virtual service, use avi.vs.table_insert(). |
Events |
HTTP_REQ HTTP_RESP. |
Parameter |
Name: Specify the name of the variable to be declared. The name is a string and must be in quotation marks. Value: Set the value of the newly declared variable. This can be string or integer. |
Returns |
None. |
Version |
17.1+. |
Related |
avi.http.get_reqvar() Retrieves the stored variable from the avi.http.set_reqvar function. |
Example |
HTTP_REQ event: avi.http.set_reqvar("foo", 10) HTTP_RESP event: if avi.http.get_reqvar("foo") > 5 then avi.vs.log("Foo=" .. avi.http.get_reqvar("foo")) end |
This API is not supported in the events SSL_PRECONNECT
, SSL_CLIENTHELLO
, and SSL_HANDSHAKE_DONE
.
avi.http.set_response_body_buffer_size
Function |
avi.http.set_response_body_buffer_size( size ) |
Description |
Sets the maximum response body to be buffered. |
Events |
HTTP_RESP |
Parameter |
size is the number of kilobytes to be buffered. It can range from 1 to 32,768 kB (32 MB). Note on memory allocation: For responses from a back-end server, the VMware NSX Advanced Load Balancer allocates 4 kB initially and for responses larger than that, allocations occur in chunks of 48 kB as follows, where ACRB is the actual length of the response body:
|
Returns |
None |
Related |
avi.http.get_response_body()reads a specified number of bytes (not to exceed 32,768 kB) from the buffered body starting at the specified byte offset. |
Example 1 |
Response Event Script: avi.http.set_response_body_buffer_size(50) |
avi.http.set_server_timeout
Function |
avi.http.set_server_timeout( time ) |
Description |
Set a custom timeout value for a particular request. By default, the VMware NSX Advanced Load Balancer allows a server one hour for its response, though clients normally terminate a connection even before this time frame. This timeout function is useful for high-speed trading applications, where a fast response is required, whether it is successful or not. By default, the VMware NSX Advanced Load Balancer sends a 504 (gateway timeout) error on server timeout. To alter the error message that the VMware NSX Advanced Load Balancer sends, add additional code to the The timeout value specified by this function is applied in two ways. First, it is applied to the Server RTT, which measures how long it takes to establish a connection with the server. Separately, the same timeout value is also applied to the App Response time, which measures the time from the last byte of the request leaving the VMware NSX Advanced Load Balancer Service Engine until the first byte of the app response is received. If either time exceeds the timeout value, the client is sent an HTTP 504 response. Features such as WAF inspection or HTTP request queuing do not have an impact on the time, as they happen prior to the request leaving the Service Engine. |
Events |
HTTP_REQ. HTTP_RESP. |
Parameter |
time is the length of time, in milliseconds, in which a server connection be established and also the time until Avi receives the first byte of the response after sending the request. Minimum value is 1. No maximum length of time. By default, the VMware NSX Advanced Load Balancer uses 3,600,000 ms (1 hour). |
Returns |
No return value. |
Example |
Requests intended for high-frequency trading path have a strict 3-second timeout enforced while other paths do not. - HTTP_REQ event if string.beginswith(avi.http.get_path(), "/hft") then avi.http.set_server_timeout(3000) end – HTTP_RESP_FAILED event if avi.http.internal_status() == "504" then avi.http.response(404, {content_type="text/html"} , "Server took too long to respond.") end |
This API is not supported in the events SSL_PRECONNECT
, SSL_CLIENTHELLO
, and SSL_HANDSHAKE_DONE
.
avi.http.set_uri
Function |
avi.http.set_uri( new_uri ) |
Description |
Rewrites the current HTTP request’s URI to the new_uribefore the request is sent to a server. This action is n transparent to the client, as opposed to a redirect, which forces a client to send a new request and incurs a round trip time cost. The highlighted portion of the request is included in the URI: http://www.avinetworks.com |
Events |
HTTP_REQ. |
Parameter |
The new URI must be specified. |
Returns |
No return value. |
Example |
Save a redirect RTT by proactively adding the '/' character to a blank URI. if avi.http.get_uri() == nil then avi.http.set_uri("/") end |
avi.http.set_userid
Function |
avi.http.set_userid() |
Description |
Sets the user ID associated with a connection. Setting this field with this command overwrites the field if it was populated through HTTP Basic Auth or through a Client Certificate. |
Events |
HTTP_REQ. HTTP_RESP. |
Parameter |
None. |
Returns |
No value returned. |
Example |
If userid does not exist, populate it with the JSessionID cookie value. if not avi.http.get_userid() then if avi.http.get_cookie("jsessionid") then avi.http.set_userid(avi.http.get_cookie("jsessionid")) else avi.http.set_userid("Unknown") end end |
avi.http.status
Function |
avi.http.status() |
Description |
Response status code that will be sent to the client. This might be different than the status code sent back from the server as a DataScript can override. See the example for avi.var.server_status. |
Events |
HTTP_RESP. |
Parameter |
None. |
Returns |
String of the status code, such as 200. |
Example |
if avi.http.status() == "400" then avi.http.response("404") end |
avi.http.update_cookie
Function |
avi.http.update_cookie( [context] ) |
Description |
Modify the existing cookie attributes value in the HTTP response. If the specified cookie(name) exists
If the cookie does not exist, do nothing. |
Events |
HTTP_RESP. |
Parameter |
name: The name of the cookie to be modified. attr: attribute of an cookie(name) which has to be modified/added. attr_val: value to be replaced with existing cookie attribute value. Attributes: path is the value (a string) of the path attribute. domain is the value (a string) of the domain attribute. expires is the value (an integer) of the expires attribute. maxage is the value (an integer) of the maxage attribute. httponly is the value (a boolean) of the httponly attribute. secure is the value (a boolean) of the secure attribute. samesite is the value (an integer) of the samesite attribute samesite attribute values: |
Returns |
None. |
Example 1 - Modifying single Set-Cookie attribute: |
Example of server sending a simple cookie with the name ‘name1’ and path as ‘/dummy’: server cookie example : Set-Cookie: name1=value1; path=/dummy If you want to modify server cookie path to /dummy1 Data Script to modify the path attribute: avi.http.update_cookie("name1","path","/dummy1") Set-Cookie will be modified to Set-Cookie: name1=value1; Path=/dummy1 |
Example 2 - Adding and modifying Set-cookie attribute: |
Example of server sending a simple cookie with the name ‘name2’ and path as ‘/dummy’: server cookie example: Set-Cookie: name2=value2; path=/dummy If you want to update this server cookie with Domain to ‘www.avinetworks2.com’, HttpOnly, modify the path to ‘/dummy2’ and set expiry to next 30 mins. Example of Data Script to add and modify cookie attributes: cookie_name="name2" if avi.http.cookie_exists(cookie_name) then avi.http.update_cookie(cookie_name, "expires", os.time() + 1800 , "path", "/dummy2", "domain", "www.avinetworks2.com", "httponly", true) end Set-cookie will be modified to : Set-Cookie: name2=value2; Path=/dummy2; Domain=www.avinetworks2.com; HttpOnly |
avi.http.update_cookie() API does not have any order for attributes.
Max-Age cookie attribute can be modified or updated using avi.http.update_cookie().
avi.http.update_cookie() API can be used to add individual or multiple attributes to an existing cookie.
If avi.http.update_cookie() is called for the same cookie name multiple times, it can result in creating multiple Set-Cookie headers for the same cookie name. So, if multiple attributes for the same cookie need to be specified, use the API to update multiple attributes in a single call as shown above.
expires calculates from epoch start time 1st January, 1970. So if the user wants it to expire in 1 hr from the current time, he must use os.time + 3600 (as the units are in seconds).
avi.http.disable_auth
Function |
avi.http.disable_auth(auth_type) |
Description |
Disables the client authentication. |
Events |
HTTP_AUTH |
Parameter |
SAML, LDAP, PAA, JWT. |
Returns |
No return value. |
Example |
if avi.http.get_path() == "/kb/" then avi.http.disable_auth(“SAML”) end |