diff -r f1f4b8cd0192 -r cd41f34e548c src/java.net.http/share/classes/jdk/internal/net/http/Http2Connection.java --- a/src/java.net.http/share/classes/jdk/internal/net/http/Http2Connection.java Wed Jul 04 16:54:56 2018 +0200 +++ b/src/java.net.http/share/classes/jdk/internal/net/http/Http2Connection.java Wed Jul 04 16:16:24 2018 +0100 @@ -673,7 +673,11 @@ client2.deleteConnection(this); List> c = new LinkedList<>(streams.values()); for (Stream s : c) { - s.connectionClosing(t); + try { + s.connectionClosing(t); + } catch (Throwable e) { + Log.logError("Failed to close stream {0}: {1}", s.streamid, e); + } } connection.close(); } @@ -738,6 +742,9 @@ } if (!(frame instanceof ResetFrame)) { + if (frame instanceof DataFrame) { + dropDataFrame((DataFrame)frame); + } if (isServerInitiatedStream(streamid)) { if (streamid < nextPushStream) { // trailing data on a cancelled push promise stream, @@ -776,6 +783,27 @@ } } + final void dropDataFrame(DataFrame df) { + if (closed) return; + if (debug.on()) { + debug.log("Dropping data frame for stream %d (%d payload bytes)", + df.streamid(), df.payloadLength()); + } + ensureWindowUpdated(df); + } + + final void ensureWindowUpdated(DataFrame df) { + try { + if (closed) return; + int length = df.payloadLength(); + if (length > 0) { + windowUpdater.update(length); + } + } catch(Throwable t) { + Log.logError("Unexpected exception while updating window: {0}", (Object)t); + } + } + private void handlePushPromise(Stream parent, PushPromiseFrame pp) throws IOException { @@ -984,7 +1012,6 @@ connection.channel().getLocalAddress(), connection.address()); SettingsFrame sf = new SettingsFrame(clientSettings); - int initialWindowSize = sf.getParameter(INITIAL_WINDOW_SIZE); ByteBuffer buf = framesEncoder.encodeConnectionPreface(PREFACE_BYTES, sf); Log.logFrames(sf, "OUT"); // send preface bytes and SettingsFrame together @@ -997,9 +1024,20 @@ Log.logTrace("Settings Frame sent"); // send a Window update for the receive buffer we are using - // minus the initial 64 K specified in protocol - final int len = windowUpdater.initialWindowSize - initialWindowSize; - if (len > 0) { + // minus the initial 64 K -1 specified in protocol: + // RFC 7540, Section 6.9.2: + // "[...] the connection flow-control window is set to the default + // initial window size until a WINDOW_UPDATE frame is received." + // + // Note that the default initial window size, not to be confused + // with the initial window size, is defined by RFC 7540 as + // 64K -1. + final int len = windowUpdater.initialWindowSize - DEFAULT_INITIAL_WINDOW_SIZE; + if (len != 0) { + if (Log.channel()) { + Log.logChannel("Sending initial connection window update frame: {0} ({1} - {2})", + len, windowUpdater.initialWindowSize, DEFAULT_INITIAL_WINDOW_SIZE); + } windowUpdater.sendWindowUpdate(len); } // there will be an ACK to the windows update - which should @@ -1132,6 +1170,7 @@ private Stream registerNewStream(OutgoingHeaders> oh) { Stream stream = oh.getAttachment(); + assert stream.streamid == 0; int streamid = nextstreamid; nextstreamid += 2; stream.registerStream(streamid);