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/08 23:36:00 UTC

svn commit: r920552 - in /shindig/trunk/java/gadgets/src: main/java/org/apache/shindig/gadgets/rewrite/AbsolutePathReferenceVisitor.java test/java/org/apache/shindig/gadgets/rewrite/AbsolutePathReferenceVisitorTest.java

Author: johnh
Date: Mon Mar  8 22:36:00 2010
New Revision: 920552

URL: http://svn.apache.org/viewvc?rev=920552&view=rev
Log:
Rewrites relative links found in HTML to being absolute. This implementation may
serve as an alternative to the use of a <base> tag.

No Gadget/ContentRewriter is introduced in this CL as yet.


Added:
    shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/rewrite/AbsolutePathReferenceVisitor.java
    shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/rewrite/AbsolutePathReferenceVisitorTest.java

Added: shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/rewrite/AbsolutePathReferenceVisitor.java
URL: http://svn.apache.org/viewvc/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/rewrite/AbsolutePathReferenceVisitor.java?rev=920552&view=auto
==============================================================================
--- shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/rewrite/AbsolutePathReferenceVisitor.java (added)
+++ shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/rewrite/AbsolutePathReferenceVisitor.java Mon Mar  8 22:36:00 2010
@@ -0,0 +1,71 @@
+/*
+ * 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 java.util.Map;
+
+import org.apache.commons.lang.StringUtils;
+import org.apache.shindig.common.uri.Uri;
+import org.apache.shindig.gadgets.Gadget;
+import org.apache.shindig.gadgets.rewrite.DomWalker.Visitor;
+import org.w3c.dom.Attr;
+import org.w3c.dom.Node;
+
+import com.google.common.collect.ImmutableMap;
+
+import java.util.List;
+
+public class AbsolutePathReferenceVisitor implements Visitor {
+  public final static Map<String, String> RESOURCE_TAGS =
+    ImmutableMap.<String, String>builder()
+        .put("a", "href")
+        .put("img", "src")
+        .put("embed", "src")
+        .put("link", "href")
+        .put("script", "src")
+        .put("object", "src").build();
+
+  public VisitStatus visit(Gadget gadget, Node node) throws RewritingException {
+    String nodeName = node.getNodeName().toLowerCase();
+    if (node.getNodeType() == Node.ELEMENT_NODE &&
+        RESOURCE_TAGS.containsKey(nodeName)) {
+      Attr attr = (Attr)node.getAttributes().getNamedItem(RESOURCE_TAGS.get(nodeName));
+      String nodeUri = attr != null ? attr.getValue() : null;
+      if (!StringUtils.isEmpty(nodeUri)) {
+        try {
+          Uri prevUri = Uri.parse(nodeUri);
+          Uri resolved = gadget.getSpec().getUrl().resolve(prevUri);
+          if (!resolved.equals(prevUri)) {
+            attr.setValue(resolved.toString());
+            return VisitStatus.MODIFY;
+          }
+        } catch (Uri.UriException e) {
+          // UriException on illegal input. Ignore.
+        }
+      }
+    }
+    return VisitStatus.BYPASS;
+  }
+
+  public boolean revisit(Gadget gadget, List<Node> node) throws RewritingException {
+    // Modification happens immediately.
+    return false;
+  }
+
+}

Added: shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/rewrite/AbsolutePathReferenceVisitorTest.java
URL: http://svn.apache.org/viewvc/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/rewrite/AbsolutePathReferenceVisitorTest.java?rev=920552&view=auto
==============================================================================
--- shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/rewrite/AbsolutePathReferenceVisitorTest.java (added)
+++ shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/rewrite/AbsolutePathReferenceVisitorTest.java Mon Mar  8 22:36:00 2010
@@ -0,0 +1,147 @@
+/*
+ * 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.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+
+import org.apache.shindig.common.uri.Uri;
+import org.apache.shindig.gadgets.rewrite.DomWalker.Visitor.VisitStatus;
+
+import org.junit.Test;
+
+import org.w3c.dom.Comment;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.Text;
+
+public class AbsolutePathReferenceVisitorTest extends DomWalkerTestBase {
+  private static final Uri ABSOLUTE_URI = Uri.parse("http://host.com/path");
+  private static final String JS_URI_STR = "javascript:foo();";
+  private static final Uri RELATIVE_URI = Uri.parse("/host/relative");
+  private static final Uri RELATIVE_RESOLVED_URI = GADGET_URI.resolve(RELATIVE_URI);
+  private static final Uri PATH_RELATIVE_URI = Uri.parse("path/relative");
+  private static final Uri PATH_RELATIVE_RESOLVED_URI = GADGET_URI.resolve(PATH_RELATIVE_URI);
+  private static final String INVALID_URI_STRING = "!^|BAD URI|^!";
+  
+  @Test
+  public void bypassComment() throws Exception {
+    Comment comment = doc.createComment("howdy pardner");
+    assertEquals(VisitStatus.BYPASS, getVisitStatus(comment));
+  }
+  
+  @Test
+  public void bypassText() throws Exception {
+    Text text = doc.createTextNode("back scratchah! get ya back scratcha he'yah!");
+    assertEquals(VisitStatus.BYPASS, getVisitStatus(text));
+  }
+  
+  @Test
+  public void bypassNonSupportedTag() throws Exception {
+    Element div = elem("div", "src", RELATIVE_URI.toString(), "href", RELATIVE_URI.toString());
+    assertEquals(VisitStatus.BYPASS, getVisitStatus(div));
+  }
+  
+  @Test
+  public void bypassTagWithoutAttrib() throws Exception {
+    Element a = elem("a");
+    assertEquals(VisitStatus.BYPASS, getVisitStatus(a));
+  }
+  
+  @Test
+  public void absolutifyTagA() throws Exception {
+    checkAbsolutifyStates("a");
+  }
+  
+  @Test
+  public void absolutifyTagImg() throws Exception {
+    checkAbsolutifyStates("img");
+  }
+  
+  @Test
+  public void absolutifyTagLink() throws Exception {
+    checkAbsolutifyStates("link");
+  }
+  
+  @Test
+  public void absolutifyTagScript() throws Exception {
+    checkAbsolutifyStates("script");
+  }
+  
+  @Test
+  public void absolutifyTagObject() throws Exception {
+    checkAbsolutifyStates("object");
+  }
+
+  @Test
+  public void revisitDoesNothing() throws Exception {
+    assertFalse(new AbsolutePathReferenceVisitor().revisit(gadget(), null));
+  }
+  
+  private void checkAbsolutifyStates(String tagName) throws Exception {
+    String lcTag = tagName.toLowerCase();
+    String ucTag = tagName.toUpperCase();
+    String validAttr = AbsolutePathReferenceVisitor.RESOURCE_TAGS.get(lcTag);
+    String invalidAttr = validAttr + "whoknows";
+    
+    // lowercase, correct attrib, relative-possible URL
+    Element lcValidRelative = elem(lcTag, validAttr, RELATIVE_URI.toString());
+    assertEquals(VisitStatus.MODIFY, getVisitStatus(lcValidRelative));
+    assertEquals(RELATIVE_RESOLVED_URI.toString(), lcValidRelative.getAttribute(validAttr));
+    
+    Element lcValidPathRelative = elem(lcTag, validAttr, PATH_RELATIVE_URI.toString());
+    assertEquals(VisitStatus.MODIFY, getVisitStatus(lcValidPathRelative));
+    assertEquals(PATH_RELATIVE_RESOLVED_URI.toString(),
+        lcValidPathRelative.getAttribute(validAttr));
+    
+    // uppercase, same
+    Element ucValidRelative = elem(ucTag, validAttr, RELATIVE_URI.toString());
+    assertEquals(VisitStatus.MODIFY, getVisitStatus(ucValidRelative));
+    assertEquals(RELATIVE_RESOLVED_URI.toString(), ucValidRelative.getAttribute(validAttr));
+
+    Element ucValidPathRelative = elem(ucTag, validAttr, PATH_RELATIVE_URI.toString());
+    assertEquals(VisitStatus.MODIFY, getVisitStatus(ucValidPathRelative));
+    assertEquals(PATH_RELATIVE_RESOLVED_URI.toString(),
+        ucValidPathRelative.getAttribute(validAttr));
+
+    // lowercase, correct attrib, invalid URL
+    Element lcValidInvalid = elem(lcTag, validAttr, INVALID_URI_STRING);
+    assertEquals(VisitStatus.BYPASS, getVisitStatus(lcValidRelative));
+    assertEquals(INVALID_URI_STRING, lcValidInvalid.getAttribute(validAttr));
+    
+    // lowercase, correct attrib, absolute URL
+    Element lcValidAbsolute = elem(lcTag, validAttr, ABSOLUTE_URI.toString());
+    assertEquals(VisitStatus.BYPASS, getVisitStatus(lcValidAbsolute));
+    assertEquals(ABSOLUTE_URI.toString(), lcValidAbsolute.getAttribute(validAttr));
+    
+    // lowercase, invalid attrib, relative-possible URL
+    Element lcInvalidRelative = elem(lcTag, invalidAttr, RELATIVE_URI.toString());
+    assertEquals(VisitStatus.BYPASS, getVisitStatus(lcInvalidRelative));
+    assertEquals(RELATIVE_URI.toString(), lcInvalidRelative.getAttribute(invalidAttr));
+      
+    // lowercase, valid attrib, absolute (JS) URL
+    Element lcValidJs = elem(lcTag, validAttr, JS_URI_STR);
+    assertEquals(VisitStatus.BYPASS, getVisitStatus(lcValidJs));
+    assertEquals(JS_URI_STR, lcValidJs.getAttribute(validAttr));
+  }
+  
+  private VisitStatus getVisitStatus(Node node) throws Exception {
+    return new AbsolutePathReferenceVisitor().visit(gadget(), node);
+  }
+}