Issue #8353 - do not attempt to send pong frame after output closed
Signed-off-by: Lachlan Roberts <lachlan@webtide.com>
This commit is contained in:
parent
4a6c2744a0
commit
8a8bc4e45b
|
@ -13,31 +13,10 @@
|
||||||
|
|
||||||
package org.eclipse.jetty.websocket.javax.common;
|
package org.eclipse.jetty.websocket.javax.common;
|
||||||
|
|
||||||
import java.lang.invoke.MethodHandle;
|
|
||||||
import java.lang.invoke.MethodType;
|
|
||||||
import java.nio.ByteBuffer;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Optional;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.concurrent.atomic.AtomicBoolean;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
import javax.websocket.ClientEndpointConfig;
|
|
||||||
import javax.websocket.CloseReason;
|
|
||||||
import javax.websocket.Decoder;
|
|
||||||
import javax.websocket.EndpointConfig;
|
|
||||||
import javax.websocket.MessageHandler;
|
|
||||||
import javax.websocket.PongMessage;
|
|
||||||
import javax.websocket.server.ServerEndpointConfig;
|
|
||||||
|
|
||||||
import org.eclipse.jetty.util.BufferUtil;
|
import org.eclipse.jetty.util.BufferUtil;
|
||||||
import org.eclipse.jetty.util.Callback;
|
import org.eclipse.jetty.util.Callback;
|
||||||
import org.eclipse.jetty.util.thread.AutoLock;
|
import org.eclipse.jetty.util.thread.AutoLock;
|
||||||
import org.eclipse.jetty.websocket.core.CloseStatus;
|
import org.eclipse.jetty.websocket.core.*;
|
||||||
import org.eclipse.jetty.websocket.core.CoreSession;
|
|
||||||
import org.eclipse.jetty.websocket.core.Frame;
|
|
||||||
import org.eclipse.jetty.websocket.core.FrameHandler;
|
|
||||||
import org.eclipse.jetty.websocket.core.OpCode;
|
|
||||||
import org.eclipse.jetty.websocket.core.exception.ProtocolException;
|
import org.eclipse.jetty.websocket.core.exception.ProtocolException;
|
||||||
import org.eclipse.jetty.websocket.core.exception.WebSocketException;
|
import org.eclipse.jetty.websocket.core.exception.WebSocketException;
|
||||||
import org.eclipse.jetty.websocket.core.internal.messages.MessageSink;
|
import org.eclipse.jetty.websocket.core.internal.messages.MessageSink;
|
||||||
|
@ -54,6 +33,18 @@ import org.eclipse.jetty.websocket.javax.common.messages.DecodedTextStreamMessag
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import javax.websocket.*;
|
||||||
|
import javax.websocket.server.ServerEndpointConfig;
|
||||||
|
import java.lang.invoke.MethodHandle;
|
||||||
|
import java.lang.invoke.MethodType;
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
public class JavaxWebSocketFrameHandler implements FrameHandler
|
public class JavaxWebSocketFrameHandler implements FrameHandler
|
||||||
{
|
{
|
||||||
private final AutoLock lock = new AutoLock();
|
private final AutoLock lock = new AutoLock();
|
||||||
|
@ -595,11 +586,25 @@ public class JavaxWebSocketFrameHandler implements FrameHandler
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onPing(Frame frame, Callback callback)
|
public void onPing(Frame frame, Callback callback)
|
||||||
|
{
|
||||||
|
if (coreSession.isOutputOpen())
|
||||||
{
|
{
|
||||||
ByteBuffer payload = BufferUtil.copy(frame.getPayload());
|
ByteBuffer payload = BufferUtil.copy(frame.getPayload());
|
||||||
coreSession.sendFrame(new Frame(OpCode.PONG).setPayload(payload), Callback.NOOP, false);
|
coreSession.sendFrame(new Frame(OpCode.PONG).setPayload(payload), Callback.from(() ->
|
||||||
|
{
|
||||||
callback.succeeded();
|
callback.succeeded();
|
||||||
coreSession.demand(1);
|
coreSession.demand(1);
|
||||||
|
}, t ->
|
||||||
|
{
|
||||||
|
callback.failed(t);
|
||||||
|
coreSession.demand(1);
|
||||||
|
}), false);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
callback.succeeded();
|
||||||
|
coreSession.demand(1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onPong(Frame frame, Callback callback)
|
public void onPong(Frame frame, Callback callback)
|
||||||
|
|
|
@ -13,39 +13,25 @@
|
||||||
|
|
||||||
package org.eclipse.jetty.websocket.common;
|
package org.eclipse.jetty.websocket.common;
|
||||||
|
|
||||||
|
import org.eclipse.jetty.util.BufferUtil;
|
||||||
|
import org.eclipse.jetty.util.Callback;
|
||||||
|
import org.eclipse.jetty.util.thread.AutoLock;
|
||||||
|
import org.eclipse.jetty.websocket.api.*;
|
||||||
|
import org.eclipse.jetty.websocket.core.CloseStatus;
|
||||||
|
import org.eclipse.jetty.websocket.core.Frame;
|
||||||
|
import org.eclipse.jetty.websocket.core.*;
|
||||||
|
import org.eclipse.jetty.websocket.core.exception.*;
|
||||||
|
import org.eclipse.jetty.websocket.core.internal.messages.MessageSink;
|
||||||
|
import org.eclipse.jetty.websocket.core.internal.util.InvokerUtils;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import java.lang.invoke.MethodHandle;
|
import java.lang.invoke.MethodHandle;
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
import java.nio.channels.ClosedChannelException;
|
import java.nio.channels.ClosedChannelException;
|
||||||
import java.util.concurrent.Executor;
|
import java.util.concurrent.Executor;
|
||||||
import java.util.concurrent.atomic.AtomicBoolean;
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
|
|
||||||
import org.eclipse.jetty.util.BufferUtil;
|
|
||||||
import org.eclipse.jetty.util.Callback;
|
|
||||||
import org.eclipse.jetty.util.thread.AutoLock;
|
|
||||||
import org.eclipse.jetty.websocket.api.BatchMode;
|
|
||||||
import org.eclipse.jetty.websocket.api.UpgradeRequest;
|
|
||||||
import org.eclipse.jetty.websocket.api.UpgradeResponse;
|
|
||||||
import org.eclipse.jetty.websocket.api.WebSocketContainer;
|
|
||||||
import org.eclipse.jetty.websocket.api.WriteCallback;
|
|
||||||
import org.eclipse.jetty.websocket.core.CloseStatus;
|
|
||||||
import org.eclipse.jetty.websocket.core.Configuration;
|
|
||||||
import org.eclipse.jetty.websocket.core.CoreSession;
|
|
||||||
import org.eclipse.jetty.websocket.core.Frame;
|
|
||||||
import org.eclipse.jetty.websocket.core.FrameHandler;
|
|
||||||
import org.eclipse.jetty.websocket.core.OpCode;
|
|
||||||
import org.eclipse.jetty.websocket.core.exception.BadPayloadException;
|
|
||||||
import org.eclipse.jetty.websocket.core.exception.CloseException;
|
|
||||||
import org.eclipse.jetty.websocket.core.exception.InvalidSignatureException;
|
|
||||||
import org.eclipse.jetty.websocket.core.exception.MessageTooLargeException;
|
|
||||||
import org.eclipse.jetty.websocket.core.exception.ProtocolException;
|
|
||||||
import org.eclipse.jetty.websocket.core.exception.UpgradeException;
|
|
||||||
import org.eclipse.jetty.websocket.core.exception.WebSocketException;
|
|
||||||
import org.eclipse.jetty.websocket.core.exception.WebSocketTimeoutException;
|
|
||||||
import org.eclipse.jetty.websocket.core.internal.messages.MessageSink;
|
|
||||||
import org.eclipse.jetty.websocket.core.internal.util.InvokerUtils;
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
public class JettyWebSocketFrameHandler implements FrameHandler
|
public class JettyWebSocketFrameHandler implements FrameHandler
|
||||||
{
|
{
|
||||||
private enum SuspendState
|
private enum SuspendState
|
||||||
|
@ -365,17 +351,38 @@ public class JettyWebSocketFrameHandler implements FrameHandler
|
||||||
{
|
{
|
||||||
throw new WebSocketException(endpointInstance.getClass().getSimpleName() + " PING method error: " + cause.getMessage(), cause);
|
throw new WebSocketException(endpointInstance.getClass().getSimpleName() + " PING method error: " + cause.getMessage(), cause);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Automatically respond
|
|
||||||
ByteBuffer payload = BufferUtil.copy(frame.getPayload());
|
|
||||||
getSession().getRemote().sendPong(payload, WriteCallback.NOOP);
|
|
||||||
}
|
|
||||||
|
|
||||||
callback.succeeded();
|
callback.succeeded();
|
||||||
demand();
|
demand();
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Automatically respond if output is open.
|
||||||
|
if (coreSession.isOutputOpen())
|
||||||
|
{
|
||||||
|
ByteBuffer payload = BufferUtil.copy(frame.getPayload());
|
||||||
|
getSession().getRemote().sendPong(payload, new WriteCallback()
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public void writeSuccess() {
|
||||||
|
callback.succeeded();
|
||||||
|
demand();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void writeFailed(Throwable x) {
|
||||||
|
callback.failed(x);
|
||||||
|
demand();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
callback.succeeded();
|
||||||
|
demand();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void onPongFrame(Frame frame, Callback callback)
|
private void onPongFrame(Frame frame, Callback callback)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue