From a989ea0867f36ddf1f0e58b71aade8a2500ffe7d Mon Sep 17 00:00:00 2001 From: Rossen Stoyanchev Date: Sat, 24 Mar 2018 08:59:16 -0400 Subject: [PATCH] Polish Synchronoss message reader Issue: SPR-16639 --- .../SynchronossPartHttpMessageReader.java | 51 ++++++++++++------- 1 file changed, 33 insertions(+), 18 deletions(-) diff --git a/spring-web/src/main/java/org/springframework/http/codec/multipart/SynchronossPartHttpMessageReader.java b/spring-web/src/main/java/org/springframework/http/codec/multipart/SynchronossPartHttpMessageReader.java index 765918bc8c5..8324c402d50 100644 --- a/spring-web/src/main/java/org/springframework/http/codec/multipart/SynchronossPartHttpMessageReader.java +++ b/spring-web/src/main/java/org/springframework/http/codec/multipart/SynchronossPartHttpMessageReader.java @@ -98,13 +98,13 @@ public class SynchronossPartHttpMessageReader implements HttpMessageReader Map hints) { return Mono.error(new UnsupportedOperationException( - "This reader does not support reading a single element.")); + "Can't read a multipart request body into a single Part.")); } /** - * Consume and feed input to the Synchronoss parser, then adapt parser - * output events to {@code Flux>}. + * Consume and feed input to the Synchronoss parser, then listen for parser + * output events and adapt to {@code Flux>}. */ private static class SynchronossPartGenerator implements Consumer> { @@ -112,11 +112,13 @@ public class SynchronossPartHttpMessageReader implements HttpMessageReader private final DataBufferFactory bufferFactory; + SynchronossPartGenerator(ReactiveHttpInputMessage inputMessage, DataBufferFactory factory) { this.inputMessage = inputMessage; this.bufferFactory = factory; } + @Override public void accept(FluxSink emitter) { HttpHeaders headers = this.inputMessage.getHeaders(); @@ -176,12 +178,14 @@ public class SynchronossPartHttpMessageReader implements HttpMessageReader private final AtomicInteger terminated = new AtomicInteger(0); - FluxSinkAdapterListener(FluxSink sink, DataBufferFactory bufferFactory, MultipartContext context) { + + FluxSinkAdapterListener(FluxSink sink, DataBufferFactory factory, MultipartContext context) { this.sink = sink; - this.bufferFactory = bufferFactory; + this.bufferFactory = factory; this.context = context; } + @Override public void onPartFinished(StreamStorage storage, Map> headers) { HttpHeaders httpHeaders = new HttpHeaders(); @@ -192,14 +196,14 @@ public class SynchronossPartHttpMessageReader implements HttpMessageReader private Part createPart(StreamStorage storage, HttpHeaders httpHeaders) { String filename = MultipartUtils.getFileName(httpHeaders); if (filename != null) { - return new SynchronossFilePart(httpHeaders, storage, this.bufferFactory, filename); + return new SynchronossFilePart(httpHeaders, filename, storage, this.bufferFactory); } else if (MultipartUtils.isFormField(httpHeaders, this.context)) { String value = MultipartUtils.readFormParameterValue(storage, httpHeaders); return new SynchronossFormFieldPart(httpHeaders, this.bufferFactory, value); } else { - return new DefaultSynchronossPart(httpHeaders, storage, this.bufferFactory); + return new SynchronossPart(httpHeaders, storage, this.bufferFactory); } } @@ -229,20 +233,25 @@ public class SynchronossPartHttpMessageReader implements HttpMessageReader private abstract static class AbstractSynchronossPart implements Part { + private final String name; + private final HttpHeaders headers; private final DataBufferFactory bufferFactory; + AbstractSynchronossPart(HttpHeaders headers, DataBufferFactory bufferFactory) { Assert.notNull(headers, "HttpHeaders is required"); Assert.notNull(bufferFactory, "'bufferFactory' is required"); + this.name = MultipartUtils.getFieldName(headers); this.headers = headers; this.bufferFactory = bufferFactory; } + @Override public String name() { - return MultipartUtils.getFieldName(this.headers); + return this.name; } @Override @@ -250,26 +259,27 @@ public class SynchronossPartHttpMessageReader implements HttpMessageReader return this.headers; } - protected DataBufferFactory getBufferFactory() { + DataBufferFactory getBufferFactory() { return this.bufferFactory; } } - private static class DefaultSynchronossPart extends AbstractSynchronossPart { + private static class SynchronossPart extends AbstractSynchronossPart { private final StreamStorage storage; - DefaultSynchronossPart(HttpHeaders headers, StreamStorage storage, DataBufferFactory factory) { + + SynchronossPart(HttpHeaders headers, StreamStorage storage, DataBufferFactory factory) { super(headers, factory); Assert.notNull(storage, "'storage' is required"); this.storage = storage; } + @Override public Flux content() { - return DataBufferUtils.readInputStream(this.storage::getInputStream, getBufferFactory(), - 4096); + return DataBufferUtils.readInputStream(getStorage()::getInputStream, getBufferFactory(), 4096); } protected StreamStorage getStorage() { @@ -278,20 +288,23 @@ public class SynchronossPartHttpMessageReader implements HttpMessageReader } - private static class SynchronossFilePart extends DefaultSynchronossPart implements FilePart { + private static class SynchronossFilePart extends SynchronossPart implements FilePart { private static final OpenOption[] FILE_CHANNEL_OPTIONS = { StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING, StandardOpenOption.WRITE }; + private final String filename; - public SynchronossFilePart( - HttpHeaders headers, StreamStorage storage, DataBufferFactory factory, String filename) { + + SynchronossFilePart(HttpHeaders headers, String filename, StreamStorage storage, + DataBufferFactory factory) { super(headers, storage, factory); this.filename = filename; } + @Override public String filename() { return this.filename; @@ -342,11 +355,13 @@ public class SynchronossPartHttpMessageReader implements HttpMessageReader private final String content; + SynchronossFormFieldPart(HttpHeaders headers, DataBufferFactory bufferFactory, String content) { super(headers, bufferFactory); this.content = content; } + @Override public String value() { return this.content; @@ -361,8 +376,8 @@ public class SynchronossPartHttpMessageReader implements HttpMessageReader } private Charset getCharset() { - return Optional.ofNullable(MultipartUtils.getCharEncoding(headers())) - .map(Charset::forName).orElse(StandardCharsets.UTF_8); + String name = MultipartUtils.getCharEncoding(headers()); + return (name != null ? Charset.forName(name) : StandardCharsets.UTF_8); } }