Package

lol

http

Permalink

package http

The core module for lolhttp.

Server.listen(8888) { request =>
  Ok("Hello world!")
}

Client.run(Get("http://localhost:8888/")) { response =>
  response.readAs[String]
}

Provides an HTTP Client and an HTTP Server. Both client and server are Service functions. A service function takes a Request and eventually returns a Response. Requests and responses are shared between the client and the server API, making it easy to assemble them. Both are seen as a set of HTTP headers, and a Content body.

The content fs2.Stream is based on fs2 and can be lazily consumed if needed. It can be encoded and decoded using the appropriate ContentEncoder and ContentDecoder.

SSL is supported on both sides.

Linear Supertypes
AnyRef, Any
Ordering
  1. Alphabetic
  2. By Inheritance
Inherited
  1. http
  2. AnyRef
  3. Any
  1. Hide All
  2. Show All
Visibility
  1. Public
  2. All

Type Members

  1. case class ClasspathResource(path: String) extends Product with Serializable

    Permalink

    A resource than can be read from the classpath.

    A resource than can be read from the classpath.

    Ok(ClasspathResource("/public/index.html"))

    A common use case is to serve static resources (html, js, images files) from the classpath. ClasspathResource values can be directly encoded as Content and used to feed an HTTP response.

    Trying to write a missing resource on an HTTP response will close the connection.

    Also, this provide a basic security by requiring the path to be asbolutely defined. No directory navigation is allowed. For example ClasspathResource("/public/../public/index.html") will resolve to a missing resource.

  2. trait Client extends Service

    Permalink

    An HTTP client.

    An HTTP client.

    val eventuallyContent = client(Get("/hello")).flatMap { response =>
      response.readAs[String]
    }

    An HTTP client is a Service function. It handles HTTP requests and eventually returns HTTP responses.

    A client maintains several TCP connections to the remote server. These connections are used to send requests and are blocked until the corresponding response has been received. If no connection is available when a new request comes, it waits for one connection to become available.

    It is important that the user code completly consumes the response content stream, so the connection is freed for the next request. That's why it is better to use the run operation if possible since this one automatically drains the request upon return.

    If the request to execute does not specify an Host header, it will be automatically added and set to the value of the client host.

  3. case class Content(stream: Stream[IO, Byte], headers: Map[HttpString, HttpString] = Map.empty) extends Product with Serializable

    Permalink

    An HTTP message content body.

    An HTTP message content body.

    It is used to represent the content body for both HTTP requests & responses. It is composed of a lazy stream of byte that can be consumed if needed, and a set of content-related HTTP headers (such as Content-Length, Content-Type, etc.).

    The provided stream is not pure and can only be consumed once.

    stream

    an fs2.Stream of Byte.

    headers

    a set of content-related HTTP headers.

  4. trait ContentDecoder[+A] extends AnyRef

    Permalink

    An HTTP content decoder.

    An HTTP content decoder.

    val textContent: Content = ???
    val textDecoder: ContentDecoder[String] = ContentDecoder.text(maxSize = 1024, defaultCodec = Codec.UTF8)
    val text: String = textDecoder(textContent).unsafeRun()

    A content decoder is able to parse an HTTP content into a scala value of type A. It will look at the content HTTP headers if needed, and consume the content stream bytes to eventually output a scala value.

  5. trait ContentEncoder[-A] extends AnyRef

    Permalink

    A HTTP content encoder.

    A HTTP content encoder.

    val text = "Hello, world"
    val textEncoder: ContentEncoder[String] = ContentEncoder.text(codec = Codec.UTF8)
    val textContent: Content = textEncoder(text)

    A content decoder is able to encode a scala value into an HTTP content . It will produce both a stream of bytes and the set of required HTTP headers like Content-Length or Content-Type.

  6. case class Error(code: Int, msg: String) extends RuntimeException with Product with Serializable

    Permalink

    Expected errors.

    Expected errors.

    See the companion object for all defined errors.

    code

    the error code.

    msg

    the error message.

  7. class HttpMethod extends AnyRef

    Permalink

    An HTTP method such as GET or POST.

  8. case class HttpString(str: String) extends Ordered[HttpString] with Product with Serializable

    Permalink

    An case insensitive string.

    An case insensitive string.

    val contentType: HttpString = h"text/plain"

    HTTP strings are case insensitive. The h string interpolation allows to create HttpString easily.

    str

    the underlying string.

  9. implicit class LiteralHttpString extends AnyRef

    Permalink

    The h interpolation creates HttpString values.

    The h interpolation creates HttpString values. You can use it as a matcher too.

    val header = h"LOCATION"
    header match {
      case h"Location" => println("this is the Location header")
      case _ => println("wrong header")
    }
  10. case class Panic(msg: String) extends RuntimeException with Product with Serializable

    Permalink

    Panics are errors that should not occur or should not be handled.

    Panics are errors that should not occur or should not be handled.

    msg

    the error message.

  11. type PartialService = PartialFunction[Request, IO[Response]]

    Permalink

    A partial service is not defined for all Request.

  12. case class Request(method: HttpMethod, url: String = "/", scheme: String = "http", content: Content = Content.empty, headers: Map[HttpString, HttpString] = Map.empty, protocol: String = HTTP, from: Option[InetAddress] = None) extends Product with Serializable

    Permalink

    An HTTP request.

    An HTTP request.

    Represent all the data available in the HTTP request headers, and the request content that can be consumed lazily if needed.

    method

    the HTTP method such as GET or POST.

    url

    the resource URL.

    scheme

    the scheme such as http or https.

    content

    the request content.

    headers

    the HTTP headers.

    protocol

    the protocol version.

  13. case class Response(status: Int, content: Content = Content.empty, headers: Map[HttpString, HttpString] = Map.empty) extends Product with Serializable

    Permalink

    An HTTP response.

    An HTTP response.

    Represent all the data available in the HTTP response headers, and the response content that can be consumed lazily if needed.

    status

    the HTTP response code such as 200 or 404.

    content

    the response content.

    headers

    the HTTP headers.

  14. trait Server extends Service

    Permalink

    An HTTP server.

    An HTTP server.

    val eventuallyContent = server(Get("/hello")).flatMap { response =>
      response.readAs[String]
    }

    An HTTP server is a service function. It handles HTTP requests and eventually returns HTTP responses.

    The server listen for HTTP connections on the socketAddress TCP socket. If ssl is defined, it supports TLS connections. Calling the stop operation asks for a graceful shutdown.

  15. type Service = (Request) ⇒ IO[Response]

    Permalink

    A service is a function from Request to eventually a Response.

  16. implicit class UrlMatcher extends AnyRef

    Permalink

    The url interpolation is mainly useful in pattern matching to match and extract dynamic parameters in URL templates.

    The url interpolation is mainly useful in pattern matching to match and extract dynamic parameters in URL templates. You can use it to build URL string too, but in this case it acts as the standard s interpolation.

    val userProfile = url"/users/$userId"
    userProfile match {
      case url"/users/$userId" => println("user id" -> userId)
      case url"/images/$image..." => println("image path" -> image)
      case url"/search?keyword=$keyword&sort=$sort" => println("keyword" -> keyword)
      case _ => println("wrong url")
    }

    The matcher allow to extract dynamic parts from both the URL path and queryString. For the path only a fragment or a fragment part can be extracted (no / will be matched):

    url"/users/$id/items" = "/users/12/items" // will match with id="12"
    url"/users/id-$id/items" = "/users/id-12/items" // will match with id="12"

    If you want to capture several fragments, you can use the ... syntax:

    url"/files/$file..." = "/files/images/lol.png" // will match with file="images/lol.png"

    You can also match and extract from the queryString. The parameter order is not important and parameters not specified in the pattern will be ignored:

    url"/?page=$page&sort=$sort" = "/?sort=asc&page=3&offset=2" // will match with page="3", sort="asc"
    url"/?section=home" = "/?section=home&update=now" // will match
    url"/?section=home&update=$date" = "/?section=contact&update=now" // won't match

