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 Avi Load Balancer.

String

Description

DataScript: avi.http.add_cookie( table )

Insert a new cookie.

DataScript: avi.http.add_header( name, value )

Insert a new header and value.

avi.http.close_conn( [reset] )

Close or reset a TCP connection.

DataScript: avi.http.cookie_exists( name, [context] )

Validate if a cookie already exists.

DataScript: avi.http.disable()

Upgrade (disable) HTTP processing for the current connection, which will subsequently be treated as layer 4 TCP.

avi.http.get_cookie( name [, context] )

Return the values of a cookie.

avi.http.get_cookie_names ( [context] )

Return the names of cookies.

avi.http.get_header( [[name] [context]] )

Return header names or their values.

avi.http.get_host_tokens( [start [, end]] )

Return a subsection of the host.

avi.http.get_path( [false] )

Returns the URI's path /path.index.htm.

avi.http.get_path_tokens( [start [, end]] )

Return a subsection of the path.

avi.http.get_query( [arg_name | avi.QUERY_TABLE] [, decode] )

Return the URI's query ?a=1&b=2.

avi.http.get_req_body([size_in_kb])

Returns part or the entire portion of the client request body.

avi.http.get_request_id()

Returns the request ID.

avi.http.get_reqvar()

Gets (reads) data stored in a variable through the avi.http.set() function.

avi.http.get_response_body(size [, offset])

Gets (reads) a specified number of kilobytes from the buffered response body starting at the specified kilobyte offset.

avi.http.get_uri( [false] )

Returns the URI (path plus query).

avi.http.get_userid( )

Returns the user ID for the session.

avi.http.hostname( )

Return the hostname requested by client.

avi.http.internal_status()

Returns HTTP status as a string.

avi.http.method( )

Return the client's request method.

avi.http.protocol( )

Returns the session protocol, http or https.

avi.http.oauth_get_token(TOKEN_TYPE)

Extracts the token of TOKEN_TYPE from the user’s OAuth session.

avi.http.redirect( uri [,status] )

Redirect a request.

avi.http.remove_cookie( name1, [name2, ...] )

Remove an existing cookie.

avi.http.remove_header( name )

Remove all instances of a header.

avi.http.replace_cookie( table )

Replace value of an existing cookie.

avi.http.replace_header( name, value )

Replace an existing header's value.

)avi.http.response( status, [headers, [body]] )

Sends a defined HTTP response page.

avi.http.saml_session_decrypt( )

Returns a string of the decrypted SAML session cookie if it exists; else nil.

avi.http.scheme( )

Returns http:// or https://.

avi.http.secure( )

Returns on for https, nil for http.

avi.http.set_path( new_uri )

Modifies the path of a request.

avi.http.set_query( integer | string | table )

Modifies the query of a request.

avi.http.set_reqvar()

Sets (write) arbitrary data from an HTTP request event into a variable. These variables have scope across the HTTP_REQ and HTTP_RESP events.

avi.http.set_response_body_buffer_size(size)

Sets the maximum response body to be buffered.

avi.http.set_server_timeout( time )

Sets a custom timeout value for a particular request.

avi.http.set_uri( new_uri )

Changes the URI.

avi.http.set_userid( )

Sets the user ID for the session.

avi.http.status( )

Returns status code to be sent to the client.

avi.http.update_cookie()

Modifies the existing cookie attributes value in the HTTP response.

avi.http.disable_auth()

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 Avi Load Balancer appends the specified value or flags to the existing cookie.

Events

HTTP_REQ

HTTP_RESP

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.

avi.http.add_cookie( name1, value1 [, name2, value2] )

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.

avi.http.add_cookie( name, value, path, domain, expires, maxage, httponly, secure )

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 reset flag will RST the connection, rather than use the default FIN.

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 true if the cookie name exists in the HTTP request or response. The context determines the request or response. When no context is specified, the default context is based on the event that the DataScript was executed from.

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 avi.HTTP_REQUEST or avi.HTTP_RESPONSE to inspect cookies from those events.

