Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
### Version 13.17

* `Request` now accepts a `null` `Request.Body` and treats it as "no body", instead of throwing a
`NullPointerException` from `body()`, `charset()`, `isBinary()` and `length()`. A request with no
body reports a `null` body and charset, is binary, and has length 0. Its `toString()` prints the
request line and headers without a body (#1210).

### Version 13.16

* Path-style expansion repeats the entry name for each collection or array value inside a map,
Expand Down
6 changes: 3 additions & 3 deletions core/src/main/java/feign/Request.java
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ public static Request create(
* @param httpMethod for the request.
* @param url for the request.
* @param headers to include.
* @param body of the request, can be {@literal null}
* @param body of the request, can be {@literal null}, meaning the request has no body.
* @return a Request
*/
public static Request create(
Expand Down Expand Up @@ -184,7 +184,7 @@ public static Request create(
this.httpMethod = checkNotNull(method, "httpMethod of %s", method.name());
this.url = checkNotNull(url, "url");
this.headers = checkNotNull(headers, "headers of %s %s", method, url);
this.body = body;
this.body = body != null ? body : Body.empty();
this.requestTemplate = requestTemplate;
protocolVersion = ProtocolVersion.HTTP_1_1;
}
Expand Down Expand Up @@ -308,7 +308,7 @@ public String toString() {
builder.append(field).append(": ").append(value).append('\n');
}
}
if (body != null) {
if (body() != null) {
builder.append('\n').append(body.asString());
}
return builder.toString();
Expand Down
50 changes: 50 additions & 0 deletions core/src/test/java/feign/RequestTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
import static org.assertj.core.api.Assertions.assertThat;

import feign.Request.Body;
import feign.Request.HttpMethod;
import java.util.Collections;
import org.junit.jupiter.api.Test;

public class RequestTest {
Expand All @@ -34,4 +36,52 @@ void stringBodyIsEncodedWithUtf8NotThePlatformDefault() {
assertThat(body.isBinary()).isFalse();
assertThat(body.asString()).isEqualTo(content);
}

@Test
void requestWithoutBodyHasNullBodyAndCharsetZeroLengthAndIsBinary() {
Request request = createGetRequestWithNullBody();

assertThat(request.body()).isNull();
assertThat(request.charset()).isNull();
assertThat(request.isBinary()).isTrue();
assertThat(request.length()).isZero();
}

@Test
void toStringOfRequestWithoutBodyOmitsBodySection() {
Request request = createGetRequestWithNullBody();

assertThat(request).hasToString("GET http://example.com HTTP/1.1\n");
}

@Test
void requestBuiltFromTemplateWithoutBodyOmitsBodyFromToString() {
Request request =
new RequestTemplate()
.method(HttpMethod.GET)
.target("http://example.com")
.resolve(Collections.emptyMap())
.request();

assertThat(request).hasToString("GET http://example.com HTTP/1.1\n");
}

@Test
void binaryBodyWithoutCharsetPrintsBinaryDataInToString() {
Request request =
new RequestTemplate()
.method(HttpMethod.POST)
.target("http://example.com")
.body(new byte[] {1, 2, 3}, null)
.resolve(Collections.emptyMap())
.request();

assertThat(request)
.hasToString("POST http://example.com HTTP/1.1\nContent-Length: 3\n\nBinary data");
}

private static Request createGetRequestWithNullBody() {
return Request.create(
HttpMethod.GET, "http://example.com", Collections.emptyMap(), (Body) null, null);
}
}