All Downloads are FREE. Search and download functionalities are using the official Maven repository.

xitrum.handler.outbound.SetCORS.scala Maven / Gradle / Ivy

There is a newer version: 3.28.18
Show newest version
package xitrum.handler.outbound

import io.netty.channel.{ChannelHandler, ChannelHandlerContext, ChannelOutboundHandlerAdapter, ChannelPromise}
import io.netty.handler.codec.http.{HttpHeaders, HttpMethod, HttpRequest, HttpResponse, HttpResponseStatus}
import ChannelHandler.Sharable
import HttpHeaders.Names._
import HttpMethod._
import HttpResponseStatus._

import xitrum.Config
import xitrum.handler.HandlerEnv

@Sharable
class SetCORS extends ChannelOutboundHandlerAdapter {
  override def write(ctx: ChannelHandlerContext, msg: Object, promise: ChannelPromise) {
    import Config.xitrum.response.corsAllowOrigins

    if (!msg.isInstanceOf[HandlerEnv] || corsAllowOrigins.isEmpty) {
      ctx.write(msg, promise)
      return
    }

    val env      = msg.asInstanceOf[HandlerEnv]
    val request  = env.request
    val response = env.response

    val requestOrigin = HttpHeaders.getHeader(request, ORIGIN)

    // Access-Control-Allow-Origin
    if (!response.headers.contains(ACCESS_CONTROL_ALLOW_ORIGIN)) {
      if (corsAllowOrigins(0).equals("*")) {
        if (requestOrigin == null || requestOrigin == "null")
          HttpHeaders.setHeader(response, ACCESS_CONTROL_ALLOW_ORIGIN, "*")
        else
          HttpHeaders.setHeader(response, ACCESS_CONTROL_ALLOW_ORIGIN, requestOrigin)
      } else {
        if (corsAllowOrigins.contains(requestOrigin)) HttpHeaders.setHeader(response, ACCESS_CONTROL_ALLOW_ORIGIN, requestOrigin)
      }
    }

    // Access-Control-Allow-Credentials
    if (!response.headers.contains(ACCESS_CONTROL_ALLOW_CREDENTIALS))
      HttpHeaders.setHeader(response, ACCESS_CONTROL_ALLOW_CREDENTIALS, true)

    // Access-Control-Allow-Methods
    if (!response.headers.contains(ACCESS_CONTROL_ALLOW_METHODS)) {
      val pathInfo = env.pathInfo
      if (pathInfo == null) {
        if (response.getStatus == NOT_FOUND)
          HttpHeaders.setHeader(response, ACCESS_CONTROL_ALLOW_METHODS, OPTIONS.name)
        else
          HttpHeaders.setHeader(response, ACCESS_CONTROL_ALLOW_METHODS, OPTIONS.name + ", "+ GET.name + ", " + HEAD.name)
      } else {
        val allowMethods = OPTIONS +: Config.routes.tryAllMethods(pathInfo)
        HttpHeaders.setHeader(response, ACCESS_CONTROL_ALLOW_METHODS, allowMethods.mkString(", "))
      }
    }

    // Access-Control-Allow-Headers
    val accessControlRequestHeaders = HttpHeaders.getHeader(request, ACCESS_CONTROL_REQUEST_HEADERS)
    if (accessControlRequestHeaders != null && !response.headers.contains(ACCESS_CONTROL_ALLOW_HEADERS))
      HttpHeaders.setHeader(response, ACCESS_CONTROL_ALLOW_HEADERS, accessControlRequestHeaders)

    ctx.write(env, promise)
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy