Author: atsushi
Date: 2008-02-16 06:10:40 -0500 (Sat, 16 Feb 2008)
New Revision: 95858
Modified:
trunk/olive/class/System.ServiceModel.Web/System/ChangeLog
trunk/olive/class/System.ServiceModel.Web/System/UriTemplate.cs
trunk/olive/class/System.ServiceModel.Web/Test/System/ChangeLog
trunk/olive/class/System.ServiceModel.Web/Test/System/UriTemplateTest.cs
Log:
2008-02-16 Atsushi Enomoto <[EMAIL PROTECTED]>
* UriTemplate.cs : rewrote query parameter retrieval part. It did
not match order-independent input and lack of parameters.
* UriTemplateTest.cs : enable query parameter matching test.
Modified: trunk/olive/class/System.ServiceModel.Web/System/ChangeLog
===================================================================
--- trunk/olive/class/System.ServiceModel.Web/System/ChangeLog 2008-02-16
09:32:58 UTC (rev 95857)
+++ trunk/olive/class/System.ServiceModel.Web/System/ChangeLog 2008-02-16
11:10:40 UTC (rev 95858)
@@ -1,3 +1,8 @@
+2008-02-16 Atsushi Enomoto <[EMAIL PROTECTED]>
+
+ * UriTemplate.cs : rewrote query parameter retrieval part. It did
+ not match order-independent input and lack of parameters.
+
2008-02-15 Atsushi Enomoto <[EMAIL PROTECTED]>
* UriTemplateMatch.cs : implement everything but WildcardPathSegments.
Modified: trunk/olive/class/System.ServiceModel.Web/System/UriTemplate.cs
===================================================================
--- trunk/olive/class/System.ServiceModel.Web/System/UriTemplate.cs
2008-02-16 09:32:58 UTC (rev 95857)
+++ trunk/olive/class/System.ServiceModel.Web/System/UriTemplate.cs
2008-02-16 11:10:40 UTC (rev 95858)
@@ -40,6 +40,7 @@
string template;
ReadOnlyCollection<string> path, query;
+ Dictionary<string,string> query_params = new
Dictionary<string,string> ();
[MonoTODO ("It needs some rewrite: template bindings should be
available only one per segment")]
public UriTemplate (string template)
@@ -56,9 +57,9 @@
p = template.Substring (idx);
}
int q = p.IndexOf ('?');
- path = ParseTemplate (p, 0, q >= 0 ? q : p.Length);
+ path = ParsePathTemplate (p, 0, q >= 0 ? q : p.Length);
if (q >= 0)
- query = ParseTemplate (p, q, p.Length);
+ ParseQueryTemplate (p, q, p.Length);
else
query = empty_strings;
}
@@ -161,7 +162,7 @@
m.RequestUri = candidate;
var vc = m.BoundVariables;
- string cp = candidate.PathAndQuery;
+ string cp = candidate.AbsolutePath;
if (template.Length > 0 && template [0] == '/')
i++;
@@ -182,24 +183,26 @@
m.RelativePathSegments.Add (value);
c += value.Length;
}
- foreach (string name in query) {
- int n = StringIndexOf (template, '{' + name +
'}', i);
- if (String.CompareOrdinal (cp, c, template, i,
n - i) != 0)
- return null; // doesn't match before
current template part.
- c += n - i;
- i = n + 2 + name.Length;
- int ce = cp.IndexOf ('&', c);
- if (ce < 0)
- ce = cp.Length;
- string value = cp.Substring (c, ce - c);
- vc [name] = value;
- m.QueryParameters.Add (name, value);
- c += value.Length;
- }
- if ((cp.Length - c) != (template.Length - i) ||
- String.CompareOrdinal (cp, c, template, i,
template.Length - i) != 0)
+ int tEnd = template.IndexOf ('?');
+ if (tEnd < 0)
+ tEnd = template.Length;
+ if ((cp.Length - c) != (tEnd - i) ||
+ String.CompareOrdinal (cp, c, template, i, tEnd -
i) != 0)
return null; // suffix doesn't match
+
+ if (candidate.Query.Length == 0)
+ return m;
+
+ string [] parameters = candidate.Query.Substring
(1).Split ('&'); // chop first '?'
+ foreach (string parameter in parameters) {
+ string [] pair = parameter.Split ('=');
+ m.QueryParameters.Add (pair [0], pair [1]);
+ if (!query.Contains (pair [0]))
+ continue;
+ vc.Add (pair [0], pair [1]);
+ }
+
return m;
}
@@ -222,7 +225,7 @@
throw new ArgumentException ("baseAddress scheme must
be either http or https.");
}
- ReadOnlyCollection<string> ParseTemplate (string template, int
index, int end)
+ ReadOnlyCollection<string> ParsePathTemplate (string template,
int index, int end)
{
List<string> list = null;
for (int i = index; i <= end; ) {
@@ -244,5 +247,29 @@
}
return list != null ? new ReadOnlyCollection<string>
(list) : empty_strings;
}
+
+ void ParseQueryTemplate (string template, int index, int end)
+ {
+ // template starts with '?'
+ string [] parameters = template.Substring (index + 1,
end - index - 1).Split ('&');
+ List<string> list = null;
+ foreach (string parameter in parameters) {
+ string [] pair = parameter.Split ('=');
+ if (pair.Length != 2)
+ throw new FormatException ("Invalid URI
query string format");
+ string pname = pair [0];
+ string pvalue = pair [1];
+ if (pvalue.Length >= 2 && pvalue [0] == '{' &&
pvalue [pvalue.Length - 1] == '}') {
+ string ptemplate = pvalue.Substring (1,
pvalue.Length - 2).ToUpperInvariant ();
+ query_params.Add (pname, ptemplate);
+ if (list == null)
+ list = new List<string> ();
+ if (list.Contains (ptemplate) || (path
!= null && path.Contains (ptemplate)))
+ throw new
InvalidOperationException (String.Format ("The URI template string contains
duplicate template item {{'{0}'}}", pvalue));
+ list.Add (ptemplate);
+ }
+ }
+ query = list != null ? new ReadOnlyCollection<string>
(list.ToArray ()) : empty_strings;
+ }
}
}
Modified: trunk/olive/class/System.ServiceModel.Web/Test/System/ChangeLog
===================================================================
--- trunk/olive/class/System.ServiceModel.Web/Test/System/ChangeLog
2008-02-16 09:32:58 UTC (rev 95857)
+++ trunk/olive/class/System.ServiceModel.Web/Test/System/ChangeLog
2008-02-16 11:10:40 UTC (rev 95858)
@@ -1,3 +1,7 @@
+2008-02-16 Atsushi Enomoto <[EMAIL PROTECTED]>
+
+ * UriTemplateTest.cs : enable query parameter matching test.
+
2008-02-15 Atsushi Enomoto <[EMAIL PROTECTED]>
* UriTemplateTest.cs : added not-working case to be fixed.
Modified:
trunk/olive/class/System.ServiceModel.Web/Test/System/UriTemplateTest.cs
===================================================================
--- trunk/olive/class/System.ServiceModel.Web/Test/System/UriTemplateTest.cs
2008-02-16 09:32:58 UTC (rev 95857)
+++ trunk/olive/class/System.ServiceModel.Web/Test/System/UriTemplateTest.cs
2008-02-16 11:10:40 UTC (rev 95858)
@@ -276,13 +276,18 @@
}
[Test]
- [Category ("NotWorking")]
public void Match2 ()
{
var t = new UriTemplate ("/{foo}/{bar}?p1={baz}");
var n = new NameValueCollection ();
Uri baseUri = new Uri ("http://localhost/");
- Assert.IsNotNull (t.Match (baseUri, new Uri
("http://localhost/X/Y")));
+ Assert.IsNotNull (t.Match (baseUri, new Uri
("http://localhost/X/Y")), "#1");
+ UriTemplateMatch m = t.Match (baseUri, new Uri
("http://localhost/X/Y?p2=v&p1=vv"));
+ Assert.IsNotNull (m, "#2");
+ // QueryParameters must contain non-template query
parameters.
+ Assert.AreEqual (2, m.QueryParameters.Count, "#3");
+ Assert.AreEqual ("v", m.QueryParameters ["p2"], "#4");
+ Assert.AreEqual ("vv", m.QueryParameters ["p1"], "#5");
}
}
}
_______________________________________________
Mono-patches maillist - [email protected]
http://lists.ximian.com/mailman/listinfo/mono-patches