Return-Path: X-Original-To: archive-asf-public-internal@cust-asf2.ponee.io Delivered-To: archive-asf-public-internal@cust-asf2.ponee.io Received: from cust-asf.ponee.io (cust-asf.ponee.io [163.172.22.183]) by cust-asf2.ponee.io (Postfix) with ESMTP id 292D1200CB0 for ; Fri, 23 Jun 2017 20:57:14 +0200 (CEST) Received: by cust-asf.ponee.io (Postfix) id 2805A160BE5; Fri, 23 Jun 2017 18:57:14 +0000 (UTC) Delivered-To: archive-asf-public@cust-asf.ponee.io Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by cust-asf.ponee.io (Postfix) with SMTP id 6C4BA160BE2 for ; Fri, 23 Jun 2017 20:57:13 +0200 (CEST) Received: (qmail 24799 invoked by uid 500); 23 Jun 2017 18:57:12 -0000 Mailing-List: contact commits-help@hc.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: "HttpComponents Project" Delivered-To: mailing list commits@hc.apache.org Received: (qmail 24788 invoked by uid 99); 23 Jun 2017 18:57:12 -0000 Received: from git1-us-west.apache.org (HELO git1-us-west.apache.org) (140.211.11.23) by apache.org (qpsmtpd/0.29) with ESMTP; Fri, 23 Jun 2017 18:57:12 +0000 Received: by git1-us-west.apache.org (ASF Mail Server at git1-us-west.apache.org, from userid 33) id 6E385DFC25; Fri, 23 Jun 2017 18:57:12 +0000 (UTC) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: olegk@apache.org To: commits@hc.apache.org Message-Id: X-Mailer: ASF-Git Admin Mailer Subject: httpcomponents-core git commit: Made HTTP/2 data window update precede sending of the DATA frame to the opposite endpoint. In some extreme circumstances the opposite endpoint can send back a WINDOW_UPDATE frame in-between of these two operation causing t Date: Fri, 23 Jun 2017 18:57:12 +0000 (UTC) archived-at: Fri, 23 Jun 2017 18:57:14 -0000 Repository: httpcomponents-core Updated Branches: refs/heads/master 79018db83 -> 8f1b4f6d1 Made HTTP/2 data window update precede sending of the DATA frame to the opposite endpoint. In some extreme circumstances the opposite endpoint can send back a WINDOW_UPDATE frame in-between of these two operation causing the data window value to exceed its maximum valid value Project: http://git-wip-us.apache.org/repos/asf/httpcomponents-core/repo Commit: http://git-wip-us.apache.org/repos/asf/httpcomponents-core/commit/8f1b4f6d Tree: http://git-wip-us.apache.org/repos/asf/httpcomponents-core/tree/8f1b4f6d Diff: http://git-wip-us.apache.org/repos/asf/httpcomponents-core/diff/8f1b4f6d Branch: refs/heads/master Commit: 8f1b4f6d16b67059e6ab98ddc1ff545f03ebc4b0 Parents: 79018db Author: Oleg Kalnichevski Authored: Fri Jun 23 20:53:32 2017 +0200 Committer: Oleg Kalnichevski Committed: Fri Jun 23 20:55:15 2017 +0200 ---------------------------------------------------------------------- .../nio/AbstractHttp2StreamMultiplexer.java | 28 +++++++++++--------- 1 file changed, 16 insertions(+), 12 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/httpcomponents-core/blob/8f1b4f6d/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/AbstractHttp2StreamMultiplexer.java ---------------------------------------------------------------------- diff --git a/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/AbstractHttp2StreamMultiplexer.java b/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/AbstractHttp2StreamMultiplexer.java index af138a8..a685617 100644 --- a/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/AbstractHttp2StreamMultiplexer.java +++ b/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/AbstractHttp2StreamMultiplexer.java @@ -307,6 +307,20 @@ abstract class AbstractHttp2StreamMultiplexer implements Identifiable, HttpConne } } + private void streamDataFrame( + final int streamId, + final AtomicInteger streamOutputWindow, + final ByteBuffer payload, + final int chunk) throws IOException { + final RawFrame dataFrame = frameFactory.createData(streamId, payload, false); + if (streamListener != null) { + streamListener.onFrameOutput(this, streamId, dataFrame); + } + updateOutputWindow(0, connOutputWindow, -chunk); + updateOutputWindow(streamId, streamOutputWindow, -chunk); + outputBuffer.write(dataFrame, ioSession.channel()); + } + private int streamData( final int streamId, final AtomicInteger streamOutputWindow, final ByteBuffer payload) throws IOException { if (outputBuffer.isEmpty() && outputQueue.isEmpty()) { @@ -319,28 +333,18 @@ abstract class AbstractHttp2StreamMultiplexer implements Identifiable, HttpConne final int chunk; if (payload.remaining() <= maxPayloadSize) { chunk = payload.remaining(); - final RawFrame dataFrame = frameFactory.createData(streamId, payload, false); - if (streamListener != null) { - streamListener.onFrameOutput(this, streamId, dataFrame); - } - outputBuffer.write(dataFrame, ioSession.channel()); + streamDataFrame(streamId, streamOutputWindow, payload, chunk); } else { chunk = maxPayloadSize; final int originalLimit = payload.limit(); try { payload.limit(payload.position() + chunk); - final RawFrame dataFrame = frameFactory.createData(streamId, payload, false); - if (streamListener != null) { - streamListener.onFrameOutput(this, streamId, dataFrame); - } - outputBuffer.write(dataFrame, ioSession.channel()); + streamDataFrame(streamId, streamOutputWindow, payload, chunk); } finally { payload.limit(originalLimit); } } payload.position(payload.position() + chunk); - updateOutputWindow(0, connOutputWindow, -chunk); - updateOutputWindow(streamId, streamOutputWindow, -chunk); ioSession.setEvent(SelectionKey.OP_WRITE); return chunk; } else {