-
Notifications
You must be signed in to change notification settings - Fork 38
/
CorsServer.scala
85 lines (72 loc) · 2.74 KB
/
CorsServer.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
/*
* Copyright 2016 Lomig Mégard
*
* 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 ch.megard.akka.http.cors.scaladsl
import akka.actor.typed.ActorSystem
import akka.actor.typed.scaladsl.Behaviors
import akka.http.scaladsl.Http
import akka.http.scaladsl.model.StatusCodes
import akka.http.scaladsl.server.Directives._
import akka.http.scaladsl.server._
import scala.io.StdIn
import scala.util.{Failure, Success}
/** Example of a Scala HTTP server using the CORS directive.
*/
object CorsServer {
def main(args: Array[String]): Unit = {
implicit val system: ActorSystem[Nothing] = ActorSystem(Behaviors.empty, "cors-server")
import system.executionContext
val futureBinding = Http().newServerAt("localhost", 8080).bind(route)
futureBinding.onComplete {
case Success(_) =>
system.log.info("Server online at http://localhost:8080/\nPress RETURN to stop...")
case Failure(exception) =>
system.log.error("Failed to bind HTTP endpoint, terminating system", exception)
system.terminate()
}
StdIn.readLine() // let it run until user presses return
futureBinding
.flatMap(_.unbind())
.onComplete(_ => system.terminate())
}
private def route: Route = {
import CorsDirectives._
// Your CORS settings are loaded from `application.conf`
// Your rejection handler
val rejectionHandler = corsRejectionHandler.withFallback(RejectionHandler.default)
// Your exception handler
val exceptionHandler = ExceptionHandler { case e: NoSuchElementException =>
complete(StatusCodes.NotFound -> e.getMessage)
}
// Combining the two handlers only for convenience
val handleErrors = handleRejections(rejectionHandler) & handleExceptions(exceptionHandler)
// Note how rejections and exceptions are handled *before* the CORS directive (in the inner route).
// This is required to have the correct CORS headers in the response even when an error occurs.
// format: off
handleErrors {
cors() {
handleErrors {
path("ping") {
complete("pong")
} ~
path("pong") {
failWith(new NoSuchElementException("pong not found, try with ping"))
}
}
}
}
// format: on
}
}