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

scalaz.http.request.RequestHeader.scala Maven / Gradle / Ivy

The newest version!
package scalaz
package http
package request

/**
 * HTTP request headers.
 * RFC 2616 Section 14 Header Field Definitions.
 *
 * @author Tony Morris
 */
sealed trait RequestHeader {
  /**
   * A string representation of this request header.
   */
  val asString: String

  /**
   * Returns true if this header is an entity header,
   * false otherwise.
   */
  lazy val isEntity = this match {
    case Entity(_) => true
    case _ => false
  }

  /**
   * Returns true if this header is a general header,
   * false otherwise.
   */
  lazy val isGeneral = this match {
    case General(_) => true
    case _ => false
  }

  /**
   * Returns the result of the given function to this header if it is an
   * entity header, otherwise returns the given value.
   */
  def entity[X](f: EntityHeader => X, x: => X) = this match {
    case Entity(h) => f(h)
    case _ => x
  }

  /**
   * Returns the result of the given function to this header if it is a
   * general header, otherwise returns the given value.
   */
  def general[X](f: GeneralHeader => X, x: => X) = this match {
    case General(h) => f(h)
    case _ => x
  }
}

/**
 * §
 */
final case object Accept extends RequestHeader {
  override val asString = toString
}

/**
 * §
 */
final case object AcceptCharset extends RequestHeader {
  override val asString = "Accept-Charset"
}

/**
 * §
 */
final case object AcceptEncoding extends RequestHeader {
  override val asString = "Accept-Encoding"
}

/**
 * §
 */
final case object AcceptLanguage extends RequestHeader {
  override val asString = "Accept-Language"
}

/**
 * §
 */
final case object Authorization extends RequestHeader {
  override val asString = toString
}

/**
 * §
 */
final case object Expect extends RequestHeader {
  override val asString = toString
}

/**
 * §
 */
final case object From extends RequestHeader {
  override val asString = toString
}

/**
 * §
 */
final case object Host extends RequestHeader {
  override val asString = toString
}

/**
 * §
 */
final case object IfMatch extends RequestHeader {
  override val asString = "If-Match"
}

/**
 * §
 */
final case object IfModifiedSince extends RequestHeader {
  override val asString = "If-Modified-Since"
}

/**
 * §
 */
final case object IfNoneMatch extends RequestHeader {
  override val asString = "If-None-Match"
}

/**
 * §
 */
final case object IfRange extends RequestHeader {
  override val asString = "If-Range"
}

/**
 * §
 */
final case object IfUnmodifiedSince extends RequestHeader {
  override val asString = "If-Unmodified-Since"
}

/**
 * §
 */
final case object MaxForwards extends RequestHeader {
  override val asString = "Max-Forwards"
}

/**
 * §
 */
final case object ProxyAuthorization extends RequestHeader {
  override val asString = "Proxy-Authorization"
}

/**
 * §
 */
final case object Range extends RequestHeader {
  override val asString = toString
}

/**
 * §
 */
final case object Referer extends RequestHeader {
  override val asString = toString
}

/**
 * §
 */
final case object TE extends RequestHeader {
  override val asString = toString
}

/**
 * §
 */
final case object UserAgent extends RequestHeader {
  override val asString = "User-Agent"
}
private final case class Entity(eh: EntityHeader) extends RequestHeader {
  override val asString = eh.asString
}
private final case class General(gh: GeneralHeader) extends RequestHeader {
  override val asString = gh.asString
}

import Character.isWhitespace
import Scalaz._
import Util.Nel._

trait RequestHeaders {
  /**
   * Converts the given entity header into a request header.
   */
  implicit def entityToRequest(eh: EntityHeader): RequestHeader = scalaz.http.request.Entity(eh)

  /**
   * Converts the given general header into a request header.
   */
  implicit def generalToRequest(gh: GeneralHeader): RequestHeader = scalaz.http.request.General(gh)

  /**
   * Converts the given string to a request header. If the string is a known request header, then it is used. If not,
   * then it if it is a known general header, then it is used. If not then it is an entity header.
   */
  implicit def StringRequestHeader(s: String): Option[RequestHeader] =
    RequestHeader.headers find {case (n, h) => n.equalsIgnoreCase(s) } map (_._2) orElse
            (s: Option[GeneralHeader]) ∘ (scalaz.http.request.General(_)) orElse
            (s: Option[EntityHeader]) ∘ (scalaz.http.request.Entity(_))

  /**
   * Converts the given list of characters to a request header. If the string is a known request header, then it is
   * used. If not, then it if it is a known general header, then it is used. If not then it is an entity header.
   */
  implicit def ListRequestHeader: (List[Char] => Option[RequestHeader]) = StringRequestHeader _ compose (_.mkString)
}

/**
 * HTTP request headers.
 * RFC 2616 Section 14 Header Field Definitions.
 */
object RequestHeader extends RequestHeaders {
  /**
   * For deconstructing request headers into entity headers.
   */
  object Entity {
    /**
     * Matches if the given request header is an entity header.
     */
    def unapply(h: RequestHeader) = h match {
      case scalaz.http.request.Entity(x) => Some(x)
      case _ => None
    }
  }

  /**
   * For deconstructing request headers into general headers.
   */
  object General {
    /**
     * Matches if the given request header is a general header.
     */
    def unapply(h: RequestHeader) = h match {
      case scalaz.http.request.General(x) => Some(x)
      case _ => None
    }
  }

  import GeneralHeader.StringGeneralHeader
  import EntityHeader.StringEntityHeader

  /**
   * A list of known headers.
   */
  val headers = List(("accept", Accept),
    ("accept-charset", AcceptCharset),
    ("accept-encoding", AcceptEncoding),
    ("accept-language", AcceptLanguage),
    ("authorization", Authorization),
    ("from", From),
    ("host", Host),
    ("if-match", IfMatch),
    ("if-modified-since", IfModifiedSince),
    ("if-none-match", IfNoneMatch),
    ("if-range", IfRange),
    ("if-unmodified-since", IfUnmodifiedSince),
    ("max-forwards", MaxForwards),
    ("proxy-authorization", ProxyAuthorization),
    ("range", Range),
    ("referer", Referer),
    ("te", TE),
    ("user-agent", UserAgent))

  /**
   * Converts a list of characters of the form "abc:def" into a potential request header and non-empty value split at
   * the colon (:).
   */
  def requestHeaderValue(cs: List[Char]): Option[(RequestHeader, NonEmptyList[Char])] =
    cs span (_ != ':') match {
      case (n, v) => {
        (n: Option[RequestHeader]) ∗ (h =>
          (v.dropWhile(x => x == ':' || isWhitespace(x))).toNel map (v => (h, v)))
      }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy