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.
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
.
Allow to configure an HTTP client.
Allow to configure an HTTP client.
the number of threads used for the IO work. Default to min(availableProcessors, 2)
.
if true disable Nagle's algorithm. Default true
.
if defined used as a hint for the TCP buffer size. If none use the system default. Default to None
.
the protocols to use to connect to the server. If SSL enabled the protocol is negociated using ALPN. Without SSL enabled only direct HTTP2 connections with prior knowledge are supported. Meaning that HTTP2 will be used if it is the only option available. If HTTP is listed, the client will always fallback to HTTP/1.0 for plain connections.
if defined log the TCP traffic with the provided logger name. Default to None
.
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.
an fs2.Stream of Byte
.
a set of content-related HTTP headers.
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.
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
.
Expected errors.
Expected errors.
See the companion object for all defined errors.
the error code.
the error message.
An HTTP method such as GET or POST.
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.
the underlying string.
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") }
Panics are errors that should not occur or should not be handled.
Panics are errors that should not occur or should not be handled.
the error message.
A partial service is not defined for all Request.
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.
the HTTP method such as GET or POST.
the resource URL.
the scheme such as http
or https
.
the request content.
the HTTP headers.
the protocol version.
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.
A response can be used to upgrade the HTTP connection to a plain TCP connection. As a server, when you create a response to accept the connection upgrade you must provide this function. It will be called if the client decide to continue and to upgrade the connection. In this case you will receive the upstream as parameter and you have to return the downstream.
If, as a client you receive a 101 response, you can call this function by providing the upstream. In return you will get the downstream.
the HTTP response code such as 200
or 404
.
the response content.
the HTTP headers.
a function that will be called to upgrade the connection to a plain TCP connection.
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.
Allow to configure an HTTP server.
Allow to configure an HTTP server.
the number of threads used for the IO work. Default to max(availableProcessors, 2)
.
if true disable Nagle's algorithm. Default true
.
if defined used as a hint for the TCP buffer size. If none use the system default. Default to None
.
the allowed protocols (HTTP, HTTP2 or both). If SSL enabled the protocol is negociated using ALPN. Without SSL enabled only direct HTTP2 connections with prior knowledge are supported.
if defined log the TCP traffic with the provided logger name. Default to None
.
A service is a function from Request to eventually a Response.
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
A 400 Bad request Response.
Define the implicit encoder for ClasspathResource.
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.
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.
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))
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")))
A 201 Created Response.
DELETE HTTP method.
Constructs a DELETE Request.
All expected errors.
GET HTTP method.
Constructs a GET Request.
HEAD HTTP method.
Protocol version for HTTP/1.1
Protocol version for HTTP/2
Constructs a HEAD Request.
A collection of HTTP header names.
HTTP method matcher.
HTTP method matcher.
request.method match { case GET => println("This is a get") case _ => println("Oops") }
Allow to match HTTP methods.
HttpString builders.
A 500 Internal server error Response.
A 404 Not found Response.
A 200 Ok Response.
POST HTTP method.
PUT HTTP method.
Allows to panic.
Constructs a POST Request.
Constructs a PUT Request.
Create 30x HTTP redirects.
Create 30x HTTP redirects.
will be used as Location
header value.
308 if true, otherwise 307.
a 30x Response.
lol SSL.
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 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 servcie function will be transfered back to the client.
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.
Create a 101 Switching protocol Response.
Create a 426 Upgrade required Response.
Create a 426 Upgrade required Response.
the new protocol the server want to switch to.
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.
Automatically convert a Response into a pure IO[Response] if needed.
Support for Server Sent Events decoding.
Support for Server Sent Events encoding.
Wrap a pure value a into an async effect that will be available after the delay
.
The core module for lolhttp.
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 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.