Author: chirino
Date: Mon Mar 19 14:55:31 2012
New Revision: 1302486
URL: http://svn.apache.org/viewvc?rev=1302486&view=rev
Log:
Fixes APLO-171 : Support allowing cross origin resource sharing (CORS) of web
admin APIs and websocket APIs.
Added:
activemq/activemq-apollo/trunk/apollo-broker/src/main/scala/org/apache/activemq/apollo/broker/web/AllowAnyOriginFilter.scala
Modified:
activemq/activemq-apollo/trunk/apollo-broker/src/main/scala/org/apache/activemq/apollo/broker/jetty/JettyWebServer.scala
activemq/activemq-apollo/trunk/apollo-broker/src/main/scala/org/apache/activemq/apollo/broker/jetty/WebSocketTransportFactory.scala
activemq/activemq-apollo/trunk/apollo-website/src/documentation/user-manual.md
Modified:
activemq/activemq-apollo/trunk/apollo-broker/src/main/scala/org/apache/activemq/apollo/broker/jetty/JettyWebServer.scala
URL:
http://svn.apache.org/viewvc/activemq/activemq-apollo/trunk/apollo-broker/src/main/scala/org/apache/activemq/apollo/broker/jetty/JettyWebServer.scala?rev=1302486&r1=1302485&r2=1302486&view=diff
==============================================================================
---
activemq/activemq-apollo/trunk/apollo-broker/src/main/scala/org/apache/activemq/apollo/broker/jetty/JettyWebServer.scala
(original)
+++
activemq/activemq-apollo/trunk/apollo-broker/src/main/scala/org/apache/activemq/apollo/broker/jetty/JettyWebServer.scala
Mon Mar 19 14:55:31 2012
@@ -22,7 +22,6 @@ import org.eclipse.jetty.webapp.WebAppCo
import org.eclipse.jetty.server.nio.SelectChannelConnector
import org.apache.activemq.apollo.util._
import org.fusesource.hawtdispatch._
-import org.apache.activemq.apollo.broker.web.{WebServer, WebServerFactory}
import org.eclipse.jetty.server.handler.HandlerList
import collection.mutable.HashMap
import org.eclipse.jetty.server.ssl.SslSelectChannelConnector
@@ -33,6 +32,8 @@ import java.net.{URL, URI}
import java.io.{FileOutputStream, File}
import java.util.jar.JarInputStream
import java.lang.String
+import org.eclipse.jetty.servlet.{FilterMapping, FilterHolder}
+import org.apache.activemq.apollo.broker.web.{AllowAnyOriginFilter, WebServer,
WebServerFactory}
/**
* <p>
@@ -171,6 +172,9 @@ class JettyWebServer(val broker:Broker)
val host = bind_uri.getHost
var port = bind_uri.getPort
+ var query = URISupport.parseQuery(bind_uri.getQuery)
+ val cors_origin = query.get("cors_origin")
+
scheme match {
case "http" =>
if (port == -1) {
@@ -216,6 +220,12 @@ class JettyWebServer(val broker:Broker)
context.setContextPath(prefix)
context.setWar(webapp_path.getCanonicalPath)
context.setClassLoader(Broker.class_loader)
+
+ if( cors_origin!=null && !cors_origin.trim().isEmpty ) {
+ val origins = cors_origin.split(",").map(_.trim()).toSet
+ context.addFilter(new FilterHolder(new
AllowAnyOriginFilter(origins)), "/*", FilterMapping.DEFAULT)
+ }
+
if( broker.tmp !=null ) {
context.setTempDirectory(broker.tmp)
}
Modified:
activemq/activemq-apollo/trunk/apollo-broker/src/main/scala/org/apache/activemq/apollo/broker/jetty/WebSocketTransportFactory.scala
URL:
http://svn.apache.org/viewvc/activemq/activemq-apollo/trunk/apollo-broker/src/main/scala/org/apache/activemq/apollo/broker/jetty/WebSocketTransportFactory.scala?rev=1302486&r1=1302485&r2=1302486&view=diff
==============================================================================
---
activemq/activemq-apollo/trunk/apollo-broker/src/main/scala/org/apache/activemq/apollo/broker/jetty/WebSocketTransportFactory.scala
(original)
+++
activemq/activemq-apollo/trunk/apollo-broker/src/main/scala/org/apache/activemq/apollo/broker/jetty/WebSocketTransportFactory.scala
Mon Mar 19 14:55:31 2012
@@ -25,7 +25,6 @@ import org.eclipse.jetty.server.nio.Sele
import javax.net.ssl.SSLContext
import org.eclipse.jetty.server.ssl.SslSelectChannelConnector
import org.eclipse.jetty.util.thread.ExecutorThreadPool
-import org.eclipse.jetty.servlet.{ServletHolder, ServletContextHandler}
import javax.servlet.http.HttpServletRequest
import org.eclipse.jetty.websocket.{WebSocket, WebSocketServlet}
import org.eclipse.jetty.server.{Connector, Server}
@@ -40,6 +39,8 @@ import org.fusesource.hawtdispatch.trans
import org.fusesource.hawtbuf.{AsciiBuffer, Buffer}
import java.io.{EOFException, IOException}
import java.security.cert.X509Certificate
+import org.apache.activemq.apollo.broker.web.AllowAnyOriginFilter
+import org.eclipse.jetty.servlet.{FilterMapping, FilterHolder, ServletHolder,
ServletContextHandler}
/**
* @author <a href="http://hiramchirino.com">Hiram Chirino</a>
@@ -67,6 +68,8 @@ object WebSocketTransportFactory extends
var transportServerListener: TransportServerListener = _
@BeanProperty
var binary_transfers = false
+ @BeanProperty
+ var cors_origin:String = null
var broker: Broker = _
@@ -123,6 +126,10 @@ object WebSocketTransportFactory extends
var context = new
ServletContextHandler(ServletContextHandler.NO_SECURITY)
context.setContextPath(prefix)
+ if( cors_origin!=null && !cors_origin.trim().isEmpty ) {
+ val origins = cors_origin.split(",").map(_.trim()).toSet
+ context.addFilter(new FilterHolder(new
AllowAnyOriginFilter(origins)), "/*", FilterMapping.DEFAULT)
+ }
context.addServlet(new ServletHolder(this), "/")
server = new Server
Added:
activemq/activemq-apollo/trunk/apollo-broker/src/main/scala/org/apache/activemq/apollo/broker/web/AllowAnyOriginFilter.scala
URL:
http://svn.apache.org/viewvc/activemq/activemq-apollo/trunk/apollo-broker/src/main/scala/org/apache/activemq/apollo/broker/web/AllowAnyOriginFilter.scala?rev=1302486&view=auto
==============================================================================
---
activemq/activemq-apollo/trunk/apollo-broker/src/main/scala/org/apache/activemq/apollo/broker/web/AllowAnyOriginFilter.scala
(added)
+++
activemq/activemq-apollo/trunk/apollo-broker/src/main/scala/org/apache/activemq/apollo/broker/web/AllowAnyOriginFilter.scala
Mon Mar 19 14:55:31 2012
@@ -0,0 +1,50 @@
+/**
+ * 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.activemq.apollo.broker.web
+
+import javax.servlet._
+import http.{HttpServletRequest, HttpServletResponse}
+
+/**
+ * Servlet filter which adds a 'Access-Control-Allow-Origin: *' HTTP header
+ * to allow CORS.
+ */
+class AllowAnyOriginFilter(val allowed:Set[String]) extends
javax.servlet.Filter {
+
+ val allow_any = allowed.contains("*")
+
+ override def init(filterConfig: FilterConfig) {}
+ override def destroy() = {}
+
+ override def doFilter(request: ServletRequest, response: ServletResponse,
chain: FilterChain) = {
+ response match {
+ case response: HttpServletResponse =>
+ if( allow_any ) {
+ response.addHeader("Access-Control-Allow-Origin", "*");
+ } else {
+ for( origin <-
Option(request.asInstanceOf[HttpServletRequest].getHeader("Origin")) ) {
+ if ( allowed.contains(origin) ) {
+ response.addHeader("Access-Control-Allow-Origin", origin);
+ }
+ }
+ }
+ case _ =>
+ }
+ chain.doFilter(request, response)
+ }
+
+}
\ No newline at end of file
Modified:
activemq/activemq-apollo/trunk/apollo-website/src/documentation/user-manual.md
URL:
http://svn.apache.org/viewvc/activemq/activemq-apollo/trunk/apollo-website/src/documentation/user-manual.md?rev=1302486&r1=1302485&r2=1302486&view=diff
==============================================================================
---
activemq/activemq-apollo/trunk/apollo-website/src/documentation/user-manual.md
(original)
+++
activemq/activemq-apollo/trunk/apollo-website/src/documentation/user-manual.md
Mon Mar 19 14:55:31 2012
@@ -247,9 +247,18 @@ Example configuraiton:
{pygmentize}
One thing worth noting is that web sockets (just as Ajax) implements the same
-origin policy, so you can access only brokers running on the same host as
+origin policy, so by default you can access only brokers running on the same
host as
where the web page originated from.
+If you want to allow cross origin resource sharing (CORS) of the WebSocket
connector,
+by different hosts then your should add `cors_origin` query parameter to the
bind URI with
+a common seperated list of domains that are allowed to access the WebSocket
+connector. Use `*` to allow access from any domain. Example:
+
+{pygmentize:: xml}
+<connector id="ws" bind="ws://0.0.0.0:61623?cors_origin=*"/>
+{pygmentize}
+
###### WebSocket Clients
You can use one of the following JavaScript libraries to access
@@ -863,6 +872,20 @@ A `web_admin` element may be configured
* `bind` : The address and port to bind the web interface on in URL syntax.
+If you want to allow cross origin resource sharing (CORS) of the web admin
APIs,
+then your should add `cors_origin` query parameter to the bind URI with
+a common seperated list of domains that are allowed to access the web
+admin APIs. Use `*` to allow access from any domain. Example:
+
+{pygmentize:: xml}
+<broker xmlns="http://activemq.apache.org/schema/activemq/apollo">
+ ...
+ <web_admin bind="http://0.0.0.0:61680?cors_origin=*"/>
+ <web_admin bind="https://0.0.0.0:61681?cors_origin=www.foo.com,bar.com"/>
+ ...
+</broker>
+{pygmentize}
+
## Managing Brokers
The rest of this section's example assume that you have created a broker