BoshHandler implements ServerRuntimeContextService { public void process(HttpServletRequest httpRequest, Stanza body) { if (!body.getNamespaceURI().equalsIgnoreCase(NamespaceURIs.XEP0124_BOSH)) { LOGGER.error("Invalid namespace for body wrapper '{}', must be '{}'!", body.getNamespaceURI(), NamespaceURIs.XEP0124_BOSH); return; } if (!body.getName().equalsIgnoreCase("body")) { LOGGER.error("Invalid body wrapper '{}'!", body.getName()); return; } if (body.getAttribute("rid") == null) { LOGGER.error("Invalid request that does not have a request identifier (rid) attribute!"); return; } final long rid; try { rid = Long.parseLong(body.getAttributeValue("rid")); } catch (NumberFormatException e) { LOGGER.error("not a valid RID: " + body.getAttributeValue("rid")); throw new RuntimeException(e); } if (rid <= 0L) { LOGGER.warn("rid is not positive: " + rid); throw new RuntimeException("BOSH rid must be a positive, large number, not " + rid); } if (rid > 9007199254740991L) { LOGGER.warn("rid too large: " + rid); } BoshRequest newBoshRequest = new BoshRequest(httpRequest, body, rid); LOGGER.debug("SID = " + body.getAttributeValue("sid") + " - new BoshRequest created for RID = " + rid); if (body.getAttribute("sid") == null) { try { createSession(newBoshRequest); } catch (IOException e) { LOGGER.error("Exception thrown while processing the session creation request: " + e.getMessage()); try { final AsyncContext context = newBoshRequest.getHttpServletRequest().startAsync(); final ServletResponse response = context.getResponse(); if (response instanceof HttpServletResponse) { HttpServletResponse httpServletResponse = (HttpServletResponse)response; try { httpServletResponse.sendError(400, "bad-request"); return; } catch (IOException ioe) { ioe.printStackTrace(); } } else { createSessionContext().sendError("bad-request"); } } catch (Exception exe) { LOGGER.warn("exception in async processing", exe); } } return; } final String sid = body.getAttributeValue("sid"); BoshBackedSessionContext session = null; if (sid != null) session = sessions.get(sid); if (session == null) { LOGGER.warn("Received an invalid sid = '{}', terminating connection", sid); try { final AsyncContext context = newBoshRequest.getHttpServletRequest().startAsync(); createSessionContext().sendError("invalid session id"); } catch (Exception exe) { LOGGER.warn("exception in async processing", exe); } return; } synchronized (session) { session.insertRequest(newBoshRequest); processIncomingClientStanzas(session, newBoshRequest.getBody()); } } BoshHandler(); ServerRuntimeContext getServerRuntimeContext(); void setServerRuntimeContext(ServerRuntimeContext serverRuntimeContext); void setStanzaProcessor(StanzaProcessor stanzaProcessor); void process(HttpServletRequest httpRequest, Stanza body); boolean removeSession(String sessionId); int getActiveSessionsCount(); String getServiceName();  }
@Test public void testProcess() throws IOException, SAXException { HttpServletRequest httpServletRequest = mocksControl.createMock(HttpServletRequest.class); expect(serverRuntimeContext.getNextSessionId()).andReturn("200"); expect(serverRuntimeContext.getServerEntity()).andReturn(new EntityImpl(null, "vysper.org", null)); expect(serverRuntimeContext.getDefaultXMLLang()).andReturn("en"); AsyncContext asyncContext = mocksControl.createMock(AsyncContext.class); expect(httpServletRequest.startAsync()).andReturn(asyncContext).atLeastOnce(); expect(httpServletRequest.getAsyncContext()).andReturn(asyncContext).atLeastOnce(); asyncContext.setTimeout(anyLong()); Capture<BoshRequest> br = new Capture<BoshRequest>(); httpServletRequest.setAttribute(eq(BOSH_REQUEST_ATTRIBUTE), EasyMock.<BoshRequest>capture(br)); asyncContext.addListener(EasyMock.<AsyncListener> anyObject()); asyncContext.dispatch(); ServerFeatures serverFeatures = mocksControl.createMock(ServerFeatures.class); expect(serverRuntimeContext.getServerFeatures()).andReturn(serverFeatures); expect(serverFeatures.getAuthenticationMethods()).andReturn(Collections.<SASLMechanism> emptyList()); expect(serverRuntimeContext.getModule(InBandRegistrationModule.class)).andReturn(null); Capture<BoshResponse> captured = new Capture<BoshResponse>(); httpServletRequest.setAttribute(eq(BOSH_RESPONSE_ATTRIBUTE), EasyMock.<BoshResponse> capture(captured)); mocksControl.replay(); Stanza boshRequest = createSessionRequest(); boshHandler.process(httpServletRequest, boshRequest); mocksControl.verify(); assertEquals(httpServletRequest, br.getValue().getHttpServletRequest()); assertEquals(boshRequest, br.getValue().getBody()); Stanza response = new XMLUtil(new String(captured.getValue().getContent())).parse(); assertNotNull(response); assertEquals("body", response.getName()); assertEquals(NamespaceURIs.XEP0124_BOSH, response.getNamespaceURI()); assertEquals("200", response.getAttributeValue("sid")); assertEquals("vysper.org", response.getAttributeValue("from")); assertEquals("60", response.getAttributeValue("wait")); assertEquals("1", response.getAttributeValue("hold")); assertEquals("1.9", response.getAttributeValue("ver")); assertEquals(1, response.getInnerElements().size()); XMLElement streamFeatures = response.getInnerElements().get(0); assertEquals("features", streamFeatures.getName()); assertEquals(NamespaceURIs.HTTP_ETHERX_JABBER_ORG_STREAMS, streamFeatures.getNamespaceURI()); assertEquals(1, streamFeatures.getInnerElements().size()); XMLElement saslMechanisms = streamFeatures.getInnerElements().get(0); assertEquals("mechanisms", saslMechanisms.getName()); assertEquals(NamespaceURIs.URN_IETF_PARAMS_XML_NS_XMPP_SASL, saslMechanisms.getNamespaceURI()); mocksControl.reset(); expect(httpServletRequest.startAsync()).andReturn(asyncContext).atLeastOnce(); expect(httpServletRequest.getAsyncContext()).andReturn(asyncContext).anyTimes(); asyncContext.setTimeout(anyLong()); httpServletRequest.setAttribute(eq(BOSH_REQUEST_ATTRIBUTE), EasyMock.capture(br)); asyncContext.addListener(EasyMock.anyObject()); Capture<Stanza> stanzaCaptured = new Capture<>(); stanzaProcessor.processStanza(eq(serverRuntimeContext), EasyMock.anyObject(), EasyMock.capture(stanzaCaptured), EasyMock.anyObject()); mocksControl.replay(); boshRequest = createSaslRequest(); boshHandler.process(httpServletRequest, boshRequest); mocksControl.verify(); assertEquals(httpServletRequest, br.getValue().getHttpServletRequest()); assertEquals(boshRequest, br.getValue().getBody()); Stanza stanza = stanzaCaptured.getValue(); assertNotNull(stanza); assertEquals("auth", stanza.getName()); assertEquals(NamespaceURIs.URN_IETF_PARAMS_XML_NS_XMPP_SASL, stanza.getNamespaceURI()); assertEquals("DIGEST-MD5", stanza.getAttributeValue("mechanism")); }