You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mina.apache.org by be...@apache.org on 2012/06/11 22:32:55 UTC
svn commit: r1348996 - in
/mina/vysper/trunk/server/extensions/xep0124-xep0206-bosh/src:
main/java/org/apache/vysper/xmpp/extension/xep0124/
test/java/org/apache/vysper/xmpp/extension/xep0124/
Author: berndf
Date: Mon Jun 11 20:32:55 2012
New Revision: 1348996
URL: http://svn.apache.org/viewvc?rev=1348996&view=rev
Log:
VYSPER-320:
add flag to BoshBackedSessionContext indicating the request to store it in HttpSession
make BoshHandler subclasses capable to override behavior
subclasses of BoshServlet might replace default BoshHandler
Modified:
mina/vysper/trunk/server/extensions/xep0124-xep0206-bosh/src/main/java/org/apache/vysper/xmpp/extension/xep0124/BoshBackedSessionContext.java
mina/vysper/trunk/server/extensions/xep0124-xep0206-bosh/src/main/java/org/apache/vysper/xmpp/extension/xep0124/BoshHandler.java
mina/vysper/trunk/server/extensions/xep0124-xep0206-bosh/src/main/java/org/apache/vysper/xmpp/extension/xep0124/BoshServlet.java
mina/vysper/trunk/server/extensions/xep0124-xep0206-bosh/src/test/java/org/apache/vysper/xmpp/extension/xep0124/BoshBackedSessionContextTest.java
Modified: mina/vysper/trunk/server/extensions/xep0124-xep0206-bosh/src/main/java/org/apache/vysper/xmpp/extension/xep0124/BoshBackedSessionContext.java
URL: http://svn.apache.org/viewvc/mina/vysper/trunk/server/extensions/xep0124-xep0206-bosh/src/main/java/org/apache/vysper/xmpp/extension/xep0124/BoshBackedSessionContext.java?rev=1348996&r1=1348995&r2=1348996&view=diff
==============================================================================
--- mina/vysper/trunk/server/extensions/xep0124-xep0206-bosh/src/main/java/org/apache/vysper/xmpp/extension/xep0124/BoshBackedSessionContext.java (original)
+++ mina/vysper/trunk/server/extensions/xep0124-xep0206-bosh/src/main/java/org/apache/vysper/xmpp/extension/xep0124/BoshBackedSessionContext.java Mon Jun 11 20:32:55 2012
@@ -53,7 +53,7 @@ public class BoshBackedSessionContext ex
private final static Logger LOGGER = LoggerFactory.getLogger(BoshBackedSessionContext.class);
- private final BoshHandler boshHandler;
+ public final static String HTTP_SESSION_ATTRIBUTE = "org.apache.vysper.xmpp.extension.xep0124.BoshBackedSessionContext";
private final int maxpause = 120;
@@ -138,21 +138,20 @@ public class BoshBackedSessionContext ex
private Long lastInactivityExpireTime;
private boolean isWatchedByInactivityChecker;
+
+ private boolean propagateSessionContextToHTTPSession = false;
/**
* Creates a new context for a session
- * @param boshHandler
* @param serverRuntimeContext
* @param inactivityChecker
*/
- public BoshBackedSessionContext(BoshHandler boshHandler, ServerRuntimeContext serverRuntimeContext, InactivityChecker inactivityChecker) {
+ public BoshBackedSessionContext(ServerRuntimeContext serverRuntimeContext, InactivityChecker inactivityChecker) {
super(serverRuntimeContext, new SessionStateHolder());
// in BOSH we jump directly to the encrypted state
sessionStateHolder.setState(SessionState.ENCRYPTED);
- this.boshHandler = boshHandler;
-
this.inactivityChecker = inactivityChecker;
updateInactivityChecker();
}
@@ -197,9 +196,17 @@ public class BoshBackedSessionContext ex
// and this is done in BoshHandler when the client requests it
}
- /*
- * This method is synchronized on the session object to prevent concurrent writes to the same BOSH client
+ /**
+ * true, iff this session context will be stored to the related BOSH HTTP session.
+ * @return
*/
+ public boolean propagateSessionContext() {
+ return propagateSessionContextToHTTPSession;
+ }
+
+ /*
+ * This method is synchronized on the session object to prevent concurrent writes to the same BOSH client
+ */
synchronized public void write(Stanza stanza) {
if (stanza == null) throw new IllegalArgumentException("stanza must not be null.");
LOGGER.debug("adding server stanza for writing to BOSH client");
@@ -207,8 +214,9 @@ public class BoshBackedSessionContext ex
}
/**
- * Writes a BOSH response (that is wrapped in a <body/> element) if there are available HTTP requests
- * to respond to, otherwise the response is queued to be sent later (when a HTTP request will be available).
+ * Writes a server-to-client XMPP stanza as a BOSH response (wrapped in a <body/> element) if there are
+ * available HTTP requests to respond to, otherwise the response is queued to be sent later
+ * (when a HTTP request becomes available).
* <p>
* (package access)
*
Modified: mina/vysper/trunk/server/extensions/xep0124-xep0206-bosh/src/main/java/org/apache/vysper/xmpp/extension/xep0124/BoshHandler.java
URL: http://svn.apache.org/viewvc/mina/vysper/trunk/server/extensions/xep0124-xep0206-bosh/src/main/java/org/apache/vysper/xmpp/extension/xep0124/BoshHandler.java?rev=1348996&r1=1348995&r2=1348996&view=diff
==============================================================================
--- mina/vysper/trunk/server/extensions/xep0124-xep0206-bosh/src/main/java/org/apache/vysper/xmpp/extension/xep0124/BoshHandler.java (original)
+++ mina/vysper/trunk/server/extensions/xep0124-xep0206-bosh/src/main/java/org/apache/vysper/xmpp/extension/xep0124/BoshHandler.java Mon Jun 11 20:32:55 2012
@@ -19,14 +19,6 @@
*/
package org.apache.vysper.xmpp.extension.xep0124;
-import java.io.IOException;
-import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
-
-import javax.servlet.AsyncContext;
-import javax.servlet.http.HttpServletRequest;
-
-import org.apache.vysper.xml.fragment.Attribute;
import org.apache.vysper.xml.fragment.XMLElement;
import org.apache.vysper.xmpp.protocol.NamespaceURIs;
import org.apache.vysper.xmpp.server.ServerRuntimeContext;
@@ -37,6 +29,13 @@ import org.apache.vysper.xmpp.stanza.Sta
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import javax.servlet.AsyncContext;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpSession;
+import java.io.IOException;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
/**
* Processes the BOSH requests from the clients
* <p>
@@ -72,6 +71,10 @@ public class BoshHandler {
return serverRuntimeContext;
}
+ protected InactivityChecker getInactivityChecker() {
+ return inactivityChecker;
+ }
+
/**
* Setter for the {@link ServerRuntimeContext}
* @param serverRuntimeContext
@@ -80,8 +83,12 @@ public class BoshHandler {
this.serverRuntimeContext = serverRuntimeContext;
}
+ protected BoshBackedSessionContext createSessionContext() {
+ return new BoshBackedSessionContext(serverRuntimeContext, inactivityChecker);
+ }
+
/**
- * Processes BOSH requests
+ * Processes incoming BOSH requests
* @param httpRequest the HTTP request
* @param body the decoded BOSH request
*/
@@ -117,42 +124,46 @@ public class BoshHandler {
// continue anyway, this is not a problem with this implementation
}
BoshRequest br = new BoshRequest(httpRequest, body, rid);
+
+ // session creation request (first request). does not have a "sid" attribute
if (body.getAttribute("sid") == null) {
- // the session creation request (first request) does not have a "sid" attribute
try {
createSession(br);
} catch (IOException e) {
LOGGER.error("Exception thrown while processing the session creation request", e);
- return;
- }
- } else {
- 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);
- final AsyncContext context = br.getHttpServletRequest().startAsync();
- // create temporary session to be able to reuse the code
- new BoshBackedSessionContext(this, serverRuntimeContext, inactivityChecker).error(br, "invalid session id");
- return;
}
- synchronized (session) {
- session.insertRequest(br);
- for (;;) {
- // When a request from the user comes in, it is possible that the request fills a gap
- // created by previous lost request, and it could be possible to process more than the current request
- // continuing with all the adjacent requests.
- br = session.getNextRequest();
- if (br == null) {
- break;
- }
- processSession(session, br);
+ return;
+ }
+
+ // in-session request, now find the server-side session
+ 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);
+ final AsyncContext context = br.getHttpServletRequest().startAsync();
+ // create temporary session to be able to reuse the code
+ createSessionContext().error(br, "invalid session id");
+ return;
+ }
+
+ // process request for the session
+ synchronized (session) {
+ session.insertRequest(br);
+ for (;;) {
+ // When a request from the user comes in, it is possible that the request fills a gap
+ // created by previous lost request, and it could be possible to process more than the current request
+ // continuing with all the adjacent requests.
+ br = session.getNextRequest();
+ if (br == null) {
+ break;
}
+ processSession(session, br);
}
}
}
- private void processSession(BoshBackedSessionContext session, BoshRequest br) {
+ protected void processSession(BoshBackedSessionContext session, BoshRequest br) {
final Stanza stanza = br.getBody();
if (session.getState() == SessionState.ENCRYPTED) {
if (stanza.getInnerElements().isEmpty()) {
@@ -184,13 +195,13 @@ public class BoshHandler {
}
}
- private void terminateSession(BoshBackedSessionContext session) {
+ protected void terminateSession(BoshBackedSessionContext session) {
sessions.remove(session.getSessionId());
session.writeBoshResponse(BoshStanzaUtils.TERMINATE_BOSH_RESPONSE);
session.close();
}
- private void processStanza(BoshBackedSessionContext session, XMLElement element) {
+ protected void processStanza(BoshBackedSessionContext session, XMLElement element) {
Stanza stanza;
if (element instanceof Stanza) {
stanza = (Stanza) element;
@@ -202,10 +213,14 @@ public class BoshHandler {
session.getStateHolder());
}
- private void createSession(BoshRequest br) throws IOException {
+ protected void createSession(BoshRequest br) throws IOException {
final Stanza stanza = br.getBody();
- BoshBackedSessionContext session = new BoshBackedSessionContext(this, serverRuntimeContext, inactivityChecker);
+ BoshBackedSessionContext session = createSessionContext();
+ if (session.propagateSessionContext() && br.getHttpServletRequest() != null) {
+ final HttpSession httpSession = br.getHttpServletRequest().getSession(true);
+ httpSession.setAttribute(BoshBackedSessionContext.HTTP_SESSION_ATTRIBUTE, session);
+ }
final String contentAttribute = stanza.getAttributeValue("content");
if (contentAttribute != null) session.setContentType(contentAttribute);
@@ -250,7 +265,7 @@ public class BoshHandler {
session.writeBoshResponse(getSessionCreationResponse(session));
}
- private Stanza getSessionCreationResponse(BoshBackedSessionContext session) {
+ protected Stanza getSessionCreationResponse(BoshBackedSessionContext session) {
StanzaBuilder body = BoshStanzaUtils.createBoshStanzaBuilder();
body.addAttribute("wait", Integer.toString(session.getWait()));
body.addAttribute("inactivity", Integer.toString(session.getInactivity()));
@@ -273,16 +288,4 @@ public class BoshHandler {
return body.build();
}
-
- public Stanza addAttribute(Stanza stanza, String attributeName, String attributeValue) {
- StanzaBuilder stanzaBuilder = BoshStanzaUtils.createBoshStanzaBuilder();
- for (Attribute attr : stanza.getAttributes()) {
- stanzaBuilder.addAttribute(attr);
- }
- stanzaBuilder.addAttribute(attributeName, attributeValue);
- for (XMLElement element : stanza.getInnerElements()) {
- stanzaBuilder.addPreparedElement(element);
- }
- return stanzaBuilder.build();
- }
}
Modified: mina/vysper/trunk/server/extensions/xep0124-xep0206-bosh/src/main/java/org/apache/vysper/xmpp/extension/xep0124/BoshServlet.java
URL: http://svn.apache.org/viewvc/mina/vysper/trunk/server/extensions/xep0124-xep0206-bosh/src/main/java/org/apache/vysper/xmpp/extension/xep0124/BoshServlet.java?rev=1348996&r1=1348995&r2=1348996&view=diff
==============================================================================
--- mina/vysper/trunk/server/extensions/xep0124-xep0206-bosh/src/main/java/org/apache/vysper/xmpp/extension/xep0124/BoshServlet.java (original)
+++ mina/vysper/trunk/server/extensions/xep0124-xep0206-bosh/src/main/java/org/apache/vysper/xmpp/extension/xep0124/BoshServlet.java Mon Jun 11 20:32:55 2012
@@ -56,7 +56,7 @@ public class BoshServlet extends HttpSer
protected static final String SERVER_IDENTIFICATION = "Vysper/0.8";
- protected final BoshHandler boshHandler = new BoshHandler();
+ protected BoshHandler boshHandler;
protected List<String> accessControlAllowOrigin;
@@ -64,6 +64,14 @@ public class BoshServlet extends HttpSer
protected String accessControlAllowMethods = "GET, POST, OPTIONS";
+ public BoshServlet() {
+ initBoshHandler();
+ }
+
+ protected void initBoshHandler() {
+ boshHandler = new BoshHandler();
+ }
+
/**
* Setter for the {@link ServerRuntimeContext}
* @param serverRuntimeContext
Modified: mina/vysper/trunk/server/extensions/xep0124-xep0206-bosh/src/test/java/org/apache/vysper/xmpp/extension/xep0124/BoshBackedSessionContextTest.java
URL: http://svn.apache.org/viewvc/mina/vysper/trunk/server/extensions/xep0124-xep0206-bosh/src/test/java/org/apache/vysper/xmpp/extension/xep0124/BoshBackedSessionContextTest.java?rev=1348996&r1=1348995&r2=1348996&view=diff
==============================================================================
--- mina/vysper/trunk/server/extensions/xep0124-xep0206-bosh/src/test/java/org/apache/vysper/xmpp/extension/xep0124/BoshBackedSessionContextTest.java (original)
+++ mina/vysper/trunk/server/extensions/xep0124-xep0206-bosh/src/test/java/org/apache/vysper/xmpp/extension/xep0124/BoshBackedSessionContextTest.java Mon Jun 11 20:32:55 2012
@@ -87,7 +87,7 @@ public class BoshBackedSessionContextTes
httpServletRequest.setAttribute(eq("response"), EasyMock.<BoshResponse> capture(captured));
mocksControl.replay();
- BoshBackedSessionContext boshBackedSessionContext = new BoshBackedSessionContext(boshHandler, serverRuntimeContext, inactivityChecker);
+ BoshBackedSessionContext boshBackedSessionContext = new BoshBackedSessionContext(serverRuntimeContext, inactivityChecker);
Stanza body = BoshStanzaUtils.EMPTY_BOSH_RESPONSE;
boshBackedSessionContext.insertRequest(new BoshRequest(httpServletRequest, body, 1L));
boshBackedSessionContext.writeBoshResponse(body);
@@ -101,7 +101,7 @@ public class BoshBackedSessionContextTes
@Test
public void testSetBoshVersion1() {
mocksControl.replay();
- BoshBackedSessionContext boshBackedSessionContext = new BoshBackedSessionContext(boshHandler, serverRuntimeContext, inactivityChecker);
+ BoshBackedSessionContext boshBackedSessionContext = new BoshBackedSessionContext(serverRuntimeContext, inactivityChecker);
boshBackedSessionContext.setBoshVersion("1.8");
assertEquals("1.8", boshBackedSessionContext.getBoshVersion());
mocksControl.verify();
@@ -110,7 +110,7 @@ public class BoshBackedSessionContextTes
@Test
public void testSetBoshVersion2() {
mocksControl.replay();
- BoshBackedSessionContext boshBackedSessionContext = new BoshBackedSessionContext(boshHandler, serverRuntimeContext, inactivityChecker);
+ BoshBackedSessionContext boshBackedSessionContext = new BoshBackedSessionContext(serverRuntimeContext, inactivityChecker);
boshBackedSessionContext.setBoshVersion("2.0");
assertEquals("1.9", boshBackedSessionContext.getBoshVersion());
mocksControl.verify();
@@ -146,7 +146,7 @@ public class BoshBackedSessionContextTes
// write0
mocksControl.replay();
- BoshBackedSessionContext boshBackedSessionContext = new BoshBackedSessionContext(boshHandler, serverRuntimeContext, inactivityChecker);
+ BoshBackedSessionContext boshBackedSessionContext = new BoshBackedSessionContext(serverRuntimeContext, inactivityChecker);
boshBackedSessionContext.insertRequest(br);
listenerCaptured.getValue().onTimeout(asyncEvent);
@@ -192,7 +192,7 @@ public class BoshBackedSessionContextTes
httpServletRequest1.setAttribute(eq("response"), EasyMock.<BoshResponse> capture(captured));
mocksControl.replay();
- BoshBackedSessionContext boshBackedSessionContext = new BoshBackedSessionContext(boshHandler, serverRuntimeContext, inactivityChecker);
+ BoshBackedSessionContext boshBackedSessionContext = new BoshBackedSessionContext(serverRuntimeContext, inactivityChecker);
boshBackedSessionContext.setHold(2);
// consecutive writes with RID 1 and 2
@@ -232,7 +232,7 @@ public class BoshBackedSessionContextTes
mocksControl.replay();
- BoshBackedSessionContext boshBackedSessionContext = new BoshBackedSessionContext(boshHandler,
+ BoshBackedSessionContext boshBackedSessionContext = new BoshBackedSessionContext(
serverRuntimeContext, inactivityChecker);
boshBackedSessionContext.writeBoshResponse(body); // queued for merging
boshBackedSessionContext.writeBoshResponse(body); // queued for merging