Skip to content

Commit 4f770ca

Browse files
committed
Synchronoss should create temp directory lazily
The SynchronossPartHttpMessageReader should only create temp directory when needed, not at startup. Closes gh-27092
1 parent d469f62 commit 4f770ca

File tree

1 file changed

+37
-19
lines changed

1 file changed

+37
-19
lines changed

spring-web/src/main/java/org/springframework/http/codec/multipart/SynchronossPartHttpMessageReader.java

Lines changed: 37 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
package org.springframework.http.codec.multipart;
1818

1919
import java.io.IOException;
20-
import java.io.UncheckedIOException;
2120
import java.nio.channels.Channels;
2221
import java.nio.channels.FileChannel;
2322
import java.nio.channels.ReadableByteChannel;
@@ -31,6 +30,7 @@
3130
import java.util.Map;
3231
import java.util.Optional;
3332
import java.util.concurrent.atomic.AtomicInteger;
33+
import java.util.concurrent.atomic.AtomicReference;
3434
import java.util.function.Consumer;
3535

3636
import org.synchronoss.cloud.nio.multipart.DefaultPartBodyStreamStorageFactory;
@@ -46,6 +46,7 @@
4646
import reactor.core.publisher.FluxSink;
4747
import reactor.core.publisher.Mono;
4848
import reactor.core.publisher.SignalType;
49+
import reactor.core.scheduler.Schedulers;
4950

5051
import org.springframework.core.ResolvableType;
5152
import org.springframework.core.codec.DecodingException;
@@ -88,7 +89,7 @@ public class SynchronossPartHttpMessageReader extends LoggingCodecSupport implem
8889

8990
private int maxParts = -1;
9091

91-
private Path fileStorageDirectory = createTempDirectory();
92+
private final AtomicReference<Path> fileStorageDirectory = new AtomicReference<>();
9293

9394

9495
/**
@@ -163,7 +164,7 @@ public void setFileStorageDirectory(Path fileStorageDirectory) throws IOExceptio
163164
if (!Files.exists(fileStorageDirectory)) {
164165
Files.createDirectory(fileStorageDirectory);
165166
}
166-
this.fileStorageDirectory = fileStorageDirectory;
167+
this.fileStorageDirectory.set(fileStorageDirectory);
167168
}
168169

169170

@@ -189,29 +190,46 @@ public boolean canRead(ResolvableType elementType, @Nullable MediaType mediaType
189190

190191
@Override
191192
public Flux<Part> read(ResolvableType elementType, ReactiveHttpInputMessage message, Map<String, Object> hints) {
192-
return Flux.create(new SynchronossPartGenerator(message, this.fileStorageDirectory))
193-
.doOnNext(part -> {
194-
if (!Hints.isLoggingSuppressed(hints)) {
195-
LogFormatUtils.traceDebug(logger, traceOn -> Hints.getLogPrefix(hints) + "Parsed " +
196-
(isEnableLoggingRequestDetails() ?
197-
LogFormatUtils.formatValue(part, !traceOn) :
198-
"parts '" + part.name() + "' (content masked)"));
199-
}
200-
});
193+
return getFileStorageDirectory().flatMapMany(directory ->
194+
Flux.create(new SynchronossPartGenerator(message, directory))
195+
.doOnNext(part -> {
196+
if (!Hints.isLoggingSuppressed(hints)) {
197+
LogFormatUtils.traceDebug(logger, traceOn -> Hints.getLogPrefix(hints) + "Parsed " +
198+
(isEnableLoggingRequestDetails() ?
199+
LogFormatUtils.formatValue(part, !traceOn) :
200+
"parts '" + part.name() + "' (content masked)"));
201+
}
202+
}));
201203
}
202204

203205
@Override
204206
public Mono<Part> readMono(ResolvableType elementType, ReactiveHttpInputMessage message, Map<String, Object> hints) {
205207
return Mono.error(new UnsupportedOperationException("Cannot read multipart request body into single Part"));
206208
}
207209

208-
private static Path createTempDirectory() {
209-
try {
210-
return Files.createTempDirectory(FILE_STORAGE_DIRECTORY_PREFIX);
211-
}
212-
catch (IOException ex) {
213-
throw new UncheckedIOException(ex);
214-
}
210+
private Mono<Path> getFileStorageDirectory() {
211+
return Mono.defer(() -> {
212+
Path directory = this.fileStorageDirectory.get();
213+
if (directory != null) {
214+
return Mono.just(directory);
215+
}
216+
else {
217+
return Mono.fromCallable(() -> {
218+
Path tempDirectory = Files.createTempDirectory(FILE_STORAGE_DIRECTORY_PREFIX);
219+
if (this.fileStorageDirectory.compareAndSet(null, tempDirectory)) {
220+
return tempDirectory;
221+
}
222+
else {
223+
try {
224+
Files.delete(tempDirectory);
225+
}
226+
catch (IOException ignored) {
227+
}
228+
return this.fileStorageDirectory.get();
229+
}
230+
}).subscribeOn(Schedulers.boundedElastic());
231+
}
232+
});
215233
}
216234

217235

0 commit comments

Comments
 (0)