Technical Tip: Logging HTTP request and response headers locally using FortiADC scripting
Description
This article describes how to use FortiADC HTTP scripting to read the client-to-server HTTP communication passing through a virtual server, extract the HTTP request headers sent by the client and the HTTP response headers returned by the real server, and write them to the local script log.
Â
This is useful in troubleshooting and auditing scenarios where the exact headers exchanged need to be inspected. The script generates two separate log entries per transaction, one for the request and one for the response and each containing only its own headers together with the relevant source and destination IP address and port.
Â
Scope
Â
FortiADC.
Â
Solution
Â
Step 1: Create the LUA Script from the FortiADC GUI.

Paste the following script:
-- ============================================================
-- FortiADC HTTP Transaction Logger
-- VS Scripting | FortiADC 7.x / 8.x
-- One log entry for the request, one for the response.
-- Each carries only its own headers + its own connection tuple.
-- ============================================================
when HTTP_REQUEST {
-- Client-side tuple (front end is unaffected by backend NAT)
sip = IP:client_addr() -- source: real client IP
sp = IP:client_port() -- source: real client port
dip = IP:local_addr() -- dest: virtual server IP
dp = IP:local_port() -- dest: virtual server port
method = HTTP:method_get()
host = HTTP:header_get_value("Host")
if (host == nil) then host = "-" end
uri = HTTP:uri_get()
log("[REQ] src=%s:%s dst=%s:%s %s %s%s
", sip, sp, dip, dp, method, host, uri)
h = HTTP:header_get_names()
if (h ~= nil) then
for k, v in pairs(h) do
log("[REQ] %s: %s
", k, v)
end
end
}
when HTTP_RESPONSE {
-- Server-side tuple (backend connection: FortiADC <-> real server)
sip = IP:server_addr() -- source: real server IP
sp = IP:server_port() -- source: real server port
dip = IP:local_addr() -- dest: FortiADC backend interface IP
dp = IP:local_port() -- dest: FortiADC backend port
status = HTTP:status_code_get()
log("[RESP] src=%s:%s dst=%s:%s status=%d
", sip, sp, dip, dp, status)
h = HTTP:header_get_names()
if (h ~= nil) then
for k, v in pairs(h) do
log("[RESP] %s: %s
", k, v)
end
end
}
Assign the script to a Virtual Server:

The Log needs to be enabled for scripting under Log & Report -> Log setting -> Local log.

Once the Logging is enabled and Scipt is applied to the Virtual Server, review the logs under the 'Log & Report -> Script Log' screen.
REQ:

RESP:

