FilePart uses correct flags when opening files

Issue: SPR-16546
This commit is contained in:
Rossen Stoyanchev
2018-03-02 10:41:40 -05:00
parent cec7204fca
commit cef98e1125
3 changed files with 58 additions and 36 deletions

View File

@@ -16,11 +16,13 @@
package org.springframework.http.codec.multipart;
import java.io.IOException;
import java.io.File;
import java.time.Duration;
import java.util.Map;
import org.junit.Test;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import reactor.test.StepVerifier;
import org.springframework.core.ResolvableType;
@@ -28,25 +30,25 @@ import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.core.io.buffer.DataBufferUtils;
import org.springframework.core.io.buffer.DefaultDataBufferFactory;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType;
import org.springframework.http.MockHttpOutputMessage;
import org.springframework.http.converter.FormHttpMessageConverter;
import org.springframework.http.client.MultipartBodyBuilder;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.mock.http.client.reactive.test.MockClientHttpRequest;
import org.springframework.mock.http.server.reactive.test.MockServerHttpRequest;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import static java.util.Collections.emptyMap;
import static java.util.Collections.*;
import static org.junit.Assert.*;
import static org.springframework.core.ResolvableType.forClassWithGenerics;
import static org.springframework.http.HttpHeaders.CONTENT_LENGTH;
import static org.springframework.http.HttpHeaders.CONTENT_TYPE;
import static org.springframework.http.MediaType.MULTIPART_FORM_DATA;
import static org.springframework.core.ResolvableType.*;
import static org.springframework.http.HttpHeaders.*;
import static org.springframework.http.MediaType.*;
/**
* Unit tests for {@link SynchronossPartHttpMessageReader}.
*
* @author Sebastien Deleuze
* @author Rossen Stoyanchev
*/
public class SynchronossPartHttpMessageReaderTests {
@@ -78,7 +80,7 @@ public class SynchronossPartHttpMessageReaderTests {
}
@Test
public void resolveParts() throws IOException {
public void resolveParts() {
ServerHttpRequest request = generateMultipartRequest();
ResolvableType elementType = forClassWithGenerics(MultiValueMap.class, String.class, Part.class);
MultiValueMap<String, Part> parts = this.reader.readMono(elementType, request, emptyMap()).block();
@@ -102,6 +104,24 @@ public class SynchronossPartHttpMessageReaderTests {
assertEquals("bar", ((FormFieldPart) part).value());
}
@Test // SPR-16545
public void transferTo() {
ServerHttpRequest request = generateMultipartRequest();
ResolvableType elementType = forClassWithGenerics(MultiValueMap.class, String.class, Part.class);
MultiValueMap<String, Part> parts = this.reader.readMono(elementType, request, emptyMap()).block();
assertNotNull(parts);
FilePart part = (FilePart) parts.getFirst("fooPart");
assertNotNull(part);
File dest = new File(System.getProperty("java.io.tmpdir") + "/" + part.filename());
part.transferTo(dest).block(Duration.ofSeconds(5));
assertTrue(dest.exists());
assertEquals(12, dest.length());
assertTrue(dest.delete());
}
@Test
public void bodyError() {
ServerHttpRequest request = generateErrorMultipartRequest();
@@ -110,29 +130,24 @@ public class SynchronossPartHttpMessageReaderTests {
}
private ServerHttpRequest generateMultipartRequest() throws IOException {
HttpHeaders fooHeaders = new HttpHeaders();
fooHeaders.setContentType(MediaType.TEXT_PLAIN);
ClassPathResource fooResource = new ClassPathResource("org/springframework/http/codec/multipart/foo.txt");
HttpEntity<ClassPathResource> fooPart = new HttpEntity<>(fooResource, fooHeaders);
HttpEntity<String> barPart = new HttpEntity<>("bar");
FormHttpMessageConverter converter = new FormHttpMessageConverter();
MockHttpOutputMessage outputMessage = new MockHttpOutputMessage();
MultiValueMap<String, Object> parts = new LinkedMultiValueMap<>();
parts.add("fooPart", fooPart);
parts.add("barPart", barPart);
converter.write(parts, MULTIPART_FORM_DATA, outputMessage);
byte[] content = outputMessage.getBodyAsBytes();
return MockServerHttpRequest
.post("/foo")
.header(CONTENT_TYPE, outputMessage.getHeaders().getContentType().toString())
.header(CONTENT_LENGTH, String.valueOf(content.length))
.body(new String(content));
private ServerHttpRequest generateMultipartRequest() {
MultipartBodyBuilder partsBuilder = new MultipartBodyBuilder();
partsBuilder.part("fooPart", new ClassPathResource("org/springframework/http/codec/multipart/foo.txt"));
partsBuilder.part("barPart", "bar");
MockClientHttpRequest outputMessage = new MockClientHttpRequest(HttpMethod.POST, "/");
new MultipartHttpMessageWriter()
.write(Mono.just(partsBuilder.build()), null, MediaType.MULTIPART_FORM_DATA, outputMessage, null)
.block(Duration.ofSeconds(5));
return MockServerHttpRequest.post("/")
.contentType(outputMessage.getHeaders().getContentType())
.body(outputMessage.getBody());
}
private ServerHttpRequest generateErrorMultipartRequest() {
return MockServerHttpRequest
.post("/foo")
return MockServerHttpRequest.post("/")
.header(CONTENT_TYPE, MULTIPART_FORM_DATA.toString())
.body(Flux.just(new DefaultDataBufferFactory().wrap("invalid content".getBytes())));
}