Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/mono.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/mcs/class
diff options
context:
space:
mode:
authorMarek Safar <marek.safar@gmail.com>2014-01-13 17:46:58 +0400
committerMarek Safar <marek.safar@gmail.com>2014-01-13 17:48:12 +0400
commit2d0272d9c2e8a99741ea9520ab02d05d84bc4981 (patch)
tree2753b5929fec45c89550503270ae622c1e30a2c0 /mcs/class
parent0b1316bccb9bfe45d3329c4ad30fa07cfd66e42c (diff)
[System.Net.Http] Add parsing of multi-value strings. Fixes #17132
Diffstat (limited to 'mcs/class')
-rw-r--r--mcs/class/System.Net.Http/System.Net.Http.Headers/AuthenticationHeaderValue.cs26
-rw-r--r--mcs/class/System.Net.Http/System.Net.Http.Headers/CollectionParser.cs117
-rw-r--r--mcs/class/System.Net.Http/System.Net.Http.Headers/ContentDispositionHeaderValue.cs2
-rw-r--r--mcs/class/System.Net.Http/System.Net.Http.Headers/EntityTagHeaderValue.cs37
-rw-r--r--mcs/class/System.Net.Http/System.Net.Http.Headers/HeaderInfo.cs45
-rw-r--r--mcs/class/System.Net.Http/System.Net.Http.Headers/HttpHeaders.cs20
-rw-r--r--mcs/class/System.Net.Http/System.Net.Http.Headers/Lexer.cs2
-rw-r--r--mcs/class/System.Net.Http/System.Net.Http.Headers/MediaTypeHeaderValue.cs37
-rw-r--r--mcs/class/System.Net.Http/System.Net.Http.Headers/MediaTypeWithQualityHeaderValue.cs37
-rw-r--r--mcs/class/System.Net.Http/System.Net.Http.Headers/NameValueHeaderValue.cs89
-rw-r--r--mcs/class/System.Net.Http/System.Net.Http.Headers/NameValueWithParametersHeaderValue.cs53
-rw-r--r--mcs/class/System.Net.Http/System.Net.Http.Headers/Parser.cs1
-rw-r--r--mcs/class/System.Net.Http/System.Net.Http.Headers/ProductHeaderValue.cs31
-rw-r--r--mcs/class/System.Net.Http/System.Net.Http.Headers/ProductInfoHeaderValue.cs10
-rw-r--r--mcs/class/System.Net.Http/System.Net.Http.Headers/StringWithQualityHeaderValue.cs23
-rw-r--r--mcs/class/System.Net.Http/System.Net.Http.Headers/TransferCodingHeaderValue.cs28
-rw-r--r--mcs/class/System.Net.Http/System.Net.Http.Headers/TransferCodingWithQualityHeaderValue.cs36
-rw-r--r--mcs/class/System.Net.Http/System.Net.Http.Headers/ViaHeaderValue.cs25
-rw-r--r--mcs/class/System.Net.Http/System.Net.Http.Headers/WarningHeaderValue.cs25
-rw-r--r--mcs/class/System.Net.Http/System.Net.Http.dll.sources1
-rw-r--r--mcs/class/System.Net.Http/Test/System.Net.Http.Headers/NameValueHeaderValueTest.cs3
-rw-r--r--mcs/class/System.Net.Http/Test/System.Net.Http/HttpRequestMessageTest.cs47
-rw-r--r--mcs/class/System.Net.Http/Test/System.Net.Http/HttpResponseMessageTest.cs50
-rw-r--r--mcs/class/System.Net.Http/Test/System.Net.Http/StreamContentTest.cs15
24 files changed, 598 insertions, 162 deletions
diff --git a/mcs/class/System.Net.Http/System.Net.Http.Headers/AuthenticationHeaderValue.cs b/mcs/class/System.Net.Http/System.Net.Http.Headers/AuthenticationHeaderValue.cs
index 33f87db8f03..7bb2496a94d 100644
--- a/mcs/class/System.Net.Http/System.Net.Http.Headers/AuthenticationHeaderValue.cs
+++ b/mcs/class/System.Net.Http/System.Net.Http.Headers/AuthenticationHeaderValue.cs
@@ -26,6 +26,8 @@
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
+using System.Collections.Generic;
+
namespace System.Net.Http.Headers
{
public class AuthenticationHeaderValue : ICloneable
@@ -85,8 +87,23 @@ namespace System.Net.Http.Headers
public static bool TryParse (string input, out AuthenticationHeaderValue parsedValue)
{
var lexer = new Lexer (input);
- var t = lexer.Scan ();
- if (t != Token.Type.Token || !(lexer.PeekChar () == ' ' || lexer.PeekChar () == -1)) {
+ Token token;
+ if (TryParseElement (lexer, out parsedValue, out token) && token == Token.Type.End)
+ return true;
+
+ parsedValue = null;
+ return false;
+ }
+
+ internal static bool TryParse (string input, int minimalCount, out List<AuthenticationHeaderValue> result)
+ {
+ return CollectionParser.TryParse (input, minimalCount, TryParseElement, out result);
+ }
+
+ static bool TryParseElement (Lexer lexer, out AuthenticationHeaderValue parsedValue, out Token t)
+ {
+ t = lexer.Scan ();
+ if (t != Token.Type.Token) {
parsedValue = null;
return false;
}
@@ -95,8 +112,11 @@ namespace System.Net.Http.Headers
parsedValue.Scheme = lexer.GetStringValue (t);
t = lexer.Scan ();
- if (t != Token.Type.End)
+ if (t == Token.Type.Token) {
+ // TODO: Wrong with multi value parsing
parsedValue.Parameter = lexer.GetRemainingStringValue (t.StartPosition);
+ t = new Token (Token.Type.End, 0, 0);
+ }
return true;
}
diff --git a/mcs/class/System.Net.Http/System.Net.Http.Headers/CollectionParser.cs b/mcs/class/System.Net.Http/System.Net.Http.Headers/CollectionParser.cs
new file mode 100644
index 00000000000..cbaafe0f808
--- /dev/null
+++ b/mcs/class/System.Net.Http/System.Net.Http.Headers/CollectionParser.cs
@@ -0,0 +1,117 @@
+//
+// CollectionParser.cs
+//
+// Authors:
+// Marek Safar <marek.safar@gmail.com>
+//
+// Copyright (C) 2014 Xamarin Inc (http://www.xamarin.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+using System.Collections.Generic;
+
+namespace System.Net.Http.Headers
+{
+ delegate bool ElementTryParser<T> (Lexer lexer, out T parsedValue, out Token token);
+
+ static class CollectionParser
+ {
+ public static bool TryParse<T> (string input, int minimalCount, ElementTryParser<T> parser, out List<T> result) where T : class
+ {
+ var lexer = new Lexer (input);
+ result = new List<T> ();
+
+ while (true) {
+ Token token;
+ T parsedValue;
+ if (!parser (lexer, out parsedValue, out token))
+ return false;
+
+ if (parsedValue != null)
+ result.Add (parsedValue);
+
+ if (token == Token.Type.SeparatorComma)
+ continue;
+
+ if (token == Token.Type.End) {
+ if (minimalCount > result.Count) {
+ result = null;
+ return false;
+ }
+
+ return true;
+ }
+
+ result = null;
+ return false;
+ }
+ }
+
+ public static bool TryParse (string input, int minimalCount, out List<string> result)
+ {
+ return TryParse (input, minimalCount, TryParseStringElement, out result);
+ }
+
+ public static bool TryParseRepetition (string input, int minimalCount, out List<string> result)
+ {
+ return TryParseRepetition (input, minimalCount, TryParseStringElement, out result);
+ }
+
+ static bool TryParseStringElement (Lexer lexer, out string parsedValue, out Token t)
+ {
+ t = lexer.Scan ();
+ if (t == Token.Type.Token) {
+ parsedValue = lexer.GetStringValue (t);
+ if (parsedValue.Length == 0)
+ parsedValue = null;
+
+ t = lexer.Scan ();
+ } else {
+ parsedValue = null;
+ }
+
+ return true;
+ }
+
+ public static bool TryParseRepetition<T> (string input, int minimalCount, ElementTryParser<T> parser, out List<T> result) where T : class
+ {
+ var lexer = new Lexer (input);
+ result = new List<T> ();
+
+ while (true) {
+ Token token;
+ T parsedValue;
+ if (!parser (lexer, out parsedValue, out token))
+ return false;
+
+ if (parsedValue != null)
+ result.Add (parsedValue);
+
+ if (token == Token.Type.End) {
+ if (minimalCount > result.Count)
+ return false;
+
+ return true;
+ }
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/mcs/class/System.Net.Http/System.Net.Http.Headers/ContentDispositionHeaderValue.cs b/mcs/class/System.Net.Http/System.Net.Http.Headers/ContentDispositionHeaderValue.cs
index a4d1ae275b4..9dd41b3d330 100644
--- a/mcs/class/System.Net.Http/System.Net.Http.Headers/ContentDispositionHeaderValue.cs
+++ b/mcs/class/System.Net.Http/System.Net.Http.Headers/ContentDispositionHeaderValue.cs
@@ -394,7 +394,7 @@ namespace System.Net.Http.Headers
switch (t.Kind) {
case Token.Type.SeparatorSemicolon:
- if (!NameValueHeaderValue.TryParseParameters (lexer, out parameters))
+ if (!NameValueHeaderValue.TryParseParameters (lexer, out parameters, out t) || t != Token.Type.End)
return false;
break;
case Token.Type.End:
diff --git a/mcs/class/System.Net.Http/System.Net.Http.Headers/EntityTagHeaderValue.cs b/mcs/class/System.Net.Http/System.Net.Http.Headers/EntityTagHeaderValue.cs
index 9b10983bbfc..8c255cfaede 100644
--- a/mcs/class/System.Net.Http/System.Net.Http.Headers/EntityTagHeaderValue.cs
+++ b/mcs/class/System.Net.Http/System.Net.Http.Headers/EntityTagHeaderValue.cs
@@ -26,6 +26,8 @@
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
+using System.Collections.Generic;
+
namespace System.Net.Http.Headers
{
public class EntityTagHeaderValue : ICloneable
@@ -85,14 +87,32 @@ namespace System.Net.Http.Headers
public static bool TryParse (string input, out EntityTagHeaderValue parsedValue)
{
+ var lexer = new Lexer (input);
+ Token token;
+ if (TryParseElement (lexer, out parsedValue, out token) && token == Token.Type.End)
+ return true;
+
parsedValue = null;
+ return false;
+ }
- var lexer = new Lexer (input);
- var t = lexer.Scan ();
+ static bool TryParseElement (Lexer lexer, out EntityTagHeaderValue parsedValue, out Token t)
+ {
+ parsedValue = null;
+
+ t = lexer.Scan ();
bool is_weak = false;
if (t == Token.Type.Token) {
- if (lexer.GetStringValue (t) != "W" || lexer.PeekChar () != '/')
+ var s = lexer.GetStringValue (t);
+ if (s == "*") {
+ parsedValue = any;
+
+ t = lexer.Scan ();
+ return true;
+ }
+
+ if (s != "W" || lexer.PeekChar () != '/')
return false;
is_weak = true;
@@ -103,15 +123,20 @@ namespace System.Net.Http.Headers
if (t != Token.Type.QuotedString)
return false;
- if (lexer.Scan () != Token.Type.End)
- return false;
-
parsedValue = new EntityTagHeaderValue ();
parsedValue.Tag = lexer.GetStringValue (t);
parsedValue.IsWeak = is_weak;
+
+ t = lexer.Scan ();
+
return true;
}
+ internal static bool TryParse (string input, int minimalCount, out List<EntityTagHeaderValue> result)
+ {
+ return CollectionParser.TryParse (input, minimalCount, TryParseElement, out result);
+ }
+
public override string ToString ()
{
return IsWeak ?
diff --git a/mcs/class/System.Net.Http/System.Net.Http.Headers/HeaderInfo.cs b/mcs/class/System.Net.Http/System.Net.Http.Headers/HeaderInfo.cs
index 3772180e52b..6337319ea1e 100644
--- a/mcs/class/System.Net.Http/System.Net.Http.Headers/HeaderInfo.cs
+++ b/mcs/class/System.Net.Http/System.Net.Http.Headers/HeaderInfo.cs
@@ -4,7 +4,7 @@
// Authors:
// Marek Safar <marek.safar@gmail.com>
//
-// Copyright (C) 2011 Xamarin Inc (http://www.xamarin.com)
+// Copyright (C) 2011, 2014 Xamarin Inc (http://www.xamarin.com)
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
@@ -32,6 +32,7 @@ using System.Collections.Generic;
namespace System.Net.Http.Headers
{
delegate bool TryParseDelegate<T> (string value, out T result);
+ delegate bool TryParseListDelegate<T> (string value, int minimalCount, out List<T> result);
abstract class HeaderInfo
{
@@ -89,6 +90,32 @@ namespace System.Net.Http.Headers
}
}
+ class CollectionHeaderTypeInfo<T, U> : HeaderTypeInfo<T, U> where U : class
+ {
+ readonly int minimalCount;
+ TryParseListDelegate<T> parser;
+
+ public CollectionHeaderTypeInfo (string name, TryParseListDelegate<T> parser, HttpHeaderKind headerKind, int minimalCount)
+ : base (name, null, headerKind)
+ {
+ this.parser = parser;
+ this.minimalCount = minimalCount;
+ AllowsMany = true;
+ }
+
+ public override bool TryParse (string value, out object result)
+ {
+ List<T> tresult;
+ if (!parser (value, minimalCount, out tresult)) {
+ result = null;
+ return false;
+ }
+
+ result = tresult;
+ return true;
+ }
+ }
+
public bool AllowsMany;
public readonly HttpHeaderKind HeaderKind;
public readonly string Name;
@@ -104,18 +131,12 @@ namespace System.Net.Http.Headers
return new HeaderTypeInfo<T, object> (name, parser, headerKind);
}
- public static HeaderInfo CreateMulti<T> (string name, TryParseDelegate<T> parser, HttpHeaderKind headerKind) where T : class
- {
- return new HeaderTypeInfo<T, T> (name, parser, headerKind) {
- AllowsMany = true,
- };
- }
-
- public static HeaderInfo CreateMultiList<T> (string name, TryParseDelegate<List<T>> parser, HttpHeaderKind headerKind) where T : class
+ //
+ // Headers with #rule for defining lists of elements or *rule for defining occurences of elements
+ //
+ public static HeaderInfo CreateMulti<T> (string name, TryParseListDelegate<T> elementParser, HttpHeaderKind headerKind, int minimalCount = 1) where T : class
{
- return new HeaderTypeInfo<List<T>, T> (name, parser, headerKind) {
- AllowsMany = true,
- };
+ return new CollectionHeaderTypeInfo<T, T> (name, elementParser, headerKind, minimalCount);
}
public object CreateCollection (HttpHeaders headers)
diff --git a/mcs/class/System.Net.Http/System.Net.Http.Headers/HttpHeaders.cs b/mcs/class/System.Net.Http/System.Net.Http.Headers/HttpHeaders.cs
index a36652ce4eb..ffef647b5ee 100644
--- a/mcs/class/System.Net.Http/System.Net.Http.Headers/HttpHeaders.cs
+++ b/mcs/class/System.Net.Http/System.Net.Http.Headers/HttpHeaders.cs
@@ -90,14 +90,14 @@ namespace System.Net.Http.Headers
HeaderInfo.CreateMulti<StringWithQualityHeaderValue> ("Accept-Charset", StringWithQualityHeaderValue.TryParse, HttpHeaderKind.Request),
HeaderInfo.CreateMulti<StringWithQualityHeaderValue> ("Accept-Encoding", StringWithQualityHeaderValue.TryParse, HttpHeaderKind.Request),
HeaderInfo.CreateMulti<StringWithQualityHeaderValue> ("Accept-Language", StringWithQualityHeaderValue.TryParse, HttpHeaderKind.Request),
- HeaderInfo.CreateMulti<string> ("Accept-Ranges", Parser.Token.TryParse, HttpHeaderKind.Response),
+ HeaderInfo.CreateMulti<string> ("Accept-Ranges", CollectionParser.TryParse, HttpHeaderKind.Response),
HeaderInfo.CreateSingle<TimeSpan> ("Age", Parser.TimeSpanSeconds.TryParse, HttpHeaderKind.Response),
- HeaderInfo.CreateMulti<string> ("Allow", Parser.Token.TryParse, HttpHeaderKind.Content),
+ HeaderInfo.CreateMulti<string> ("Allow", CollectionParser.TryParse, HttpHeaderKind.Content, 0),
HeaderInfo.CreateSingle<AuthenticationHeaderValue> ("Authorization", AuthenticationHeaderValue.TryParse, HttpHeaderKind.Request),
HeaderInfo.CreateSingle<CacheControlHeaderValue> ("Cache-Control", CacheControlHeaderValue.TryParse, HttpHeaderKind.Request | HttpHeaderKind.Response),
- HeaderInfo.CreateMulti<string> ("Connection", Parser.Token.TryParse, HttpHeaderKind.Request | HttpHeaderKind.Response),
- HeaderInfo.CreateMulti<string> ("Content-Encoding", Parser.Token.TryParse, HttpHeaderKind.Content),
- HeaderInfo.CreateMulti<string> ("Content-Language", Parser.Token.TryParse, HttpHeaderKind.Content),
+ HeaderInfo.CreateMulti<string> ("Connection", CollectionParser.TryParse, HttpHeaderKind.Request | HttpHeaderKind.Response),
+ HeaderInfo.CreateMulti<string> ("Content-Encoding", CollectionParser.TryParse, HttpHeaderKind.Content),
+ HeaderInfo.CreateMulti<string> ("Content-Language", CollectionParser.TryParse, HttpHeaderKind.Content),
HeaderInfo.CreateSingle<long> ("Content-Length", Parser.Long.TryParse, HttpHeaderKind.Content),
HeaderInfo.CreateSingle<Uri> ("Content-Location", Parser.Uri.TryParse, HttpHeaderKind.Content),
HeaderInfo.CreateSingle<byte[]> ("Content-MD5", Parser.MD5.TryParse, HttpHeaderKind.Content),
@@ -117,19 +117,19 @@ namespace System.Net.Http.Headers
HeaderInfo.CreateSingle<DateTimeOffset> ("Last-Modified", Parser.DateTime.TryParse, HttpHeaderKind.Content),
HeaderInfo.CreateSingle<Uri> ("Location", Parser.Uri.TryParse, HttpHeaderKind.Response),
HeaderInfo.CreateSingle<int> ("Max-Forwards", Parser.Int.TryParse, HttpHeaderKind.Request),
- HeaderInfo.CreateMultiList<NameValueHeaderValue> ("Pragma", NameValueHeaderValue.TryParsePragma, HttpHeaderKind.Request | HttpHeaderKind.Response),
+ HeaderInfo.CreateMulti<NameValueHeaderValue> ("Pragma", NameValueHeaderValue.TryParsePragma, HttpHeaderKind.Request | HttpHeaderKind.Response),
HeaderInfo.CreateMulti<AuthenticationHeaderValue> ("Proxy-Authenticate", AuthenticationHeaderValue.TryParse, HttpHeaderKind.Response),
HeaderInfo.CreateSingle<AuthenticationHeaderValue> ("Proxy-Authorization", AuthenticationHeaderValue.TryParse, HttpHeaderKind.Request),
HeaderInfo.CreateSingle<RangeHeaderValue> ("Range", RangeHeaderValue.TryParse, HttpHeaderKind.Request),
HeaderInfo.CreateSingle<Uri> ("Referer", Parser.Uri.TryParse, HttpHeaderKind.Request),
HeaderInfo.CreateSingle<RetryConditionHeaderValue> ("Retry-After", RetryConditionHeaderValue.TryParse, HttpHeaderKind.Response),
HeaderInfo.CreateMulti<ProductInfoHeaderValue> ("Server", ProductInfoHeaderValue.TryParse, HttpHeaderKind.Response),
- HeaderInfo.CreateMulti<TransferCodingWithQualityHeaderValue> ("TE", TransferCodingWithQualityHeaderValue.TryParse, HttpHeaderKind.Request),
- HeaderInfo.CreateMulti<string> ("Trailer", Parser.Token.TryParse, HttpHeaderKind.Request | HttpHeaderKind.Response),
+ HeaderInfo.CreateMulti<TransferCodingWithQualityHeaderValue> ("TE", TransferCodingWithQualityHeaderValue.TryParse, HttpHeaderKind.Request, 0),
+ HeaderInfo.CreateMulti<string> ("Trailer", CollectionParser.TryParse, HttpHeaderKind.Request | HttpHeaderKind.Response),
HeaderInfo.CreateMulti<TransferCodingHeaderValue> ("Transfer-Encoding", TransferCodingHeaderValue.TryParse, HttpHeaderKind.Request | HttpHeaderKind.Response),
HeaderInfo.CreateMulti<ProductHeaderValue> ("Upgrade", ProductHeaderValue.TryParse, HttpHeaderKind.Request | HttpHeaderKind.Response),
- HeaderInfo.CreateMultiList<ProductInfoHeaderValue> ("User-Agent", ProductInfoHeaderValue.TryParse, HttpHeaderKind.Request),
- HeaderInfo.CreateMulti<string> ("Vary", Parser.Token.TryParse, HttpHeaderKind.Response),
+ HeaderInfo.CreateMulti<ProductInfoHeaderValue> ("User-Agent", ProductInfoHeaderValue.TryParse, HttpHeaderKind.Request),
+ HeaderInfo.CreateMulti<string> ("Vary", CollectionParser.TryParse, HttpHeaderKind.Response),
HeaderInfo.CreateMulti<ViaHeaderValue> ("Via", ViaHeaderValue.TryParse, HttpHeaderKind.Request | HttpHeaderKind.Response),
HeaderInfo.CreateMulti<WarningHeaderValue> ("Warning", WarningHeaderValue.TryParse, HttpHeaderKind.Request | HttpHeaderKind.Response),
HeaderInfo.CreateMulti<AuthenticationHeaderValue> ("WWW-Authenticate", AuthenticationHeaderValue.TryParse, HttpHeaderKind.Response)
diff --git a/mcs/class/System.Net.Http/System.Net.Http.Headers/Lexer.cs b/mcs/class/System.Net.Http/System.Net.Http.Headers/Lexer.cs
index 0f98be658d1..f87d4f741bf 100644
--- a/mcs/class/System.Net.Http/System.Net.Http.Headers/Lexer.cs
+++ b/mcs/class/System.Net.Http/System.Net.Http.Headers/Lexer.cs
@@ -46,6 +46,8 @@ namespace System.Net.Http.Headers
OpenParens,
}
+ public static readonly Token Empty = new Token (Type.Token, 0, 0);
+
readonly Type type;
public Token (Type type, int startPosition, int endPosition)
diff --git a/mcs/class/System.Net.Http/System.Net.Http.Headers/MediaTypeHeaderValue.cs b/mcs/class/System.Net.Http/System.Net.Http.Headers/MediaTypeHeaderValue.cs
index 5379a6099f1..296010aa2ad 100644
--- a/mcs/class/System.Net.Http/System.Net.Http.Headers/MediaTypeHeaderValue.cs
+++ b/mcs/class/System.Net.Http/System.Net.Http.Headers/MediaTypeHeaderValue.cs
@@ -33,7 +33,7 @@ namespace System.Net.Http.Headers
public class MediaTypeHeaderValue : ICloneable
{
internal List<NameValueHeaderValue> parameters;
- string media_type;
+ internal string media_type;
public MediaTypeHeaderValue (string mediaType)
{
@@ -150,7 +150,8 @@ namespace System.Net.Http.Headers
switch (token.Value.Kind) {
case Token.Type.SeparatorSemicolon:
- if (!NameValueHeaderValue.TryParseParameters (lexer, out parameters))
+ Token t;
+ if (!NameValueHeaderValue.TryParseParameters (lexer, out parameters, out t) || t != Token.Type.End)
return false;
break;
case Token.Type.End:
@@ -167,37 +168,7 @@ namespace System.Net.Http.Headers
return true;
}
- internal static bool TryParse<T> (string input, out T parsedValue, Func<T> factory) where T : MediaTypeHeaderValue
- {
- parsedValue = null;
-
- var lexer = new Lexer (input);
-
- string media;
- List<NameValueHeaderValue> parameters = null;
- var token = TryParseMediaType (lexer, out media);
- if (token == null)
- return false;
-
- switch (token.Value.Kind) {
- case Token.Type.SeparatorSemicolon:
- if (!NameValueHeaderValue.TryParseParameters (lexer, out parameters))
- return false;
- break;
- case Token.Type.End:
- break;
- default:
- return false;
- }
-
- parsedValue = factory ();
- parsedValue.media_type = media;
- parsedValue.parameters = parameters;
-
- return true;
- }
-
- static Token? TryParseMediaType (Lexer lexer, out string media)
+ internal static Token? TryParseMediaType (Lexer lexer, out string media)
{
media = null;
diff --git a/mcs/class/System.Net.Http/System.Net.Http.Headers/MediaTypeWithQualityHeaderValue.cs b/mcs/class/System.Net.Http/System.Net.Http.Headers/MediaTypeWithQualityHeaderValue.cs
index a3415fc1e1a..1cf406dbfdc 100644
--- a/mcs/class/System.Net.Http/System.Net.Http.Headers/MediaTypeWithQualityHeaderValue.cs
+++ b/mcs/class/System.Net.Http/System.Net.Http.Headers/MediaTypeWithQualityHeaderValue.cs
@@ -26,6 +26,8 @@
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
+using System.Collections.Generic;
+
namespace System.Net.Http.Headers
{
public sealed class MediaTypeWithQualityHeaderValue : MediaTypeHeaderValue
@@ -65,7 +67,40 @@ namespace System.Net.Http.Headers
public static bool TryParse (string input, out MediaTypeWithQualityHeaderValue parsedValue)
{
- return TryParse (input, out parsedValue, () => new MediaTypeWithQualityHeaderValue ());
+ var lexer = new Lexer (input);
+ Token token;
+ if (TryParseElement (lexer, out parsedValue, out token) && token == Token.Type.End)
+ return true;
+
+ parsedValue = null;
+ return false;
+ }
+
+ static bool TryParseElement (Lexer lexer, out MediaTypeWithQualityHeaderValue parsedValue, out Token t)
+ {
+ parsedValue = null;
+
+ string media;
+ List<NameValueHeaderValue> parameters = null;
+ var token = TryParseMediaType (lexer, out media);
+ if (token == null) {
+ t = Token.Empty;
+ return false;
+ }
+
+ t = token.Value;
+ if (t == Token.Type.SeparatorSemicolon && (!NameValueHeaderValue.TryParseParameters (lexer, out parameters, out t) || t != Token.Type.End))
+ return false;
+
+ parsedValue = new MediaTypeWithQualityHeaderValue ();
+ parsedValue.media_type = media;
+ parsedValue.parameters = parameters;
+ return true;
+ }
+
+ internal static bool TryParse (string input, int minimalCount, out List<MediaTypeWithQualityHeaderValue> result)
+ {
+ return CollectionParser.TryParse (input, minimalCount, TryParseElement, out result);
}
}
}
diff --git a/mcs/class/System.Net.Http/System.Net.Http.Headers/NameValueHeaderValue.cs b/mcs/class/System.Net.Http/System.Net.Http.Headers/NameValueHeaderValue.cs
index 906ab3aa657..e3766a4eb15 100644
--- a/mcs/class/System.Net.Http/System.Net.Http.Headers/NameValueHeaderValue.cs
+++ b/mcs/class/System.Net.Http/System.Net.Http.Headers/NameValueHeaderValue.cs
@@ -32,7 +32,7 @@ namespace System.Net.Http.Headers
{
public class NameValueHeaderValue : ICloneable
{
- string value;
+ internal string value;
public NameValueHeaderValue (string name)
: this (name, null)
@@ -53,11 +53,11 @@ namespace System.Net.Http.Headers
this.value = source.value;
}
- private NameValueHeaderValue ()
+ internal NameValueHeaderValue ()
{
}
- public string Name { get; private set; }
+ public string Name { get; internal set; }
public string Value {
get {
@@ -121,27 +121,22 @@ namespace System.Net.Http.Headers
throw new FormatException (input);
}
- internal static bool TryParseParameters (Lexer lexer, out List<NameValueHeaderValue> result)
+ internal static bool TryParsePragma (string input, int minimalCount, out List<NameValueHeaderValue> result)
{
- return TryParseCollection (lexer, out result, Token.Type.SeparatorSemicolon);
+ return CollectionParser.TryParse (input, minimalCount, TryParseElement, out result);
}
- internal static bool TryParsePragma (string input, out List<NameValueHeaderValue> result)
- {
- return TryParseCollection (new Lexer (input), out result, Token.Type.SeparatorComma);
- }
-
- static bool TryParseCollection (Lexer lexer, out List<NameValueHeaderValue> result, Token.Type separator)
+ internal static bool TryParseParameters (Lexer lexer, out List<NameValueHeaderValue> result, out Token t)
{
var list = new List<NameValueHeaderValue> ();
result = null;
- Token t;
-
- do {
+ while (true) {
var attr = lexer.Scan ();
- if (attr != Token.Type.Token)
+ if (attr != Token.Type.Token) {
+ t = Token.Empty;
return false;
+ }
string value = null;
@@ -156,19 +151,17 @@ namespace System.Net.Http.Headers
t = lexer.Scan ();
}
- if (t == separator|| t == Token.Type.End) {
- list.Add (new NameValueHeaderValue () {
- Name = lexer.GetStringValue (attr),
- value = value
- });
- } else {
- return false;
- }
+ list.Add (new NameValueHeaderValue () {
+ Name = lexer.GetStringValue (attr),
+ value = value
+ });
- } while (t == separator);
+ if (t == Token.Type.SeparatorSemicolon)
+ continue;
- result = list;
- return true;
+ result = list;
+ return true;
+ }
}
public override string ToString ()
@@ -181,35 +174,39 @@ namespace System.Net.Http.Headers
public static bool TryParse (string input, out NameValueHeaderValue parsedValue)
{
- parsedValue = null;
-
var lexer = new Lexer (input);
- var t = lexer.Scan ();
- if (t != Token.Type.Token && t != Token.Type.QuotedString)
- return false;
+ Token token;
+ if (TryParseElement (lexer, out parsedValue, out token) && token == Token.Type.End)
+ return true;
- string v = null;
- var token2 = lexer.Scan ();
- if (token2 != Token.Type.End) {
- if (token2 != Token.Type.SeparatorEqual)
- return false;
-
- token2 = lexer.Scan ();
+ parsedValue = null;
+ return false;
+ }
- if (token2 == Token.Type.Token || token2 == Token.Type.QuotedString) {
- v = lexer.GetStringValue (token2);
- token2 = lexer.Scan ();
- }
+ static bool TryParseElement (Lexer lexer, out NameValueHeaderValue parsedValue, out Token t)
+ {
+ parsedValue = null;
- if (token2 != Token.Type.End)
- return false;
- }
+ t = lexer.Scan ();
+ if (t != Token.Type.Token)
+ return false;
parsedValue = new NameValueHeaderValue () {
Name = lexer.GetStringValue (t),
- value = v
};
+ t = lexer.Scan ();
+ if (t == Token.Type.SeparatorEqual) {
+ t = lexer.Scan ();
+
+ if (t == Token.Type.Token || t == Token.Type.QuotedString) {
+ parsedValue.value = lexer.GetStringValue (t);
+ t = lexer.Scan ();
+ } else {
+ return false;
+ }
+ }
+
return true;
}
}
diff --git a/mcs/class/System.Net.Http/System.Net.Http.Headers/NameValueWithParametersHeaderValue.cs b/mcs/class/System.Net.Http/System.Net.Http.Headers/NameValueWithParametersHeaderValue.cs
index 81d7bb089c1..3d328341845 100644
--- a/mcs/class/System.Net.Http/System.Net.Http.Headers/NameValueWithParametersHeaderValue.cs
+++ b/mcs/class/System.Net.Http/System.Net.Http.Headers/NameValueWithParametersHeaderValue.cs
@@ -53,8 +53,8 @@ namespace System.Net.Http.Headers
}
}
- private NameValueWithParametersHeaderValue (NameValueHeaderValue source)
- : base (source)
+ private NameValueWithParametersHeaderValue ()
+ : base ()
{
}
@@ -102,15 +102,52 @@ namespace System.Net.Http.Headers
public static bool TryParse (string input, out NameValueWithParametersHeaderValue parsedValue)
{
- List<NameValueHeaderValue> values;
- if (!TryParseParameters (new Lexer (input), out values)) {
- parsedValue = null;
+ var lexer = new Lexer (input);
+ Token token;
+ if (TryParseElement (lexer, out parsedValue, out token) && token == Token.Type.End)
+ return true;
+
+ parsedValue = null;
+ return false;
+ }
+
+ internal static bool TryParse (string input, int minimalCount, out List<NameValueWithParametersHeaderValue> result)
+ {
+ return CollectionParser.TryParse (input, minimalCount, TryParseElement, out result);
+ }
+
+ static bool TryParseElement (Lexer lexer, out NameValueWithParametersHeaderValue parsedValue, out Token t)
+ {
+ parsedValue = null;
+
+ t = lexer.Scan ();
+ if (t != Token.Type.Token)
return false;
+
+ parsedValue = new NameValueWithParametersHeaderValue () {
+ Name = lexer.GetStringValue (t),
+ };
+
+ t = lexer.Scan ();
+ if (t == Token.Type.SeparatorEqual) {
+ t = lexer.Scan ();
+
+ if (t == Token.Type.Token || t == Token.Type.QuotedString) {
+ parsedValue.value = lexer.GetStringValue (t);
+ t = lexer.Scan ();
+ } else {
+ return false;
+ }
+ }
+
+ if (t == Token.Type.SeparatorSemicolon) {
+ List<NameValueHeaderValue> result;
+ if (!TryParseParameters (lexer, out result, out t))
+ return false;
+
+ parsedValue.parameters = result;
}
- parsedValue = new NameValueWithParametersHeaderValue (values[0]);
- values.RemoveAt (0);
- parsedValue.parameters = values;
return true;
}
}
diff --git a/mcs/class/System.Net.Http/System.Net.Http.Headers/Parser.cs b/mcs/class/System.Net.Http/System.Net.Http.Headers/Parser.cs
index a6d80d7375b..79a3ca380c8 100644
--- a/mcs/class/System.Net.Http/System.Net.Http.Headers/Parser.cs
+++ b/mcs/class/System.Net.Http/System.Net.Http.Headers/Parser.cs
@@ -28,6 +28,7 @@
using System.Net.Mail;
using System.Globalization;
+using System.Collections.Generic;
namespace System.Net.Http.Headers
{
diff --git a/mcs/class/System.Net.Http/System.Net.Http.Headers/ProductHeaderValue.cs b/mcs/class/System.Net.Http/System.Net.Http.Headers/ProductHeaderValue.cs
index 306c9f228c8..9614df12939 100644
--- a/mcs/class/System.Net.Http/System.Net.Http.Headers/ProductHeaderValue.cs
+++ b/mcs/class/System.Net.Http/System.Net.Http.Headers/ProductHeaderValue.cs
@@ -26,6 +26,8 @@
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
+using System.Collections.Generic;
+
namespace System.Net.Http.Headers
{
public class ProductHeaderValue : ICloneable
@@ -87,15 +89,30 @@ namespace System.Net.Http.Headers
public static bool TryParse (string input, out ProductHeaderValue parsedValue)
{
+ var lexer = new Lexer (input);
+ Token token;
+ if (TryParseElement (lexer, out parsedValue, out token) && token == Token.Type.End)
+ return true;
+
parsedValue = null;
+ return false;
+ }
- var lexer = new Lexer (input);
- var t = lexer.Scan ();
+ internal static bool TryParse (string input, int minimalCount, out List<ProductHeaderValue> result)
+ {
+ return CollectionParser.TryParse (input, minimalCount, TryParseElement, out result);
+ }
+
+ static bool TryParseElement (Lexer lexer, out ProductHeaderValue parsedValue, out Token t)
+ {
+ parsedValue = null;
+
+ t = lexer.Scan ();
if (t != Token.Type.Token)
return false;
- var value = new ProductHeaderValue ();
- value.Name = lexer.GetStringValue (t);
+ parsedValue = new ProductHeaderValue ();
+ parsedValue.Name = lexer.GetStringValue (t);
t = lexer.Scan ();
if (t == Token.Type.SeparatorSlash) {
@@ -103,14 +120,10 @@ namespace System.Net.Http.Headers
if (t != Token.Type.Token)
return false;
- value.Version = lexer.GetStringValue (t);
+ parsedValue.Version = lexer.GetStringValue (t);
t = lexer.Scan ();
}
- if (t != Token.Type.End)
- return false;
-
- parsedValue = value;
return true;
}
diff --git a/mcs/class/System.Net.Http/System.Net.Http.Headers/ProductInfoHeaderValue.cs b/mcs/class/System.Net.Http/System.Net.Http.Headers/ProductInfoHeaderValue.cs
index daf47ac31e8..baace53ed8e 100644
--- a/mcs/class/System.Net.Http/System.Net.Http.Headers/ProductInfoHeaderValue.cs
+++ b/mcs/class/System.Net.Http/System.Net.Http.Headers/ProductInfoHeaderValue.cs
@@ -106,7 +106,7 @@ namespace System.Net.Http.Headers
return true;
}
- internal static bool TryParse (string input, out List<ProductInfoHeaderValue> result)
+ internal static bool TryParse (string input, int minimalCount, out List<ProductInfoHeaderValue> result)
{
var list = new List<ProductInfoHeaderValue> ();
var lexer = new Lexer (input);
@@ -118,8 +118,12 @@ namespace System.Net.Http.Headers
return false;
if (element == null) {
- result = list;
- return true;
+ if (list != null && minimalCount <= list.Count) {
+ result = list;
+ return true;
+ }
+
+ return false;
}
list.Add (element);
diff --git a/mcs/class/System.Net.Http/System.Net.Http.Headers/StringWithQualityHeaderValue.cs b/mcs/class/System.Net.Http/System.Net.Http.Headers/StringWithQualityHeaderValue.cs
index 635ed00223c..648d4222e36 100644
--- a/mcs/class/System.Net.Http/System.Net.Http.Headers/StringWithQualityHeaderValue.cs
+++ b/mcs/class/System.Net.Http/System.Net.Http.Headers/StringWithQualityHeaderValue.cs
@@ -27,6 +27,8 @@
//
using System.Globalization;
+using System.Collections.Generic;
+
namespace System.Net.Http.Headers
{
public class StringWithQualityHeaderValue : ICloneable
@@ -82,10 +84,24 @@ namespace System.Net.Http.Headers
public static bool TryParse (string input, out StringWithQualityHeaderValue parsedValue)
{
+ var lexer = new Lexer (input);
+ Token token;
+ if (TryParseElement (lexer, out parsedValue, out token) && token == Token.Type.End)
+ return true;
+
parsedValue = null;
+ return false;
+ }
- var lexer = new Lexer (input);
- var t = lexer.Scan ();
+ internal static bool TryParse (string input, int minimalCount, out List<StringWithQualityHeaderValue> result)
+ {
+ return CollectionParser.TryParse (input, minimalCount, TryParseElement, out result);
+ }
+
+ static bool TryParseElement (Lexer lexer, out StringWithQualityHeaderValue parsedValue, out Token t)
+ {
+ parsedValue = null;
+ t = lexer.Scan ();
if (t != Token.Type.Token)
return false;
@@ -120,9 +136,6 @@ namespace System.Net.Http.Headers
t = lexer.Scan ();
}
- if (t != Token.Type.End)
- return false;
-
parsedValue = value;
return true;
}
diff --git a/mcs/class/System.Net.Http/System.Net.Http.Headers/TransferCodingHeaderValue.cs b/mcs/class/System.Net.Http/System.Net.Http.Headers/TransferCodingHeaderValue.cs
index 8f0db592831..6e9825ea4ce 100644
--- a/mcs/class/System.Net.Http/System.Net.Http.Headers/TransferCodingHeaderValue.cs
+++ b/mcs/class/System.Net.Http/System.Net.Http.Headers/TransferCodingHeaderValue.cs
@@ -32,7 +32,7 @@ namespace System.Net.Http.Headers
{
public class TransferCodingHeaderValue : ICloneable
{
- string value;
+ internal string value;
internal List<NameValueHeaderValue> parameters;
public TransferCodingHeaderValue (string value)
@@ -106,30 +106,36 @@ namespace System.Net.Http.Headers
public static bool TryParse (string input, out TransferCodingHeaderValue parsedValue)
{
- return TryParse (input, out parsedValue, () => new TransferCodingHeaderValue ());
+ var lexer = new Lexer (input);
+ Token token;
+ if (TryParseElement (lexer, out parsedValue, out token) && token == Token.Type.End)
+ return true;
+
+ parsedValue = null;
+ return false;
}
- internal static bool TryParse<T> (string input, out T parsedValue, Func<T> factory) where T : TransferCodingHeaderValue
+ internal static bool TryParse (string input, int minimalCount, out List<TransferCodingHeaderValue> result)
+ {
+ return CollectionParser.TryParse (input, minimalCount, TryParseElement, out result);
+ }
+
+ static bool TryParseElement (Lexer lexer, out TransferCodingHeaderValue parsedValue, out Token t)
{
parsedValue = null;
- var lexer = new Lexer (input);
- var t = lexer.Scan ();
+ t = lexer.Scan ();
if (t != Token.Type.Token)
return false;
- var result = factory ();
+ var result = new TransferCodingHeaderValue ();
result.value = lexer.GetStringValue (t);
t = lexer.Scan ();
// Parameters parsing
- if (t == Token.Type.SeparatorSemicolon) {
- if (!NameValueHeaderValue.TryParseParameters (lexer, out result.parameters))
- return false;
- } else if (t != Token.Type.End) {
+ if (t == Token.Type.SeparatorSemicolon && (!NameValueHeaderValue.TryParseParameters (lexer, out result.parameters, out t) || t != Token.Type.End))
return false;
- }
parsedValue = result;
return true;
diff --git a/mcs/class/System.Net.Http/System.Net.Http.Headers/TransferCodingWithQualityHeaderValue.cs b/mcs/class/System.Net.Http/System.Net.Http.Headers/TransferCodingWithQualityHeaderValue.cs
index 0a6e08373c6..845b95ef5cb 100644
--- a/mcs/class/System.Net.Http/System.Net.Http.Headers/TransferCodingWithQualityHeaderValue.cs
+++ b/mcs/class/System.Net.Http/System.Net.Http.Headers/TransferCodingWithQualityHeaderValue.cs
@@ -26,6 +26,8 @@
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
+using System.Collections.Generic;
+
namespace System.Net.Http.Headers
{
public sealed class TransferCodingWithQualityHeaderValue : TransferCodingHeaderValue
@@ -65,7 +67,39 @@ namespace System.Net.Http.Headers
public static bool TryParse (string input, out TransferCodingWithQualityHeaderValue parsedValue)
{
- return TryParse (input, out parsedValue, () => new TransferCodingWithQualityHeaderValue ());
+ var lexer = new Lexer (input);
+ Token token;
+ if (TryParseElement (lexer, out parsedValue, out token) && token == Token.Type.End)
+ return true;
+
+ parsedValue = null;
+ return false;
+ }
+
+ internal static bool TryParse (string input, int minimalCount, out List<TransferCodingWithQualityHeaderValue> result)
+ {
+ return CollectionParser.TryParse (input, minimalCount, TryParseElement, out result);
+ }
+
+ static bool TryParseElement (Lexer lexer, out TransferCodingWithQualityHeaderValue parsedValue, out Token t)
+ {
+ parsedValue = null;
+
+ t = lexer.Scan ();
+ if (t != Token.Type.Token)
+ return false;
+
+ var result = new TransferCodingWithQualityHeaderValue ();
+ result.value = lexer.GetStringValue (t);
+
+ t = lexer.Scan ();
+
+ // Parameters parsing
+ if (t == Token.Type.SeparatorSemicolon && (!NameValueHeaderValue.TryParseParameters (lexer, out result.parameters, out t) || t != Token.Type.End))
+ return false;
+
+ parsedValue = result;
+ return true;
}
}
}
diff --git a/mcs/class/System.Net.Http/System.Net.Http.Headers/ViaHeaderValue.cs b/mcs/class/System.Net.Http/System.Net.Http.Headers/ViaHeaderValue.cs
index 4da14004e13..9381977ee17 100644
--- a/mcs/class/System.Net.Http/System.Net.Http.Headers/ViaHeaderValue.cs
+++ b/mcs/class/System.Net.Http/System.Net.Http.Headers/ViaHeaderValue.cs
@@ -26,6 +26,8 @@
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
+using System.Collections.Generic;
+
namespace System.Net.Http.Headers
{
public class ViaHeaderValue : ICloneable
@@ -110,11 +112,25 @@ namespace System.Net.Http.Headers
public static bool TryParse (string input, out ViaHeaderValue parsedValue)
{
+ var lexer = new Lexer (input);
+ Token token;
+ if (TryParseElement (lexer, out parsedValue, out token) && token == Token.Type.End)
+ return true;
+
parsedValue = null;
+ return false;
+ }
- var lexer = new Lexer (input);
+ internal static bool TryParse (string input, int minimalCount, out List<ViaHeaderValue> result)
+ {
+ return CollectionParser.TryParse (input, minimalCount, TryParseElement, out result);
+ }
- var t = lexer.Scan ();
+ static bool TryParseElement (Lexer lexer, out ViaHeaderValue parsedValue, out Token t)
+ {
+ parsedValue = null;
+
+ t = lexer.Scan ();
if (t != Token.Type.Token)
return false;
@@ -150,8 +166,9 @@ namespace System.Net.Http.Headers
value.ReceivedBy = lexer.GetStringValue (next, t);
string comment;
- if (!lexer.ScanCommentOptional (out comment))
- return false;
+ if (lexer.ScanCommentOptional (out comment, out t)) {
+ t = lexer.Scan ();
+ }
value.Comment = comment;
parsedValue = value;
diff --git a/mcs/class/System.Net.Http/System.Net.Http.Headers/WarningHeaderValue.cs b/mcs/class/System.Net.Http/System.Net.Http.Headers/WarningHeaderValue.cs
index fc58299cf0b..5c65339ef7a 100644
--- a/mcs/class/System.Net.Http/System.Net.Http.Headers/WarningHeaderValue.cs
+++ b/mcs/class/System.Net.Http/System.Net.Http.Headers/WarningHeaderValue.cs
@@ -27,6 +27,7 @@
//
using System.Globalization;
+using System.Collections.Generic;
namespace System.Net.Http.Headers
{
@@ -100,13 +101,28 @@ namespace System.Net.Http.Headers
throw new FormatException (input);
}
-
+
public static bool TryParse (string input, out WarningHeaderValue parsedValue)
{
+ var lexer = new Lexer (input);
+ Token token;
+ if (TryParseElement (lexer, out parsedValue, out token) && token == Token.Type.End)
+ return true;
+
parsedValue = null;
+ return false;
+ }
- var lexer = new Lexer (input);
- var t = lexer.Scan ();
+ internal static bool TryParse (string input, int minimalCount, out List<WarningHeaderValue> result)
+ {
+ return CollectionParser.TryParse (input, minimalCount, TryParseElement, out result);
+ }
+
+ static bool TryParseElement (Lexer lexer, out WarningHeaderValue parsedValue, out Token t)
+ {
+ parsedValue = null;
+
+ t = lexer.Scan ();
if (t != Token.Type.Token)
return false;
@@ -148,9 +164,6 @@ namespace System.Net.Http.Headers
t = lexer.Scan ();
}
- if (t != Token.Type.End)
- return false;
-
parsedValue = value;
return true;
}
diff --git a/mcs/class/System.Net.Http/System.Net.Http.dll.sources b/mcs/class/System.Net.Http/System.Net.Http.dll.sources
index ccca104fd9d..b40b2a170c1 100644
--- a/mcs/class/System.Net.Http/System.Net.Http.dll.sources
+++ b/mcs/class/System.Net.Http/System.Net.Http.dll.sources
@@ -22,6 +22,7 @@ System.Net.Http/StringContent.cs
System.Net.Http.Headers/AuthenticationHeaderValue.cs
System.Net.Http.Headers/CacheControlHeaderValue.cs
System.Net.Http.Headers/CollectionExtensions.cs
+System.Net.Http.Headers/CollectionParser.cs
System.Net.Http.Headers/ContentDispositionHeaderValue.cs
System.Net.Http.Headers/ContentRangeHeaderValue.cs
System.Net.Http.Headers/EntityTagHeaderValue.cs
diff --git a/mcs/class/System.Net.Http/Test/System.Net.Http.Headers/NameValueHeaderValueTest.cs b/mcs/class/System.Net.Http/Test/System.Net.Http.Headers/NameValueHeaderValueTest.cs
index 7d08832868a..32cf785a0e9 100644
--- a/mcs/class/System.Net.Http/Test/System.Net.Http.Headers/NameValueHeaderValueTest.cs
+++ b/mcs/class/System.Net.Http/Test/System.Net.Http.Headers/NameValueHeaderValueTest.cs
@@ -157,6 +157,9 @@ namespace MonoTests.System.Net.Http.Headers
NameValueHeaderValue res;
Assert.IsFalse (NameValueHeaderValue.TryParse ("", out res), "#1");
Assert.IsNull (res, "#2");
+
+ Assert.IsFalse (NameValueHeaderValue.TryParse ("\"a\"=b", out res), "#3");
+ Assert.IsNull (res, "#4");
}
}
}
diff --git a/mcs/class/System.Net.Http/Test/System.Net.Http/HttpRequestMessageTest.cs b/mcs/class/System.Net.Http/Test/System.Net.Http/HttpRequestMessageTest.cs
index b852fdc05fd..79ae114f65b 100644
--- a/mcs/class/System.Net.Http/Test/System.Net.Http/HttpRequestMessageTest.cs
+++ b/mcs/class/System.Net.Http/Test/System.Net.Http/HttpRequestMessageTest.cs
@@ -35,6 +35,7 @@ using System.Net.Http;
using System.Net;
using System.Net.Http.Headers;
using System.Linq;
+using System.IO;
namespace MonoTests.System.Net.Http
{
@@ -361,15 +362,55 @@ namespace MonoTests.System.Net.Http
}
[Test]
- public void Headers_Complex ()
+ public void Headers_MultiValues ()
{
HttpRequestMessage message = new HttpRequestMessage ();
HttpRequestHeaders headers = message.Headers;
+ headers.Add ("Accept", "application/vnd.citrix.requesttokenresponse+xml, application/vnd.citrix.requesttokenchoices+xml");
+ headers.Add ("Accept-Charset", "aa ;Q=0,bb;Q=1");
+ headers.Add ("Expect", "x=1; v, y=5");
+ headers.Add ("If-Match", "\"a\",*, \"b\",*");
headers.Add ("user-Agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/29.0.1547.62 Safari/537.36");
+ Assert.AreEqual (2, headers.Accept.Count, "#1a");
+ Assert.IsTrue (headers.Accept.SequenceEqual (
+ new[] {
+ new MediaTypeWithQualityHeaderValue ("application/vnd.citrix.requesttokenresponse+xml"),
+ new MediaTypeWithQualityHeaderValue ("application/vnd.citrix.requesttokenchoices+xml"),
+ }
+ ), "#1b");
- Assert.AreEqual (6, headers.UserAgent.Count);
+ Assert.AreEqual (2, headers.AcceptCharset.Count, "#2a");
+ Assert.IsTrue (headers.AcceptCharset.SequenceEqual (
+ new[] {
+ new StringWithQualityHeaderValue ("aa", 0),
+ new StringWithQualityHeaderValue ("bb", 1),
+ }
+ ), "#2b");
+
+ Assert.AreEqual (2, headers.Expect.Count, "#3a");
+ var expect_expected = new[] {
+ new NameValueWithParametersHeaderValue ("x", "1") {
+ },
+ new NameValueWithParametersHeaderValue ("y", "5"),
+ };
+ expect_expected [0].Parameters.Add (new NameValueHeaderValue ("v"));
+ Assert.IsTrue (headers.Expect.SequenceEqual (
+ expect_expected
+ ), "#3b");
+
+ Assert.AreEqual (4, headers.IfMatch.Count, "#4a");
+ Assert.IsTrue (headers.IfMatch.SequenceEqual (
+ new[] {
+ new EntityTagHeaderValue ("\"a\""),
+ EntityTagHeaderValue.Any,
+ new EntityTagHeaderValue ("\"b\""),
+ EntityTagHeaderValue.Any
+ }
+ ), "#4b");
+
+ Assert.AreEqual (6, headers.UserAgent.Count, "#10a");
Assert.IsTrue (headers.UserAgent.SequenceEqual (
new[] {
@@ -380,7 +421,7 @@ namespace MonoTests.System.Net.Http
new ProductInfoHeaderValue ("Chrome", "29.0.1547.62"),
new ProductInfoHeaderValue ("Safari", "537.36")
}
- ));
+ ), "#10b");
}
[Test]
diff --git a/mcs/class/System.Net.Http/Test/System.Net.Http/HttpResponseMessageTest.cs b/mcs/class/System.Net.Http/Test/System.Net.Http/HttpResponseMessageTest.cs
index b92b3e644d6..b13e8cae417 100644
--- a/mcs/class/System.Net.Http/Test/System.Net.Http/HttpResponseMessageTest.cs
+++ b/mcs/class/System.Net.Http/Test/System.Net.Http/HttpResponseMessageTest.cs
@@ -295,6 +295,56 @@ namespace MonoTests.System.Net.Http
}
[Test]
+ public void Headers_MultiValues ()
+ {
+ var message = new HttpResponseMessage ();
+ var headers = message.Headers;
+
+ headers.Add ("Proxy-Authenticate", "x, y, z,i");
+ headers.Add ("Upgrade", "HTTP/2.0, SHTTP/1.3, IRC, RTA/x11");
+ headers.Add ("Via", "1.0 fred, 1.1 nowhere.com (Apache/1.1)");
+ headers.Add ("Warning", "199 Miscellaneous \"w\", 200 a \"b\"");
+
+ Assert.AreEqual (4, headers.ProxyAuthenticate.Count, "#1a");
+ Assert.IsTrue (headers.ProxyAuthenticate.SequenceEqual (
+ new[] {
+ new AuthenticationHeaderValue ("x"),
+
+ new AuthenticationHeaderValue ("y"),
+ new AuthenticationHeaderValue ("z"),
+ new AuthenticationHeaderValue ("i")
+ }
+ ), "#1b");
+
+
+ Assert.AreEqual (4, headers.Upgrade.Count, "#2a");
+ Assert.IsTrue (headers.Upgrade.SequenceEqual (
+ new[] {
+ new ProductHeaderValue ("HTTP", "2.0"),
+ new ProductHeaderValue ("SHTTP", "1.3"),
+ new ProductHeaderValue ("IRC"),
+ new ProductHeaderValue ("RTA", "x11")
+ }
+ ), "#2b");
+
+ Assert.AreEqual (2, headers.Via.Count, "#3a");
+ Assert.IsTrue (headers.Via.SequenceEqual (
+ new[] {
+ new ViaHeaderValue ("1.0", "fred"),
+ new ViaHeaderValue ("1.1", "nowhere.com", null, "(Apache/1.1)")
+ }
+ ), "#2b");
+
+ Assert.AreEqual (2, headers.Warning.Count, "#4a");
+ Assert.IsTrue (headers.Warning.SequenceEqual (
+ new[] {
+ new WarningHeaderValue (199, "Miscellaneous", "\"w\""),
+ new WarningHeaderValue (200, "a", "\"b\"")
+ }
+ ), "#4b");
+ }
+
+ [Test]
public void Header_BaseImplementation ()
{
HttpResponseMessage message = new HttpResponseMessage ();
diff --git a/mcs/class/System.Net.Http/Test/System.Net.Http/StreamContentTest.cs b/mcs/class/System.Net.Http/Test/System.Net.Http/StreamContentTest.cs
index edd4b839c16..413e459526e 100644
--- a/mcs/class/System.Net.Http/Test/System.Net.Http/StreamContentTest.cs
+++ b/mcs/class/System.Net.Http/Test/System.Net.Http/StreamContentTest.cs
@@ -309,6 +309,21 @@ namespace MonoTests.System.Net.Http
}
[Test]
+ public void Headers_Multi ()
+ {
+ var sc = new StreamContent (MemoryStream.Null);
+ var headers = sc.Headers;
+
+ headers.Add ("Allow", "");
+ headers.Add ("Allow", "a , b, c");
+
+ Assert.AreEqual (3, headers.Allow.Count, "#1a");
+ Assert.IsTrue (headers.Allow.SequenceEqual (
+ new[] { "a", "b", "c" }
+ ), "#1b");
+ }
+
+ [Test]
public void LoadIntoBuffer ()
{
var ms = new MemoryStream ();