Value Members

  1. lazy val BadRequest: Response

    Permalink

    A 400 Bad request Response.

  2. object ClasspathResource extends Serializable

    Permalink

    Define the implicit encoder for ClasspathResource.

  3. object Client

    Permalink

    Build HTTP clients.

    Build HTTP clients.

    val client = Client("github.com")
    val fetchGithubHomePage: IO[String] =
      for {
        homePage <- client.run(Get("/"))(_.readAs[String])
        _ <- client.stop()
      } yield (homePage)
    println(fetchGithubHomePage.unsafeRunSync)

    Once created an HTTP client maintains several TCP connections to the remote server, and can be reused to run several requests. It is better to create a dedicated client this way if you plan to send many requests to the same server.

    However there are some situations where you have a single request to run, or you have a batch of requests to send over an unknown set of servers. In this case you can use the run operation that automatically create a temporary HTTP client to run the request and trash it after the exchange completion.

    val homePage = Client.run(Get("http://github.com/"))(_.readAs[String])

    Note that in this case, for each request, a new client (including the whole IO infrastructure) will to be created, and a new TCP connection will be opened to the server.

  4. object Content extends Serializable

    Permalink

    Build HTTP message content body.

    Build HTTP message content body.

    val textContent: Content = Content.of("Hello world!")

    Given an existing ContentDecoder for a type A, this object allows to create HTTP content from A values. Meaning, it will encode the value into a stream of bytes, and a set of appropriate HTTP headers.

  5. object ContentDecoder

    Permalink

    Library of built-in content decoders.

    Library of built-in content decoders.

    This provides content decoder functions for the common scala types, and implicit decoder configured with a set of sensible default.

    The implicitly provided decoders are chosen by the compiler and cannot be explicitly configured. In particular they are automatically configured with a MaxSize limit that specify the maximum amount of bytes they are authorized to read in memory.

    It means that for example, this code:

    val str: String = request.readAs[String]

    will truncate the content body if it is bigger than the MaxSize property. The default for MaxSize is 1MB, and can be configured globally via the lol.http.ContentDecoder.maxSizeInMemory system property.

    If you want to configure the content decoder to allow it to read more data despite the maximum set in MaxSize, you can just pass the content decoder yourself instead of relying on implicit resolution:

    val str: String = request.readAs(text(maxSize = 10 * 1024 * 1024))
  6. object ContentEncoder

    Permalink

    Library of built-in content encoders.

    Library of built-in content encoders.

    This provides content encoder functions for the common scala types, and implicit encoder configured with a set of sensible default.

    The implicitly provided encoders are chosen by the compiler and cannot be explicitly configured.

    For example, this code:

    val response = Ok("Hello, world!")

    will generate an HTTP response body by encoding the provided string using the UTF-8 charset.

    If you want to configure the content encoder, you can just pass it yourself instead of relying on implicit resolution:

    val response = Ok("Hello, world!")(text(codec = Codec("us-ascii")))
  7. lazy val Created: Response

    Permalink

    A 201 Created Response.

  8. val DELETE: HttpMethod

    Permalink

    DELETE HTTP method.

  9. def Delete(url: String): Request

    Permalink

    Constructs a DELETE Request.

    Constructs a DELETE Request.

    url

    the request URL.

    returns

    a Request value.

  10. object Error extends Serializable

    Permalink

    All expected errors.

  11. val GET: HttpMethod

    Permalink

    GET HTTP method.

  12. def Get(url: String): Request

    Permalink

    Constructs a GET Request.

    Constructs a GET Request.

    url

    the request URL.

    returns

    a Request value.

  13. val HEAD: HttpMethod

    Permalink

    HEAD HTTP method.

  14. val HTTP: String

    Permalink

    Protocol version for HTTP/1.1

  15. val HTTP2: String

    Permalink

    Protocol version for HTTP/2

  16. def Head(url: String): Request

    Permalink

    Constructs a HEAD Request.

    Constructs a HEAD Request.

    url

    the request URL.

    returns

    a Request value.

  17. object Headers

    Permalink

    A collection of HTTP header names.

  18. object HttpMethod

    Permalink

    HTTP method matcher.

    HTTP method matcher.

    request.method match {
      case GET => println("This is a get")
      case _ => println("Oops")
    }

    Allow to match HTTP methods.

  19. object HttpString extends Serializable

    Permalink

    HttpString builders.

  20. lazy val InternalServerError: Response

    Permalink

    A 500 Internal server error Response.

  21. lazy val NotFound: Response

    Permalink

    A 404 Not found Response.

  22. lazy val Ok: Response

    Permalink

    A 200 Ok Response.

  23. val POST: HttpMethod

    Permalink

    POST HTTP method.

  24. val PUT: HttpMethod

    Permalink

    PUT HTTP method.

  25. object Panic extends Serializable

    Permalink

    Allows to panic.

  26. def Post[A](url: String, content: A)(implicit encoder: ContentEncoder[A]): Request

    Permalink

    Constructs a POST Request.

    Constructs a POST Request.

    url

    the request URL.

    content

    the request content body.

    encoder

    the content encoder to use.

    returns

    a Request value.

  27. def Put[A](url: String, content: A)(implicit encoder: ContentEncoder[A]): Request

    Permalink

    Constructs a PUT Request.

    Constructs a PUT Request.

    url

    the request URL.

    content

    the request content body.

    encoder

    the content encoder to use.

    returns

    a Request value.

  28. def Redirect(url: String, code: Int = 307): Response

    Permalink

    Create 30x HTTP redirects.

    Create 30x HTTP redirects.

    url

    will be used as Location header value.

    code

    the actual status code to use (default to 307).

    returns

    a 30x Response.

  29. object SSL

    Permalink

    lol SSL.

  30. object Server

    Permalink

    Build and start HTTP servers.

    Build and start HTTP servers.

    Server.listen(8888) { request =>
      Ok("Hello world!")
    }

    Starting an HTTP server require a service function. The service function will be run on the provided scala.concurrent.ExecutionContext. This function should be non-blocking, but you can also decide to go with a blocking service if you provide an appropriate ExecutionContext (just note that if the ExecutionContext is fully blocked, the HTTP server is fully blocked).

    The service function will be called by the server as soon as new HTTP request header has been received. The server also set up a lazy stream for the body. User code can pull from this stream and consume it if needed. Otherwise it will be drained after exchange completion (ie. when the response has been fully sent).

    The response value returned by the service function will be transfered back to the client.

  31. object ServerSentEvents

    Permalink

    Support for Server Sent Events content.

    Support for Server Sent Events content. It allows a server to stream events to a client. Events are string (utf-8) encoded, and a proper EventEncoder or EventDecoded must be available for your event payload type.

  32. def UpgradeRequired(protocol: HttpString): Response

    Permalink

    Create a 426 Upgrade required Response.

    Create a 426 Upgrade required Response.

    protocol

    the new protocol the server want to switch to.

  33. object at

    Permalink

    Request extractor.

    Request extractor.

    val app: PartialService = {
      case GET at "/" =>
        Ok("Home")
      case _ =>
        NotFound
    }

    Matches Request values by splitting them in a (HTTP method, URL) pair.

  34. implicit def pureResponse(response: Response): IO[Response]

    Permalink

    Automatically convert a Response into a pure IO[Response] if needed.

  35. implicit def sseDecoder[A](implicit eventDecoder: EventDecoder[A]): ContentDecoder[Stream[IO, Event[A]]]

    Permalink

    Support for Server Sent Events decoding.

  36. implicit def sseEncoder[A](implicit eventEncoder: EventEncoder[A]): ContentEncoder[Stream[IO, Event[A]]]

    Permalink

    Support for Server Sent Events encoding.

Inherited from AnyRef

Inherited from Any

Ungrouped