public AuthenticationHeaderValue (string scheme, string parameter)
{
- if (scheme == null)
- throw new ArgumentNullException ("scheme");
-
Parser.Token.Check (scheme);
this.Scheme = scheme;
this.Parameter = parameter;
}
+ private AuthenticationHeaderValue ()
+ {
+ }
+
public string Parameter { get; private set; }
public string Scheme { get; private set; }
public static bool TryParse (string input, out AuthenticationHeaderValue parsedValue)
{
- throw new NotImplementedException ();
+ var lexer = new Lexer (input);
+ var t = lexer.Scan ();
+ if (t != Token.Type.Token || !(lexer.PeekChar () == ' ' || lexer.PeekChar () == -1)) {
+ parsedValue = null;
+ return false;
+ }
+
+ parsedValue = new AuthenticationHeaderValue ();
+ parsedValue.Scheme = lexer.GetStringValue (t);
+
+ t = lexer.Scan ();
+ if (t != Token.Type.End)
+ parsedValue.Parameter = lexer.GetRemainingStringValue (t.StartPosition);
+
+ return true;
+ }
+
+ public override string ToString ()
+ {
+ return Parameter != null ?
+ Scheme + " " + Parameter :
+ Scheme;
}
}
}
//
using System.Collections.Generic;
+using System.Text;
+using System.Globalization;
namespace System.Net.Http.Headers
{
public static bool TryParse (string input, out CacheControlHeaderValue parsedValue)
{
- throw new NotImplementedException ();
+ parsedValue = null;
+ if (input == null)
+ return true;
+
+ var value = new CacheControlHeaderValue ();
+
+ var lexer = new Lexer (input);
+ Token t;
+ do {
+ t = lexer.Scan ();
+ if (t != Token.Type.Token)
+ return false;
+
+ string s = lexer.GetStringValue (t);
+ bool token_read = false;
+ TimeSpan? ts;
+ switch (s) {
+ case "no-store":
+ value.NoStore = true;
+ break;
+ case "no-transform":
+ value.NoTransform = true;
+ break;
+ case "only-if-cached":
+ value.OnlyIfCached = true;
+ break;
+ case "public":
+ value.Public = true;
+ break;
+ case "must-revalidate":
+ value.MustRevalidate = true;
+ break;
+ case "proxy-revalidate":
+ value.ProxyRevalidate = true;
+ break;
+ case "max-stale":
+ value.MaxStale = true;
+ t = lexer.Scan ();
+ if (t != Token.Type.SeparatorEqual) {
+ token_read = true;
+ break;
+ }
+
+ t = lexer.Scan ();
+ if (t != Token.Type.Token)
+ return false;
+
+ ts = lexer.TryGetTimeSpanValue (t);
+ if (ts == null)
+ return false;
+
+ value.MaxStaleLimit = ts;
+ break;
+ case "max-age":
+ case "s-maxage":
+ case "min-fresh":
+ t = lexer.Scan ();
+ if (t != Token.Type.SeparatorEqual) {
+ return false;
+ }
+
+ t = lexer.Scan ();
+ if (t != Token.Type.Token)
+ return false;
+
+ ts = lexer.TryGetTimeSpanValue (t);
+ if (ts == null)
+ return false;
+
+ switch (s.Length) {
+ case 7:
+ value.MaxAge = ts;
+ break;
+ case 8:
+ value.SharedMaxAge = ts;
+ break;
+ default:
+ value.MinFresh = ts;
+ break;
+ }
+
+ break;
+ case "private":
+ case "no-cache":
+ if (s.Length == 7) {
+ value.Private = true;
+ } else {
+ value.NoCache = true;
+ }
+
+ t = lexer.Scan ();
+ if (t != Token.Type.SeparatorEqual) {
+ token_read = true;
+ break;
+ }
+
+ t = lexer.Scan ();
+ if (t != Token.Type.QuotedString)
+ return false;
+
+ foreach (var entry in lexer.GetQuotedStringValue (t).Split (',')) {
+ var qs = entry.Trim ('\t', ' ');
+
+ if (s.Length == 7) {
+ value.PrivateHeaders.Add (qs);
+ } else {
+ value.NoCache = true;
+ value.NoCacheHeaders.Add (qs);
+ }
+ }
+ break;
+ default:
+ string name = lexer.GetStringValue (t);
+ string svalue = null;
+
+ t = lexer.Scan ();
+ if (t == Token.Type.SeparatorEqual) {
+ t = lexer.Scan ();
+ switch (t.Kind) {
+ case Token.Type.Token:
+ case Token.Type.QuotedString:
+ svalue = lexer.GetStringValue (t);
+ break;
+ default:
+ return false;
+ }
+ } else {
+ token_read = true;
+ }
+
+ value.Extensions.Add (NameValueHeaderValue.Create (name, svalue));
+ break;
+ }
+
+ if (!token_read)
+ t = lexer.Scan ();
+ } while (t == Token.Type.SeparatorComma);
+
+ if (t != Token.Type.End)
+ return false;
+
+ parsedValue = value;
+ return true;
+ }
+
+ public override string ToString ()
+ {
+ const string separator = ", ";
+
+ var sb = new StringBuilder ();
+ if (NoStore) {
+ sb.Append ("no-store");
+ sb.Append (separator);
+ }
+
+ if (NoTransform) {
+ sb.Append ("no-transform");
+ sb.Append (separator);
+ }
+
+ if (OnlyIfCached) {
+ sb.Append ("only-if-cached");
+ sb.Append (separator);
+ }
+
+ if (Public) {
+ sb.Append ("public");
+ sb.Append (separator);
+ }
+
+ if (MustRevalidate) {
+ sb.Append ("must-revalidate");
+ sb.Append (separator);
+ }
+
+ if (ProxyRevalidate) {
+ sb.Append ("proxy-revalidate");
+ sb.Append (separator);
+ }
+
+ if (NoCache) {
+ sb.Append ("no-cache");
+ if (no_cache_headers != null) {
+ sb.Append ("=\"");
+ no_cache_headers.ToStringBuilder (sb);
+ sb.Append ("\"");
+ }
+
+ sb.Append (separator);
+ }
+
+ if (MaxAge != null) {
+ sb.Append ("max-age=");
+ sb.Append (MaxAge.Value.TotalSeconds.ToString (CultureInfo.InvariantCulture));
+ sb.Append (separator);
+ }
+
+ if (SharedMaxAge != null) {
+ sb.Append ("s-maxage=");
+ sb.Append (SharedMaxAge.Value.TotalSeconds.ToString (CultureInfo.InvariantCulture));
+ sb.Append (separator);
+ }
+
+ if (MaxStale) {
+ sb.Append ("max-stale");
+ if (MaxStaleLimit != null) {
+ sb.Append ("=");
+ sb.Append (MaxStaleLimit.Value.TotalSeconds.ToString (CultureInfo.InvariantCulture));
+ }
+
+ sb.Append (separator);
+ }
+
+ if (MinFresh != null) {
+ sb.Append ("min-fresh=");
+ sb.Append (MinFresh.Value.TotalSeconds.ToString (CultureInfo.InvariantCulture));
+ sb.Append (separator);
+ }
+
+ if (Private) {
+ sb.Append ("private");
+ if (private_headers != null) {
+ sb.Append ("=\"");
+ private_headers.ToStringBuilder (sb);
+ sb.Append ("\"");
+ }
+
+ sb.Append (separator);
+ }
+
+ CollectionExtensions.ToStringBuilder (extensions, sb);
+
+ if (sb.Length > 2 && sb[sb.Length - 2] == ',' && sb[sb.Length - 1] == ' ')
+ sb.Remove (sb.Length - 2, 2);
+
+ return sb.ToString ();
}
}
}
return sb.ToString ();
}
+
+ public static void ToStringBuilder<T> (this List<T> list, StringBuilder sb)
+ {
+ if (list == null || list.Count == 0)
+ return;
+
+ const string separator = ", ";
+
+ for (int i = 0; i < list.Count; ++i) {
+ if (i > 0) {
+ sb.Append (separator);
+ }
+
+ sb.Append (list[i]);
+ }
+ }
}
}
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
+using System.Globalization;
+
namespace System.Net.Http.Headers
{
struct Token
SeparatorEqual,
SeparatorSemicolon,
SeparatorSlash,
+ SeparatorDash,
+ SeparatorComma,
+ OpenParens,
}
readonly Type type;
return s.Substring (token.StartPosition, token.EndPosition - token.StartPosition);
}
+ public string GetStringValue (Token start, Token end)
+ {
+ return s.Substring (start.StartPosition, end.EndPosition - start.StartPosition);
+ }
+
+ public string GetQuotedStringValue (Token start)
+ {
+ return s.Substring (start.StartPosition + 1, start.EndPosition - start.StartPosition - 2);
+ }
+
+ public string GetRemainingStringValue (int position)
+ {
+ return position > s.Length ? null : s.Substring (position);
+ }
+
+ public bool TryGetNumericValue (Token token, out int value)
+ {
+ return int.TryParse (GetStringValue (token), out value);
+ }
+
+ public TimeSpan? TryGetTimeSpanValue (Token token)
+ {
+ int seconds;
+ if (TryGetNumericValue (token, out seconds)) {
+ return TimeSpan.FromSeconds (seconds);
+ }
+
+ return null;
+ }
+
+ public bool TryGetDateValue (Token token, out DateTimeOffset value)
+ {
+ string text = token == Token.Type.QuotedString ?
+ s.Substring (token.StartPosition + 1, token.EndPosition - token.StartPosition - 2) :
+ GetStringValue (token);
+
+ const DateTimeStyles DefaultStyles = DateTimeStyles.AssumeUniversal | DateTimeStyles.AllowWhiteSpaces;
+
+ return
+ DateTimeOffset.TryParseExact (text, "r", DateTimeFormatInfo.InvariantInfo, DefaultStyles, out value) ||
+ DateTimeOffset.TryParseExact (text, "dddd, dd'-'MMM'-'yy HH:mm:ss 'GMT'", DateTimeFormatInfo.InvariantInfo, DefaultStyles, out value) ||
+ DateTimeOffset.TryParseExact (text, "ddd MMM d HH:mm:ss yyyy", DateTimeFormatInfo.InvariantInfo, DefaultStyles, out value);
+ }
+
public static bool IsValidToken (string input)
{
int i = 0;
return i > 0;
}
+ public void EatChar ()
+ {
+ ++pos;
+ }
+
+ public int PeekChar ()
+ {
+ return pos < s.Length ? s[pos] : -1;
+ }
+
+ public bool ScanCommentOptional (out string value)
+ {
+ var t = Scan ();
+ if (t != Token.Type.OpenParens) {
+ value = null;
+ return t == Token.Type.End;
+ }
+
+ while (pos < s.Length) {
+ var ch = s[pos];
+ if (ch == ')') {
+ ++pos;
+ var start = t.StartPosition;
+ value = s.Substring (start, pos - start);
+ return true;
+ }
+
+ // any OCTET except CTLs, but including LWS
+ if (ch < 32 || ch > 126)
+ break;
+
+ ++pos;
+ }
+
+ value = null;
+ return false;
+ }
+
public Token Scan ()
{
int start = pos;
case '/':
ttype = Token.Type.SeparatorSlash;
break;
+ case '-':
+ ttype = Token.Type.SeparatorDash;
+ break;
+ case ',':
+ ttype = Token.Type.SeparatorComma;
+ break;
case '"':
// Quoted string
start = pos - 1;
break;
case '(':
+ start = pos - 1;
+ ttype = Token.Type.OpenParens;
break;
default:
if (ch <= last_token_char && token_chars[ch]) {
}
}
+ internal static NameValueHeaderValue Create (string name, string value)
+ {
+ return new NameValueHeaderValue () {
+ Name = name,
+ value = value
+ };
+ }
+
object ICloneable.Clone ()
{
return new NameValueHeaderValue (this);
throw new FormatException (s);
}
}
+
+ public static void CheckQuotedString (string s)
+ {
+ if (s == null)
+ throw new ArgumentNullException ();
+
+ var lexer = new Lexer (s);
+ if (lexer.Scan () == Headers.Token.Type.QuotedString && lexer.Scan () == Headers.Token.Type.End)
+ return;
+
+ if (s.Length == 0)
+ throw new ArgumentException ();
+
+ throw new FormatException (s);
+ }
+
+ public static void CheckComment (string s)
+ {
+ if (s == null)
+ throw new ArgumentNullException ();
+
+ var lexer = new Lexer (s);
+
+ string temp;
+ if (!lexer.ScanCommentOptional (out temp)) {
+ if (s.Length == 0)
+ throw new ArgumentException ();
+
+ throw new FormatException (s);
+ }
+ }
}
public static class DateTime
{
public static bool TryParse (string input, out System.Uri result)
{
- throw new NotImplementedException ();
+ return System.Uri.TryCreate ("http://" + input + "/", UriKind.Absolute, out result);
+ }
+
+ public static void Check (string s)
+ {
+ if (s == null)
+ throw new ArgumentNullException ();
+
+ System.Uri uri;
+ if (!TryParse (s, out uri)) {
+ if (s.Length == 0)
+ throw new ArgumentException ();
+
+ throw new FormatException (s);
+ }
}
}
}
public class ProductHeaderValue : ICloneable
{
public ProductHeaderValue (string name)
- : this (name, null)
{
+ Parser.Token.Check (name);
+ Name = name;
}
public ProductHeaderValue (string name, string version)
+ : this (name)
{
- Name = name;
+ if (version != null)
+ Parser.Token.Check (version);
+
Version = version;
}
+ private ProductHeaderValue ()
+ {
+ }
+
public string Name { get; private set; }
public string Version { get; private set; }
public static bool TryParse (string input, out ProductHeaderValue parsedValue)
{
- throw new NotImplementedException ();
+ parsedValue = null;
+
+ var lexer = new Lexer (input);
+ var t = lexer.Scan ();
+ if (t != Token.Type.Token)
+ return false;
+
+ var value = new ProductHeaderValue ();
+ value.Name = lexer.GetStringValue (t);
+
+ t = lexer.Scan ();
+ if (t == Token.Type.SeparatorSlash) {
+ t = lexer.Scan ();
+ if (t != Token.Type.Token)
+ return false;
+
+ value.Version = lexer.GetStringValue (t);
+ t = lexer.Scan ();
+ }
+
+ if (t != Token.Type.End)
+ return false;
+
+ parsedValue = value;
+ return true;
+ }
+
+ public override string ToString ()
+ {
+ return Version == null ? Name : Name + "/" + Version;
}
}
}
{
public ProductInfoHeaderValue (ProductHeaderValue product)
{
+ if (product == null)
+ throw new ArgumentNullException ();
+
Product = product;
}
public ProductInfoHeaderValue (string comment)
{
+ Parser.Token.CheckComment (comment);
Comment = comment;
}
Product = new ProductHeaderValue (productName, productVersion);
}
+ private ProductInfoHeaderValue ()
+ {
+ }
+
public string Comment { get; private set; }
public ProductHeaderValue Product { get; private set; }
public static bool TryParse (string input, out ProductInfoHeaderValue parsedValue)
{
- throw new NotImplementedException ();
+ parsedValue = null;
+
+ var lexer = new Lexer (input);
+ string comment;
+
+ if (lexer.ScanCommentOptional (out comment)) {
+ if (comment == null)
+ return false;
+
+ parsedValue = new ProductInfoHeaderValue ();
+ parsedValue.Comment = comment;
+ return true;
+ }
+
+ ProductHeaderValue res;
+ if (!ProductHeaderValue.TryParse (input, out res))
+ return false;
+
+ parsedValue = new ProductInfoHeaderValue (res);
+ return true;
+ }
+
+ public override string ToString ()
+ {
+ if (Product == null)
+ return Comment;
+
+ return Product.ToString ();
}
}
}
//
using System.Collections.Generic;
+using System.Text;
namespace System.Net.Http.Headers
{
public static bool TryParse (string input, out RangeHeaderValue parsedValue)
{
- throw new NotImplementedException ();
+ parsedValue = null;
+
+ var lexer = new Lexer (input);
+ var t = lexer.Scan ();
+ if (t != Token.Type.Token)
+ return false;
+
+ var value = new RangeHeaderValue ();
+ value.unit = lexer.GetStringValue (t);
+
+ t = lexer.Scan ();
+ if (t != Token.Type.SeparatorEqual)
+ return false;
+
+ bool token_read;
+ do {
+ int? from = null, to = null;
+ int number;
+ token_read = false;
+
+ t = lexer.Scan ();
+ switch (t.Kind) {
+ case Token.Type.SeparatorDash:
+ t = lexer.Scan ();
+ if (!lexer.TryGetNumericValue (t, out number))
+ return false;
+
+ to = number;
+ break;
+ case Token.Type.Token:
+ string s = lexer.GetStringValue (t);
+ var values = s.Split (new [] { '-' }, StringSplitOptions.RemoveEmptyEntries);
+ if (!int.TryParse (values[0], out number))
+ return false;
+
+ switch (values.Length) {
+ case 1:
+ t = lexer.Scan ();
+ switch (t.Kind) {
+ case Token.Type.SeparatorDash:
+ from = number;
+
+ t = lexer.Scan ();
+ if (t != Token.Type.Token) {
+ token_read = true;
+ break;
+ }
+
+ if (!lexer.TryGetNumericValue (t, out number))
+ return false;
+
+ to = number;
+ if (to < from)
+ return false;
+
+ break;
+ default:
+ return false;
+ }
+ break;
+ case 2:
+ from = number;
+
+ if (!int.TryParse (values[1], out number))
+ return false;
+
+ to = number;
+ if (to < from)
+ return false;
+
+ break;
+ default:
+ return false;
+ }
+
+ break;
+ default:
+ return false;
+ }
+
+ value.Ranges.Add (new RangeItemHeaderValue (from, to));
+ if (!token_read)
+ t = lexer.Scan ();
+
+ } while (t == Token.Type.SeparatorComma);
+
+ if (t != Token.Type.End)
+ return false;
+
+ parsedValue = value;
+ return true;
+ }
+
+ public override string ToString ()
+ {
+ var sb = new StringBuilder (unit);
+ sb.Append ("=");
+ for (int i = 0; i < Ranges.Count; ++i) {
+ if (i > 0)
+ sb.Append (", ");
+
+ sb.Append (ranges[i]);
+ }
+
+ return sb.ToString ();
}
}
}
{
public RangeItemHeaderValue (long? from, long? to)
{
+ if (from == null && to == null)
+ throw new ArgumentException ();
+
+ if (from != null && to != null && from > to) {
+ throw new ArgumentOutOfRangeException ("from");
+ }
+
+ if (from < 0)
+ throw new ArgumentOutOfRangeException ("from");
+
+ if (to < 0)
+ throw new ArgumentOutOfRangeException ("to");
+
From = from;
To = to;
}
{
return From.GetHashCode () ^ To.GetHashCode ();
}
+
+ public override string ToString ()
+ {
+ if (From == null)
+ return "-" + To.Value;
+
+ if (To == null)
+ return From.Value + "-";
+
+ return From.Value + "-" + To.Value;
+ }
}
}
{
public ViaHeaderValue (string protocolVersion, string receivedBy)
{
+ Parser.Token.Check (protocolVersion);
+ Parser.Uri.Check (receivedBy);
+
ProtocolVersion = protocolVersion;
ReceivedBy = receivedBy;
}
public ViaHeaderValue (string protocolVersion, string receivedBy, string protocolName)
: this (protocolVersion, receivedBy)
{
- ProtocolName = protocolName;
+ if (!string.IsNullOrEmpty (protocolName)) {
+ Parser.Token.Check (protocolName);
+ ProtocolName = protocolName;
+ }
}
public ViaHeaderValue (string protocolVersion, string receivedBy, string protocolName, string comment)
: this (protocolVersion, receivedBy, protocolName)
{
- Comment = comment;
+ if (!string.IsNullOrEmpty (comment)) {
+ Parser.Token.CheckComment (comment);
+ Comment = comment;
+ }
+ }
+
+ private ViaHeaderValue ()
+ {
}
public string Comment { get; private set; }
public static bool TryParse (string input, out ViaHeaderValue parsedValue)
{
- throw new NotImplementedException ();
+ parsedValue = null;
+
+ var lexer = new Lexer (input);
+
+ var t = lexer.Scan ();
+ if (t != Token.Type.Token)
+ return false;
+
+ var next = lexer.Scan ();
+ ViaHeaderValue value = new ViaHeaderValue ();
+
+ if (next == Token.Type.SeparatorSlash) {
+ next = lexer.Scan ();
+ if (next != Token.Type.Token)
+ return false;
+
+ value.ProtocolName = lexer.GetStringValue (t);
+ value.ProtocolVersion = lexer.GetStringValue (next);
+
+ next = lexer.Scan ();
+ } else {
+ value.ProtocolVersion = lexer.GetStringValue (t);
+ }
+
+ if (next != Token.Type.Token)
+ return false;
+
+ if (lexer.PeekChar () == ':') {
+ lexer.EatChar ();
+
+ t = lexer.Scan ();
+ if (t != Token.Type.Token)
+ return false;
+ } else {
+ t = next;
+ }
+
+ value.ReceivedBy = lexer.GetStringValue (next, t);
+
+ string comment;
+ if (!lexer.ScanCommentOptional (out comment))
+ return false;
+
+ value.Comment = comment;
+ parsedValue = value;
+ return true;
+ }
+
+ public override string ToString ()
+ {
+ string s = ProtocolName != null ?
+ ProtocolName + "/" + ProtocolVersion + " " + ReceivedBy :
+ ProtocolVersion + " " + ReceivedBy;
+
+ return Comment != null ? s + " " + Comment : s;
}
}
}
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
+using System.Globalization;
+
namespace System.Net.Http.Headers
{
public class WarningHeaderValue : ICloneable
{
public WarningHeaderValue (int code, string agent, string text)
{
+ if (!IsCodeValid (code))
+ throw new ArgumentOutOfRangeException ("code");
+
+ Parser.Uri.Check (agent);
+ Parser.Token.CheckQuotedString (text);
+
Code = code;
Agent = agent;
Text = text;
Date = date;
}
+ private WarningHeaderValue ()
+ {
+ }
+
public string Agent { get; private set; }
public int Code { get; private set; }
public DateTimeOffset? Date { get; private set; }
public string Text { get; private set; }
+ static bool IsCodeValid (int code)
+ {
+ return code >= 0 && code < 1000;
+ }
+
object ICloneable.Clone ()
{
return MemberwiseClone ();
public static bool TryParse (string input, out WarningHeaderValue parsedValue)
{
- throw new NotImplementedException ();
+ parsedValue = null;
+
+ var lexer = new Lexer (input);
+ var t = lexer.Scan ();
+
+ if (t != Token.Type.Token)
+ return false;
+
+ int code;
+ if (!lexer.TryGetNumericValue (t, out code) || !IsCodeValid (code))
+ return false;
+
+ t = lexer.Scan ();
+ if (t != Token.Type.Token)
+ return false;
+
+ var next = t;
+ if (lexer.PeekChar () == ':') {
+ lexer.EatChar ();
+
+ next = lexer.Scan ();
+ if (next != Token.Type.Token)
+ return false;
+ }
+
+ var value = new WarningHeaderValue ();
+ value.Code = code;
+ value.Agent = lexer.GetStringValue (t, next);
+
+ t = lexer.Scan ();
+ if (t != Token.Type.QuotedString)
+ return false;
+
+ value.Text = lexer.GetStringValue (t);
+
+ t = lexer.Scan ();
+ if (t == Token.Type.QuotedString) {
+ DateTimeOffset date;
+ if (!lexer.TryGetDateValue (t, out date))
+ return false;
+
+ value.Date = date;
+ t = lexer.Scan ();
+ }
+
+ if (t != Token.Type.End)
+ return false;
+
+ parsedValue = value;
+ return true;
+ }
+
+ public override string ToString ()
+ {
+ string s = Code.ToString ("000") + " " + Agent + " " + Text;
+ if (Date.HasValue)
+ s = s + " \"" + Date.Value.ToString ("r", CultureInfo.InvariantCulture) + "\"";
+
+ return s;
}
}
}
var res = AuthenticationHeaderValue.Parse ("c");
Assert.AreEqual ("c", res.Scheme, "#1");
Assert.IsNull (res.Parameter, "#2");
+ Assert.AreEqual ("c", res.ToString (), "#3");
+
+ res = AuthenticationHeaderValue.Parse ("ss p=3 , q = \"vvv\"");
+
+ Assert.AreEqual ("ss", res.Scheme, "#11");
+ Assert.AreEqual ("p=3 , q = \"vvv\"", res.Parameter, "#12");
+ Assert.AreEqual ("ss p=3 , q = \"vvv\"", res.ToString (), "#13");
}
[Test]
var res = CacheControlHeaderValue.Parse ("audio");
Assert.AreEqual ("audio", res.Extensions.First ().Name, "#1");
Assert.IsNull (res.Extensions.First ().Value, "#2");
+ Assert.AreEqual ("audio", res.ToString (), "#3");
res = CacheControlHeaderValue.Parse (null);
- Assert.IsNull (res, "#3");
+ Assert.IsNull (res, "#4");
+
+ res = CacheControlHeaderValue.Parse ("no-cache, no-store , max-age = 44, max-stale = 66, min-fresh=333 ,no-transform, only-if-cached");
+ Assert.IsTrue (res.NoCache, "#10");
+ Assert.IsTrue (res.NoStore, "#11");
+ Assert.AreEqual (new TimeSpan (0, 0, 44), res.MaxAge, "#12");
+ Assert.IsTrue (res.MaxStale, "#13");
+ Assert.AreEqual (new TimeSpan (0, 1, 6), res.MaxStaleLimit, "#14");
+ Assert.AreEqual (new TimeSpan (0, 5, 33), res.MinFresh, "#15");
+ Assert.IsTrue (res.NoTransform, "#16");
+ Assert.IsTrue (res.OnlyIfCached, "#17");
+ Assert.AreEqual ("no-store, no-transform, only-if-cached, no-cache, max-age=44, max-stale=66, min-fresh=333", res.ToString (), "#18");
+
+ res = CacheControlHeaderValue.Parse ("anu = 333");
+ Assert.AreEqual ("anu", res.Extensions.First ().Name, "#20");
+ Assert.AreEqual ("333", res.Extensions.First ().Value, "#21");
+ Assert.AreEqual ("anu=333", res.ToString (), "#22");
+
+ res = CacheControlHeaderValue.Parse ("public, private = \"nnn \", no-cache =\"mmm\" , must-revalidate, proxy-revalidate, s-maxage=443");
+ Assert.IsTrue (res.Public, "#30");
+ Assert.IsTrue (res.Private, "#31");
+ Assert.AreEqual ("nnn", res.PrivateHeaders.First (), "#32");
+ Assert.IsTrue (res.NoCache, "#33");
+ Assert.AreEqual ("mmm", res.NoCacheHeaders.First (), "#34");
+ Assert.IsTrue (res.MustRevalidate, "#35");
+ Assert.IsTrue (res.ProxyRevalidate, "#36");
+ Assert.AreEqual (new TimeSpan (0, 7, 23), res.SharedMaxAge, "#37");
+ Assert.AreEqual ("public, must-revalidate, proxy-revalidate, no-cache=\"mmm\", s-maxage=443, private=\"nnn\"", res.ToString (), "#38");
+
+ res = CacheControlHeaderValue.Parse ("private = \"nnn , oo, xx\", bb= \" x \"");
+ Assert.IsTrue (res.Private, "#40");
+ Assert.AreEqual (3, res.PrivateHeaders.Count, "#41");
+ Assert.AreEqual ("oo", res.PrivateHeaders.ToList ()[1], "#42");
+ Assert.AreEqual ("\" x \"", res.Extensions.First ().Value, "#43");
+ Assert.AreEqual ("private=\"nnn, oo, xx\", bb=\" x \"", res.ToString (), "#44");
}
[Test]
Assert.Fail ("#1");
} catch (FormatException) {
}
+
+ try {
+ CacheControlHeaderValue.Parse ("max-age=");
+ Assert.Fail ("#2");
+ } catch (FormatException) {
+ }
+
+ try {
+ CacheControlHeaderValue.Parse ("me=");
+ Assert.Fail ("#3");
+ } catch (FormatException) {
+ }
}
[Test]
Assert.Fail ("#2");
} catch (FormatException) {
}
+
+ try {
+ new ProductHeaderValue ("/");
+ Assert.Fail ("#3");
+ } catch (FormatException) {
+ }
+ }
+
+ [Test]
+ public void Ctor ()
+ {
+ new ProductHeaderValue ("aa", null);
}
[Test]
var res = ProductHeaderValue.Parse ("c");
Assert.AreEqual ("c", res.Name, "#1");
Assert.IsNull (res.Version, "#2");
+ Assert.AreEqual ("c", res.ToString (), "#3");
+
+ res = ProductHeaderValue.Parse (" mm / ppp");
+ Assert.AreEqual ("mm", res.Name, "#4");
+ Assert.AreEqual ("ppp", res.Version, "#5");
+ Assert.AreEqual ("mm/ppp", res.ToString (), "#6");
}
[Test]
Assert.Fail ("#3");
} catch (FormatException) {
}
+
+ try {
+ ProductHeaderValue.Parse ("a/");
+ Assert.Fail ("#4");
+ } catch (FormatException) {
+ }
}
[Test]
Assert.AreEqual ("c", res.Product.Name, "#1");
Assert.IsNull (res.Product.Version, "#2");
Assert.IsNull (res.Comment, "#3");
+ Assert.AreEqual ("c", res.ToString (), "#4");
+
+ res = ProductInfoHeaderValue.Parse (" b / 6");
+ Assert.AreEqual ("b", res.Product.Name, "#11");
+ Assert.AreEqual ("6", res.Product.Version, "#12");
+ Assert.IsNull (res.Comment, "#13");
+ Assert.AreEqual ("b/6", res.ToString (), "#14");
+
+ res = ProductInfoHeaderValue.Parse (" ( cccc ) ");
+ Assert.IsNull (res.Product, "#21");
+ Assert.AreEqual ("( cccc )", res.Comment, "#22");
+ Assert.AreEqual ("( cccc )", res.ToString (), "#23");
}
[Test]
Assert.AreEqual ("bytes", res.Unit, "#1");
Assert.AreEqual (2, res.Ranges.First ().From, "#2");
Assert.AreEqual (40, res.Ranges.First ().To, "#3");
+ Assert.AreEqual ("bytes=2-40", res.ToString (), "#4");
+
+ res = RangeHeaderValue.Parse ("d-dd = 2 - ");
+ Assert.AreEqual ("d-dd", res.Unit, "#10");
+ Assert.AreEqual (2, res.Ranges.First ().From, "#11");
+ Assert.IsNull (res.Ranges.First ().To, "#12");
+ Assert.AreEqual ("d-dd=2-", res.ToString (), "#13");
+
+ res = RangeHeaderValue.Parse ("zz = - 6 , 5 - 9, -8");
+ Assert.AreEqual ("zz", res.Unit, "#20");
+ Assert.IsNull (res.Ranges.First ().From, "#21");
+ Assert.AreEqual (6, res.Ranges.First ().To, "#22");
+ Assert.AreEqual (5, res.Ranges.Skip (1).First ().From, "#21b");
+ Assert.AreEqual (9, res.Ranges.Skip (1).First ().To, "#22b");
+ Assert.AreEqual ("zz=-6, 5-9, -8", res.ToString (), "#23");
+
+ res = RangeHeaderValue.Parse ("ddd = 2 -, 1-4");
+ Assert.AreEqual ("ddd", res.Unit, "#30");
+ Assert.AreEqual (2, res.Ranges.First ().From, "#31");
+ Assert.IsNull (res.Ranges.First ().To, "#32");
+ Assert.AreEqual ("ddd=2-, 1-4", res.ToString (), "#33");
}
[Test]
Assert.Fail ("#4");
} catch (FormatException) {
}
+
+ try {
+ RangeHeaderValue.Parse ("byte=1");
+ Assert.Fail ("#5");
+ } catch (FormatException) {
+ }
+
+ try {
+ RangeHeaderValue.Parse ("byte=10-6");
+ Assert.Fail ("#6");
+ } catch (FormatException) {
+ }
}
[Test]
Assert.Fail ("#2");
} catch (ArgumentOutOfRangeException) {
}
+
+ try {
+ new RangeItemHeaderValue (-1, 2);
+ Assert.Fail ("#3");
+ } catch (ArgumentOutOfRangeException) {
+ }
}
[Test]
public void Ctor ()
{
- new RangeItemHeaderValue (1, null);
+ var v = new RangeItemHeaderValue (1, null);
+ Assert.AreEqual ("1-", v.ToString (), "#1");
+
+ v = new RangeItemHeaderValue (null, 1);
+ Assert.AreEqual ("-1", v.ToString (), "#2");
}
[Test]
try {
new StringWithQualityHeaderValue ("s", 1.1);
- Assert.Fail ("#2");
+ Assert.Fail ("#3");
} catch (ArgumentOutOfRangeException) {
}
}
Assert.AreEqual (value, new StringWithQualityHeaderValue ("ab"), "#1");
Assert.AreEqual (value, new StringWithQualityHeaderValue ("AB"), "#2");
Assert.AreNotEqual (value, new StringWithQualityHeaderValue ("AA"), "#3");
+ Assert.AreEqual ("ab", value.ToString (), "#33");
value = new StringWithQualityHeaderValue ("ab", 1);
Assert.AreEqual (value, new StringWithQualityHeaderValue ("Ab", 1), "#4");
try {
new ViaHeaderValue ("a", null);
- Assert.Fail ("#1");
+ Assert.Fail ("#3");
} catch (ArgumentException) {
}
+
+ try {
+ new ViaHeaderValue ("a", "b", "::");
+ Assert.Fail ("#4");
+ } catch (FormatException) {
+ }
+
+ try {
+ new ViaHeaderValue ("a", "b", null, "(aaa");
+ Assert.Fail ("#5");
+ } catch (FormatException) {
+ }
}
[Test]
Assert.IsNull (res.ProtocolName, "#1");
Assert.AreEqual ("nowhere.com", res.ReceivedBy, "#2");
Assert.AreEqual ("1.1", res.ProtocolVersion, "#3");
+ Assert.AreEqual ("1.1 nowhere.com", res.ToString (), "#4");
+
+ res = ViaHeaderValue.Parse ("foo / 1.1 nowhere.com:43 ( lalala ) ");
+ Assert.AreEqual ("foo", res.ProtocolName, "#10");
+ Assert.AreEqual ("1.1", res.ProtocolVersion, "#11");
+ Assert.AreEqual ("nowhere.com:43", res.ReceivedBy, "#12");
+ Assert.AreEqual ("( lalala )", res.Comment, "#13");
+ Assert.AreEqual ("foo/1.1 nowhere.com:43 ( lalala )", res.ToString (), "#14");
}
[Test]
}
try {
- ViaHeaderValue.Parse ("a;b");
+ ViaHeaderValue.Parse ("a");
Assert.Fail ("#3");
} catch (FormatException) {
}
+
+ try {
+ ViaHeaderValue.Parse ("1 nowhere.com :43");
+ Assert.Fail ("#4");
+ } catch (FormatException) {
+ }
}
[Test]
Assert.AreEqual (1, res.Code, "#2");
Assert.AreEqual ("n", res.Agent, "#3");
Assert.AreEqual ("\"\"", res.Text, "#4");
+ Assert.AreEqual ("001 n \"\"", res.ToString (), "#5");
+
+ res = WarningHeaderValue.Parse ("155 foo:8080 \"tttext \" \"Sun, 06 Nov 1994 08:49:37 GMT\" ");
+ Assert.AreEqual (res.Date, new DateTimeOffset (1994, 11, 6, 8, 49, 37, TimeSpan.Zero), "#11");
+ Assert.AreEqual (155, res.Code, "#12");
+ Assert.AreEqual ("foo:8080", res.Agent, "#13");
+ Assert.AreEqual ("\"tttext \"", res.Text, "#14");
+ Assert.AreEqual ("155 foo:8080 \"tttext \" \"Sun, 06 Nov 1994 08:49:37 GMT\"", res.ToString (), "#5");
}
[Test]
Assert.Fail ("#3");
} catch (FormatException) {
}
+
+ try {
+ WarningHeaderValue.Parse ("5555 foo:8080 \"\"");
+ Assert.Fail ("#4");
+ } catch (FormatException) {
+ }
}