All Downloads are FREE. Search and download functionalities are using the official Maven repository.

sttp.client3.internal.WwwAuthHeaderParser.scala Maven / Gradle / Ivy

The newest version!
package sttp.client3.internal

object WwwAuthHeaderParser {
  def parse(text: String): WwwAuthHeaderValue = {
    WwwAuthHeaderValue(
      text
        .foldLeft(KeyParser(Map.empty): Parser) { (parser, char) => parser.parseNext(char) }
        .close()
    )
  }
}

case class WwwAuthHeaderValue(values: Map[String, String]) {
  val qop = values.get("qop")
  val realm = values.get("realm")
  val nonce = values.get("nonce")
  val algorithm = values.get("algorithm")
  val isStale = values.get("stale").map(_.equalsIgnoreCase("true"))
  val opaque = values.get("opaque")
}

private case class KeyParser private (currentKey: String, parsed: Map[String, String]) extends Parser {
  override def parseNext(input: Char): Parser = {
    if (input == '=') {
      ValueParser(currentKey, parsed)
    } else if (input == ' ') {
      KeyParser("", parsed)
    } else {
      this.copy(currentKey = currentKey + input)
    }
  }

  override def close(): Map[String, String] = throw new IllegalStateException(this.toString)
}

private object KeyParser {
  def apply(parsed: Map[String, String]) = new KeyParser("", parsed)
}

private case class ValueParser private (
    currentKey: String,
    currentValue: String,
    parsed: Map[String, String]
) extends Parser {
  override def parseNext(input: Char): Parser = {
    if (input == '"') {
      QuotedValueParser(currentKey, parsed)
    } else {
      UnquotedValueParser(currentKey, input.toString, parsed)
    }
  }

  override def close(): Map[String, String] = throw new IllegalStateException(this.toString)
}

private object ValueParser {
  def apply(key: String, parsed: Map[String, String]) = new ValueParser(key, "", parsed)
}

private case class QuotedValueParser private (
    currentKey: String,
    currentValue: String,
    parsed: Map[String, String]
) extends Parser {
  override def parseNext(input: Char): Parser = {
    if (input == '"') {
      UnquotedValueParser(currentKey, currentValue, parsed)
    } else {
      this.copy(currentValue = currentValue + input)
    }
  }
  override def close(): Map[String, String] = throw new IllegalStateException(this.toString)
}

private object QuotedValueParser {
  def apply(key: String, parsed: Map[String, String]) = new QuotedValueParser(key, "", parsed)
}

private case class UnquotedValueParser(
    currentKey: String,
    currentValue: String,
    parsed: Map[String, String]
) extends Parser {
  override def parseNext(input: Char): Parser = {
    if (input == ',') {
      SeparatorParser(parsed + (currentKey -> currentValue)).parseNext(input)
    } else {
      this.copy(currentValue = currentValue + input)
    }
  }
  override def close(): Map[String, String] = parsed + (currentKey -> currentValue)
}

private case class SeparatorParser(parsed: Map[String, String]) extends Parser {
  override def parseNext(input: Char): Parser = {
    input match {
      case ',' => this
      case ' ' => KeyParser(parsed)
      case o   => KeyParser(parsed).parseNext(o)
    }
  }

  override def close(): Map[String, String] = parsed
}

private trait Parser {
  def parseNext(input: Char): Parser

  def close(): Map[String, String]
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy