diff --git a/okhttp/third_party/okhttp/main/java/io/grpc/okhttp/internal/framed/Http2.java b/okhttp/third_party/okhttp/main/java/io/grpc/okhttp/internal/framed/Http2.java index 0eb49b9f076..f6408ae61d1 100644 --- a/okhttp/third_party/okhttp/main/java/io/grpc/okhttp/internal/framed/Http2.java +++ b/okhttp/third_party/okhttp/main/java/io/grpc/okhttp/internal/framed/Http2.java @@ -397,6 +397,10 @@ static final class Writer implements io.grpc.okhttp.internal.framed.FrameWriter @Override public synchronized void ackSettings(io.grpc.okhttp.internal.framed.Settings peerSettings) throws IOException { if (closed) throw new IOException("closed"); this.maxFrameSize = peerSettings.getMaxFrameSize(maxFrameSize); + int headerTableSize = peerSettings.getHeaderTableSize(); + if (headerTableSize >= 0) { + hpackWriter.resizeHeaderTable(headerTableSize); + } int length = 0; byte type = TYPE_SETTINGS; byte flags = FLAG_ACK; diff --git a/okhttp/third_party/okhttp/test/java/io/grpc/okhttp/internal/framed/Http2Test.java b/okhttp/third_party/okhttp/test/java/io/grpc/okhttp/internal/framed/Http2Test.java index 5631a18515d..ab608d0dfcf 100644 --- a/okhttp/third_party/okhttp/test/java/io/grpc/okhttp/internal/framed/Http2Test.java +++ b/okhttp/third_party/okhttp/test/java/io/grpc/okhttp/internal/framed/Http2Test.java @@ -26,8 +26,10 @@ import java.io.IOException; import java.nio.charset.StandardCharsets; import java.util.Arrays; +import java.util.List; import okio.Buffer; import okio.BufferedSink; +import okio.ByteString; import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; @@ -75,6 +77,46 @@ public void dataFramePadding() throws IOException { assertEquals(2037 - 125, bufferIn.size()); } + @Test + public void writerAckSettingsResizesHpackWriter() throws IOException { + Buffer sink = new Buffer(); + Http2.Writer writer = new Http2.Writer(sink, true); + + // Peer sends SETTINGS_HEADER_TABLE_SIZE = 2048 + Settings peerSettings = new Settings(); + peerSettings.set(Settings.HEADER_TABLE_SIZE, 0, 2048); + + writer.ackSettings(peerSettings); + + // Verify ACK frame is written (9 bytes) + ByteString expectedAck = ByteString.decodeHex("000000040100000000"); + assertEquals(expectedAck, sink.readByteString()); + + // Write headers to trigger dynamic table size update + List
headers = Arrays.asList(new Header("foo", "bar")); + writer.headers(STREAM_ID, headers); + + // Read back the HEADERS frame and verify it has the dynamic table size update + Buffer buffer = sink; + int length = ((buffer.readByte() & 0xff) << 16) + | ((buffer.readByte() & 0xff) << 8) + | (buffer.readByte() & 0xff); + int type = buffer.readByte() & 0xff; + int flags = buffer.readByte() & 0xff; + int streamId = buffer.readInt() & 0x7fffffff; + + assertEquals(Http2.TYPE_HEADERS, type); + assertEquals(12, length); + assertEquals(Http2.FLAG_END_HEADERS, flags); + assertEquals(STREAM_ID, streamId); + + // Verify first bytes of payload are the dynamic table size update (2048) + // In HPACK, table size 2048 update is 0x3F, 0xE1, 0x0F + assertEquals(0x3F, buffer.readByte() & 0xff); + assertEquals(0xE1, buffer.readByte() & 0xff); + assertEquals(0x0F, buffer.readByte() & 0xff); + } + private Buffer createData(int flag, int length, int paddingLength) throws IOException { Buffer sink = new Buffer(); writeLength(sink, length);