You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@shindig.apache.org by jo...@apache.org on 2010/03/09 02:34:47 UTC
svn commit: r920611 - in /shindig/trunk/java/gadgets/src:
main/java/org/apache/shindig/gadgets/rewrite/
test/java/org/apache/shindig/gadgets/rewrite/
Author: johnh
Date: Tue Mar 9 01:34:46 2010
New Revision: 920611
URL: http://svn.apache.org/viewvc?rev=920611&view=rev
Log:
Implementation of content reference proxying by way of the DomWalker.Visitor paradigm. Not activated in RewriteModule.
Added:
shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/rewrite/ProxyingContentRewriter.java
shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/rewrite/ProxyingVisitor.java
shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/rewrite/ProxyingContentRewriterTest.java
shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/rewrite/ProxyingVisitorTest.java
Added: shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/rewrite/ProxyingContentRewriter.java
URL: http://svn.apache.org/viewvc/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/rewrite/ProxyingContentRewriter.java?rev=920611&view=auto
==============================================================================
--- shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/rewrite/ProxyingContentRewriter.java (added)
+++ shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/rewrite/ProxyingContentRewriter.java Tue Mar 9 01:34:46 2010
@@ -0,0 +1,48 @@
+/*
+ * 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.shindig.gadgets.rewrite;
+
+import com.google.inject.Inject;
+
+import org.apache.shindig.common.uri.Uri;
+import org.apache.shindig.gadgets.Gadget;
+import org.apache.shindig.gadgets.rewrite.DomWalker;
+import org.apache.shindig.gadgets.rewrite.DomWalker.Visitor;
+import org.apache.shindig.gadgets.uri.ProxyUriManager;
+
+import java.util.Arrays;
+import java.util.List;
+
+public class ProxyingContentRewriter extends DomWalker.Rewriter {
+ private final ContentRewriterFeature.Factory featureConfigFactory;
+ private final ProxyUriManager proxyUriManager;
+
+ @Inject
+ public ProxyingContentRewriter(ContentRewriterFeature.Factory featureConfigFactory,
+ ProxyUriManager proxyUriManager) {
+ this.featureConfigFactory = featureConfigFactory;
+ this.proxyUriManager = proxyUriManager;
+ }
+
+ @Override
+ protected List<Visitor> makeVisitors(Gadget context, Uri gadgetUri) {
+ ContentRewriterFeature.Config config = featureConfigFactory.get(gadgetUri);
+ return Arrays.<Visitor>asList(new ProxyingVisitor(config, proxyUriManager));
+ }
+}
Added: shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/rewrite/ProxyingVisitor.java
URL: http://svn.apache.org/viewvc/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/rewrite/ProxyingVisitor.java?rev=920611&view=auto
==============================================================================
--- shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/rewrite/ProxyingVisitor.java (added)
+++ shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/rewrite/ProxyingVisitor.java Tue Mar 9 01:34:46 2010
@@ -0,0 +1,119 @@
+/*
+ * 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.shindig.gadgets.rewrite;
+
+import org.apache.shindig.common.Pair;
+import org.apache.shindig.common.uri.Uri;
+import org.apache.shindig.gadgets.Gadget;
+import org.apache.shindig.gadgets.uri.ProxyUriManager;
+import org.w3c.dom.Attr;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Lists;
+
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Simple visitor that, when plugged into a DomWalker, rewrites
+ * resource links to proxied versions of the same.
+ */
+public class ProxyingVisitor implements DomWalker.Visitor {
+ public final static Map<String, String> RESOURCE_TAGS =
+ ImmutableMap.of(
+ "img", "src",
+ "embed", "src",
+ "link", "href",
+ "script", "src",
+ "object", "src");
+
+ private final ContentRewriterFeature.Config featureConfig;
+ private final ProxyUriManager uriManager;
+
+ public ProxyingVisitor(ContentRewriterFeature.Config featureConfig,
+ ProxyUriManager uriManager) {
+ this.featureConfig = featureConfig;
+ this.uriManager = uriManager;
+ }
+
+ public VisitStatus visit(Gadget gadget, Node node) throws RewritingException {
+ String nodeName = node.getNodeName().toLowerCase();
+ if (node.getNodeType() == Node.ELEMENT_NODE &&
+ RESOURCE_TAGS.containsKey(nodeName) &&
+ featureConfig.shouldRewriteTag(nodeName)) {
+ Attr attr = (Attr)node.getAttributes().getNamedItem(
+ RESOURCE_TAGS.get(nodeName));
+ if (attr != null) {
+ String urlValue = attr.getValue();
+ if (featureConfig.shouldRewriteURL(urlValue)) {
+ return VisitStatus.RESERVE_NODE;
+ }
+ }
+ }
+ return VisitStatus.BYPASS;
+ }
+
+ public boolean revisit(Gadget gadget, List<Node> nodes) throws RewritingException {
+ List<Pair<Node, Uri>> proxiedUris = getProxiedUris(gadget, nodes);
+
+ boolean mutated = false;
+ for (Pair<Node, Uri> proxyPair : proxiedUris) {
+ if (proxyPair.two == null) {
+ continue;
+ }
+ Element element = (Element)proxyPair.one;
+ element.setAttribute(RESOURCE_TAGS.get(element.getNodeName()), proxyPair.two.toString());
+ mutated = true;
+ }
+
+ return mutated;
+ }
+
+ private List<Pair<Node, Uri>> getProxiedUris(Gadget gadget, List<Node> nodes) {
+ List<ProxyUriManager.ProxyUri> reservedUris =
+ Lists.newArrayListWithCapacity(nodes.size());
+
+ for (Node node : nodes) {
+ Element element = (Element)node;
+ String uriStr = element.getAttribute(RESOURCE_TAGS.get(element.getNodeName()));
+ try {
+ reservedUris.add(new ProxyUriManager.ProxyUri(gadget, Uri.parse(uriStr)));
+ } catch (Exception e) {
+ // Uri parse exception, add null.
+ reservedUris.add(null);
+ }
+ }
+
+ List<Uri> resourceUris = uriManager.make(reservedUris, featureConfig.getExpires());
+
+ // By contract, resourceUris matches by index with inbound Uris. Create an easy-access
+ // List with the results.
+ List<Pair<Node, Uri>> proxiedUris = Lists.newArrayListWithCapacity(nodes.size());
+
+ Iterator<Uri> uriIt = resourceUris.iterator();
+ for (Node node : nodes) {
+ proxiedUris.add(Pair.of(node, uriIt.next()));
+ }
+
+ return proxiedUris;
+ }
+}
Added: shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/rewrite/ProxyingContentRewriterTest.java
URL: http://svn.apache.org/viewvc/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/rewrite/ProxyingContentRewriterTest.java?rev=920611&view=auto
==============================================================================
--- shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/rewrite/ProxyingContentRewriterTest.java (added)
+++ shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/rewrite/ProxyingContentRewriterTest.java Tue Mar 9 01:34:46 2010
@@ -0,0 +1,28 @@
+/*
+ * 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.shindig.gadgets.rewrite;
+
+import org.junit.Test;
+
+public class ProxyingContentRewriterTest {
+ @Test
+ public void implementIntegrationTests() throws Exception {
+ // TODO: what the method says
+ }
+}
Added: shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/rewrite/ProxyingVisitorTest.java
URL: http://svn.apache.org/viewvc/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/rewrite/ProxyingVisitorTest.java?rev=920611&view=auto
==============================================================================
--- shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/rewrite/ProxyingVisitorTest.java (added)
+++ shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/rewrite/ProxyingVisitorTest.java Tue Mar 9 01:34:46 2010
@@ -0,0 +1,142 @@
+/*
+ * 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.shindig.gadgets.rewrite;
+
+import static org.easymock.classextension.EasyMock.capture;
+import static org.easymock.classextension.EasyMock.createMock;
+import static org.easymock.classextension.EasyMock.expect;
+import static org.easymock.classextension.EasyMock.replay;
+import static org.easymock.classextension.EasyMock.verify;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.assertTrue;
+
+import org.apache.shindig.common.uri.Uri;
+import org.apache.shindig.gadgets.Gadget;
+import org.apache.shindig.gadgets.rewrite.DomWalker.Visitor.VisitStatus;
+import org.apache.shindig.gadgets.uri.ProxyUriManager;
+import org.easymock.Capture;
+import org.junit.Test;
+
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Lists;
+
+import java.util.List;
+
+/**
+ * Test of proxying rewriter
+ */
+public class ProxyingVisitorTest extends DomWalkerTestBase {
+ private static final String URL_STRING = "http://www.foo.com/";
+
+ @Test
+ public void imgVisitReserved() throws Exception {
+ checkVisitReserved("img", true);
+ }
+
+ @Test
+ public void embedVisitReserved() throws Exception {
+ checkVisitReserved("embed", true);
+ }
+
+ @Test
+ public void linkVisitReserved() throws Exception {
+ checkVisitReserved("link", true);
+ }
+
+ @Test
+ public void scriptVisitReserved() throws Exception {
+ checkVisitReserved("script", true);
+ }
+
+ @Test
+ public void objectVisitReserved() throws Exception {
+ checkVisitReserved("object", true);
+ }
+
+ @Test
+ public void otherVisitNotReserved() throws Exception {
+ checkVisitReserved("other", false);
+ }
+
+ private void checkVisitReserved(String tag, boolean result) throws Exception {
+ tag = tag.toLowerCase();
+ assertEquals(result, ProxyingVisitor.RESOURCE_TAGS.containsKey(tag));
+ assertEquals(result, getVisitReserved(tag, true, true));
+ assertEquals(result, getVisitReserved(tag.toUpperCase(), true, true));
+ assertFalse(getVisitReserved(tag, false, true));
+ assertFalse(getVisitReserved(tag, true, false));
+ assertFalse(getVisitReserved(tag, false, false));
+ }
+
+ private boolean getVisitReserved(String tag, boolean resUrl, boolean resTag) throws Exception {
+ // Reserved when lower-case and both URL and Tag reserved.
+ String attrName = ProxyingVisitor.RESOURCE_TAGS.get(tag.toLowerCase());
+ Node node = elem(tag, attrName != null ? attrName : "src", URL_STRING);
+ ContentRewriterFeature.Config config = createMock(ContentRewriterFeature.Config.class);
+ expect(config.shouldRewriteURL(URL_STRING)).andReturn(resUrl).anyTimes();
+ expect(config.shouldRewriteTag(tag.toLowerCase())).andReturn(resTag).anyTimes();
+ replay(config);
+
+ ProxyingVisitor rewriter = new ProxyingVisitor(config, null);
+ VisitStatus status = rewriter.visit(null, node);
+ verify(config);
+
+ return status != VisitStatus.BYPASS;
+ }
+
+ @Test
+ public void revisitModifyValidSkipInvalid() throws Exception {
+ // Batch test: ensures in-order modification.
+ // Includes one mod and one skip.
+ // No need to test invalid nodes since visit() and DomWalker tests preclude this.
+ String scriptSrc = "http://script.com/foo.js";
+ Element e1 = elem("script", "src", scriptSrc);
+ Element e2 = elem("script", "src", "^!,,|BLARGH");
+ List<Node> nodes = ImmutableList.<Node>of(e1, e2);
+ ProxyUriManager uriManager = createMock(ProxyUriManager.class);
+ Uri rewrittenUri = Uri.parse("http://bar.com/");
+ List<Uri> returned = Lists.newArrayList(rewrittenUri, null);
+ ContentRewriterFeature.Config config = createMock(ContentRewriterFeature.Config.class);
+ Integer expires = new Integer(3);
+ expect(config.getExpires()).andReturn(expires).once();
+ expect(config);
+ Capture<List<ProxyUriManager.ProxyUri>> cap = new Capture<List<ProxyUriManager.ProxyUri>>();
+ Capture<Integer> intCap = new Capture<Integer>();
+ expect(uriManager.make(capture(cap), capture(intCap))).andReturn(returned).once();
+ replay(config, uriManager);
+ Gadget gadget = gadget();
+
+ ProxyingVisitor rewriter = new ProxyingVisitor(config, uriManager);
+ assertTrue(rewriter.revisit(gadget, nodes));
+ verify(config, uriManager);
+
+ assertEquals(2, cap.getValue().size());
+ assertEquals(Uri.parse(scriptSrc), cap.getValue().get(0).getResource());
+ assertNull(cap.getValue().get(1));
+ assertSame(expires, intCap.getValue());
+ assertEquals(rewrittenUri.toString(), e1.getAttribute("src"));
+ assertEquals("^!,,|BLARGH", e2.getAttribute("src"));
+ }
+}