Aias00 opened a new issue, #7771:
URL: https://github.com/apache/shenyu/issues/7771

   ### Current behavior
   
   The Spring contract creates static header values with 
`Collections.singleton`, while request/template cloning copies at most the 
outer header map. `RequestHeaderParameterProcessor` then appends dynamic values 
to the existing value collection.
   
   There are two manifestations of the same collection-ownership problem:
   
   1. Normal annotation-created static headers are immutable: combining one 
with a dynamic parameter for the same header throws before any transport 
request.
   2. If a programmatic/customized template uses mutable value collections, the 
shallow copy shares those values with the reusable template. Dynamic values 
accumulate across subsequent invocations.
   
   ### Locations / reachable flow
   
   - 
[SpringMvcContract.java:123–129](https://github.com/apache/shenyu/blob/66d7d954ca37d651a5ad916f988a8081157a7ab4/shenyu-sdk/shenyu-sdk-spring/src/main/java/org/apache/shenyu/sdk/spring/support/SpringMvcContract.java#L123)
 creates singleton static values.
   - 
[RequestTemplate.java:81–103](https://github.com/apache/shenyu/blob/66d7d954ca37d651a5ad916f988a8081157a7ab4/shenyu-sdk/shenyu-sdk-core/src/main/java/org/apache/shenyu/sdk/core/common/RequestTemplate.java#L81)
 shares/copies only the outer map.
   - 
[RequestHeaderParameterProcessor.java:49–77](https://github.com/apache/shenyu/blob/66d7d954ca37d651a5ad916f988a8081157a7ab4/shenyu-sdk/shenyu-sdk-spring/src/main/java/org/apache/shenyu/sdk/spring/annotation/RequestHeaderParameterProcessor.java#L49)
 mutates existing collections.
   - `CookieValueParameterProcessor.java:54–62` has the same ownership pattern, 
taking the collection from the template before merging it into request headers.
   
   ### Reproduction / validation
   
   Define this ordinary Spring SDK method:
   
   ```java
   @GetMapping(value = "/items", headers = "X-Mode=static")
   String call(@RequestHeader("X-Mode") String value);
   ```
   
   A probe compiled the current contract, RequestTemplate, response handler and 
header processor. It parsed the actual interface through `SpringMvcContract`, 
then called public `ShenyuClientMethodHandler.invoke()` with a recording 
in-process transport:
   
   ```text
   BUILTIN_CONTRACT_EXCEPTION=UnsupportedOperationException TRANSPORT_CALLS=0
   ```
   
   As a separate control, the probe changed only that parsed template's value 
collection to a mutable `[static]`, then invoked with `one` and `two`:
   
   ```text
   MUTABLE_TEMPLATE_REQUESTS=[[static, one], [static, one, two]]
   TEMPLATE_AFTER_CALLS=[static, one, two]
   ```
   
   The ordinary built-in case is the first-call exception, **not** repeated 
accumulation from a built-in ArrayList. Independent review corrected that 
initial assumption after inspecting `Collections.singleton`. The executed 
reproduction covers the RequestHeader branch; the CookieValue counterpart is 
source-inspected. No external HTTP service or sensitive header values were 
involved.
   
   ### Impact / suggested fix
   
   Combining supported static and dynamic headers fails; mutable reusable 
templates can also retain prior invocation state. Give each invocation mutable, 
independently owned value collections before parameter processing, and avoid 
modifying template-owned collections in the processors. Preserve the intended 
append/replace contract without duplicating static cookie/header values during 
merges.
   
   ### Related existing work
   
   #7711 concerns response status handling, #7712 path replacement syntax, 
#7464 query encoding and #7465 annotation name aliases. #6254 concerns a 
different MCP request-template header substitution path. Complete-title/open-PR 
and live RequestTemplate/header/UnsupportedOperationException searches found no 
matching collection-ownership report.
   
   
   ### Reviewed revision
   
   Apache ShenYu 2.7.2-SNAPSHOT, 
`master@66d7d954ca37d651a5ad916f988a8081157a7ab4`. P2 / Medium; high 
confidence. Unit-test and CI issue categories excluded.
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to