@Override public Object get() { return DECODING_STATE.get(session); }
@Override protected IoHandler getHandler(IoSession session, boolean throwIfNull) throws Exception { IoHandler handler = DELEGATE_KEY.get(session); if (handler == null) { ResourceAddress localAddress = LOCAL_ADDRESS.get(session); // If there is an exception in sessionCreated(), it may not set up LOCAL_ADDRESS // and hence localAddress could be null. So return null in this case when // exceptionCaught()/sessionClosed() looks up the handler. handler = localAddress == null ? null : acceptor.getHandler(localAddress); if (handler != null) { DELEGATE_KEY.set(session, handler); } else if (throwIfNull) { throw new Exception("No handler found for: " + localAddress); } } return handler; } }
@Override protected void doExceptionCaught(IoSessionEx session, Throwable cause) throws Exception { if (logger.isDebugEnabled()) { String message = format("Error on WebSocket connection: %s", cause); if (logger.isTraceEnabled()) { // note: still debug level, but with extra detail about the exception logger.debug(message, cause); } else { logger.debug(message); } } WsnSession wsnSession = SESSION_KEY.get(session); if (wsnSession != null) { wsnSession.setCloseException(cause); } session.close(true); ConnectFuture wsnConnectFuture = WSN_CONNECT_FUTURE_KEY.remove(session); if (wsnConnectFuture != null) { wsnConnectFuture.setException(cause); } }
protected Queue<InboundEvent> suspendInboundEvents(NextFilter nextFilter, IoSession session) throws Exception { Queue<InboundEvent> inboundEvents = inboundEventsKey.get(session); if (inboundEvents == null) { Queue<InboundEvent> newInboundEvents = new ConcurrentLinkedQueue<>(); inboundEvents = inboundEventsKey.setIfAbsent(session, newInboundEvents); if (inboundEvents == null) { inboundEvents = newInboundEvents; } } return inboundEvents; }
@Override protected void doSessionOpened(HttpSession session) throws Exception { // TODO session.get[Ready]Future().addListener(...) to check // response status / headers IoFilterChain filterChain = session.getFilterChain(); addBridgeFilters(filterChain); SseSession sseSession = SSE_SESSION_KEY.get(session); if (sseSession == null) { Callable<SseSession> sessionFactory = SSE_SESSION_FACTORY_KEY.remove(session); SseSession newSseSession = sessionFactory.call(); SSE_SESSION_KEY.set(session, newSseSession); } }
private <T extends ConnectFuture> IoSessionInitializer<ConnectFuture> createParentInitializer(final ResourceAddress connectAddress, final ConnectFuture httpConnectFuture, HttpConnectSessionFactory httpSessionFactory) { // initialize parent session before connection attempt return (parent, future) -> { HTTP_SESSION_FACTORY_KEY.set(parent, httpSessionFactory); HTTP_CONNECT_FUTURE_KEY.set(parent, httpConnectFuture); }; }
@Override protected void doSessionOpened(final HttpConnectSession createSession) throws Exception { Callable<WsebSession> sessionFactory = WSE_SESSION_FACTORY_KEY.remove(createSession); final WsebSession wsebSession = sessionFactory.call(); // clean up session idle tracker wsebSession.getCloseFuture().addListener(new IoFutureListener<CloseFuture>() { @Override public void operationComplete(CloseFuture future) { currentSessionIdleTracker.get().removeSession(wsebSession); // handle exception during create response createSession.close(false); } }); // store created session to process during session close, or exception WSE_SESSION_KEY.set(createSession, wsebSession); WSE_CONNECT_FUTURE_KEY.remove(createSession); }
public interface BridgeSession extends IoSessionEx { TypedAttributeKey<String> NEXT_PROTOCOL_KEY = new TypedAttributeKey<>(BridgeSession.class, "nextProtocol"); TypedAttributeKey<ResourceAddress> LOCAL_ADDRESS = new TypedAttributeKey<ResourceAddress>(BridgeAcceptor.class, "localAddress") { TypedAttributeKey<ResourceAddress> REMOTE_ADDRESS = new TypedAttributeKey<ResourceAddress>(BridgeConnector.class, "remoteAddress") {
@Override protected void doMessageReceived(final IoSessionEx session, Object message) throws Exception { if (message == SslFilter.SESSION_SECURED) { IoFilterChain filterChain = session.getFilterChain(); removeFilter(filterChain, certificateSelection); // create session IoSession sslSession = SESSION_KEY.get(session); assert (sslSession == null); SslSession newSslSession = createSslSession(session); SESSION_KEY.set(session, newSslSession); } else if (message == SslFilter.SESSION_UNSECURED) { SslSession sslSession = SESSION_KEY.remove(session); if (sslSession != null && !sslSession.isClosing()) { sslSession.getProcessor().remove(sslSession); } } else { IoSession sslSession = SESSION_KEY.get(session); assert (sslSession != null); IoFilterChain filterChain = sslSession.getFilterChain(); filterChain.fireMessageReceived(message); } }
@Override public void set(Object state) { DECODING_STATE.set(session, state); } }
@Override protected void doSessionOpened(IoSessionEx session) throws Exception { IoFilterChain filterChain = session.getFilterChain(); addBridgeFilters(filterChain); // defer creation of WsnSession until WebSocket handshake completed Callable<WsnSession> sessionFactory = WSN_SESSION_FACTORY_KEY.remove(session); WsnSession wsnSession = sessionFactory.call(); SESSION_KEY.set(session, wsnSession); }
@Override public void closeWebSocketConnection(IoSession session) { WsnSession wsnSession = SESSION_KEY.get(session); assert wsnSession != null; wsnSession.close(false); }
@Override protected void doMessageReceived(HttpAcceptSession session, Object message) throws Exception { // when we get the content coming up, then we can create and finalize the response. String contentLengthStr = session.getReadHeader("Content-Length"); if (contentLengthStr != null && !"0".equals(contentLengthStr)) { Integer expectedContentLength = Integer.valueOf(contentLengthStr); IoBufferEx buffer = (IoBufferEx) message; Integer readSoFar = CREATE_CONTENT_LENGTH_READ.get(session); if (readSoFar == null) { readSoFar=0; } readSoFar += buffer.remaining(); if (readSoFar.intValue()==expectedContentLength) { createWsebSessionAndFinalizeResponse(session); } else if (readSoFar < expectedContentLength) { CREATE_CONTENT_LENGTH_READ.set(session, readSoFar); } else if (readSoFar > expectedContentLength) { logger.error(String.format("Unexpected content while reading WSE create message content: %s", buffer)); } } else { super.doMessageReceived(session, message); } }
private ResourceAddress getSslSessionLocalAddress(IoSession session) { // note: bound address is unified in SSL options during bind to avoid conflicts like different cipher suites ResourceAddress boundAddress = SslAcceptor.SSL_RESOURCE_ADDRESS.remove(session); assert (boundAddress != null); // construct the candidate address with observed transport and next protocol String candidateURI = boundAddress.getExternalURI(); ResourceOptions candidateOptions = ResourceOptions.FACTORY.newResourceOptions(boundAddress); candidateOptions.setOption(NEXT_PROTOCOL, NEXT_PROTOCOL_KEY.get(session)); candidateOptions.setOption(TRANSPORT, LOCAL_ADDRESS.get(session)); ResourceAddress candidateAddress = resourceAddressFactory.newResourceAddress(candidateURI, candidateOptions); // lookup the binding for this candidate address Binding binding = bindings.getBinding(candidateAddress); return (binding != null) ? binding.bindAddress() : null; }
@Override public void initializeSession(IoSession session, T future) { SslAcceptor.SSL_RESOURCE_ADDRESS.set(session, connectAddress); if (parentInitializer != null) { parentInitializer.initializeSession(session, future); } } };
@Override public void doSessionClosed(IoSessionEx session) throws Exception { AbstractNioAcceptor.LOG.debug("AbstractNioAcceptor.doSessionClosed for session " + session); NEXT_PROTOCOL_KEY.remove(session); LOCAL_ADDRESS.remove(session); REMOTE_ADDRESS.remove(session); IoSession tcpBridgeSession = getTcpBridgeSession(session); if (tcpBridgeSession != null) { tcpBridgeSession.getFilterChain().fireSessionClosed(); } }
@Override protected void doSessionOpened(IoSessionEx session) throws Exception { IoFilterChain filterChain = session.getFilterChain(); addBridgeFilters(filterChain); HttpConnectSessionFactory sessionFactory = HTTP_SESSION_FACTORY_KEY.remove(session); DefaultHttpSession httpSession = sessionFactory.get(session); HTTP_SESSION_KEY.set(session, httpSession); DefaultConnectFuture connectFuture = (DefaultConnectFuture) HTTP_CONNECT_FUTURE_KEY.remove(session); if (!connectFuture.isDone()) { // needed for http redirect as there will be a new connect on the wire connectFuture.setValue(httpSession); } }