cancel
Showing results for 
Search instead for 
Did you mean: 
Lee_Sutcliffe
Nacreous
Nacreous

Problem this snippet solves:

Like rewriting the Location field in a redirect, it's sometimes required to rewrite JSON data, returned in an HTTP response. Whilst it would be possible to write using traditional iRules, the task is made more simple (and less risky) by using iRulesLX.

In the following example, an HTTP response contains JSON data with fields containing external URLs. These need to be rewritten to an internal URL for the purpose of internal routing.

{  
    "firstUrl":"https://some.public.host.com/api/preauth/ABCDEFGHIJKLM",
    "secondUrl":"https://some.public.host.com/api/documents/{documentId}/discussion"
}

The concept can be used to rewrite any JSON data, however more complicated JSON containing arrays for example would need to be taken into consideration.

How to use this snippet:

use the following iRule to call iRulesLX and pass the necessary parameters

when CLIENT_CONNECTED {
    set newHost "internal.host.local"
    set jsonKeys "firstUrl secondUrl"
    set rpcHandle [ILX::init "json-parse-plugin" "json-parse-extension"]
}

when HTTP_RESPONSE {
    if {[HTTP::header "Content-Type"] eq "application/json"} {
        HTTP::collect [HTTP::header "Content-Length"]
    }
}

when HTTP_RESPONSE_DATA {
    set payload [HTTP::payload]
    set result [ILX::call $rpcHandle "setInternalUrl" $payload $jsonKeys $newHost]
    HTTP::payload replace 0 [HTTP::header "Content-Length"] $result
}

When used in combination with the iRulesLX code below the host portion of the URIs in the JSON data are rewritten and sent back to the origin by replacing the HTTP payload

  {  
    "firstUrl":"https://internal.host.local/api/preauth/ABCDEFGHIJKLM",
    "secondUrl":"https://internal.host.local/api/documents/{documentId}/discussion"
  }

Code :

const f5 = require('f5-nodejs');
const url = require('url');
const ilx = new f5.ILXServer();

function setInternalUrl(req, res) {

    var json = JSON.parse(req.params()[0]);
    var jsonObj = req.params()[1].split(' ');
    var newHost = req.params()[2];

    for (var i = 0; i < jsonObj.length; i++) {
        if (typeof json[jsonObj[i]] == "string") {
            var oldUrl = url.parse(json[jsonObj[i]]);
            oldUrl.host = newHost;
            var newUrl = decodeURI(url.format(oldUrl));
            json[jsonObj[i]] = newUrl;
        } else {
            json = {"error":"unable to rewrite"};
        }
    }
    res.reply(JSON.stringify(json));
}

ilx.addMethod('setInternalUrl', setInternalUrl);
ilx.listen();

Tested this on version:

12.1
Version history
Last update:
‎27-Feb-2019 02:00
Updated by:
Contributors