HTTP Request and Response Handling
- Handle an HTTP server exchange
- Read the incoming request
- Query parameters
- Request headers
- Request body
- Construct the server response
- Return a JSON body
- Return an XML or text body
- Return no body
- Use an HTTP backend
- Fill the backend request
- Fill backend query parameters
- Fill a JSON backend body
- Fill an XML backend body
- Read the backend response
Radiator supports HTTP servers and HTTP backends:
- An HTTP server receives a request and returns a response.
- An HTTP backend sends a request and receives a response.
See Execution Context for
the complete http variable reference.
Handle an HTTP server exchange
An HTTP server pipeline reads an incoming request and constructs the response returned to that client.
Read the incoming request
Use handler conditions to select requests by HTTP method, path, and query
parameters. This handler selects a summary request that includes supi:
aaa {
policy "DEFAULT" {
handler "READ_SUBSCRIBER_SUMMARY" {
conditions all {
http.method == "GET";
http.path == "/subscriber";
http.query.supi == any;
http.query.view == "summary";
}
@execute {
set vars.supi http.query.supi;
set vars.view http.query.view;
accept;
}
}
}
}
The conditions all block requires every condition to match. http.path
contains only the path component, such as /subscriber. Use
http.query.NAME == any to require a query parameter, or compare it with a
string to require a specific decoded value.
Query parameters
Read one decoded query parameter through http.query.NAME. The value is
none when the parameter is absent.
For /subscriber?supi=imsi-244120000000001&view=summary, http.query.supi
contains imsi-244120000000001 and http.query.view contains summary.
http.query provides all query parameters as a map. Query parameters are
read-only.
Request headers
Read a request header through http.header.NAME. Header names in the request
context are lowercase.
@execute {
set vars.correlation_id http.header.x-correlation-id;
set vars.content_type http.header.content-type;
}
http.headers.NAME is an alias for http.header.NAME. Request headers are
read-only. Response headers use the separate http.response_header namespace.
Request body
http.request contains the complete request body when one is available. Radiator
handles incoming bodies according to the request Content-Type:
application/jsonbecomes a structured JSON value.application/x-www-form-urlencodedbecomes an object.- Other media types become strings.
- A
GETrequest has nohttp.requestvalue.
If an application/json body is not valid JSON, http.request has no value.
Read a field from a JSON or form body through http.request.PATH. For example:
@execute {
set vars.display_name http.request.subscriber.displayName;
}
http.request.PATH uses JSONPath and is read-only. Assign to the top-level
http.request variable to replace the complete body.
set http.request "plain text body";
Assign an existing structured value directly. For example, a Lua script can
store an object in vars.newbody before radconf assigns it.
set http.request vars.newbody;
Use ?= to set a body only when the request has no body.
modify http.request ?= vars.default_body;
Set the value to none to clear the request body. Assigning nil to
context.http.request in Lua has the same effect.
set http.request none;
Lua scripts can read and replace the same value through context.http.request.
local request = context.http.request
context.http.request = {
subscriber = request.subscriber,
forwarded = true,
}
Appending to http.request is not supported. http.body and
context.http.body are deprecated compatibility aliases for the request body.
Create a structured JSON body with a triple-quoted string. Apply the json
filter after interpolation.
@execute {
set vars.supi "imsi-244120000000002";
set vars.uplink 1000;
set vars.display_name "Alice \"Example\"";
modify {
# Quote string placeholders and leave numeric placeholders unquoted.
# Escape interpolated double quotes before parsing the string as JSON.
http.request = """
{
"supi": "%{vars.supi}",
"uplink": %{vars.uplink},
"displayName": "%{vars.display_name | escape_double_quotes}",
"escapedQuote": "He said \u0022hello\u0022",
"escapedBackslash": "C:\u005ctemp\u005cfile"
}
""" | json;
}
}
Comments inside the triple-quoted string become part of the body. Keep comments outside the string when the result must be valid JSON.
An XML body remains a string. Apply xml_escape to each interpolated XML value.
The filter escapes &, <, >, ", and '.
@execute {
set vars.supi "imsi-244120000000002";
set vars.display_name "Alice & Bob <Test>";
modify {
http.request = """
<request>
<supi>%{vars.supi | xml_escape}</supi>
<displayName>%{vars.display_name | xml_escape}</displayName>
</request>
""";
}
}
Replacing http.request does not change the incoming request Content-Type.
Construct the server response
Use these variables to construct the response returned to the client:
http.statussets the HTTP status code.http.responsesets the complete optional response body.http.response.KEYsets a field in an object response body.http.jsonselects JSON or non-JSON response serialization.http.response_header.NAMEsets an outgoing response header.
If the pipeline does not set a response body, Radiator creates the default JSON result response described in HTTP server configuration.
Return a JSON body
With the default http.json = true, assignments through http.response.KEY
build a JSON object. Radiator sets Content-Type to application/json.
modify {
http.status = http.OK;
http.response.result = "accept";
http.response.message = "Request processed";
}
Set a response header separately. Header names are case-insensitive.
modify {
http.response_header.X-Correlation-Id = http.header.x-correlation-id;
}
Return an XML or text body
Set http.json = false for XML, plain text, or another non-JSON body. Set
http.response_header.Content-Type explicitly. Otherwise, a non-JSON response
uses text/html; charset=utf-8.
@execute {
set vars.result "accept";
set vars.message "Request processed";
modify {
http.status = http.OK;
http.json = false;
http.response_header.Content-Type = "application/xml";
http.response = """
<response>
<result>%{vars.result | xml_escape}</result>
<message>%{vars.message | xml_escape}</message>
</response>
""";
}
}
Use the top-level http.response variable for a non-JSON body. Assignments
through http.response.KEY still build an object when http.json is false.
http.response.header and http.response.header.NAME create response body
fields named header. They do not set response headers.
Return no body
Set http.response = none to return no body. Set http.NO_CONTENT when the
response should be an explicit 204 No Content.
modify {
http.status = http.NO_CONTENT;
http.response = none;
}
Use an HTTP backend
An HTTP backend creates an outbound request and receives its response when a
backend action invokes a query. Request values can come from vars or any
other namespace available in the current protocol context.
Fill the backend request
Use the query path expression and bindings to fill the request. The get,
post, put, patch, or delete query block selects the method. Interpolate
escaped values in path when the backend URL contains dynamic path segments.
get "LOOK_UP_SUBSCRIBER" {
path "/subscriber/%{vars.supi | url_escape}";
}
The binding type determines where Radiator places the values and which
Content-Type it sends:
| Binding type | Outbound data | Request body Content-Type |
|---|---|---|
query | URL query parameters | Not applicable |
form | URL-encoded form body | application/x-www-form-urlencoded |
json | JSON body | application/json |
xml | Formatted XML string body | application/xml |
plain | Formatted string body | text/plain |
Backend bindings do not set general outbound request headers. Use the HTTP backend authentication configuration for its supported authentication headers.
Fill backend query parameters
Use bindings query to add values to the backend URL. This request has no
body.
get "LOOK_UP_SUBSCRIBER" {
path "/subscriber";
bindings query {
supi vars.supi;
correlation_id vars.correlation_id;
}
}
Fill a JSON backend body
Use named JSON bindings to construct a new object from context values.
post "CREATE_SESSION" {
path "/sessions";
bindings json {
supi vars.supi;
subscriber vars.subscriber;
}
}
Use the root binding . to send a complete structured value.
post "FORWARD_JSON" {
path "/json";
bindings json {
. vars.backend_body;
}
}
When an HTTP server policy deliberately forwards its current request body, use
. http.request; as the root binding instead.
Fill an XML backend body
Use bindings xml to format an XML request body. Apply xml_escape to each
interpolated XML value.
post "SEND_XML" {
path "/xml";
bindings xml """
<request>
<supi>%{vars.supi | xml_escape}</supi>
<displayName>%{vars.display_name | xml_escape}</displayName>
</request>
""";
}
The XML binding sets Content-Type to application/xml. It does not parse or
validate the generated XML.
See HTTP backend configuration for the surrounding backend configuration.
Read the backend response
Use backend mapping blocks to copy response values into context variables.
Use mapping head for the status code and response headers.
post "CREATE_SESSION" {
path "/sessions";
bindings json {
. vars.backend_body;
}
mapping json {
vars.backend_result = "$.result";
vars.backend_message = "$.message";
}
mapping head {
vars.backend_status = status_code;
vars.backend_request_id = headers.x-request-id;
}
}
The mapped variables are available after the backend action completes and
can be used by subsequent policy actions.