Skip to content

Commit

Permalink
Merge pull request square#1116 from square/jwilson_1102_peer_close
Browse files Browse the repository at this point in the history
Don't close the SPDY peer too early.
  • Loading branch information
adriancole committed Nov 2, 2014
2 parents 6e7f147 + b1091b3 commit ee56def
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 15 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ public int frameCount() {
}

public FrameWriter sendFrame() {
outFrames.add(new OutFrame(frameCount++, bytesOut.size(), Integer.MAX_VALUE));
outFrames.add(new OutFrame(frameCount++, bytesOut.size(), false));
return frameWriter;
}

Expand All @@ -83,17 +83,27 @@ public FrameWriter sendFrame() {
* won't be generated naturally.
*/
public void sendFrame(byte[] frame) throws IOException {
outFrames.add(new OutFrame(frameCount++, bytesOut.size(), Integer.MAX_VALUE));
outFrames.add(new OutFrame(frameCount++, bytesOut.size(), false));
bytesOut.write(frame);
}

/**
* Sends a frame, truncated to {@code truncateToLength} bytes. This is only
* useful for testing error handling as the truncated frame will be
* malformed.
* Shortens the last frame from its original length to {@code length}. This
* will cause the peer to close the socket as soon as this frame has been
* written; otherwise the peer stays open until explicitly closed.
*/
public FrameWriter sendTruncatedFrame(int truncateToLength) {
outFrames.add(new OutFrame(frameCount++, bytesOut.size(), truncateToLength));
public FrameWriter truncateLastFrame(int length) {
OutFrame lastFrame = outFrames.remove(outFrames.size() - 1);
if (length >= bytesOut.size() - lastFrame.start) throw new IllegalArgumentException();

// Move everything from bytesOut into a new buffer.
Buffer fullBuffer = new Buffer();
bytesOut.read(fullBuffer, bytesOut.size());

// Copy back all but what we're truncating.
fullBuffer.read(bytesOut, lastFrame.start + length);

outFrames.add(new OutFrame(lastFrame.sequence, lastFrame.start, true));
return frameWriter;
}

Expand Down Expand Up @@ -136,26 +146,32 @@ private void readAndWriteFrames() throws IOException {

if (nextOutFrame != null && nextOutFrame.sequence == i) {
long start = nextOutFrame.start;
int truncateToLength = nextOutFrame.truncateToLength;
boolean truncated;
long end;
if (outFramesIterator.hasNext()) {
nextOutFrame = outFramesIterator.next();
end = nextOutFrame.start;
truncated = false;
} else {
end = outBytes.length;
truncated = nextOutFrame.truncated;
}

// write a frame
int length = (int) Math.min(end - start, truncateToLength);
// Write a frame.
int length = (int) (end - start);
out.write(outBytes, (int) start, length);

// If the last frame was truncated, immediately close the connection.
if (truncated) {
socket.close();
}
} else {
// read a frame
InFrame inFrame = new InFrame(i, reader);
reader.nextFrame(inFrame);
inFrames.add(inFrame);
}
}
Util.closeQuietly(socket);
}

public Socket openSocket() throws IOException {
Expand All @@ -179,12 +195,12 @@ public Socket openSocket() throws IOException {
private static class OutFrame {
private final int sequence;
private final long start;
private final int truncateToLength;
private final boolean truncated;

private OutFrame(int sequence, long start, int truncateToLength) {
private OutFrame(int sequence, long start, boolean truncated) {
this.sequence = sequence;
this.start = start;
this.truncateToLength = truncateToLength;
this.truncated = truncated;
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1109,7 +1109,8 @@ private Buffer data(int byteCount) {
// write the mocking script
peer.acceptFrame(); // SYN_STREAM
peer.sendFrame().synReply(false, 1, headerEntries("a", "android"));
peer.sendTruncatedFrame(8 + 100).data(false, 1, data(1024), 1024);
peer.sendFrame().data(false, 1, data(1024), 1024);
peer.truncateLastFrame(8 + 100);
peer.play();

// play it back
Expand Down

0 comments on commit ee56def

Please sign in to comment.