[squid-dev] Proposal: Helper response: concatenated values with custom delimiter

Amos Jeffries squid3 at treenet.co.nz
Tue Apr 21 19:57:01 UTC 2026


On 22/04/2026 03:11, Alex Rousskov wrote:
> On 2026-04-21 09:06, Andrey K wrote:
>> Hello,
>>
>> I've mentioned this briefly in another thread, but I’d like to start a 
>> dedicated discussion regarding the support for a "concatenated" value 
>> format in helper responses.
>>
>> In a recent PR discussion (https://github.com/squid-cache/squid/ 
>> pull/2395#discussion_r3022844826 <https://github.com/squid-cache/ 
>> squid/pull/2395#discussion_r3022844826>), Alex pointed out issues with 
>> using concatenated formats for passing tag values.
>>
>> I propose adding support for a custom delimiter for concatenated 
>> values within a single KV-pair in the helper output.
>>
>> The proposed syntax is:
>> <key>=<delimiter>"<value1><delimiter><value2>..."
>>
>> Examples:
>> group=,"group1,group2,group3"
>> clt_con_tag=;"tag1;tag2;tag3"
>>
>> Escaping logic:
>>      If the delimiter appears inside a value within the token, it must 
>> be double-escaped (\\) by the helper.
>> For example:
>> group=,"Staff:accountants\\,lawyers\\,security,Main_Office"
>> This should produce two separate annotations:
>> group=Staff:accountants,lawyers,security
>> group=Main_Office
>>
>> The choice of double escaping is intentional to maintain consistency 
>> with the way strwordtok() processes quoted values in Squid.
>> This approach ensures that we can preserve the underlying logic for 
>> handling values while correctly splitting the "glued" tokens.


%-encoding can perform the same role, also supported, has the same 
bandwidth cost, does not require double-quoted string, and far easier to 
get right than nested \-escape.

I suggest using that as the documented protection instead.


Issues I forsee with this proposal;

  * The helper parser splitting the value-list will have unpredictable 
impact on all user configurations - ranging from no change, to 
"surprise! Squid behaviour just got weird".


  * The custom delimiter will have issues the non-quoted key=token 
syntax. There is _no_ requirement that annotation lists are inside 
quoted-string.



>>
>> Currently, a comma-separated format is often used de facto, but Squid 
>> stores these as a single Entry, requiring the -m option for annotation 
>> checks.
>>
>> Proposed Change:
>> A minor modification to Helper::Reply::parseResponseKeys().
>>
>> Pros:
>> - More compact data transfer format.

That assumes the fully expanded "key=v1 key=v2" form is transmitted.

The opposite has been demonstrated already for the preferred key=v1,v2 
form. Data transfer increases by at least the octet signalling delimiter 
to use, plus any extra encoding characters when there is a conflicted 
character.



>> - Proper data storage on the Squid side (separate values instead of 
>> one blob).

"Proper" is subjective.

FWIW, I agree, and it seems Alex does too.


>> - Flexibility for plugin developers via custom delimiters.

Sure, but does anyone need it that flexible?

The helper protocol documents ',' as list delimiter and provides two 
encoding methods to protect conflicting characters.

Even if the helper logic splits the value-list based on some custom 
delimiter. The annotation storage will still be re-splitting based on 
its own ideas about what a value-list is. The same problems just get 
worse as we no longer can rely on ',' being the delimiter to validate.


I really think we should fix the annotation storage before going near 
custom delimiters. Only storing the key=value instead of serialized 
lists will go a long way towards fixing problem. Callers can request 
serialization as-needed and supply delimiters even if desired.



>> - Eliminates the need for admins to manually manage the -m option for 
>> these cases.

I am not convinced the proposal will be able to meet this claim. Simply 
because the "-m" flag is part of an entirely different component of 
Squid than the helper being modified.

Once the ACL bug is fixed the helper needs only to %-encode or \-escape 
the conflicting comma characters properly and their need to use "-m" 
flag disappears.

Until that bug is fixed (and NotePairs stops storing serialized lists) 
using custom delimiters just adds risk that a comma inside some value 
reaches the buggy ACL (or somewhere else assuming comma delimited lists).


>>
>> I am interested in implementing this and submitting a PR. Do you think 
>> this solution is needed and fits the project's direction?
> 
> I do not know whether this problem needs a solution, but I am not 
> excited about the proposed solution, especially because (AFAICT) Squid 
> already supports helper responses with multiple same-name annotations 
> and treats them correctly.

I agree having the helper response parser doing value-list splitting is 
a good idea.


I still do not see a need for custom delimiter.



> 
> [ If there is a real, serious need to optimize that existing support, 
> then ] can we invent another syntax that will not result in mishandling 
> any existing helper annotation (that is not treated as a list today)? 
> For example, perhaps we can use isKeyNameChar() restrictions to place 
> the delimiter first, before the annotation name?
> 
>      (m=,)name=value1,value2
> 

Hmm.  When I combine that idea with older proposals floated about 
kv-pair append/replace syntax there are some nice implications.

How about this:

1) change of kv-pair grammar to:

    kv-pair = [ '_' ] key [ flag ] '=' ( value / list )

2) create a NotePairs::update(key, value, flag) method that uses flag to 
decide which operation to perform as the update.

Pros:
  * flag does not need to be limited to a single character. It could be 
several.

  * Most callers could be converted to de-serializing the value-list by 
simply sending the ',' flag if none is provided explicitly via other means.

Cons:
  * more complexity to the kv-pair concept and implementation.


Cheers
Amos



More information about the squid-dev mailing list