// emitToken emits the token value from <name>=<value> func emitToken(l *lexrec.Lexer, t lexrec.ItemType) { if !l.Accept("=") { l.Errorf("emitToken expected '=' after '%s', got %q'", itemName(t), l.Peek()) return } l.Skip() if !l.ExceptRun(nontoken) { l.Errorf("emitToken expected a token character, got %q", l.Peek()) return } l.Emit(t) }
// emitBoolToken emits the token value from <name>=<value>, where the // value is either "true" or "false" (case insensitive) func emitBoolToken(l *lexrec.Lexer, t lexrec.ItemType) { if !l.Accept("=") { l.Errorf("emitBoolToken: expected '=' after '%s', got %q'", itemName(t), l.Peek()) return } l.Skip() if !l.ExceptRun(nontoken) { l.Errorf("emitBoolToken: expected a token character, got %q", l.Peek()) return } s := strings.ToLower(string(l.Bytes())) if s == "true" || s == "false" { l.Emit(t) return } else { l.Errorf("emitBoolToken: expected token to be 'true' or 'false', got %q", s) } }
// emitWWWAuthenticate drives a lexer to parse an RFC 2617 // Basic or Digest authentication challenge // // The specification defines a Basic authentication challenge as: // // challenge = "Basic" realm // // realm = "realm" "=" realm-value // realm-value = quoted-string // // The specification defines a Digest authentication challenge as: // // challenge = "Digest" digest-challenge // // digest-challenge = 1#( realm | [ domain ] | nonce | [ opaque ] |[ stale ] // | [ algorithm ] | [ qop-options ] | [auth-param] ) // // The BNF for these constructs: // // domain = "domain" "=" <"> URI ( 1*SP URI ) <"> // URI = absoluteURI | abs_path // nonce = "nonce" "=" nonce-value // nonce-value = quoted-string // opaque = "opaque" "=" quoted-string // stale = "stale" "=" ( "true" | "false" ) // algorithm = "algorithm" "=" ( "MD5" | "MD5-sess" | token ) // qop-options = "qop" "=" <"> 1#qop-value <"> // qop-value = "auth" | "auth-int" | token // auth-param = token "=" ( token | quoted-string ) // // token = 1*<any CHAR except CTLs or separators> // separators = "(" | ")" | "<" | ">" | "@" // | "," | ";" | ":" | "\" | <"> // | "/" | "[" | "]" | "?" | "=" // | "{" | "}" | SP | HT // // quoted-string = ( <"> *(qdtext | quoted-pair ) <"> ) // qdtext = <any TEXT except <">> // quoted-pair = "\" CHAR // // An example challenge: // // Digest realm="Sample Digest Realm", // nonce="nWjG15v1BAA=744a97693b14ea8805cadf32fcc3f57f245d08eb", // algorithm=MD5, domain="/", qop="auth" // func emitWWWAuthenticate(l *lexrec.Lexer) { defer l.Emit(lexrec.ItemEOF) if l.Peek() == lexrec.EOF { l.Errorf("emitWWWAuthenticate: expected token character, got EOF") return } if l.AcceptRun(whitespace) { l.Skip() } if !l.ExceptRun(nontoken) { l.Errorf("emitWWWAuthenticate: expected token character, got %q", l.Peek()) return } for { if l.Peek() == lexrec.EOF { return } switch strings.ToLower(string(l.Bytes())) { case "basic": l.Emit(ItemBasic) if l.AcceptRun(whitespace) { l.Skip() } else { l.Errorf("expected whitespace after 'Basic', got %q", l.Peek()) return } emitBasicParams(l) case "digest": l.Emit(ItemDigest) if l.AcceptRun(whitespace) { l.Skip() } else { l.Errorf("expected whitespace after 'Digest', got %q", l.Peek()) return } emitDigestParams(l) default: advanceChallenge(l) } } }