Skip to content

Instantly share code, notes, and snippets.

What would you like to do?
Parsing HTTP authentication challenge with Sprache
void Main()
ParseAndPrintChallenge(@"Bearer realm=""FooCorp"", error=invalid_token, error_description=""The access token has expired""");
void ParseAndPrintChallenge(string input)
var challenge = Grammar.Challenge.Parse(input);
Console.WriteLine($"Scheme: {challenge.Scheme}");
foreach (var p in challenge.Parameters)
Console.WriteLine($"- {p.Name} = {p.Value}");
static class Grammar
private static readonly Parser<char> DoubleQuote = Parse.Char('"');
private static readonly Parser<char> EqualSign = Parse.Char('=');
private static readonly Parser<char> Backslash = Parse.Char('\\');
private static readonly Parser<char> Comma = Parse.Char(',');
private static readonly Parser<char> SeparatorChar =
Parse.Chars("()<>@,;:\\\"/[]?={} \t");
private static readonly Parser<char> ControlChar =
Parse.Char(Char.IsControl, "Control character");
private static readonly Parser<char> TokenChar =
private static readonly Parser<string> Token =
private static readonly Parser<char> QdText =
private static readonly Parser<char> QuotedPair =
from _ in Backslash
from c in Parse.AnyChar
select c;
private static readonly Parser<string> QuotedString =
from open in DoubleQuote
from text in QuotedPair.Or(QdText).Many().Text()
from close in DoubleQuote
select text;
private static readonly Parser<string> ParameterValue =
private static readonly Parser<Parameter> Parameter =
from name in Token
from _ in EqualSign
from value in ParameterValue
select new Parameter(name, value);
private static readonly Parser<char> ListDelimiter =
from leading in Parse.WhiteSpace.Many()
from c in Comma
from trailing in Parse.WhiteSpace.Or(Comma).Many()
select c;
private static readonly Parser<Parameter[]> Parameters =
from p in Parameter.DelimitedBy(ListDelimiter)
select p.ToArray();
public static readonly Parser<Challenge> Challenge =
from scheme in Token
from _ in Parse.WhiteSpace.AtLeastOnce()
from parameters in Parameters
select new Challenge(scheme, parameters);
class Parameter
public Parameter(string name, string value)
Name = name;
Value = value;
public string Name { get; }
public string Value { get; }
class Challenge
public Challenge(string scheme, Parameter[] parameters)
Scheme = scheme;
Parameters = parameters;
public string Scheme { get; }
public Parameter[] Parameters { get; }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment