Skip to content

Commit 7ad60d3

Browse files
committed
Fix issue with copying headers in NativeMessageHeaderAccessor
Closes gh-25821
1 parent 4b9c3fa commit 7ad60d3

File tree

2 files changed

+45
-4
lines changed

2 files changed

+45
-4
lines changed

spring-messaging/src/main/java/org/springframework/messaging/support/NativeMessageHeaderAccessor.java

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -75,8 +75,6 @@ protected NativeMessageHeaderAccessor(@Nullable Message<?> message) {
7575
@SuppressWarnings("unchecked")
7676
Map<String, List<String>> map = (Map<String, List<String>>) getHeader(NATIVE_HEADERS);
7777
if (map != null) {
78-
// Force removal since setHeader checks for equality
79-
removeHeader(NATIVE_HEADERS);
8078
setHeader(NATIVE_HEADERS, new LinkedMultiValueMap<>(map));
8179
}
8280
}
@@ -105,14 +103,40 @@ public void setImmutable() {
105103
if (isMutable()) {
106104
Map<String, List<String>> map = getNativeHeaders();
107105
if (map != null) {
108-
// Force removal since setHeader checks for equality
109-
removeHeader(NATIVE_HEADERS);
110106
setHeader(NATIVE_HEADERS, Collections.unmodifiableMap(map));
111107
}
112108
super.setImmutable();
113109
}
114110
}
115111

112+
@Override
113+
public void setHeader(String name, @Nullable Object value) {
114+
if (name.equalsIgnoreCase(NATIVE_HEADERS)) {
115+
// Force removal since setHeader checks for equality
116+
removeHeader(NATIVE_HEADERS);
117+
}
118+
super.setHeader(name, value);
119+
}
120+
121+
@Override
122+
@SuppressWarnings("unchecked")
123+
public void copyHeaders(@Nullable Map<String, ?> headersToCopy) {
124+
if (headersToCopy != null) {
125+
Map<String, List<String>> nativeHeaders = getNativeHeaders();
126+
Map<String, List<String>> map = (Map<String, List<String>>) headersToCopy.get(NATIVE_HEADERS);
127+
if (map != null) {
128+
if (nativeHeaders != null) {
129+
nativeHeaders.putAll(map);
130+
}
131+
else {
132+
nativeHeaders = new LinkedMultiValueMap<>(map);
133+
}
134+
}
135+
super.copyHeaders(headersToCopy);
136+
setHeader(NATIVE_HEADERS, nativeHeaders);
137+
}
138+
}
139+
116140
/**
117141
* Whether the native header map contains the give header name.
118142
*/

spring-messaging/src/test/java/org/springframework/messaging/support/NativeMessageHeaderAccessorTests.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -224,4 +224,21 @@ public void setImmutableIdempotent() {
224224
headerAccessor.setImmutable();
225225
}
226226

227+
@Test // gh-25821
228+
void copyImmutableToMutable() {
229+
NativeMessageHeaderAccessor source = new NativeMessageHeaderAccessor();
230+
source.addNativeHeader("foo", "bar");
231+
Message<String> message = MessageBuilder.createMessage("payload", source.getMessageHeaders());
232+
233+
NativeMessageHeaderAccessor target = new NativeMessageHeaderAccessor();
234+
target.copyHeaders(message.getHeaders());
235+
target.setLeaveMutable(true);
236+
message = MessageBuilder.createMessage(message.getPayload(), target.getMessageHeaders());
237+
238+
MessageHeaderAccessor accessor = MessageHeaderAccessor.getMutableAccessor(message);
239+
assertThat(accessor.isMutable());
240+
((NativeMessageHeaderAccessor) accessor).addNativeHeader("foo", "baz");
241+
assertThat(((NativeMessageHeaderAccessor) accessor).getNativeHeader("foo")).containsExactly("bar", "baz");
242+
}
243+
227244
}

0 commit comments

Comments
 (0)