-
Notifications
You must be signed in to change notification settings - Fork 38.5k
Multipart File upload: Sometimes receiving empty files! [SPR-15955] #20507
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
Alexander Wilhelmer commented Added a single threaded remote test. The server instance is hosted on ubuntu with SNAPSHOT version, so this bug don't hit windows only. The server instance is online for max 7 days. |
Alexander Wilhelmer commented Okay i was able to reproduce with another setting, so i can say the problem is the WebClient Sender. Somehting to do with the Multipart POST. I did this change on the Spring5 App: @PostMapping(value = "/file-upload")
public Mono<ResponseEntity<String>> uploadFile(ServerHttpRequest request) {
LOG.info("uploadFile called ...");
Mono<String> stringMono = webClient.post()
.uri(uriBuilder -> uriBuilder.path("/file-upload2").build())
.body(request.getBody(), DataBuffer.class)
.headers(httpHeaders -> {
httpHeaders.put(HttpHeaders.CONTENT_TYPE, request.getHeaders().get(HttpHeaders.CONTENT_TYPE)) ;
})
.retrieve()
.bodyToMono(String.class);
return stringMono.map(s -> new ResponseEntity<>(s, HttpStatus.OK));
} The receiver wasn't a Spring5 App and checks the request against zero byte files. |
Brian Clozel commented I've spent quite some time with your repro project given its complexity, I can't figure out what's the feature under test nor what is actually failing. I can point you to a few places that could explain the current behavior though:
Could you rework your sample with this feedback? |
Alexander Wilhelmer commented Hi Brian Clozel, i reworked my example to make the test more simple. That was possible, cause i identified the problem is the WebClient sender, not the Server instance itself (see my last comment). Some comments on your points.
Please update my repo and you have a very simple construct to reproduce. |
Brian Clozel commented I took your sample app and rewrote the test to avoid playing with threads: @Test
public void uploadFile() throws Exception {
MultiValueMap<String, Object> parts = createParts();
Flux<String> responses = Flux.range(0, 100)
.subscribeOn(Schedulers.elastic())
.flatMap(count -> webClient.post()
.uri("/test/file-upload")
.body(BodyInserters.fromMultipartData(parts))
.exchange()
.returnResult(String.class)
.getResponseBody());
StepVerifier.create(responses)
.expectComplete()
.verify(Duration.ofSeconds(30));
} I can't reproduce the issue. |
Alexander Wilhelmer commented I added the concurrency threads to reproduce it on localhost. Just removing concurrency against localhost to fix the issue doesn't help, when testing against remote server (network!) still fails without concurrency. |
Alexander Wilhelmer commented Test RemoteTest.java: int iterations = 500;
for (int i = 0; i < iterations; i++) {
LOG.info("Calling test post...");
webClient.post()
.uri(uriBuilder -> uriBuilder.path("/test/file-upload").build())
.accept(MediaType.MULTIPART_FORM_DATA)
.body(BodyInserters.fromMultipartData(parts))
.exchange()
.expectBody(String.class)
.consumeWith(body -> {
if (body.getResponseBody() != null) {
throw new AssertionError(String.format("Error, File size incorrect! Server Message: %s", body.getResponseBody()));
}
});
} Result:
|
Brian Clozel commented This is getting really confusing - weren't you pointing to the |
Alexander Wilhelmer commented Because when i run this remote test with a simple HTTP Apache Client instead of the WebClient Junit Test i can't reproduce the zero byte file error. |
Brian Clozel commented I've just confirmed that there might be an issue in
Headers ans boundary are properly written, but not the actual file content. |
Brian Clozel commented There's been quite a few changes around the client and the multipart parser lately. @Test
public void multipartTest() throws Exception {
MultiValueMap<String, Object> parts = createParts();
ReactorClientHttpConnector connector = new ReactorClientHttpConnector();
WebClient client = WebClient.builder().clientConnector(connector).baseUrl("http://spring5-multipart.cfapps.io").build();
Flux<String> responses = Flux.range(0, 100)
.flatMap(count -> client.post()
.uri("/test/file-upload")
.body(BodyInserters.fromMultipartData(parts))
.retrieve()
.bodyToMono(String.class));
StepVerifier.create(responses)
.expectNextCount(100)
.expectComplete()
.verify(Duration.ofSeconds(30));
} Alexander Wilhelmer, could you let me know if you can still reproduce that issue against that service instance? |
Alexander Wilhelmer opened SPR-15955 and commented
On my example repo in branch "zero-bytes-files" i was able to reproduce a bug something to do with multipart file upload and the resulting transferTo method. I'm transferring files into temp files and i'm checking against zero byte files, so no data seems to be revceived on the netty server or its a bug in the synchronoss parser,
This test seems to be unfair, because it is starting 20 concurrent threads against the endpoint, but i was able to reproduce this bug on another setting, only with one thread and 100 iterations you are able to reproduce it. But you must host the first endpoint on a remote server. Some files will reproduce it more frequently, some files never. The concurrent threads force the test to reproduce it on localhost. You have to run the test min. five times, search for the first exception.
Tested with M3 (RC3) and SNAPSHOT(RC4) version from spring bootstrap, mainly on windows.
Exception:
I'm working on a temporary remote test to show the not-threaded reproduction.
Affects: 5.0 RC3, 5.0 RC4
Reference URL: https://github.com/awilhelmer/spring5-multipart-demo/tree/zero-bytes-files
Issue Links:
The text was updated successfully, but these errors were encountered: