Author: ngn
Date: Wed Jun 23 21:24:39 2010
New Revision: 957353
URL: http://svn.apache.org/viewvc?rev=957353&view=rev
Log:
Foundation for SASL, HTTP queuing, access control for Ajax cross domain
(VYSPER-213, by Bogdan Pistol)
Added:
mina/vysper/trunk/server/extensions/xep0124-xep0206-bosh/src/main/java/org/apache/vysper/xmpp/extension/xep0124/BoshResponse.java
Removed:
mina/vysper/trunk/server/extensions/xep0124-xep0206-bosh/src/main/java/org/apache/vysper/xmpp/extension/xep0124/BoshRequestContext.java
mina/vysper/trunk/server/extensions/xep0124-xep0206-bosh/src/main/java/org/apache/vysper/xmpp/extension/xep0124/ContentType.java
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/BoshDecoder.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/BoshSaxContentHandler.java
mina/vysper/trunk/server/extensions/xep0124-xep0206-bosh/src/main/java/org/apache/vysper/xmpp/extension/xep0124/BoshServlet.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=957353&r1=957352&r2=957353&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
Wed Jun 23 21:24:39 2010
@@ -19,12 +19,20 @@
*/
package org.apache.vysper.xmpp.extension.xep0124;
+import java.util.LinkedList;
+import java.util.Queue;
+
+import javax.servlet.http.HttpServletRequest;
+
+import org.apache.vysper.xml.fragment.Renderer;
import org.apache.vysper.xmpp.protocol.SessionStateHolder;
import org.apache.vysper.xmpp.server.AbstractSessionContext;
import org.apache.vysper.xmpp.server.ServerRuntimeContext;
import org.apache.vysper.xmpp.server.SessionState;
import org.apache.vysper.xmpp.stanza.Stanza;
import org.apache.vysper.xmpp.writer.StanzaWriter;
+import org.eclipse.jetty.continuation.Continuation;
+import org.eclipse.jetty.continuation.ContinuationSupport;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -35,32 +43,44 @@ import org.slf4j.LoggerFactory;
*/
public class BoshBackedSessionContext extends AbstractSessionContext implements
StanzaWriter {
-
- private final static Logger LOGGER = LoggerFactory
- .getLogger(BoshBackedSessionContext.class);
+
+ private final static Logger LOGGER =
LoggerFactory.getLogger(BoshBackedSessionContext.class);
+
+ private final BoshHandler boshHandler;
private final int inactivity = 60;
private final int polling = 15;
private final int requests = 2;
+
+ private String boshVersion = "1.9";
- private String ver = "1.9";
-
- private String contentType = ContentType.XML_CONTENT_TYPE;
+ private String contentType = BoshServlet.XML_CONTENT_TYPE;
private int wait = 60;
private int hold = 1;
-
+
+ private Queue<HttpServletRequest> requestQueue;
+
+ private Queue<BoshResponse> delayedResponseQueue;
+
/**
* Creates a new context for a session
* @param serverRuntimeContext
* @param boshHandler
*/
- public BoshBackedSessionContext(ServerRuntimeContext serverRuntimeContext)
{
+ public BoshBackedSessionContext(BoshHandler boshHandler,
ServerRuntimeContext serverRuntimeContext) {
super(serverRuntimeContext, new SessionStateHolder());
sessionStateHolder.setState(SessionState.INITIATED);
+ this.boshHandler = boshHandler;
+ requestQueue = new LinkedList<HttpServletRequest>();
+ delayedResponseQueue = new LinkedList<BoshResponse>();
+ }
+
+ public SessionStateHolder getStateHolder() {
+ return sessionStateHolder;
}
public StanzaWriter getResponseWriter() {
@@ -71,6 +91,18 @@ public class BoshBackedSessionContext ex
}
public void write(Stanza stanza) {
+ write(getResponse(stanza));
+ }
+
+ public void write(BoshResponse resp) {
+ HttpServletRequest req = requestQueue.poll();
+ if (req == null) {
+ delayedResponseQueue.offer(resp);
+ return;
+ }
+ Continuation continuation = ContinuationSupport.getContinuation(req);
+ continuation.setAttribute("response", resp);
+ continuation.resume();
}
public void close() {
@@ -106,25 +138,24 @@ public class BoshBackedSessionContext ex
return hold;
}
- public void setVer(String ver) {
- String[] serverVer = this.ver.split("\\.");
- int serverMajor = Integer.parseInt(serverVer[0]);
- int serverMinor = Integer.parseInt(serverVer[1]);
- String[] clientVer = ver.split("\\.");
+ public void setBoshVersion(String version) {
+ String[] v = boshVersion.split("\\.");
+ int major = Integer.parseInt(v[0]);
+ int minor = Integer.parseInt(v[1]);
+ v = version.split("\\.");
- if (clientVer.length == 2) {
- int clientMajor = Integer.parseInt(clientVer[0]);
- int clientMinor = Integer.parseInt(clientVer[1]);
-
- if (clientMajor < serverMajor
- || (clientMajor == serverMajor && clientMinor <
serverMinor)) {
- this.ver = ver;
+ if (v.length == 2) {
+ int clientMajor = Integer.parseInt(v[0]);
+ int clientMinor = Integer.parseInt(v[1]);
+
+ if (clientMajor < major || (clientMajor == major && clientMinor <
minor)) {
+ boshVersion = version;
}
}
}
- public String getVer() {
- return ver;
+ public String getBoshVersion() {
+ return boshVersion;
}
public int getInactivity() {
@@ -138,5 +169,41 @@ public class BoshBackedSessionContext ex
public int getRequests() {
return requests;
}
+
+ synchronized public void requestExpired(HttpServletRequest req) {
+ for (;;) {
+ HttpServletRequest r = requestQueue.peek();
+ if (r == null) {
+ return;
+ }
+ write(boshHandler.getEmptyStanza());
+ if (r == req) {
+ return;
+ }
+ }
+ }
+
+ public void addRequest(HttpServletRequest req) {
+ Continuation continuation = ContinuationSupport.getContinuation(req);
+ continuation.setTimeout(wait * 1000);
+ continuation.suspend();
+ continuation.setAttribute("session", this);
+ requestQueue.offer(req);
+
+ BoshResponse resp = delayedResponseQueue.poll();
+ if (resp != null) {
+ write(resp);
+ return;
+ }
+
+ if (requestQueue.size() > hold) {
+ write(boshHandler.getEmptyStanza());
+ }
+ }
+
+ public BoshResponse getResponse(Stanza stanza) {
+ byte[] content = new Renderer(stanza).getComplete().getBytes();
+ return new BoshResponse(contentType, content);
+ }
}
Modified:
mina/vysper/trunk/server/extensions/xep0124-xep0206-bosh/src/main/java/org/apache/vysper/xmpp/extension/xep0124/BoshDecoder.java
URL:
http://svn.apache.org/viewvc/mina/vysper/trunk/server/extensions/xep0124-xep0206-bosh/src/main/java/org/apache/vysper/xmpp/extension/xep0124/BoshDecoder.java?rev=957353&r1=957352&r2=957353&view=diff
==============================================================================
---
mina/vysper/trunk/server/extensions/xep0124-xep0206-bosh/src/main/java/org/apache/vysper/xmpp/extension/xep0124/BoshDecoder.java
(original)
+++
mina/vysper/trunk/server/extensions/xep0124-xep0206-bosh/src/main/java/org/apache/vysper/xmpp/extension/xep0124/BoshDecoder.java
Wed Jun 23 21:24:39 2010
@@ -44,16 +44,12 @@ public class BoshDecoder {
private final NonBlockingXMLReader reader;
- private final BoshRequestContext boshRequestContext;
+ private final HttpServletRequest request;
- /**
- * Creates a new decoder associated with a {...@link BoshRequestContext}
- * @param boshHandler
- */
- public BoshDecoder(BoshHandler boshHandler, BoshRequestContext
boshRequestContext) {
- this.boshRequestContext = boshRequestContext;
+ public BoshDecoder(BoshHandler boshHandler, HttpServletRequest req) {
+ request = req;
reader = new DefaultNonBlockingXMLReader();
- ContentHandler contentHandler = new BoshSaxContentHandler(boshHandler,
boshRequestContext);
+ ContentHandler contentHandler = new BoshSaxContentHandler(boshHandler,
req);
reader.setContentHandler(contentHandler);
}
@@ -67,7 +63,7 @@ public class BoshDecoder {
IoBuffer ioBuf = IoBuffer.allocate(1024);
ioBuf.setAutoExpand(true);
byte[] buf = new byte[1024];
- InputStream in = boshRequestContext.getRequest().getInputStream();
+ InputStream in = request.getInputStream();
for (;;) {
int i = in.read(buf);
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=957353&r1=957352&r2=957353&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
Wed Jun 23 21:24:39 2010
@@ -23,9 +23,10 @@ import java.io.IOException;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
-import javax.servlet.http.HttpServletResponse;
+import javax.servlet.http.HttpServletRequest;
-import org.apache.vysper.xml.fragment.Renderer;
+import org.apache.vysper.xmpp.authorization.SASLMechanism;
+import org.apache.vysper.xmpp.protocol.NamespaceURIs;
import org.apache.vysper.xmpp.server.ServerRuntimeContext;
import org.apache.vysper.xmpp.stanza.Stanza;
import org.apache.vysper.xmpp.stanza.StanzaBuilder;
@@ -44,8 +45,6 @@ public class BoshHandler {
private static final Logger LOGGER =
LoggerFactory.getLogger(BoshHandler.class);
- private static final String BOSH_NS =
"http://jabber.org/protocol/httpbind";
-
private ServerRuntimeContext serverRuntimeContext;
private Map<String, BoshBackedSessionContext> sessions;
@@ -61,12 +60,12 @@ public class BoshHandler {
/**
* Processes BOSH stanzas concurrently
- * @param boshRequestContext
+ * @param httpContext
* @param stanza
*/
- public void process(BoshRequestContext boshRequestContext, Stanza stanza) {
- if (!stanza.getNamespaceURI().equalsIgnoreCase(BOSH_NS)) {
- LOGGER.error("Invalid namespace for body wrapper '{}', should be
'{}'!", stanza.getNamespaceURI(), BOSH_NS);
+ public void process(HttpServletRequest req, Stanza stanza) {
+ if
(!stanza.getNamespaceURI().equalsIgnoreCase(NamespaceURIs.XEP0124_BOSH)) {
+ LOGGER.error("Invalid namespace for body wrapper '{}', must be
'{}'!", stanza.getNamespaceURI(), NamespaceURIs.XEP0124_BOSH);
return;
}
if (!stanza.getName().equalsIgnoreCase("body")) {
@@ -81,19 +80,18 @@ public class BoshHandler {
if (stanza.getAttribute("sid") == null) {
// the session creation request (first request) does not have a
"sid" attribute
try {
- createSession(boshRequestContext, stanza);
+ createSession(req, stanza);
} catch (IOException e) {
LOGGER.error("Exception thrown while processing the session
creation request", e);
return;
}
} else {
-// handleSession(boshRequestContext, stanza);
+// handleSession(req, stanza);
}
}
- private void createSession(BoshRequestContext boshRequestContext,
- Stanza stanza) throws IOException {
- BoshBackedSessionContext session = new
BoshBackedSessionContext(serverRuntimeContext);
+ private void createSession(HttpServletRequest req, Stanza stanza) throws
IOException {
+ BoshBackedSessionContext session = new BoshBackedSessionContext(this,
serverRuntimeContext);
if (stanza.getAttribute("content") != null) {
session.setContentType(stanza.getAttributeValue("content"));
}
@@ -107,30 +105,43 @@ public class BoshHandler {
}
if (stanza.getAttribute("ver") != null) {
String ver = stanza.getAttributeValue("ver");
- session.setVer(ver);
+ session.setBoshVersion(ver);
}
+ session.addRequest(req);
sessions.put(session.getSessionId(), session);
- HttpServletResponse resp = boshRequestContext.getResponse();
- resp.setContentType(session.getContentType());
- String msg = new
Renderer(getSessionCreationResponse(session)).getComplete();
- resp.setContentLength(msg.length());
- resp.addDateHeader("Date", System.currentTimeMillis());
- resp.addHeader("Access-control-allow-origin", "*");
- resp.addHeader("Access-control-allow-headers", "Content-Type");
- resp.getWriter().print(msg);
- resp.flushBuffer();
+
+ session.write(getSessionCreationStanza(session));
}
- public Stanza getSessionCreationResponse(BoshBackedSessionContext session)
{
- StanzaBuilder stanzaBuilder = new StanzaBuilder("body", BOSH_NS);
- stanzaBuilder.addAttribute("wait",
Integer.toString(session.getWait()));
- stanzaBuilder.addAttribute("inactivity",
Integer.toString(session.getInactivity()));
- stanzaBuilder.addAttribute("polling",
Integer.toString(session.getPolling()));
- stanzaBuilder.addAttribute("requests",
Integer.toString(session.getRequests()));
- stanzaBuilder.addAttribute("hold",
Integer.toString(session.getHold()));
- stanzaBuilder.addAttribute("sid", session.getSessionId());
- stanzaBuilder.addAttribute("ver", session.getVer());
- stanzaBuilder.addAttribute("from",
session.getServerJID().getFullQualifiedName());
+ public Stanza getSessionCreationStanza(BoshBackedSessionContext session) {
+ StanzaBuilder body = new StanzaBuilder("body",
NamespaceURIs.XEP0124_BOSH);
+ body.addAttribute("wait", Integer.toString(session.getWait()));
+ body.addAttribute("inactivity",
Integer.toString(session.getInactivity()));
+ body.addAttribute("polling", Integer.toString(session.getPolling()));
+ body.addAttribute("requests", Integer.toString(session.getRequests()));
+ body.addAttribute("hold", Integer.toString(session.getHold()));
+ body.addAttribute("sid", session.getSessionId());
+ body.addAttribute("ver", session.getBoshVersion());
+ body.addAttribute("from",
session.getServerJID().getFullQualifiedName());
+
+ StanzaBuilder features = new StanzaBuilder("features",
+ NamespaceURIs.HTTP_ETHERX_JABBER_ORG_STREAMS, "stream");
+ features.startInnerElement("mechanisms",
+ NamespaceURIs.URN_IETF_PARAMS_XML_NS_XMPP_SASL);
+ for (SASLMechanism authenticationMethod : serverRuntimeContext
+ .getServerFeatures().getAuthenticationMethods()) {
+ features.startInnerElement("mechanism",
+ NamespaceURIs.URN_IETF_PARAMS_XML_NS_XMPP_SASL)
+ .addText(authenticationMethod.getName()).endInnerElement();
+ }
+ features.endInnerElement();
+
+ body.addPreparedElement(features.build());
+ return body.build();
+ }
+
+ public Stanza getEmptyStanza() {
+ StanzaBuilder stanzaBuilder = new StanzaBuilder("body",
NamespaceURIs.XEP0124_BOSH);
return stanzaBuilder.build();
}
Added:
mina/vysper/trunk/server/extensions/xep0124-xep0206-bosh/src/main/java/org/apache/vysper/xmpp/extension/xep0124/BoshResponse.java
URL:
http://svn.apache.org/viewvc/mina/vysper/trunk/server/extensions/xep0124-xep0206-bosh/src/main/java/org/apache/vysper/xmpp/extension/xep0124/BoshResponse.java?rev=957353&view=auto
==============================================================================
---
mina/vysper/trunk/server/extensions/xep0124-xep0206-bosh/src/main/java/org/apache/vysper/xmpp/extension/xep0124/BoshResponse.java
(added)
+++
mina/vysper/trunk/server/extensions/xep0124-xep0206-bosh/src/main/java/org/apache/vysper/xmpp/extension/xep0124/BoshResponse.java
Wed Jun 23 21:24:39 2010
@@ -0,0 +1,46 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.vysper.xmpp.extension.xep0124;
+
+/**
+ * The response sent to BOSH clients
+ *
+ * @author The Apache MINA Project ([email protected])
+ */
+public class BoshResponse {
+
+ private final String contentType;
+
+ private final byte[] content;
+
+ public BoshResponse(String contentType, byte[] content) {
+ this.contentType = contentType;
+ this.content = content;
+ }
+
+ public String getContentType() {
+ return contentType;
+ }
+
+ public byte[] getContent() {
+ return content;
+ }
+
+}
Modified:
mina/vysper/trunk/server/extensions/xep0124-xep0206-bosh/src/main/java/org/apache/vysper/xmpp/extension/xep0124/BoshSaxContentHandler.java
URL:
http://svn.apache.org/viewvc/mina/vysper/trunk/server/extensions/xep0124-xep0206-bosh/src/main/java/org/apache/vysper/xmpp/extension/xep0124/BoshSaxContentHandler.java?rev=957353&r1=957352&r2=957353&view=diff
==============================================================================
---
mina/vysper/trunk/server/extensions/xep0124-xep0206-bosh/src/main/java/org/apache/vysper/xmpp/extension/xep0124/BoshSaxContentHandler.java
(original)
+++
mina/vysper/trunk/server/extensions/xep0124-xep0206-bosh/src/main/java/org/apache/vysper/xmpp/extension/xep0124/BoshSaxContentHandler.java
Wed Jun 23 21:24:39 2010
@@ -19,6 +19,8 @@
*/
package org.apache.vysper.xmpp.extension.xep0124;
+import javax.servlet.http.HttpServletRequest;
+
import org.apache.vysper.mina.codec.StanzaBuilderFactory;
import org.apache.vysper.xml.decoder.XMLElementBuilderFactory;
import org.apache.vysper.xml.decoder.XMPPContentHandler;
@@ -47,7 +49,7 @@ public class BoshSaxContentHandler imple
private final BoshHandler boshHandler;
- private final BoshRequestContext boshRequestContext;
+ private final HttpServletRequest request;
private final XMLElementBuilderFactory builderFactory;
@@ -58,10 +60,9 @@ public class BoshSaxContentHandler imple
private boolean isBodyPayloadDecoded = false;
- public BoshSaxContentHandler(BoshHandler boshHandler,
- BoshRequestContext boshRequestContext) {
+ public BoshSaxContentHandler(BoshHandler boshHandler, HttpServletRequest
req) {
this.boshHandler = boshHandler;
- this.boshRequestContext = boshRequestContext;
+ request = req;
builderFactory = new StanzaBuilderFactory();
}
@@ -91,7 +92,7 @@ public class BoshSaxContentHandler imple
LOGGER.debug("BOSH decoding stanza: {}",
new Renderer(element).getComplete());
}
- boshHandler.process(boshRequestContext, (Stanza) element);
+ boshHandler.process(request, (Stanza) element);
builder = null;
}
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=957353&r1=957352&r2=957353&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
Wed Jun 23 21:24:39 2010
@@ -30,6 +30,7 @@ import javax.servlet.http.HttpServletReq
import javax.servlet.http.HttpServletResponse;
import org.apache.vysper.xmpp.server.ServerRuntimeContext;
+import org.eclipse.jetty.continuation.ContinuationSupport;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.xml.sax.SAXException;
@@ -40,6 +41,12 @@ import org.xml.sax.SAXException;
* @author The Apache MINA Project ([email protected])
*/
public class BoshServlet extends HttpServlet {
+
+ public static final String TXT_CONTENT_TYPE = "text/plain";
+
+ public static final String HTML_CONTENT_TYPE = "text/html; charset=UTF-8";
+
+ public static final String XML_CONTENT_TYPE = "text/xml; charset=UTF-8";
private static final long serialVersionUID = 1979722775762481476L;
@@ -47,12 +54,20 @@ public class BoshServlet extends HttpSer
private static final String INFO_GET = "This is an XMPP BOSH connection
manager, you need to use a compatible BOSH client to use its services!";
+ private static final String SERVER_IDENTIFICATION = "Vysper/0.5";
+
private final Logger logger = LoggerFactory.getLogger(BoshServlet.class);
private final BoshHandler boshHandler = new BoshHandler();
- private ByteArrayOutputStream flashCrossDomainPolicy;
-
+ private byte[] flashCrossDomainPolicy;
+
+ private String accessControlAllowOrigin = "*";
+
+ private String accessControlMaxAge = "86400"; // one day in seconds
+
+ private String accessControlAllowMethods = "GET, POST, OPTIONS";
+
/**
* Setter for the {...@link ServerRuntimeContext}
* @param serverRuntimeContext
@@ -70,41 +85,88 @@ public class BoshServlet extends HttpSer
public void setFlashCrossDomainPolicy(String policyPath) throws
IOException {
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(
policyPath));
- flashCrossDomainPolicy = new ByteArrayOutputStream();
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] buf = new byte[1024];
for (;;) {
int i = bis.read(buf);
if (i == -1) {
break;
}
- flashCrossDomainPolicy.write(buf, 0, i);
+ baos.write(buf, 0, i);
}
bis.close();
+ flashCrossDomainPolicy = baos.toByteArray();
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
+ resp.addDateHeader("Date", System.currentTimeMillis());
+ resp.addHeader("Server", SERVER_IDENTIFICATION);
if (FLASH_CROSS_DOMAIN_POLICY_URI.equals(req.getRequestURI())) {
- resp.setContentType(ContentType.XML_CONTENT_TYPE);
- flashCrossDomainPolicy.writeTo(resp.getOutputStream());
+ resp.setContentType(XML_CONTENT_TYPE);
+ resp.setContentLength(flashCrossDomainPolicy.length);
+ resp.getOutputStream().write(flashCrossDomainPolicy);
} else {
- resp.setContentType(ContentType.HTML_CONTENT_TYPE);
+ resp.setContentType(HTML_CONTENT_TYPE);
+ resp.setContentLength(INFO_GET.length());
resp.getWriter().println(INFO_GET);
}
resp.flushBuffer();
}
+
+ @Override
+ protected void doOptions(HttpServletRequest req, HttpServletResponse resp)
+ throws ServletException, IOException {
+ // used for preflighted requests
+ resp.addDateHeader("Date", System.currentTimeMillis());
+ resp.addHeader("Server", SERVER_IDENTIFICATION);
+ resp.setContentType(TXT_CONTENT_TYPE);
+ resp.setContentLength(0);
+ resp.addHeader("Access-Control-Allow-Origin",
accessControlAllowOrigin);
+ resp.addHeader("Access-Control-Allow-Methods",
accessControlAllowMethods);
+ resp.addHeader("Access-Control-Max-Age", accessControlMaxAge);
+ resp.flushBuffer();
+ }
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
- BoshRequestContext boshRequestContext = new BoshRequestContext(req,
resp);
- BoshDecoder boshDecoder = new BoshDecoder(boshHandler,
boshRequestContext);
+ BoshResponse boshResponse = (BoshResponse)
req.getAttribute("response");
+ if (boshResponse != null) {
+ // if continuation is resumed
+ writeResponse(resp, boshResponse);
+ return;
+ }
+
+ if (ContinuationSupport.getContinuation(req).isExpired()) {
+ // BOSH wait time is reached
+ BoshBackedSessionContext session = (BoshBackedSessionContext)
req.getAttribute("session");
+ if (session == null) {
+ logger.error("Continuation expired without having a session
associated!");
+ return;
+ }
+ session.requestExpired(req);
+// writeResponse(resp,
session.getResponse(boshHandler.getEmptyStanza()));
+ return;
+ }
+
+ BoshDecoder decoder = new BoshDecoder(boshHandler, req);
try {
- boshDecoder.decode();
+ decoder.decode();
} catch (SAXException e) {
logger.error("Exception thrown while decoding XML", e);
}
}
+
+ private void writeResponse(HttpServletResponse resp, BoshResponse
respData) throws IOException {
+ resp.addDateHeader("Date", System.currentTimeMillis());
+ resp.addHeader("Server", SERVER_IDENTIFICATION);
+ resp.setContentType(respData.getContentType());
+ resp.setContentLength(respData.getContent().length);
+ resp.addHeader("Access-control-allow-origin",
accessControlAllowOrigin);
+ resp.getOutputStream().write(respData.getContent());
+ resp.flushBuffer();
+ }
}