http client: Only read response body if response code < 400.

The jdk http client will not allow reading the body if the response code >= 400.

Relates to elastic/elasticsearch#271

Original commit: elastic/x-pack-elasticsearch@08836f92ae
This commit is contained in:
Martijn van Groningen 2015-04-29 12:11:29 +02:00
parent 04f4a09feb
commit 7f24f229e2
4 changed files with 43 additions and 15 deletions

View File

@ -42,8 +42,10 @@ public class ExecutableHttpInput extends ExecutableInput<HttpInput, HttpInput.Re
HttpRequest request = input.getRequest().render(templateEngine, model);
HttpResponse response = client.execute(request);
Payload payload;
if (input.getExtractKeys() != null) {
final Payload payload;
if (!response.hasContent()) {
payload = Payload.EMPTY;
} else if (input.getExtractKeys() != null) {
XContentParser parser = XContentHelper.createParser(response.body());
Map<String, Object> filteredKeys = XContentFilterKeysUtils.filterMapOrdered(input.getExtractKeys(), parser);
payload = new Payload.Simple(filteredKeys);

View File

@ -112,10 +112,15 @@ public class HttpClient extends AbstractComponent {
}
urlConnection.connect();
byte[] body = Streams.copyToByteArray(urlConnection.getInputStream());
HttpResponse response = new HttpResponse(urlConnection.getResponseCode(), body);
logger.debug("http status code [{}]", response.status());
final HttpResponse response;
final int statusCode = urlConnection.getResponseCode();
logger.debug("http status code [{}]", statusCode);
if (statusCode < 400) {
byte[] body = Streams.copyToByteArray(urlConnection.getInputStream());
response = new HttpResponse(statusCode, body);
} else {
response = new HttpResponse(statusCode);
}
return response;
}

View File

@ -24,7 +24,7 @@ public class HttpResponse implements ToXContent {
private final BytesReference body;
public HttpResponse(int status) {
this(status, BytesArray.EMPTY);
this(status, (BytesReference) null);
}
public HttpResponse(int status, String body) {
@ -44,6 +44,10 @@ public class HttpResponse implements ToXContent {
return status;
}
public boolean hasContent() {
return body != null;
}
public BytesReference body() {
return body;
}
@ -69,10 +73,12 @@ public class HttpResponse implements ToXContent {
@Override
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
return builder.startObject()
.field(STATUS_FIELD.getPreferredName(), status)
.field(BODY_FIELD.getPreferredName(), body.toUtf8())
.endObject();
builder = builder.startObject().field(STATUS_FIELD.getPreferredName(), status);
if (hasContent()) {
builder = builder.field(BODY_FIELD.getPreferredName(), body.toUtf8());
}
builder.endObject();
return builder;
}
public static HttpResponse parse(XContentParser parser) throws IOException {
@ -108,12 +114,11 @@ public class HttpResponse implements ToXContent {
if (status < 0) {
throw new ParseException("could not parse http response. missing [status] numeric field holding the response's http status code");
}
if (body == null) {
throw new ParseException("could not parse http response. missing [status] string field holding the response's body");
return new HttpResponse(status);
} else {
return new HttpResponse(status, body);
}
return new HttpResponse(status, body);
}
public static class ParseException extends WatcherException {

View File

@ -29,6 +29,7 @@ import java.nio.file.Paths;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.nullValue;
import static org.hamcrest.core.Is.is;
/**
*/
@ -154,4 +155,19 @@ public class HttpClientTest extends ElasticsearchTestCase {
assertThat(recordedRequest.getBody().readUtf8Line(), equalTo("body"));
}
@Test
public void test400Code() throws Exception {
webServer.enqueue(new MockResponse().setResponseCode(400));
HttpRequest.Builder request = HttpRequest.builder("localhost", webPort)
.method(HttpMethod.POST)
.path("/test")
.auth(new BasicAuth("user", "pass".toCharArray()))
.body("body");
HttpResponse response = httpClient.execute(request.build());
assertThat(response.status(), equalTo(400));
assertThat(response.hasContent(), is(false));
assertThat(response.body(), nullValue());
}
}