Skip to content

Commit

Permalink
feat: cors
Browse files Browse the repository at this point in the history
  • Loading branch information
tkqubo committed Feb 3, 2016
1 parent dc8d559 commit a742782
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import java.util.NoSuchElementException
import akka.actor.{Actor, ActorContext, ActorLogging}
import com.github.qubo.seed.swagger.{SwaggerDefinition, SwaggerDefinitionConfig}
import spray.http.MediaTypes._
import spray.http.StatusCodes
import spray.http.{AllOrigins, StatusCodes}
import spray.httpx.SprayJsonSupport
import spray.json.DefaultJsonProtocol
import spray.routing.{ExceptionHandler, HttpService, Route}
Expand All @@ -19,6 +19,7 @@ class ApiRouterActor
with DefaultJsonProtocol
with SprayJsonSupport
with UserApi
with CorsHelper
with HttpService {
def actorRefFactory: ActorContext = context
implicit val ec: ExecutionContext = actorRefFactory.dispatcher
Expand All @@ -28,7 +29,7 @@ class ApiRouterActor
)

def receive: Receive = runRoute(
respondWithMediaType(`application/json`) {
(cors(AllOrigins) & respondWithMediaType(`application/json`)) {
apiRoute ~ swaggerRoute
} ~ swaggerUiRoute
)
Expand Down
55 changes: 55 additions & 0 deletions src/main/scala/com/github/qubo/seed/routes/CorsHelper.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package com.github.qubo.seed.routes


import spray.http.HttpHeaders._
import spray.http.HttpMethods._
import spray.http._
import spray.routing._
import spray.util._

trait CorsHelper {
this: HttpService =>
val MaxAge = 1728000

def p3p(value: String = """CP="CAO PSA OUR""""): Directive0 =
mapHttpResponseHeaders(_ ++ List(RawHeader("P3P", value)))

def cors(origins: Seq[String]): Directive0 =
cors(SomeOrigins(origins.map(HttpOrigin(_))))

def cors(origin: String): Directive0 =
if (origin == "*") {
cors(AllOrigins)
} else {
cors(SomeOrigins(Seq(HttpOrigin(origin))))
}

def cors(origins: AllowedOrigins): Directive0 = mapRequestContext { ctx =>
val originHeader = if (origins == AllOrigins) {
ctx.request.headers.findByType[`Origin`]
} else {
None
}
val resOrigins = originHeader.map { case Origin(origin) => SomeOrigins(origin) }.getOrElse(origins)
ctx.withRouteResponseHandling({
//It is an option request for a resource that responds to some other method
case Rejected(x) if ctx.request.method.equals(HttpMethods.OPTIONS) =>
ctx.complete(HttpResponse().withHeaders(
allowOriginHeader(resOrigins) ++ fixedCorsHeaders
))
}).withHttpResponseHeadersMapped { headers =>
allowOriginHeader(resOrigins) ++ fixedCorsHeaders ++ headers
}
} & p3p()

private def fixedCorsHeaders: List[HttpHeader] =
List(
`Access-Control-Allow-Methods`(GET, POST, PATCH, PUT, DELETE, OPTIONS),
`Access-Control-Allow-Headers`("Content-Type,Accept-Language,Authorization"),
`Access-Control-Allow-Credentials`(true),
`Access-Control-Max-Age`(MaxAge)
)

private def allowOriginHeader(origins: AllowedOrigins): List[HttpHeader] =
List(`Access-Control-Allow-Origin`(origins))
}

0 comments on commit a742782

Please sign in to comment.