On Tue, Nov 08, 2011 at 03:04:23PM +0100, Arran Cudbard-Bell wrote:
What about:
"<attribute>":{ "value":[[<value>,<tag>],<value>,[<value>,<tag>]] }
I don't see that there's any other possible use for nested arrays in the value key?
Possibly the update operator (=, +=, :=, !* etc). As for tags, the first option which springs to mind is to put them in the attribute label, as they are in FreeRadius today. However with tags, the update operators don't behave how I'd expect. If I write Tunnel-Server-Endpoint:0 := 1.2.3.4 Tunnel-Server-Endpoint:1 := 5.6.7.8 then the second := erases all previous instances of Tunnel-Server-Endpoint. The tag behaves not as part of the attribute, but as part of the value (which in fact it is). This isn't a problem with standard FreeRadius where the AV pairs are always returned in some order - apart from the limitation that there's no facility to replace just Tunnel-Server-Endpoint:1. But it would be a problem for this JSON: { "Tunnel-Server-Endpoint:0": [["1.2.3.4",":="]], "Tunnel-Server-Endpoint:1": [["5.6.7.8",":="]] } because many JSON consumers don't guarantee the order in which object members are returned. A more convenient way to handle tags would be as object keys: { "Tunnel-Server-Endpoint": {"0"=>"1.2.3.4", "1"=>"5.6.7.8"} } But this still has the problem of element ordering given the same example as above: { "Tunnel-Server-Endpoint": {"0"=>["1.2.3.4",":="], "1"=>["5.6.7.8",":="]} } Semantically, having repeated := is not very useful. Normally you'd have := on the first value and += on the others. Can we rely on this? That is, apply := to the whole attribute and have it expand to := on the first value and += on the rest? Then += would apply as += to all values. But when you start to consider other update operators, it would prohibit cases like this: Reply-Message += "foo" Reply-Message -= "bar" and the only way I can see to support that is that firstly every value needs to be tagged with an operator, and secondly the values must be in an array so that they are processed in a deterministic sequence. If not, you get non-deterministic behaviour in this sort of edge case (admittedly useless): Reply-Message += "foo" Reply-Message -= "foo" Final point: if you are returning a bundle of attributes, currently these are always *merged* into the reply packet. You can delete individual attributes using -= or !* operators, but there is no way to say "replace the entire reply list built so far" without invoking something like attr_filter in unlang. This is no worse for rlm_rest than we have today, but I'd really like some way to return maybe a magic attribute which either deletes all attributes, or all attributes apart from those listed in the reply, or triggers a specific entry in rlm_attr_filter. But this is going outside the realm of JSON formatting. Regards, Brian.