-
Notifications
You must be signed in to change notification settings - Fork 787
/
ServerBuilder.scala
87 lines (71 loc) · 2.94 KB
/
ServerBuilder.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
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
/*
* Copyright 2014 http4s.org
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.http4s
package server
import cats.effect._
import cats.syntax.all._
import fs2._
import fs2.concurrent.Signal
import fs2.concurrent.SignallingRef
import org.http4s.internal.BackendBuilder
import java.net.InetSocketAddress
import scala.collection.immutable
trait ServerBuilder[F[_]] extends BackendBuilder[F, Server] {
type Self <: ServerBuilder[F]
implicit protected def F: Concurrent[F]
def bindSocketAddress(socketAddress: InetSocketAddress): Self
final def bindHttp(port: Int = defaults.HttpPort, host: String = defaults.IPv4Host): Self =
bindSocketAddress(InetSocketAddress.createUnresolved(host, port))
final def bindLocal(port: Int): Self = bindHttp(port, defaults.IPv4Host)
final def bindAny(host: String = defaults.IPv4Host): Self = bindHttp(0, host)
/** Sets the handler for errors thrown invoking the service. Is not
* guaranteed to be invoked on errors on the server backend, such as
* parsing a request or handling a context timeout.
*/
def withServiceErrorHandler(
serviceErrorHandler: Request[F] => PartialFunction[Throwable, F[Response[F]]]
): Self
/** Returns a Server resource. The resource is not acquired until the
* server is started and ready to accept requests.
*/
def resource: Resource[F, Server]
/** Runs the server as a process that never emits. Useful for a server
* that runs for the rest of the JVM's life.
*/
final def serve: Stream[F, ExitCode] =
for {
signal <- Stream.eval(SignallingRef[F, Boolean](false))
exitCode <- Stream.eval(F.ref(ExitCode.Success))
serve <- serveWhile(signal, exitCode)
} yield serve
/** Runs the server as a Stream that emits only when the terminated signal becomes true.
* Useful for servers with associated lifetime behaviors.
*/
final def serveWhile(
terminateWhenTrue: Signal[F, Boolean],
exitWith: Ref[F, ExitCode],
): Stream[F, ExitCode] =
Stream.resource(resource) *> (terminateWhenTrue.discrete
.takeWhile(_ === false)
.drain ++ Stream.eval(exitWith.get))
/** Set the banner to display when the server starts up */
def withBanner(banner: immutable.Seq[String]): Self
/** Disable the banner when the server starts up */
final def withoutBanner: Self = withBanner(immutable.Seq.empty)
}
object SSLKeyStoreSupport {
final case class StoreInfo(path: String, password: String)
}