Browse Source

Allow repeatable writes in StreamingHttpOutputMessage

This commit adds a repeatable property to
StreamingHttpOutputMessage.Body, indicating that the body can be written
 multiple times. In HttpComponentsClientHttpRequest, this property is
 exposed via org.apache.hc.core5.http.HttpEntity.isRepeatable, to allow
 for redirects.

Closes gh-31449
pull/30079/head
Arjen Poutsma 11 months ago
parent
commit
e0ac000415
  1. 14
      spring-web/src/main/java/org/springframework/http/StreamingHttpOutputMessage.java
  2. 13
      spring-web/src/main/java/org/springframework/http/client/BufferingClientHttpRequestWrapper.java
  3. 4
      spring-web/src/main/java/org/springframework/http/client/HttpComponentsClientHttpRequest.java

14
spring-web/src/main/java/org/springframework/http/StreamingHttpOutputMessage.java

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2002-2018 the original author or authors.
* Copyright 2002-2023 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.
@ -50,6 +50,18 @@ public interface StreamingHttpOutputMessage extends HttpOutputMessage { @@ -50,6 +50,18 @@ public interface StreamingHttpOutputMessage extends HttpOutputMessage {
* @throws IOException in case of I/O errors
*/
void writeTo(OutputStream outputStream) throws IOException;
/**
* Indicates whether this body is capable of
* {@linkplain #writeTo(OutputStream) writing its data} more than
* once. Default implementation returns {@code false}.
* @return {@code true} if this body can be written repeatedly,
* {@code false} otherwise
* @since 6.1
*/
default boolean repeatable() {
return false;
}
}
}

13
spring-web/src/main/java/org/springframework/http/client/BufferingClientHttpRequestWrapper.java

@ -17,6 +17,7 @@ @@ -17,6 +17,7 @@
package org.springframework.http.client;
import java.io.IOException;
import java.io.OutputStream;
import java.net.URI;
import org.springframework.http.HttpHeaders;
@ -55,7 +56,17 @@ final class BufferingClientHttpRequestWrapper extends AbstractBufferingClientHtt @@ -55,7 +56,17 @@ final class BufferingClientHttpRequestWrapper extends AbstractBufferingClientHtt
this.request.getHeaders().putAll(headers);
if (this.request instanceof StreamingHttpOutputMessage streamingHttpOutputMessage) {
streamingHttpOutputMessage.setBody(outputStream -> StreamUtils.copy(bufferedOutput, outputStream));
streamingHttpOutputMessage.setBody(new StreamingHttpOutputMessage.Body() {
@Override
public void writeTo(OutputStream outputStream) throws IOException {
StreamUtils.copy(bufferedOutput, outputStream);
}
@Override
public boolean repeatable() {
return true;
}
});
}
else {
StreamUtils.copy(bufferedOutput, this.request.getBody());

4
spring-web/src/main/java/org/springframework/http/client/HttpComponentsClientHttpRequest.java

@ -153,12 +153,12 @@ final class HttpComponentsClientHttpRequest extends AbstractStreamingClientHttpR @@ -153,12 +153,12 @@ final class HttpComponentsClientHttpRequest extends AbstractStreamingClientHttpR
@Override
public boolean isRepeatable() {
return false;
return this.body.repeatable();
}
@Override
public boolean isStreaming() {
return true;
return false;
}
@Override

Loading…
Cancel
Save