From 2b79b93a4e8e656b673236c400b4e20aad785a9a Mon Sep 17 00:00:00 2001 From: Adrian Cole Date: Sun, 2 Aug 2015 11:23:55 -0700 Subject: [PATCH] Avoids InputStream.available when determining if a stream is empty InputStream.available isn't a reliable api. This uses an alternative approach, which is to read the first byte to see if it is present. This allows us to continue to avoid "No content to map due to end-of-input" errors, but in a more supportable way. Fixes #250 --- .../main/java/feign/jackson/JacksonDecoder.java | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/jackson/src/main/java/feign/jackson/JacksonDecoder.java b/jackson/src/main/java/feign/jackson/JacksonDecoder.java index fc28bed1..1a2cb782 100644 --- a/jackson/src/main/java/feign/jackson/JacksonDecoder.java +++ b/jackson/src/main/java/feign/jackson/JacksonDecoder.java @@ -20,8 +20,9 @@ import com.fasterxml.jackson.databind.Module; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.RuntimeJsonMappingException; +import java.io.BufferedReader; import java.io.IOException; -import java.io.InputStream; +import java.io.Reader; import java.lang.reflect.Type; import java.util.Collections; @@ -50,12 +51,18 @@ public class JacksonDecoder implements Decoder { if (response.body() == null) { return null; } - InputStream inputStream = response.body().asInputStream(); + Reader reader = response.body().asReader(); + if (!reader.markSupported()) { + reader = new BufferedReader(reader, 1); + } try { - if (inputStream.available() <= 0){ - return null; + // Read the first byte to see if we have any data + reader.mark(1); + if (reader.read() == -1) { + return null; // Eagerly returning null avoids "No content to map due to end-of-input" } - return mapper.readValue(inputStream, mapper.constructType(type)); + reader.reset(); + return mapper.readValue(reader, mapper.constructType(type)); } catch (RuntimeJsonMappingException e) { if (e.getCause() != null && e.getCause() instanceof IOException) { throw IOException.class.cast(e.getCause());