For example, during an HTTP response event, check for a cookie sent by the client during the request event.

Note:

You cannot provide avi.HTTP_RESPONSE as the context argument to get_cookie if calling the function in HTTP_REQ or HTTP_REQ_BODY events.

Returns

Boolean true if the cookie name exists, else false.

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 avi.http.disable() function, a DataScript can monitor the client to server handshake over HTTP, and disable HTTP process when the protocol switches to non-HTTP.

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 avi.http.disable() function can be invoked during the HTTP response event. The Service Engine sends the server's response to the client and upgrades (disables) HTTP processing for the current connection, which will subsequently be treated as layer 4 TCP. If SSL termination is being performed, this process will continue without interruption. HTTP processing cannot be turned on again for the connection.

Events

HTTP_RESP

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 avi.HTTP_REQUEST or avi.HTTP_RESPONSE to inspect cookies from those events.

For example, during an HTTP response event, check for a cookie sent by the client during the request event.

Note:

You cannot provide avi.HTTP_RESPONSE as the context argument to get_cookie if calling the function in HTTP_REQ or HTTP_REQ_BODY events.

Return Value

If a name is provided:

  • String of the cookie’s value if it exists, else nil.

  • (Only in HTTP_RESP && did not provide avi.HTTP_REQUEST as context arg): Table of attributes provided in the Set-Cookie header as they appear in the response.Key: attribute name, Value: Attribute Value

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:

  • Table of all cookies provided in the Request or Response headers. Key: Cookie Name, Value: Cookie Value

    • Example

{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 avi.HTTP_REQUEST or avi.HTTP_RESPONSE to inspect cookies from those events.

For example, during an HTTP response event, check for a cookie sent by the client during the request event by passing avi.HTTP_REQUEST.

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 HTTP_RESP event and client request headers when executed within an HTTP_REQ event.

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 avi.HTTP_REQUEST or avi.HTTP_RESPONSE events. For example, during an HTTP_RESP event, the client request headers can be inspected.

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

  • avi.http.get_host_tokens("MODIFIED")or avi.http.get_host_tokens("MODIFIED", start) or avi.http.get_host_tokens("MODIFIED", start, end): Returns the updated host header tokens. For example, when the host header is overwritten by the rewrite URL action of HTTP policies.

  • avi.http.get_host_tokens( [start [, end]] ): Retrieves individual host sections or tokens from the hostname (strings separated by the delimiter ‘.’) when called without arguments. The command provides the flexibility to get a section of host tokens (see examples below) when start or end indices are provided.

Events

HTTP_REQ

HTTP_RESP

Parameter

start or end indices, which allow parsing out section of the host header.

Returns

If no start and end indices are specified, returns a table of all the host tokens.

If either start index or both start and end indices are specified, returns a string.

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
Note:

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

start and end indices allow parsing out section of the path. These parameters are expressed as an integer.

Returns

If no start and end indices are specified, returns a Lua table of all the path tokens. If either start index is specified or both start and end indices are specified, returns a string.

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)
Note:

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?a=b&c=d.

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.

  • Arguments in this table are always URI decoded.

  • If an argument occurs multiple times within the query, the corresponding value of the key will be a table holding the values of the key.

  • If the argument key has no value, the value returned is a Boolean true.

  • If the argument is presented with an empty value (/index.htm?a=&c=d), the key will have an empty value.

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 true. By providing the decode parameter as false, the query returns non-decoded URI.

Note:

The decode parameter does not have an effect if the format arg provided is avi.QUERY_TABLE.

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:,

Note:

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:
  1. Enable request_body_buffering (through the Application Profile under the DDOS tab or in the VMware Avi Load Balancer CLI).

  2. Buffer size is specified in client_max_body_size but is limited to a maximum of 32 MB.

  3. The default for client_max_body_size is 0, which is interpreted as unlimited, but limited to 32 MB.

  4. To set client_max_body_size use http_profile CLI command.

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 nil.

Example

