1
0
mirror of https://github.com/square/okhttp.git synced 2026-01-18 20:40:58 +03:00

Merge pull request #939 from square/jwilson_0617_window_size_bugs

Fix two problems with the window size.
This commit is contained in:
Jesse Wilson
2014-06-18 13:02:11 -04:00
4 changed files with 26 additions and 21 deletions

View File

@@ -211,17 +211,17 @@ public final class Http2ConnectionTest {
@Test public void readSendsWindowUpdateHttp2() throws Exception {
peer.setVariantAndClient(HTTP_2, false);
int windowUpdateThreshold = DEFAULT_INITIAL_WINDOW_SIZE / 2;
int windowSize = 100;
int windowUpdateThreshold = 50;
// Write the mocking script.
peer.acceptFrame(); // SYN_STREAM
peer.sendFrame().synReply(false, 3, headerEntries("a", "android"));
for (int i = 0; i < 3; i++) {
// Send frames summing to windowUpdateThreshold.
for (int sent = 0, count; sent < windowUpdateThreshold; sent += count) {
count = Math.min(HTTP_2.maxFrameSize(), windowUpdateThreshold - sent);
peer.sendFrame().data(false, 3, data(count));
}
// Send frames of summing to size 50, which is windowUpdateThreshold.
peer.sendFrame().data(false, 3, data(24));
peer.sendFrame().data(false, 3, data(25));
peer.sendFrame().data(false, 3, data(1));
peer.acceptFrame(); // connection WINDOW UPDATE
peer.acceptFrame(); // stream WINDOW UPDATE
}
@@ -230,15 +230,15 @@ public final class Http2ConnectionTest {
// Play it back.
SpdyConnection connection = connection(peer, HTTP_2);
connection.okHttpSettings.set(Settings.INITIAL_WINDOW_SIZE, 0, windowSize);
SpdyStream stream = connection.newStream(headerEntries("b", "banana"), false, true);
assertEquals(0, stream.unacknowledgedBytesRead);
assertEquals(headerEntries("a", "android"), stream.getResponseHeaders());
Source in = stream.getSource();
Buffer buffer = new Buffer();
while (in.read(buffer, 1024) != -1) {
if (buffer.size() == 3 * windowUpdateThreshold) break;
}
buffer.writeAll(in);
assertEquals(-1, in.read(buffer, 1));
assertEquals(150, buffer.size());
MockSpdyPeer.InFrame synStream = peer.takeFrame();
assertEquals(TYPE_HEADERS, synStream.type);

View File

@@ -1013,17 +1013,17 @@ public final class Spdy3ConnectionTest {
@Test public void readSendsWindowUpdate() throws Exception {
peer.setVariantAndClient(SPDY3, false);
int windowUpdateThreshold = DEFAULT_INITIAL_WINDOW_SIZE / 2;
int windowSize = 100;
int windowUpdateThreshold = 50;
// Write the mocking script.
peer.acceptFrame(); // SYN_STREAM
peer.sendFrame().synReply(false, 1, headerEntries("a", "android"));
for (int i = 0; i < 3; i++) {
// Send frames summing to windowUpdateThreshold.
for (int sent = 0, count; sent < windowUpdateThreshold; sent += count) {
count = Math.min(SPDY3.maxFrameSize(), windowUpdateThreshold - sent);
peer.sendFrame().data(false, 1, data(count));
}
// Send frames of summing to size 50, which is windowUpdateThreshold.
peer.sendFrame().data(false, 1, data(24));
peer.sendFrame().data(false, 1, data(25));
peer.sendFrame().data(false, 1, data(1));
peer.acceptFrame(); // connection WINDOW UPDATE
peer.acceptFrame(); // stream WINDOW UPDATE
}
@@ -1032,15 +1032,15 @@ public final class Spdy3ConnectionTest {
// Play it back.
SpdyConnection connection = connection(peer, SPDY3);
connection.okHttpSettings.set(Settings.INITIAL_WINDOW_SIZE, 0, windowSize);
SpdyStream stream = connection.newStream(headerEntries("b", "banana"), false, true);
assertEquals(0, stream.unacknowledgedBytesRead);
assertEquals(headerEntries("a", "android"), stream.getResponseHeaders());
Source in = stream.getSource();
Buffer buffer = new Buffer();
while (in.read(buffer, 1024) != -1) {
if (buffer.size() == 3 * windowUpdateThreshold) break;
}
buffer.writeAll(in);
assertEquals(-1, in.read(buffer, 1));
assertEquals(150, buffer.size());
MockSpdyPeer.InFrame synStream = peer.takeFrame();
assertEquals(TYPE_HEADERS, synStream.type);

View File

@@ -113,6 +113,7 @@ public final class SpdyConnection implements Closeable {
// TODO: Do we want to dynamically adjust settings, or KISS and only set once?
final Settings okHttpSettings = new Settings();
// okHttpSettings.set(Settings.MAX_CONCURRENT_STREAMS, 0, max);
private static final int OKHTTP_CLIENT_WINDOW_SIZE = 16 * 1024 * 1024;
/** Settings we receive from the peer. */
// TODO: MWS will need to guard on this setting before attempting to push.
@@ -145,7 +146,7 @@ public final class SpdyConnection implements Closeable {
// thrashing window updates every 64KiB, yet small enough to avoid blowing
// up the heap.
if (builder.client) {
okHttpSettings.set(Settings.INITIAL_WINDOW_SIZE, 0, 16 * 1024 * 1024);
okHttpSettings.set(Settings.INITIAL_WINDOW_SIZE, 0, OKHTTP_CLIENT_WINDOW_SIZE);
}
hostName = builder.hostName;
@@ -503,6 +504,10 @@ public final class SpdyConnection implements Closeable {
public void sendConnectionPreface() throws IOException {
frameWriter.connectionPreface();
frameWriter.settings(okHttpSettings);
int windowSize = okHttpSettings.getInitialWindowSize(Settings.DEFAULT_INITIAL_WINDOW_SIZE);
if (windowSize != Settings.DEFAULT_INITIAL_WINDOW_SIZE) {
frameWriter.windowUpdate(0, windowSize - Settings.DEFAULT_INITIAL_WINDOW_SIZE);
}
}
public static class Builder {

View File

@@ -350,7 +350,7 @@ public final class SpdyStream {
// Flow control: notify the peer that we're ready for more data!
unacknowledgedBytesRead += read;
if (unacknowledgedBytesRead
>= connection.peerSettings.getInitialWindowSize(DEFAULT_INITIAL_WINDOW_SIZE) / 2) {
>= connection.okHttpSettings.getInitialWindowSize(DEFAULT_INITIAL_WINDOW_SIZE) / 2) {
connection.writeWindowUpdateLater(id, unacknowledgedBytesRead);
unacknowledgedBytesRead = 0;
}
@@ -360,7 +360,7 @@ public final class SpdyStream {
synchronized (connection) { // Multiple application threads may hit this section.
connection.unacknowledgedBytesRead += read;
if (connection.unacknowledgedBytesRead
>= connection.peerSettings.getInitialWindowSize(DEFAULT_INITIAL_WINDOW_SIZE) / 2) {
>= connection.okHttpSettings.getInitialWindowSize(DEFAULT_INITIAL_WINDOW_SIZE) / 2) {
connection.writeWindowUpdateLater(0, connection.unacknowledgedBytesRead);
connection.unacknowledgedBytesRead = 0;
}