)]}'
{
  "commit": "dbf14c61b69a2b2a4dc5da8d2ef159e496a07a9a",
  "tree": "be8801ae37882420187cf7338a9502ad0330aac8",
  "parents": [
    "9e122640ebb7b8949b7327ff5ca5b2519b613cbf"
  ],
  "author": {
    "name": "Simon Mavi Stewart",
    "email": "simon.m.stewart@gmail.com",
    "time": "Sun May 10 21:56:11 2026"
  },
  "committer": {
    "name": "GitHub",
    "email": "noreply@github.com",
    "time": "Sun May 10 21:56:11 2026"
  },
  "message": "[grid] Fix latent bugs in WebSocket proxy (#17429)\n\n* [grid] Forward orphan WebSocket frames inbound, not outbound\n\nMessageInboundConverter handled orphan continuation frames and unknown\nframe types by calling ctx.write(frame), which sends the frame back out\nto the peer. They should travel forward through the inbound pipeline so\nthe upgrade/keepalive handlers can deal with them.\n\n* [grid] Propagate ChannelPromise through MessageOutboundConverter\n\nThe converter was calling ctx.writeAndFlush(frame) and dropping the\nincoming ChannelPromise, so any caller awaiting the original future\nwould never see it complete. Pipe the promise through ctx.write(...,\npromise) and rely on the upstream writeAndFlush() to trigger the flush.\n\n* [grid] Size BinaryMessage by readable bytes, not buffer capacity\n\nBinaryMessage(ByteBuffer) sized its array by capacity(), which works\nonly because Netty\u0027s ByteBuf.nioBuffer() happens to return a slice\nwhere capacity \u003d\u003d remaining. A caller passing a flipped ByteBuffer\nbacked by a larger array would either pad zero bytes onto the message\nor hit a BufferUnderflowException. Use remaining() so the contract\nmatches the comment \"data to use\".\n\n* [grid] Latch upstreamClosing when WebSocketFrameProxy send fails\n\nA failing forward currently fires the exception through the pipeline\nbut leaves upstreamClosing unset, so any frames already queued behind\nthis one re-attempt the same failing send before the close handshake\nruns. Set the flag on first failure so subsequent frames short-circuit\nto the drop path immediately.\n\n* [grid] Release WebSocket consumer when handshake fails\n\nThe factory passed to WebSocketUpgradeHandler may have already opened\nan upstream WebSocket and acquired a connection slot by the time the\nWS handshake itself fails (unsupported Sec-WebSocket-Version, or the\nhandshake future completing exceptionally). The previous code dropped\nthe produced consumer without invoking it, so the upstream and the\nslot leaked. Drive each failure path through the consumer\u0027s CloseMessage\ncleanup so existing consumer logic frees the resources.\n\n---------\n\nCo-authored-by: Diego Molina \u003cdiemol@users.noreply.github.com\u003e",
  "tree_diff": [
    {
      "type": "modify",
      "old_id": "377362972472bb726639471014fc63f254dd11d4",
      "old_mode": 33188,
      "old_path": "java/src/org/openqa/selenium/netty/server/MessageInboundConverter.java",
      "new_id": "61a843922e672dc539f4b54970c9a3bb01194b34",
      "new_mode": 33188,
      "new_path": "java/src/org/openqa/selenium/netty/server/MessageInboundConverter.java"
    },
    {
      "type": "modify",
      "old_id": "0dcfab0eb7a6f9981b6f2aaf56255aae3c18a5be",
      "old_mode": 33188,
      "old_path": "java/src/org/openqa/selenium/netty/server/MessageOutboundConverter.java",
      "new_id": "99e74623cecf0b61b026d7d8ff4c619601496b0a",
      "new_mode": 33188,
      "new_path": "java/src/org/openqa/selenium/netty/server/MessageOutboundConverter.java"
    },
    {
      "type": "modify",
      "old_id": "aad98b13e7523141011ca8d52bcae428c4ae9b7f",
      "old_mode": 33188,
      "old_path": "java/src/org/openqa/selenium/netty/server/WebSocketFrameProxy.java",
      "new_id": "93a8a35fdba7cebc68430d70987c8eb3797a72a2",
      "new_mode": 33188,
      "new_path": "java/src/org/openqa/selenium/netty/server/WebSocketFrameProxy.java"
    },
    {
      "type": "modify",
      "old_id": "109bd0351e557c1ddfe1d96288621f492d0f2578",
      "old_mode": 33188,
      "old_path": "java/src/org/openqa/selenium/netty/server/WebSocketUpgradeHandler.java",
      "new_id": "ed371727619203ab5cc7d9f4d27bdd5348cef4de",
      "new_mode": 33188,
      "new_path": "java/src/org/openqa/selenium/netty/server/WebSocketUpgradeHandler.java"
    },
    {
      "type": "modify",
      "old_id": "7a6274801d538da9c41342c9be8f561b47d301be",
      "old_mode": 33188,
      "old_path": "java/src/org/openqa/selenium/remote/http/BinaryMessage.java",
      "new_id": "e0ba78b1d434489d45dddd1b679660e51634a4f9",
      "new_mode": 33188,
      "new_path": "java/src/org/openqa/selenium/remote/http/BinaryMessage.java"
    },
    {
      "type": "modify",
      "old_id": "d6bfcefcad06a17dfb8e0fb184b9b975f3e9a29c",
      "old_mode": 33188,
      "old_path": "java/test/org/openqa/selenium/netty/server/BUILD.bazel",
      "new_id": "ab63f9446c736e2d1682e0715855d5f97c803a5b",
      "new_mode": 33188,
      "new_path": "java/test/org/openqa/selenium/netty/server/BUILD.bazel"
    },
    {
      "type": "add",
      "old_id": "0000000000000000000000000000000000000000",
      "old_mode": 0,
      "old_path": "/dev/null",
      "new_id": "569c286044573aac9ea0259c572310c2c6234875",
      "new_mode": 33188,
      "new_path": "java/test/org/openqa/selenium/netty/server/MessageInboundConverterTest.java"
    },
    {
      "type": "add",
      "old_id": "0000000000000000000000000000000000000000",
      "old_mode": 0,
      "old_path": "/dev/null",
      "new_id": "24df1b7c9f399a7fdbc5525b9e92b513b4252964",
      "new_mode": 33188,
      "new_path": "java/test/org/openqa/selenium/netty/server/MessageOutboundConverterTest.java"
    },
    {
      "type": "add",
      "old_id": "0000000000000000000000000000000000000000",
      "old_mode": 0,
      "old_path": "/dev/null",
      "new_id": "ce7e404a865cb22ad863775eb37906ef91849e77",
      "new_mode": 33188,
      "new_path": "java/test/org/openqa/selenium/netty/server/WebSocketFrameProxyTest.java"
    },
    {
      "type": "add",
      "old_id": "0000000000000000000000000000000000000000",
      "old_mode": 0,
      "old_path": "/dev/null",
      "new_id": "46dd04e6f2cdddbd25c966a1c38df136dd3b72e1",
      "new_mode": 33188,
      "new_path": "java/test/org/openqa/selenium/netty/server/WebSocketUpgradeHandlerTest.java"
    },
    {
      "type": "add",
      "old_id": "0000000000000000000000000000000000000000",
      "old_mode": 0,
      "old_path": "/dev/null",
      "new_id": "0f5a833f32f1ef893204449eb445a87b2033593e",
      "new_mode": 33188,
      "new_path": "java/test/org/openqa/selenium/remote/http/BinaryMessageTest.java"
    }
  ]
}
