Skip to content

Commit

Permalink
Update readStreamFrame() to error when a partial buffer is read.
Browse files Browse the repository at this point in the history
When zero bytes are read when trying to read the 8 byte header, assume the
stream is done and stop iterating. If 1-7 bytes are read when trying to read
the 8 byte header, throw an IOException indicating the error. If anything other
than the full N bytes are read for the message, i.e. if 0 to N-1 bytes are
read, also throw an IOException.

This ensures that unexpected log stream behavior is propaged as an error to the
user.

Signed-off-by: Thomas Van Doren <thomas.vandoren@gmail.com>
  • Loading branch information
thomasvandoren committed May 5, 2016
1 parent 2de9724 commit d4180c7
Showing 1 changed file with 29 additions and 3 deletions.
32 changes: 29 additions & 3 deletions src/main/java/io/fabric8/maven/docker/access/log/LogRequestor.java
Original file line number Diff line number Diff line change
Expand Up @@ -102,16 +102,42 @@ public void run() {
}
}

private static class NoBytesReadException extends IOException {
public NoBytesReadException() {
}
}

/**
* This is a copy of ByteStreams.readFully(), with the slight change that it throws
* NoBytesReadException if zero bytes are read. Otherwise it is identical.
*
* @param in
* @param bytes
* @throws IOException
*/
private void readFully(InputStream in, byte[] bytes) throws IOException {
int read = ByteStreams.read(in, bytes, 0, bytes.length);
if (read == 0) {
throw new NoBytesReadException();
} else if (read != bytes.length) {
throw new EOFException("reached end of stream after reading "
+ read + " bytes; " + bytes.length + " bytes expected");
}
}

private boolean readStreamFrame(InputStream is) throws IOException, LogCallback.DoneException {
// Read the header, which is composed of eight bytes. The first byte is an integer
// indicating the stream type (0 = stdin, 1 = stdout, 2 = stderr), the next three are thrown
// out, and the final four are the size of the remaining stream as an integer.
ByteBuffer headerBuffer = ByteBuffer.allocate(8);
headerBuffer.order(ByteOrder.BIG_ENDIAN);
try {
ByteStreams.readFully(is, headerBuffer.array());
} catch (EOFException e) {
this.readFully(is, headerBuffer.array());
} catch (NoBytesReadException e) {
// Not bytes read for stream. Return false to stop consuming stream.
return false;
} catch (EOFException e) {
throw new IOException("Failed to read log header. Could not read all 8 bytes. " + e.getMessage(), e);
}

// Grab the stream type (stdout, stderr, stdin) from first byte and throw away other 3 bytes.
Expand All @@ -130,7 +156,7 @@ private boolean readStreamFrame(InputStream is) throws IOException, LogCallback.
try {
ByteStreams.readFully(is, payload.array());
} catch (EOFException e) {
return false;
throw new IOException("Failed to read log message. Could not read all " + size + " bytes. " + e.getMessage(), e);
}

String message = Charsets.UTF_8.newDecoder().decode(payload).toString();
Expand Down

0 comments on commit d4180c7

Please sign in to comment.