@Test public void testAuthentication() throws Exception { final AtomicReference<String> sessionId = new AtomicReference<>(); class A extends DefaultSecurityPolicy implements ServerSession.RemoveListener { @Override public boolean canHandshake( BayeuxServer server, ServerSession session, ServerMessage message) { Map<String, Object> ext = message.getExt(); if (ext == null) return false; Object authn = ext.get("authentication"); if (!(authn instanceof Map)) return false; @SuppressWarnings("unchecked") Map<String, Object> authentication = (Map<String, Object>) authn; String token = (String) authentication.get("token"); if (token == null) return false; sessionId.set(session.getId()); session.addListener(this); return true; } @Override public void removed(ServerSession session, boolean timeout) { sessionId.set(null); } } A authenticator = new A(); bayeux.setSecurityPolicy(authenticator); BayeuxClient client = newBayeuxClient(); Map<String, Object> authentication = new HashMap<>(); authentication.put("token", "1234567890"); Message.Mutable fields = new HashMapMessage(); fields.getExt(true).put("authentication", authentication); client.handshake(fields); Assert.assertTrue(client.waitFor(5000, State.CONNECTED)); Assert.assertEquals(client.getId(), sessionId.get()); disconnectBayeuxClient(client); Assert.assertNull(sessionId.get()); }
@Test public void testIdleLongPollDoesNotCauseMultipleClientsAdvice() throws Exception { startServer(null); final long timeout = 2000; final long sleep = 500; bayeux.setTransports( new JSONTransport(bayeux) { { setOption(TIMEOUT_OPTION, timeout); init(); } @Override protected LongPollScheduler newLongPollScheduler( ServerSessionImpl session, AsyncContext asyncContext, ServerMessage.Mutable metaConnectReply, String browserId) { return new LongPollScheduler(session, asyncContext, metaConnectReply, browserId) { private final AtomicInteger decrements = new AtomicInteger(); @Override public void onComplete(final AsyncEvent asyncEvent) throws IOException { if (decrements.incrementAndGet() == 1) { // Simulate that onComplete() is delayed without blocking // this thread, to cause a race condition new Thread() { @Override public void run() { try { Thread.sleep(sleep); superOnComplete(asyncEvent); } catch (Exception x) { x.printStackTrace(); } } }.start(); } else { superOnComplete(asyncEvent); } } private void superOnComplete(AsyncEvent asyncEvent) throws IOException { super.onComplete(asyncEvent); } }; } }); Request handshake = newBayeuxRequest( "[{" + "\"channel\": \"/meta/handshake\"," + "\"version\": \"1.0\"," + "\"minimumVersion\": \"1.0\"," + "\"supportedConnectionTypes\": [\"long-polling\"]" + "}]"); ContentResponse response = handshake.send(); Assert.assertEquals(200, response.getStatus()); String clientId = extractClientId(response); Request connect1 = newBayeuxRequest( "[{" + "\"channel\": \"/meta/connect\"," + "\"clientId\": \"" + clientId + "\"," + "\"connectionType\": \"long-polling\"" + "}]"); response = connect1.send(); Assert.assertEquals(200, response.getStatus()); ServerSession serverSession = bayeux.getSession(clientId); Assert.assertNotNull(serverSession); Request connect2 = newBayeuxRequest( "[{" + "\"channel\": \"/meta/connect\"," + "\"clientId\": \"" + clientId + "\"," + "\"connectionType\": \"long-polling\"" + "}]"); response = connect2.send(); Assert.assertEquals(200, response.getStatus()); Request connect3 = newBayeuxRequest( "[{" + "\"channel\": \"/meta/connect\"," + "\"clientId\": \"" + clientId + "\"," + "\"connectionType\": \"long-polling\"" + "}]"); response = connect3.send(); Assert.assertEquals(200, response.getStatus()); JSONContext.Client jsonContext = new JettyJSONContextClient(); Message.Mutable[] messages = jsonContext.parse(response.getContentAsString()); Assert.assertEquals(1, messages.length); Message.Mutable message = messages[0]; Map<String, Object> advice = message.getAdvice(); Assert.assertNull(advice); }