/
HttpVersion.scala
51 lines (44 loc) · 2.17 KB
/
HttpVersion.scala
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
package org.http4s
import cats._
import cats.data.{Writer => _, _}
import cats.implicits._
import org.http4s.parser._
import org.http4s.util._
import org.http4s.internal.parboiled2._
/**
* An HTTP version, as seen on the start line of an HTTP request or response.
*
* @see [http://tools.ietf.org/html/rfc7230#section-2.6 RFC 7320, Section 2.6
*/
final case class HttpVersion private[HttpVersion] (major: Int, minor: Int) extends Renderable with Ordered[HttpVersion] {
override def render(writer: Writer): writer.type = writer << "HTTP/" << major << '.' << minor
override def compare(that: HttpVersion): Int = (this.major, this.minor) compare ((that.major, that.minor))
}
object HttpVersion extends HttpVersionInstances {
val `HTTP/1.0` = new HttpVersion(1, 0)
val `HTTP/1.1` = new HttpVersion(1, 1)
val `HTTP/2.0` = new HttpVersion(2, 0)
def fromString(s: String): ParseResult[HttpVersion] = s match {
case "HTTP/1.1" => Either.right(`HTTP/1.1`)
case "HTTP/1.0" => Either.right(`HTTP/1.0`)
case other => new Parser(s).HttpVersion.run()(Parser.DeliveryScheme.Either).leftMap { _ =>
ParseFailure("Invalid HTTP version", s"$s was not found to be a valid HTTP version")
}
}
private class Parser(val input: ParserInput) extends org.http4s.internal.parboiled2.Parser with Rfc2616BasicRules {
def HttpVersion: Rule1[org.http4s.HttpVersion] = rule {
"HTTP/" ~ capture(Digit) ~ "." ~ capture(Digit) ~> { (major: String, minor: String) => new HttpVersion(major.toInt, minor.toInt) }
}
}
def fromVersion(major: Int, minor: Int): ParseResult[HttpVersion] = {
if (major < 0) ParseResult.fail("Invalid HTTP version", s"major must be > 0: $major")
else if (major > 9) ParseResult.fail("Invalid HTTP version", s"major must be <= 9: $major")
else if (minor < 0) ParseResult.fail("Invalid HTTP version", s"major must be > 0: $minor")
else if (minor > 9) ParseResult.fail("Invalid HTTP version", s"major must be <= 9: $minor")
else ParseResult.success(new HttpVersion(major, minor))
}
}
trait HttpVersionInstances {
implicit val HttpVersionShow = Show.fromToString[HttpVersion]
implicit val HttpVersionOrder = Order.fromOrdering[HttpVersion]
}