From 5cbbbed3777e315658954e3e8674434b146825cf Mon Sep 17 00:00:00 2001 From: Arjen Poutsma Date: Mon, 31 May 2021 15:17:12 +0200 Subject: [PATCH] Use given name in MultipartBodyBuilder::part Make sure that we use the parameter name in MultipartBodyBuilder::part when adding a Part, instead of using the name specified in the 'Content-Disposition' header that might have been in the part's headers. Closes gh-27007 --- .../http/client/MultipartBodyBuilder.java | 9 +++++++-- .../codec/multipart/MultipartHttpMessageWriterTests.java | 7 +++++-- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/spring-web/src/main/java/org/springframework/http/client/MultipartBodyBuilder.java b/spring-web/src/main/java/org/springframework/http/client/MultipartBodyBuilder.java index 08f10762d8..9d76f72f15 100644 --- a/spring-web/src/main/java/org/springframework/http/client/MultipartBodyBuilder.java +++ b/spring-web/src/main/java/org/springframework/http/client/MultipartBodyBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -131,7 +131,12 @@ public final class MultipartBodyBuilder { Part partObject = (Part) part; PartBuilder builder = asyncPart(name, partObject.content(), DataBuffer.class); if (!partObject.headers().isEmpty()) { - builder.headers(headers -> headers.putAll(partObject.headers())); + builder.headers(headers -> { + headers.putAll(partObject.headers()); + String filename = headers.getContentDisposition().getFilename(); + // reset to parameter name + headers.setContentDispositionFormData(name, filename); + }); } if (contentType != null) { builder.contentType(contentType); diff --git a/spring-web/src/test/java/org/springframework/http/codec/multipart/MultipartHttpMessageWriterTests.java b/spring-web/src/test/java/org/springframework/http/codec/multipart/MultipartHttpMessageWriterTests.java index 7219fab928..17c057d6d6 100644 --- a/spring-web/src/test/java/org/springframework/http/codec/multipart/MultipartHttpMessageWriterTests.java +++ b/spring-web/src/test/java/org/springframework/http/codec/multipart/MultipartHttpMessageWriterTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -105,7 +105,7 @@ public class MultipartHttpMessageWriterTests extends AbstractLeakCheckingTests { FilePart mockPart = mock(FilePart.class); HttpHeaders partHeaders = new HttpHeaders(); partHeaders.setContentType(MediaType.TEXT_PLAIN); - partHeaders.setContentDispositionFormData("filePublisher", "file.txt"); + partHeaders.setContentDispositionFormData("foo", "file.txt"); partHeaders.add("foo", "bar"); given(mockPart.headers()).willReturn(partHeaders); given(mockPart.content()).willReturn(bufferPublisher); @@ -159,17 +159,20 @@ public class MultipartHttpMessageWriterTests extends AbstractLeakCheckingTests { assertThat(part.headers().getContentLength()).isEqualTo(utf8.getFile().length()); part = requestParts.getFirst("json"); + assertThat(part).isNotNull(); assertThat(part.name()).isEqualTo("json"); assertThat(part.headers().getContentType()).isEqualTo(MediaType.APPLICATION_JSON); String value = decodeToString(part); assertThat(value).isEqualTo("{\"bar\":\"bar\"}"); part = requestParts.getFirst("publisher"); + assertThat(part).isNotNull(); assertThat(part.name()).isEqualTo("publisher"); value = decodeToString(part); assertThat(value).isEqualTo("foobarbaz"); part = requestParts.getFirst("filePublisher"); + assertThat(part).isNotNull(); assertThat(part.name()).isEqualTo("filePublisher"); assertThat(part.headers()).containsEntry("foo", Collections.singletonList("bar")); assertThat(((FilePart) part).filename()).isEqualTo("file.txt");