HTTP_REQ_DATA event:

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:[string "vs-1"]:2: 1Vt-RoC2-m5O6

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:

Request ID: gQJ-0MYI-YZi6

Note:

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 avi.http.set_reqvar() function. These variables have scope across the HTTP_REQ and HTTP_RESPevents. Typically this function is used when data must be stored (set) in the HTTP request event, and retrieved (get) during the HTTP response event. The lifetime of data stored in the reqvar functions are limited to the HTTP request/response transaction.

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 Avi Load Balancer and not only DataScripts. The VMware Avi Load Balancer supports three levels of storing data in variables.

  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.

Returns

If data exists, returns the data stored in the variable. Else returns nil.

Related

avi.http.set_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
Note:

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/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 is unparsed, i.e. It is not URI decoded.

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 
Note:

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 none.

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:

  • Host name from the request line.

  • Host name from the Host request header field.

  • The server name matching a request.

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 HTTP Response event.

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
This API is not supported in the events 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 Avi 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 GET or POST.

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
Note:

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
Note:

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:

  • avi.OAUTH_ACCESS_TOKEN

  • avi.OAUTH_ID_TOKEN

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 HTTP_REQ event. If a redirect needs to be performed in HTTP_RESP event, use avi.http.response() which can be used to craft a response.

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:

  • 301 avi.HTTP_MOVED_PERMANENTLY

  • 302 avi.HTTP_MOVED_TEMPORARILY

  • 307 avi.HTTP_TEMPORARY_REDIRECT

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")
This API is not supported in the events 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 avi.http.add_cookie.

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 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.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
Note:

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.

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

All status codes in the range 200-599.

Status codes from 470 to 475 are not supported for local response.

Returns

No return value.

Examples

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

The request to trigger the token validation logic and potential simulation of the 499 response.

local authorization_header = avi.http.get_header("Authorization")
  local token = string.match(authorization_header, "Bearer (.+)")
  if not token then
    -- Invalid or missing token in the authorization header
    --499 -: This is used to indicate a missing or invalid authentication token.
    avi.http.response(499, {content_type="text/html"},
     "Token Required: Authentication token is missing or invalid")
  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 ‘on’ if client to the Virtual Service connection operates in SSL/TLS mode, or an empty string if false.

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/path1/path2/index.html?a=b&c=d.

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?a=b&c=d.

From the example a=b, a is the argument, b is the value.

Events

HTTP_REQ

Parameter

The new query can be an integer, a string, or a table. When the input is a string, it must not be prefixed with a ‘?’ character. When the input is a table, the query string is formed by treating the keys as arguments and the values as the value of the corresponding argument.

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 HTTP_REQ and HTTP_RESP events. Their lifetime is limited to the HTTP request/response transaction, so it does not need to be manually unset. Any Lua value can be stored within this variable. This variable type can be used by other components within the VMware Avi Load Balancer and not just DataScripts. The VMware Avi Load Balancer supports three levels of storing data in variables.

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
Note:

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 Avi 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:

  • If ACRB < 4 kB, 4 kB is allocated.

  • If ACRB < avi.http.set_response_body_buffer_size(), 4 kB + 48 kB * ((ACRB / 48 kB) +1) is allocated.

  • If ACRB > avi.http.set_response_body_buffer_size(), 4 kB + 48 kB * ((avi.http.set_response_body_buffer_size()/48 kB +1) is allocated.

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 Avi 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 Avi Load Balancer sends a 504 (gateway timeout) error on server timeout. To alter the error message that the VMware Avi Load Balancer sends, add additional code to the HTTP_RESP_FAILED event. See the example given below.

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 Avi 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 Avi 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
Note:

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/path1/path2/index.html?a=b&c=d

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 cookie attribute/attributes are already present in an existing cookie, the function will modify the mentioned cookie attribute/attributes to attribute_value.

  • If cookie attribute/attributes does not exist, function will add the mentioned cookie attribute/attributes to the cookie.

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: avi.http.Lax avi.http.None avi.http.Strict.

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
Note:
  • 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