Current Behavior
With the current implementation of session handling, Gorouter sets a __VCAP_ID__ cookie in the response when a session cookie (by default JSESSIONID) is present in the application response. Some cookie attributes, such as the Expires timestamp and the Partitioned flag, are copied from the session cookie to __VCAP_ID__. However, the Max-Age attribute is only copied if its value is negative (internally represented as MaxAge < 0 in Go's cookie implementation). This is inconsistent behavior, as the Expires attribute is always copied, and Max-Age takes precedence over Expires.
This leads to unexpected and undesired behavior: When an application provides a positive Max-Age value for the session cookie, the session cookie expires once Max-Age seconds have elapsed, but the __VCAP_ID__ cookie remains valid as a session cookie (no expiration). In the next request, Gorouter will not consider the __VCAP_ID__ cookie because the expired session cookie is missing. As a result, the request is routed to an arbitrary application instance, breaking sticky session routing.
The conditional Max-Age copying was introduced 10 years ago in a bugfix that resolved an issue preventing sticky session re-establishment.
Desired Behavior
The Max-Age cookie attribute should be unconditionally copied from the session cookie to the __VCAP_ID__ cookie, regardless of whether its value is negative or positive. This ensures that both cookies have synchronized expiration behavior.
Affected Version
Current main branch
Current Behavior
With the current implementation of session handling, Gorouter sets a
__VCAP_ID__cookie in the response when a session cookie (by defaultJSESSIONID) is present in the application response. Some cookie attributes, such as theExpirestimestamp and thePartitionedflag, are copied from the session cookie to__VCAP_ID__. However, theMax-Ageattribute is only copied if its value is negative (internally represented asMaxAge < 0in Go's cookie implementation). This is inconsistent behavior, as theExpiresattribute is always copied, andMax-Agetakes precedence overExpires.This leads to unexpected and undesired behavior: When an application provides a positive
Max-Agevalue for the session cookie, the session cookie expires onceMax-Ageseconds have elapsed, but the__VCAP_ID__cookie remains valid as a session cookie (no expiration). In the next request, Gorouter will not consider the__VCAP_ID__cookie because the expired session cookie is missing. As a result, the request is routed to an arbitrary application instance, breaking sticky session routing.The conditional
Max-Agecopying was introduced 10 years ago in a bugfix that resolved an issue preventing sticky session re-establishment.Desired Behavior
The
Max-Agecookie attribute should be unconditionally copied from the session cookie to the__VCAP_ID__cookie, regardless of whether its value is negative or positive. This ensures that both cookies have synchronized expiration behavior.Affected Version
Current
mainbranch