|
50 | 50 | import java.io.InputStreamReader;
|
51 | 51 | import java.io.OutputStream;
|
52 | 52 | import java.io.Reader;
|
| 53 | +import java.io.SequenceInputStream; |
53 | 54 | import java.io.StringReader;
|
54 | 55 | import java.net.URLDecoder;
|
55 | 56 | import java.nio.charset.StandardCharsets;
|
@@ -235,18 +236,32 @@ public InputStream asInputStream() {
|
235 | 236 |
|
236 | 237 | @Override
|
237 | 238 | public Reader asReader() {
|
| 239 | + InputStream inputStream = asInputStream(); |
238 | 240 | Integer maybeLength = length();
|
239 |
| - if (maybeLength != null && maybeLength < 8192) { |
240 |
| - // Avoid InputStreamReader / HeapByteBuffer overhead for small (less than 8KiB) inputs, |
241 |
| - // see https://github.com/FasterXML/jackson-core/pull/1081 |
242 |
| - try (InputStream inputStream = asInputStream()) { |
243 |
| - return new StringReader(new String(inputStream.readAllBytes(), StandardCharsets.UTF_8)); |
244 |
| - } catch (IOException e) { |
245 |
| - throw new SafeUncheckedIoException( |
246 |
| - "Failed to read response body", e, SafeArg.of("length", maybeLength)); |
| 241 | + if (maybeLength != null) { |
| 242 | + int length = maybeLength; |
| 243 | + if (length < 8192) { |
| 244 | + // Avoid InputStreamReader / HeapByteBuffer overhead for small (less than 8KiB) inputs, |
| 245 | + // see https://github.com/FasterXML/jackson-core/pull/1081 |
| 246 | + // try to read an extra byte to determine if more bytes were provided than actual content-length |
| 247 | + int toRead = length + 1; |
| 248 | + byte[] bytes = new byte[toRead]; |
| 249 | + try { |
| 250 | + int read = inputStream.readNBytes(bytes, 0, toRead); |
| 251 | + if (read == length) { |
| 252 | + // fully read input |
| 253 | + inputStream.close(); |
| 254 | + return new StringReader(new String(bytes, 0, read, StandardCharsets.UTF_8)); |
| 255 | + } |
| 256 | + // input was larger than provided content length, fallback to stream path |
| 257 | + inputStream = new SequenceInputStream(new ByteArrayInputStream(bytes), inputStream); |
| 258 | + } catch (IOException e) { |
| 259 | + throw new SafeUncheckedIoException( |
| 260 | + "Failed to read response body", e, SafeArg.of("length", maybeLength)); |
| 261 | + } |
247 | 262 | }
|
248 | 263 | }
|
249 |
| - return new InputStreamReader(asInputStream(), StandardCharsets.UTF_8); |
| 264 | + return new InputStreamReader(inputStream, StandardCharsets.UTF_8); |
250 | 265 | }
|
251 | 266 |
|
252 | 267 | @Override
|
|
0 commit comments