You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@abdera.apache.org by jm...@apache.org on 2011/12/22 06:30:32 UTC
svn commit: r1222042 - in /abdera/abdera2:
common/src/main/java/org/apache/abdera2/common/http/
common/src/main/java/org/apache/abdera2/common/text/
test/src/main/java/org/apache/abdera2/test/common/http/
Author: jmsnell
Date: Thu Dec 22 05:30:31 2011
New Revision: 1222042
URL: http://svn.apache.org/viewvc?rev=1222042&view=rev
Log:
Test cases and fixes....
now we're passing all but one of these: http://greenbytes.de/tech/tc/httplink/
the one we're not is a crazy edge case.. not worried about it for now
Added:
abdera/abdera2/test/src/main/java/org/apache/abdera2/test/common/http/WebLinkTest.java (with props)
Modified:
abdera/abdera2/common/src/main/java/org/apache/abdera2/common/http/Authentication.java
abdera/abdera2/common/src/main/java/org/apache/abdera2/common/http/Preference.java
abdera/abdera2/common/src/main/java/org/apache/abdera2/common/http/WebLink.java
abdera/abdera2/common/src/main/java/org/apache/abdera2/common/text/CharUtils.java
abdera/abdera2/test/src/main/java/org/apache/abdera2/test/common/http/AuthenticationTest.java
Modified: abdera/abdera2/common/src/main/java/org/apache/abdera2/common/http/Authentication.java
URL: http://svn.apache.org/viewvc/abdera/abdera2/common/src/main/java/org/apache/abdera2/common/http/Authentication.java?rev=1222042&r1=1222041&r2=1222042&view=diff
==============================================================================
--- abdera/abdera2/common/src/main/java/org/apache/abdera2/common/http/Authentication.java (original)
+++ abdera/abdera2/common/src/main/java/org/apache/abdera2/common/http/Authentication.java Thu Dec 22 05:30:31 2011
@@ -29,6 +29,7 @@ import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.abdera2.common.misc.MoreFunctions;
+import org.apache.abdera2.common.text.CharUtils;
import org.apache.abdera2.common.text.CharUtils.Profile;
import org.apache.abdera2.common.text.Codec;
@@ -91,13 +92,6 @@ public class Authentication implements I
}
};
- public static String unescape(String quoted) {
- StringBuilder buf = new StringBuilder();
- for (char c : quoted.toCharArray())
- if (c != '\\') buf.append(c);
- return buf.toString();
- }
-
public static Iterable<Authentication> parse(String challenge) {
checkNotNull(challenge);
List<Authentication> challenges = new ArrayList<Authentication>();
@@ -119,7 +113,7 @@ public class Authentication implements I
String name = ps[0];
if (name.charAt(name.length()-1)=='*')
name = name.substring(0,name.length()-1);
- auth.param(name, Codec.decode(unquote(unescape(ps[1]))));
+ auth.param(name, Codec.decode(unquote(CharUtils.unescape(ps[1]))));
}
}
challenges.add(auth.get());
Modified: abdera/abdera2/common/src/main/java/org/apache/abdera2/common/http/Preference.java
URL: http://svn.apache.org/viewvc/abdera/abdera2/common/src/main/java/org/apache/abdera2/common/http/Preference.java?rev=1222042&r1=1222041&r2=1222042&view=diff
==============================================================================
--- abdera/abdera2/common/src/main/java/org/apache/abdera2/common/http/Preference.java (original)
+++ abdera/abdera2/common/src/main/java/org/apache/abdera2/common/http/Preference.java Thu Dec 22 05:30:31 2011
@@ -364,7 +364,7 @@ public class Preference implements Seria
String[] ps = pref.split("\\s*\\*?=\\s*", 2);
token = ps[0].trim();
if (ps.length == 2)
- tokenval = Codec.decode(CharUtils.unquote(Authentication.unescape(ps[1])));
+ tokenval = Codec.decode(CharUtils.unquote(CharUtils.unescape(ps[1])));
}
Preference.Builder maker =
@@ -375,7 +375,7 @@ public class Preference implements Seria
String p = mparams.group(1);
String[] ps = p.split("\\s*\\*?=\\s*", 2);
if (ps.length == 2)
- maker.param(ps[0], Codec.decode(CharUtils.unquote(Authentication.unescape(ps[1]))));
+ maker.param(ps[0], Codec.decode(CharUtils.unquote(CharUtils.unescape(ps[1]))));
else maker.param(ps[0]);
}
}
Modified: abdera/abdera2/common/src/main/java/org/apache/abdera2/common/http/WebLink.java
URL: http://svn.apache.org/viewvc/abdera/abdera2/common/src/main/java/org/apache/abdera2/common/http/WebLink.java?rev=1222042&r1=1222041&r2=1222042&view=diff
==============================================================================
--- abdera/abdera2/common/src/main/java/org/apache/abdera2/common/http/WebLink.java (original)
+++ abdera/abdera2/common/src/main/java/org/apache/abdera2/common/http/WebLink.java Thu Dec 22 05:30:31 2011
@@ -426,26 +426,26 @@ public class WebLink implements Serializ
String name = text.substring(s+1,text.charAt(e-1)=='*'?e-1:e).trim();
s = scanFor(';', text,e+1,false);
String val = s!=-1?text.substring(e+1,s).trim():text.substring(e+1).trim();
- val = Codec.decode(val).toLowerCase(Locale.US);
+ val = unescape(unquote(Codec.decode(val)));
if (name.equals("rel"))
- for (String v : unquote(val).split("\\s+"))
+ for (String v : val.toLowerCase(Locale.US).split("\\s+"))
maker.rel(v);
else if (name.equals("anchor"))
maker.anchor(unwrap(val, '<', '>'));
else if (name.equals("rev"))
- for (String v : unquote(val).split("\\s+"))
+ for (String v : val.toLowerCase(Locale.US).split("\\s+"))
maker.rev(v);
else if (name.equals("hreflang"))
- maker.lang(unquote(val));
+ maker.lang(val.toLowerCase(Locale.US));
else if (name.equals("media"))
- for (String v : unquote(val).split("\\s+"))
+ for (String v : val.toLowerCase(Locale.US).split("\\s+"))
maker.media(v);
else if (name.equals("title"))
- maker.title(unquote(val));
+ maker.title(val);
else if (name.equals("type"))
- maker.mediaType(unquote(val));
+ maker.mediaType(val.toLowerCase(Locale.US));
else
- maker.param(name,unquote(val));
+ maker.param(name,val);
}
links.add(maker.get());
if (s == -1) break;
Modified: abdera/abdera2/common/src/main/java/org/apache/abdera2/common/text/CharUtils.java
URL: http://svn.apache.org/viewvc/abdera/abdera2/common/src/main/java/org/apache/abdera2/common/text/CharUtils.java?rev=1222042&r1=1222041&r2=1222042&view=diff
==============================================================================
--- abdera/abdera2/common/src/main/java/org/apache/abdera2/common/text/CharUtils.java (original)
+++ abdera/abdera2/common/src/main/java/org/apache/abdera2/common/text/CharUtils.java Thu Dec 22 05:30:31 2011
@@ -122,12 +122,20 @@ public final class CharUtils {
}
public static String unquote(String s) {
- if (s == null || s.length() == 0)
- return s;
- int n = 0, e = s.length();
- if (s.charAt(0) == '"') n++;
- if (s.charAt(e-1) == '"' && s.charAt(e-2) != '\\') e--;
- return s.substring(n,e);
+ StringBuilder buf = new StringBuilder();
+ int i = s.length();
+ boolean quoted = false, escaped = false;
+ for (int n = 0; n < s.length(); n++) {
+ char c = s.charAt(n);
+ if (n == 0 && c == '"') {
+ quoted = true;
+ } else if (!(quoted && n+1==i && !escaped && c == '"'))
+ buf.append(c);
+ if (escaped) escaped = false;
+ else if (c == '\\' && !escaped)
+ escaped = true;
+ }
+ return buf.toString();
}
public static String[] splitAndTrim(
@@ -210,4 +218,18 @@ public final class CharUtils {
public static final Joiner joiner = Joiner.on(',').skipNulls();
+ public static String unescape(String quoted) {
+ StringBuilder buf = new StringBuilder();
+ int i = quoted.length();
+ for (int n = 0; n < i; n++) {
+ char c = quoted.charAt(n);
+ if (c != '\\') buf.append(c);
+ else if (n < i-1 && quoted.charAt(n+1) == '\\') {
+ buf.append(c);
+ n++;
+ }
+ }
+ return buf.toString();
+ }
+
}
Modified: abdera/abdera2/test/src/main/java/org/apache/abdera2/test/common/http/AuthenticationTest.java
URL: http://svn.apache.org/viewvc/abdera/abdera2/test/src/main/java/org/apache/abdera2/test/common/http/AuthenticationTest.java?rev=1222042&r1=1222041&r2=1222042&view=diff
==============================================================================
--- abdera/abdera2/test/src/main/java/org/apache/abdera2/test/common/http/AuthenticationTest.java (original)
+++ abdera/abdera2/test/src/main/java/org/apache/abdera2/test/common/http/AuthenticationTest.java Thu Dec 22 05:30:31 2011
@@ -11,7 +11,7 @@ import org.apache.abdera2.common.http.Au
import org.junit.Test;
import com.google.common.collect.Iterables;
-
+@SuppressWarnings("unchecked")
public class AuthenticationTest {
@Test
Added: abdera/abdera2/test/src/main/java/org/apache/abdera2/test/common/http/WebLinkTest.java
URL: http://svn.apache.org/viewvc/abdera/abdera2/test/src/main/java/org/apache/abdera2/test/common/http/WebLinkTest.java?rev=1222042&view=auto
==============================================================================
--- abdera/abdera2/test/src/main/java/org/apache/abdera2/test/common/http/WebLinkTest.java (added)
+++ abdera/abdera2/test/src/main/java/org/apache/abdera2/test/common/http/WebLinkTest.java Thu Dec 22 05:30:31 2011
@@ -0,0 +1,282 @@
+package org.apache.abdera2.test.common.http;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import org.apache.abdera2.common.http.WebLink;
+import org.apache.abdera2.common.iri.IRI;
+import org.apache.abdera2.common.mediatype.MimeTypeHelper;
+import org.junit.Test;
+import static org.junit.Assert.assertThat;
+import static org.junit.matchers.JUnitMatchers.*;
+import static org.hamcrest.CoreMatchers.*;
+
+import com.google.common.collect.Iterables;
+import org.apache.abdera2.common.text.InvalidCharacterException;
+
+public class WebLinkTest {
+
+ @Test
+ public void simplecss() {
+ Iterable<WebLink> il = WebLink.parse("<simple.css>; rel=stylesheet");
+ assertEquals(1,Iterables.size(il));
+ WebLink link = il.iterator().next();
+ assertEquals(new IRI("simple.css"),link.getIri());
+ assertThat(link.getRel(),hasItem("stylesheet"));
+ }
+
+ @Test(expected=InvalidCharacterException.class)
+ public void simplecssreversed() {
+ WebLink.parse("rel=stylesheet; <fail.css>");
+ }
+
+ @Test
+ public void simplecsssq() {
+ Iterable<WebLink> il = WebLink.parse("<fail.css>; rel='stylesheet'");
+ assertEquals(1,Iterables.size(il));
+ WebLink link = il.iterator().next();
+ assertThat(link.getRel(),not(hasItem("stylesheet"))); // it will be 'stylesheet', which is incorrect
+ }
+
+ @Test
+ public void simplecssmrel() {
+ Iterable<WebLink> il = WebLink.parse("<simple.css>; rel=\"foobar stylesheet\"");
+ assertEquals(1,Iterables.size(il));
+ WebLink link = il.iterator().next();
+ assertEquals(new IRI("simple.css"),link.getIri());
+ assertThat(link.getRel(),hasItems("stylesheet","foobar"));
+ }
+
+ @SuppressWarnings("unchecked")
+ @Test
+ public void simplecssmlink() {
+ Iterable<WebLink> il = WebLink.parse("<foo>; rel=bar, <simple.css>; rel=stylesheet");
+ assertEquals(2,Iterables.size(il));
+ for (WebLink link : il) {
+ assertThat(link.getIri().toString(), anyOf(is("foo"),is("simple.css")));
+ assertThat(link.getRel(), anyOf(hasItems("bar"),hasItems("stylesheet")));
+ }
+ }
+
+ @Test
+ public void simplecssanchr() {
+ Iterable<WebLink> il = WebLink.parse("<fail.css>; anchor=\"http://example.com/\"; rel=stylesheet");
+ assertEquals(1,Iterables.size(il));
+ WebLink link = il.iterator().next();
+ assertEquals("fail.css",link.getIri().toString());
+ assertEquals("http://example.com/fail.css",link.getResolvedIri(new IRI("http://foo.com/")).toString());
+ // this is a redflag! this IRI resolved to a different base URI than
+ // what was passed in! applications need to take great care as this
+ // could be a possible attack vector!
+ }
+
+ @Test
+ public void simplecssanchrsame() {
+ Iterable<WebLink> il = WebLink.parse("<fail.css>; anchor=\"\"; rel=stylesheet");
+ assertEquals(1,Iterables.size(il));
+ WebLink link = il.iterator().next();
+ assertEquals("fail.css",link.getIri().toString());
+ assertEquals("http://foo.com/fail.css",link.getResolvedIri(new IRI("http://foo.com/")).toString());
+ // this is an appropriate response
+ }
+
+ @Test
+ public void simplecssanchrsame2() {
+ Iterable<WebLink> il = WebLink.parse("<fail.css>; anchor=\"\"; rel=stylesheet");
+ assertEquals(1,Iterables.size(il));
+ WebLink link = il.iterator().next();
+ assertEquals("fail.css",link.getIri().toString());
+ assertEquals("http://foo.com/fail.css",link.getResolvedIri(new IRI("http://foo.com/#foo")).toString());
+ // this is an appropriate response
+ }
+
+ @Test
+ public void simplecssanchrsamefrag() {
+ Iterable<WebLink> il = WebLink.parse("<fail.css>; anchor=\"#foo\"; rel=stylesheet");
+ assertEquals(1,Iterables.size(il));
+ WebLink link = il.iterator().next();
+ assertEquals("fail.css",link.getIri().toString());
+ assertEquals("http://foo.com/fail.css",link.getResolvedIri(new IRI("http://foo.com/")).toString());
+ // this is an appropriate response
+ }
+
+ @Test
+ public void simplecssanchrsamefrag2() {
+ Iterable<WebLink> il = WebLink.parse("<fail.css>; anchor=\"#foo\"; rel=stylesheet");
+ assertEquals(1,Iterables.size(il));
+ WebLink link = il.iterator().next();
+ assertEquals("fail.css",link.getIri().toString());
+ assertEquals("http://foo.com/fail.css",link.getResolvedIri(new IRI("http://foo.com/#foo")).toString());
+ // this is an appropriate response
+ }
+
+ @Test
+ public void simplexslttypenotype() {
+ Iterable<WebLink> il = WebLink.parse("<simple.xslt>; rel=stylesheet");
+ assertEquals(1,Iterables.size(il));
+ WebLink link = il.iterator().next();
+ assertEquals("simple.xslt",link.getIri().toString());
+ assertThat(link.getRel(),hasItem("stylesheet"));
+ }
+
+ @Test
+ public void simplexslttypedepr() {
+ Iterable<WebLink> il = WebLink.parse("<simple.xslt>; rel=stylesheet; type=\"text/xsl\"");
+ assertEquals(1,Iterables.size(il));
+ WebLink link = il.iterator().next();
+ assertEquals("simple.xslt",link.getIri().toString());
+ assertThat(link.getRel(),hasItem("stylesheet"));
+ assertTrue(MimeTypeHelper.isMatch(link.getMediaType(), MimeTypeHelper.create("text/xsl")));
+ }
+
+ @Test
+ public void simplexslttypedepr2() {
+ Iterable<WebLink> il = WebLink.parse("<simple.xslt.asis>; rel=stylesheet; type=\"text/xsl\"");
+ assertEquals(1,Iterables.size(il));
+ WebLink link = il.iterator().next();
+ assertEquals("simple.xslt.asis",link.getIri().toString());
+ assertThat(link.getRel(),hasItem("stylesheet"));
+ assertTrue(MimeTypeHelper.isMatch(link.getMediaType(), MimeTypeHelper.create("text/xsl")));
+ }
+
+ @Test
+ public void simplexslttypeoff() {
+ Iterable<WebLink> il = WebLink.parse("<simple.xslt>; rel=stylesheet; type=\"application/xslt+xml\"");
+ assertEquals(1,Iterables.size(il));
+ WebLink link = il.iterator().next();
+ assertEquals("simple.xslt.asis",link.getIri().toString());
+ assertThat(link.getRel(),hasItem("stylesheet"));
+ assertTrue(MimeTypeHelper.isMatch(link.getMediaType(), MimeTypeHelper.create("text/xsl")));
+ }
+
+ @Test
+ public void simplecsstitle() {
+ Iterable<WebLink> il = WebLink.parse("<simple.css>; rel=stylesheet; title=\"A simple CSS stylesheet\"");
+ assertEquals(1,Iterables.size(il));
+ WebLink link = il.iterator().next();
+ assertEquals("simple.css",link.getIri().toString());
+ assertThat(link.getRel(),hasItem("stylesheet"));
+ assertEquals(link.getTitle(),"A simple CSS stylesheet");
+ }
+
+ @Test
+ public void simplecsstitleq() {
+ Iterable<WebLink> il = WebLink.parse("<simple.css>; rel=stylesheet; title=\"title with a DQUOTE \\\" and backslash: \\\\\"");
+ assertEquals(1,Iterables.size(il));
+ WebLink link = il.iterator().next();
+ assertEquals("title with a DQUOTE \" and backslash: \\",link.getTitle());
+ }
+
+ @Test
+ public void simplecsstitleq2() {
+ Iterable<WebLink> il = WebLink.parse("<simple.css>; title=\"title with a DQUOTE \\\" and backslash: \\\\\"; rel=stylesheet");
+ assertEquals(1,Iterables.size(il));
+ WebLink link = il.iterator().next();
+ assertEquals("title with a DQUOTE \" and backslash: \\",link.getTitle());
+ }
+
+ @Test
+ public void simplecsstitletok() {
+ Iterable<WebLink> il = WebLink.parse("<simple.css>; rel=stylesheet; title=AsimpleCSSstylesheet");
+ assertEquals(1,Iterables.size(il));
+ WebLink link = il.iterator().next();
+ assertEquals("AsimpleCSSstylesheet",link.getTitle());
+ // not strictly allowed per the spec
+ }
+
+ @Test
+ public void simplecsstitle5987() {
+ Iterable<WebLink> il = WebLink.parse("<simple.css>; rel=stylesheet; title*=UTF-8''stylesheet-%E2%82%AC");
+ assertEquals(1,Iterables.size(il));
+ WebLink link = il.iterator().next();
+ assertEquals("stylesheet-\u20AC",link.getTitle());
+ }
+
+ @Test
+ public void simplecsstitle5987r() {
+ Iterable<WebLink> il = WebLink.parse("<simple.css>; title*=UTF-8''stylesheet-%E2%82%AC; rel=stylesheet");
+ assertEquals(1,Iterables.size(il));
+ WebLink link = il.iterator().next();
+ assertEquals("stylesheet-\u20AC",link.getTitle());
+ }
+
+ @Test
+ public void simplecsstitle5987iso88591() {
+ Iterable<WebLink> il = WebLink.parse("<simple.css>; title*=iso-8859-1''stylesheet-%E4; rel=stylesheet");
+ assertEquals(1,Iterables.size(il));
+ WebLink link = il.iterator().next();
+ assertEquals("stylesheet-\u00E4",link.getTitle());
+ }
+
+ @Test
+ public void simplecsstitle5987noenc() {
+ Iterable<WebLink> il = WebLink.parse("<simple.css>; title*=''A%20simple%20CSS%20stylesheet; title=\"fallback title\"; rel=stylesheet");
+ assertEquals(1,Iterables.size(il));
+ WebLink link = il.iterator().next();
+ assertEquals("fallback title", link.getTitle());
+ // this passes, but not for the reason its supposed to
+ }
+
+ @Test
+ public void simplecsstitle5987parseerror() {
+ Iterable<WebLink> il = WebLink.parse("<simple.css>; title*=foobar; title=\"fallback title\"; rel=stylesheet");
+ assertEquals(1,Iterables.size(il));
+ WebLink link = il.iterator().next();
+ assertEquals("fallback title", link.getTitle());
+ // this passes, but not for the reason its supposed to
+ }
+
+ @Test
+ public void simplecsstitle5987parseerror2() {
+ Iterable<WebLink> il = WebLink.parse("<simple.css>; title*=UTF-8''foobar%; title=\"fallback title\"; rel=stylesheet");
+ assertEquals(1,Iterables.size(il));
+ WebLink link = il.iterator().next();
+ assertEquals("fallback title", link.getTitle());
+ // this passes, but not for the reason its supposed to
+ }
+
+ @Test
+ public void simpleext() {
+ Iterable<WebLink> il = WebLink.parse("<simple.css>; ext=foo; rel=stylesheet");
+ assertEquals(1,Iterables.size(il));
+ WebLink link = il.iterator().next();
+ assertEquals("foo",link.getParam("ext"));
+ }
+
+ @Test
+ public void simpleextq() {
+ Iterable<WebLink> il = WebLink.parse("<simple.css>; ext=\"\\\"\"; rel=stylesheet");
+ assertEquals(1,Iterables.size(il));
+ WebLink link = il.iterator().next();
+ assertEquals("\"",link.getParam("ext"));
+ }
+
+// This isn't supported
+// @Test
+// public void simpleexta() {
+// Iterable<WebLink> il = WebLink.parse("<simple.css>; ext1='start; rel=stylesheet; ext2=end'");
+// assertEquals(1,Iterables.size(il));
+// WebLink link = il.iterator().next();
+// System.out.println(link.getParam("ext1"));
+// }
+
+ @Test
+ public void simpleextrel() {
+ Iterable<WebLink> il = WebLink.parse("<simple.css>; rel=\"http://example.com/myrel stylesheet\"");
+ assertEquals(1,Iterables.size(il));
+ WebLink link = il.iterator().next();
+ assertThat(link.getRel(),hasItems("stylesheet","http://example.com/myrel"));
+ }
+
+ @Test
+ public void simplecss2() {
+ Iterable<WebLink> il = WebLink.parse("<ybg.css>; rel=stylesheet, <simple.css>; rel=stylesheet");
+ assertEquals(2, Iterables.size(il));
+ }
+
+ @Test
+ public void simplecssafterother() {
+ Iterable<WebLink> il = WebLink.parse("<ybf.css>; rel=foobar, <simple.css>; rel=stylesheet");
+ assertEquals(2, Iterables.size(il));
+ }
+}
Propchange: abdera/abdera2/test/src/main/java/org/apache/abdera2/test/common/http/WebLinkTest.java
------------------------------------------------------------------------------
svn:mime-type = text/plain