You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@shindig.apache.org by li...@apache.org on 2010/05/08 00:51:17 UTC
svn commit: r942261 - in /shindig/trunk: ./ config/
java/common/src/main/java/org/apache/shindig/common/servlet/
java/common/src/main/java/org/apache/shindig/config/
java/common/src/main/java/org/apache/shindig/protocol/
java/common/src/test/java/org/a...
Author: lindner
Date: Fri May 7 22:51:16 2010
New Revision: 942261
URL: http://svn.apache.org/viewvc?rev=942261&view=rev
Log:
Support Cross-Origin-Request-Sharing on the server side
Modified:
shindig/trunk/UPGRADING
shindig/trunk/config/container.js
shindig/trunk/java/common/src/main/java/org/apache/shindig/common/servlet/HttpUtil.java
shindig/trunk/java/common/src/main/java/org/apache/shindig/config/AbstractContainerConfig.java
shindig/trunk/java/common/src/main/java/org/apache/shindig/config/ContainerConfig.java
shindig/trunk/java/common/src/main/java/org/apache/shindig/protocol/ApiServlet.java
shindig/trunk/java/common/src/main/java/org/apache/shindig/protocol/DataServiceServlet.java
shindig/trunk/java/common/src/main/java/org/apache/shindig/protocol/JsonRpcServlet.java
shindig/trunk/java/common/src/test/java/org/apache/shindig/common/servlet/HttpUtilTest.java
shindig/trunk/java/common/src/test/java/org/apache/shindig/protocol/DataServiceServletTest.java
shindig/trunk/java/common/src/test/java/org/apache/shindig/protocol/JsonRpcServletTest.java
shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/servlet/RpcServletTest.java
shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/dataservice/integration/AbstractLargeRestfulTests.java
Modified: shindig/trunk/UPGRADING
URL: http://svn.apache.org/viewvc/shindig/trunk/UPGRADING?rev=942261&r1=942260&r2=942261&view=diff
==============================================================================
--- shindig/trunk/UPGRADING (original)
+++ shindig/trunk/UPGRADING Fri May 7 22:51:16 2010
@@ -4,9 +4,19 @@ FROM 1.0.x TO 1.1.x
Almost all interfaces have been updated from 1.0.x -> 1.1.x. The
following information is not complete.
+== container.js config changes ==
+
+* gadgets.parentOrigins: Default ["*"]
+
+An array of valid origin domains for the container.
== Java Interface Changes ==
+* AbstractContainerConfig
+
+Changed signature on getMap() and getList() to use Java
+generics.
+
* SecurityTokenDecoder
The interface and implementation are replaced
@@ -15,6 +25,7 @@ with the new SecurityTokenCodec interfac
You will need to adjust any custom SecurityToken decoders to
encode tokens as well as decode them.
+
== Java Guice Changes ==
1.1.x uses Guice 2.0 which allows for @Provides annotations and much more.
Modified: shindig/trunk/config/container.js
URL: http://svn.apache.org/viewvc/shindig/trunk/config/container.js?rev=942261&r1=942260&r2=942261&view=diff
==============================================================================
--- shindig/trunk/config/container.js (original)
+++ shindig/trunk/config/container.js Fri May 7 22:51:16 2010
@@ -60,6 +60,10 @@
// DNS domain on which gadgets should render.
"gadgets.lockedDomainSuffix" : "-a.example.com:8080",
+// Origins for CORS requests and/or Referer validation
+// Indicate a set of origins or an entry with * to indicate that all origins are allowed
+"gadgets.parentOrigins" : ["*"],
+
// Various urls generated throughout the code base.
// iframeBaseUri will automatically have the host inserted
// if locked domain is enabled and the implementation supports it.
Modified: shindig/trunk/java/common/src/main/java/org/apache/shindig/common/servlet/HttpUtil.java
URL: http://svn.apache.org/viewvc/shindig/trunk/java/common/src/main/java/org/apache/shindig/common/servlet/HttpUtil.java?rev=942261&r1=942260&r2=942261&view=diff
==============================================================================
--- shindig/trunk/java/common/src/main/java/org/apache/shindig/common/servlet/HttpUtil.java (original)
+++ shindig/trunk/java/common/src/main/java/org/apache/shindig/common/servlet/HttpUtil.java Fri May 7 22:51:16 2010
@@ -18,10 +18,12 @@
*/
package org.apache.shindig.common.servlet;
+import org.apache.commons.lang.StringUtils;
import org.apache.shindig.common.util.TimeSource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
+import java.util.Collection;
import java.util.regex.Pattern;
/**
@@ -129,4 +131,22 @@ public class HttpUtil {
}
return true;
}
+
+
+ public static final String ACCESS_CONTROL_ALLOW_ORIGIN_HEADER = "Access-Control-Allow-Origin";
+
+ /**
+ * Set the header for Cross-Site Resource Sharing.
+ * @param resp HttpServletResponse to modify
+ * @param validOrigins a space separated list of Origins as defined by the html5 spec
+ * @see http://dev.w3.org/html5/spec/browsers.html#origin-0
+ */
+ public static void setCORSheader(HttpServletResponse resp, Collection<String> validOrigins) {
+ if (validOrigins == null) {
+ return;
+ }
+ for (String origin : validOrigins) {
+ resp.addHeader(ACCESS_CONTROL_ALLOW_ORIGIN_HEADER, origin);
+ }
+ }
}
\ No newline at end of file
Modified: shindig/trunk/java/common/src/main/java/org/apache/shindig/config/AbstractContainerConfig.java
URL: http://svn.apache.org/viewvc/shindig/trunk/java/common/src/main/java/org/apache/shindig/config/AbstractContainerConfig.java?rev=942261&r1=942260&r2=942261&view=diff
==============================================================================
--- shindig/trunk/java/common/src/main/java/org/apache/shindig/config/AbstractContainerConfig.java (original)
+++ shindig/trunk/java/common/src/main/java/org/apache/shindig/config/AbstractContainerConfig.java Fri May 7 22:51:16 2010
@@ -53,19 +53,19 @@ public abstract class AbstractContainerC
}
@SuppressWarnings("unchecked")
- public List<Object> getList(String container, String property) {
+ public <T> List<T> getList(String container, String property) {
Object value = getProperty(container, property);
if (value instanceof List) {
- return (List<Object>) value;
+ return (List<T>) value;
}
return Collections.emptyList();
}
@SuppressWarnings("unchecked")
- public Map<String, Object> getMap(String container, String property) {
+ public <T> Map<String, T> getMap(String container, String property) {
Object value = getProperty(container, property);
if (value instanceof Map) {
- return (Map<String, Object>) value;
+ return (Map<String, T>) value;
}
return Collections.emptyMap();
}
Modified: shindig/trunk/java/common/src/main/java/org/apache/shindig/config/ContainerConfig.java
URL: http://svn.apache.org/viewvc/shindig/trunk/java/common/src/main/java/org/apache/shindig/config/ContainerConfig.java?rev=942261&r1=942260&r2=942261&view=diff
==============================================================================
--- shindig/trunk/java/common/src/main/java/org/apache/shindig/config/ContainerConfig.java (original)
+++ shindig/trunk/java/common/src/main/java/org/apache/shindig/config/ContainerConfig.java Fri May 7 22:51:16 2010
@@ -79,11 +79,11 @@ public interface ContainerConfig {
* @return The configuration property stored under the given name for the given container, or an
* empty list if it is not defined or not a list.
*/
- List<Object> getList(String container, String name);
+ <T> List<T> getList(String container, String name);
/**
* @return The configuration property stored under the given name for the given container, or an
* empty map if it is not defined or not a map.
*/
- Map<String, Object> getMap(String container, String name);
+ <T> Map<String, T> getMap(String container, String name);
}
Modified: shindig/trunk/java/common/src/main/java/org/apache/shindig/protocol/ApiServlet.java
URL: http://svn.apache.org/viewvc/shindig/trunk/java/common/src/main/java/org/apache/shindig/protocol/ApiServlet.java?rev=942261&r1=942260&r2=942261&view=diff
==============================================================================
--- shindig/trunk/java/common/src/main/java/org/apache/shindig/protocol/ApiServlet.java (original)
+++ shindig/trunk/java/common/src/main/java/org/apache/shindig/protocol/ApiServlet.java Fri May 7 22:51:16 2010
@@ -17,9 +17,11 @@
*/
package org.apache.shindig.protocol;
+import com.google.inject.Provider;
import org.apache.shindig.auth.AuthInfo;
import org.apache.shindig.auth.SecurityToken;
import org.apache.shindig.common.servlet.InjectedServlet;
+import org.apache.shindig.config.ContainerConfig;
import org.apache.shindig.protocol.conversion.BeanConverter;
import org.apache.shindig.protocol.conversion.BeanJsonConverter;
@@ -93,6 +95,14 @@ public abstract class ApiServlet extends
this.dispatcher = dispatcher;
}
+ protected ContainerConfig containerConfig;
+
+ @Inject
+ public void setContainerConfig(ContainerConfig containerConfig) {
+ this.containerConfig = containerConfig;
+ }
+
+
@Inject(optional = true)
public void setDisallowUnknownContentTypes(
@Named("shindig.api.disallow-unknown-content-types") boolean disallowUnknownContentTypes) {
Modified: shindig/trunk/java/common/src/main/java/org/apache/shindig/protocol/DataServiceServlet.java
URL: http://svn.apache.org/viewvc/shindig/trunk/java/common/src/main/java/org/apache/shindig/protocol/DataServiceServlet.java?rev=942261&r1=942260&r2=942261&view=diff
==============================================================================
--- shindig/trunk/java/common/src/main/java/org/apache/shindig/protocol/DataServiceServlet.java (original)
+++ shindig/trunk/java/common/src/main/java/org/apache/shindig/protocol/DataServiceServlet.java Fri May 7 22:51:16 2010
@@ -17,7 +17,11 @@
*/
package org.apache.shindig.protocol;
+import com.google.inject.Inject;
+import com.google.inject.Provider;
import org.apache.shindig.auth.SecurityToken;
+import org.apache.shindig.common.servlet.HttpUtil;
+import org.apache.shindig.config.ContainerConfig;
import org.apache.shindig.protocol.conversion.BeanConverter;
import com.google.common.collect.ImmutableMap;
@@ -103,6 +107,8 @@ public class DataServiceServlet extends
return;
}
+ HttpUtil.setCORSheader(servletResponse, containerConfig.<String>getList(token.getContainer(), "gadgets.parentOrigins"));
+
BeanConverter converter = getConverterForRequest(servletRequest);
handleSingleRequest(servletRequest, servletResponse, token, converter);
@@ -169,7 +175,13 @@ public class DataServiceServlet extends
response = ImmutableMap.of("entry", response);
}
+ // JSONP style callbacks
+ String callback = (HttpUtil.isJSONP(servletRequest) && ContentTypes.OUTPUT_JSON_CONTENT_TYPE.equals(converter.getContentType())) ?
+ servletRequest.getParameter("callback") : null;
+
+ if (callback != null) writer.write(callback + "(");
writer.write(converter.convertToString(response));
+ if (callback != null) writer.write(");\n");
} else {
sendError(servletResponse, responseItem);
}
Modified: shindig/trunk/java/common/src/main/java/org/apache/shindig/protocol/JsonRpcServlet.java
URL: http://svn.apache.org/viewvc/shindig/trunk/java/common/src/main/java/org/apache/shindig/protocol/JsonRpcServlet.java?rev=942261&r1=942260&r2=942261&view=diff
==============================================================================
--- shindig/trunk/java/common/src/main/java/org/apache/shindig/protocol/JsonRpcServlet.java (original)
+++ shindig/trunk/java/common/src/main/java/org/apache/shindig/protocol/JsonRpcServlet.java Fri May 7 22:51:16 2010
@@ -89,6 +89,7 @@ public class JsonRpcServlet extends ApiS
return;
}
+ HttpUtil.setCORSheader(servletResponse, containerConfig.<String>getList(token.getContainer(), "gadgets.parentOrigins"));
try {
String content = null;
@@ -123,6 +124,7 @@ public class JsonRpcServlet extends ApiS
JSONObject request = new JSONObject(content);
dispatch(request, formData, servletRequest, servletResponse, token, callback);
}
+ return;
} catch (JSONException je) {
sendJsonParseError(je, servletResponse);
} catch (IllegalArgumentException e) {
@@ -189,7 +191,7 @@ public class JsonRpcServlet extends ApiS
// Generate the output
Writer writer = servletResponse.getWriter();
- if (callback != null) writer.append(callback).append('(');
+ if (callback != null) writer.append(callback+'(');
jsonConverter.append(writer, result);
if (callback != null) writer.append(");\n");
}
@@ -213,7 +215,7 @@ public class JsonRpcServlet extends ApiS
// Generate the output
Writer writer = servletResponse.getWriter();
- if (callback != null) writer.append(callback).append('(');
+ if (callback != null) writer.append(callback+'(');
jsonConverter.append(writer, result);
if (callback != null) writer.append(");\n");
}
Modified: shindig/trunk/java/common/src/test/java/org/apache/shindig/common/servlet/HttpUtilTest.java
URL: http://svn.apache.org/viewvc/shindig/trunk/java/common/src/test/java/org/apache/shindig/common/servlet/HttpUtilTest.java?rev=942261&r1=942260&r2=942261&view=diff
==============================================================================
--- shindig/trunk/java/common/src/test/java/org/apache/shindig/common/servlet/HttpUtilTest.java (original)
+++ shindig/trunk/java/common/src/test/java/org/apache/shindig/common/servlet/HttpUtilTest.java Fri May 7 22:51:16 2010
@@ -28,9 +28,11 @@ import org.apache.shindig.common.servlet
import org.apache.shindig.common.util.DateUtil;
import org.apache.shindig.common.util.FakeTimeSource;
import org.easymock.classextension.EasyMock;
+import org.junit.Ignore;
import org.junit.Test;
import java.util.Arrays;
+import java.util.Collections;
import java.util.List;
import javax.servlet.http.HttpServletResponse;
@@ -91,7 +93,26 @@ public class HttpUtilTest {
HttpUtil.setNoCache(recorder);
checkCacheControlHeaders(testStartTime, recorder, 0, true);
}
-
+
+ @Test
+ public void testCORSstar() {
+ HttpUtil.setCORSheader(recorder, Collections.singleton("*"));
+ assertEquals(recorder.getHeader(HttpUtil.ACCESS_CONTROL_ALLOW_ORIGIN_HEADER), "*");
+ }
+
+ @Test
+ public void testCORSnull() {
+ HttpUtil.setCORSheader(recorder, null);
+ assertEquals(recorder.getHeader(HttpUtil.ACCESS_CONTROL_ALLOW_ORIGIN_HEADER), null);
+ }
+
+ @Test
+ @Ignore("HttpServletResponseRecorder doesn't support multiple headers")
+ public void testCORSmultiple() {
+ HttpUtil.setCORSheader(recorder, Arrays.asList("http://foo.example.com", "http://bar.example.com"));
+ // TODO fix HttpServletResponseRecorder and add multi-header test here
+ }
+
public static void checkCacheControlHeaders(long testStartTime,
HttpServletResponseRecorder response, int ttl, boolean noProxy) {
Modified: shindig/trunk/java/common/src/test/java/org/apache/shindig/protocol/DataServiceServletTest.java
URL: http://svn.apache.org/viewvc/shindig/trunk/java/common/src/test/java/org/apache/shindig/protocol/DataServiceServletTest.java?rev=942261&r1=942260&r2=942261&view=diff
==============================================================================
--- shindig/trunk/java/common/src/test/java/org/apache/shindig/protocol/DataServiceServletTest.java (original)
+++ shindig/trunk/java/common/src/test/java/org/apache/shindig/protocol/DataServiceServletTest.java Fri May 7 22:51:16 2010
@@ -27,6 +27,7 @@ import org.apache.commons.lang.StringUti
import org.apache.shindig.auth.AuthInfo;
import org.apache.shindig.common.testing.FakeGadgetToken;
import org.apache.shindig.common.testing.FakeHttpServletRequest;
+import org.apache.shindig.config.ContainerConfig;
import org.apache.shindig.protocol.conversion.BeanConverter;
import org.apache.shindig.protocol.conversion.BeanJsonConverter;
import org.easymock.IMocksControl;
@@ -49,7 +50,7 @@ public class DataServiceServletTest exte
private BeanJsonConverter jsonConverter;
private BeanConverter xmlConverter;
private BeanConverter atomConverter;
-
+ private ContainerConfig containerConfig;
private IMocksControl mockControl = EasyMock.createNiceControl();
@@ -61,6 +62,7 @@ public class DataServiceServletTest exte
jsonConverter = mockControl.createMock(BeanJsonConverter.class);
xmlConverter = mockControl.createMock(BeanConverter.class);
atomConverter = mockControl.createMock(BeanConverter.class);
+ containerConfig = mockControl.createMock(ContainerConfig.class);
EasyMock.expect(jsonConverter.getContentType()).andReturn(
ContentTypes.OUTPUT_JSON_CONTENT_TYPE).anyTimes();
@@ -68,12 +70,13 @@ public class DataServiceServletTest exte
ContentTypes.OUTPUT_XML_CONTENT_TYPE).anyTimes();
EasyMock.expect(atomConverter.getContentType()).andReturn(
ContentTypes.OUTPUT_ATOM_CONTENT_TYPE).anyTimes();
-
+
HandlerRegistry registry = new DefaultHandlerRegistry(null, jsonConverter,
new HandlerExecutionListener.NoOpHandler());
registry.addHandlers(Sets.<Object>newHashSet(new TestHandler()));
servlet.setHandlerRegistry(registry);
+ servlet.setContainerConfig(containerConfig);
servlet.setBeanConverters(jsonConverter, xmlConverter, atomConverter);
}
Modified: shindig/trunk/java/common/src/test/java/org/apache/shindig/protocol/JsonRpcServletTest.java
URL: http://svn.apache.org/viewvc/shindig/trunk/java/common/src/test/java/org/apache/shindig/protocol/JsonRpcServletTest.java?rev=942261&r1=942260&r2=942261&view=diff
==============================================================================
--- shindig/trunk/java/common/src/test/java/org/apache/shindig/protocol/JsonRpcServletTest.java (original)
+++ shindig/trunk/java/common/src/test/java/org/apache/shindig/protocol/JsonRpcServletTest.java Fri May 7 22:51:16 2010
@@ -24,6 +24,7 @@ import static org.easymock.classextensio
import org.apache.shindig.common.JsonAssert;
import org.apache.shindig.common.testing.FakeGadgetToken;
+import org.apache.shindig.config.ContainerConfig;
import org.apache.shindig.protocol.conversion.BeanJsonConverter;
import org.apache.shindig.protocol.multipart.FormDataItem;
import org.apache.shindig.protocol.multipart.MultipartFormParser;
@@ -66,6 +67,7 @@ public class JsonRpcServletTest extends
private HttpServletResponse res;
private JsonRpcServlet servlet;
private MultipartFormParser multipartFormParser;
+ private ContainerConfig containerConfig;
private final IMocksControl mockControl = EasyMock.createNiceControl();
@@ -78,6 +80,7 @@ public class JsonRpcServletTest extends
servlet = new JsonRpcServlet();
req = mockControl.createMock(HttpServletRequest.class);
res = mockControl.createMock(HttpServletResponse.class);
+ containerConfig = mockControl.createMock(ContainerConfig.class);
multipartFormParser = mockControl.createMock(MultipartFormParser.class);
EasyMock.expect(multipartFormParser.isMultipartContent(req)).andStubReturn(false);
@@ -91,6 +94,8 @@ public class JsonRpcServletTest extends
servlet.setHandlerRegistry(registry);
servlet.setBeanConverters(converter, null, null);
+ servlet.setContainerConfig(containerConfig);
+
handler.setMock(new TestHandler() {
@Override
public Object get(RequestItem req) {
Modified: shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/servlet/RpcServletTest.java
URL: http://svn.apache.org/viewvc/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/servlet/RpcServletTest.java?rev=942261&r1=942260&r2=942261&view=diff
==============================================================================
--- shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/servlet/RpcServletTest.java (original)
+++ shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/servlet/RpcServletTest.java Fri May 7 22:51:16 2010
@@ -26,10 +26,12 @@ import static org.easymock.classextensio
import java.io.IOException;
import java.io.PrintWriter;
+import java.util.Collections;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
+import org.apache.shindig.common.servlet.HttpUtil;
import org.json.JSONException;
import org.json.JSONObject;
import org.junit.Assert;
Modified: shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/dataservice/integration/AbstractLargeRestfulTests.java
URL: http://svn.apache.org/viewvc/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/dataservice/integration/AbstractLargeRestfulTests.java?rev=942261&r1=942260&r2=942261&view=diff
==============================================================================
--- shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/dataservice/integration/AbstractLargeRestfulTests.java (original)
+++ shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/dataservice/integration/AbstractLargeRestfulTests.java Fri May 7 22:51:16 2010
@@ -21,6 +21,7 @@ import org.apache.shindig.auth.AuthInfo;
import org.apache.shindig.common.EasyMockTestCase;
import org.apache.shindig.common.testing.FakeGadgetToken;
import org.apache.shindig.common.testing.FakeHttpServletRequest;
+import org.apache.shindig.config.ContainerConfig;
import org.apache.shindig.protocol.DataServiceServlet;
import org.apache.shindig.protocol.HandlerRegistry;
import org.apache.shindig.protocol.conversion.BeanJsonConverter;
@@ -55,6 +56,7 @@ import javax.xml.stream.XMLStreamReader;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.PrintWriter;
+import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -96,6 +98,9 @@ public abstract class AbstractLargeRestf
dispatcher.addHandlers(injector.getInstance(Key.get(new TypeLiteral<Set<Object>>(){},
Names.named("org.apache.shindig.social.handlers"))));
servlet.setHandlerRegistry(dispatcher);
+ ContainerConfig containerConfig = EasyMock.createMock(ContainerConfig.class);
+ EasyMock.expect(containerConfig.<String>getList(null, "gadgets.parentOrigins")).andReturn(Collections.<String>singletonList("*"));
+ servlet.setContainerConfig(EasyMock.createMock(ContainerConfig.class));
servlet.setBeanConverters(new BeanJsonConverter(injector),
new BeanXStreamConverter(new XStream081Configuration(injector)),
new BeanXStreamAtomConverter(new XStream081Configuration(injector)));