def cors()

in http-cors/src/main/scala/org/apache/pekko/http/cors/scaladsl/CorsDirectives.scala [67:133]


  def cors(settings: CorsSettings): Directive0 = {
    import settings._

    /** Return the invalid origins, or `Nil` if one is valid. */
    def validateOrigins(origins: Seq[HttpOrigin]): List[CorsRejection.Cause] =
      if (allowedOrigins == HttpOriginMatcher.* || origins.exists(allowedOrigins.matches)) {
        Nil
      } else {
        CorsRejection.InvalidOrigin(origins) :: Nil
      }

    /** Return the method if invalid, `Nil` otherwise. */
    def validateMethod(method: HttpMethod): List[CorsRejection.Cause] =
      if (allowedMethods.contains(method)) {
        Nil
      } else {
        CorsRejection.InvalidMethod(method) :: Nil
      }

    /** Return the list of invalid headers, or `Nil` if they are all valid. */
    def validateHeaders(headers: Seq[String]): List[CorsRejection.Cause] = {
      val invalidHeaders = headers.filterNot(allowedHeaders.matches)
      if (invalidHeaders.isEmpty) {
        Nil
      } else {
        CorsRejection.InvalidHeaders(invalidHeaders) :: Nil
      }
    }

    extractRequest.flatMap { request =>
      import request._

      (method, header[Origin].map(_.origins.toSeq), header[`Access-Control-Request-Method`].map(_.method)) match {
        case (OPTIONS, Some(origins), Some(requestMethod)) if origins.lengthCompare(1) <= 0 =>
          // Case 1: pre-flight CORS request

          val headers = header[`Access-Control-Request-Headers`].map(_.headers.toSeq).getOrElse(Seq.empty)

          validateOrigins(origins) ::: validateMethod(requestMethod) ::: validateHeaders(headers) match {
            case Nil    => complete(HttpResponse(StatusCodes.OK, preflightResponseHeaders(origins, headers)))
            case causes => reject(causes.map(CorsRejection(_)): _*)
          }

        case (_, Some(origins), None) =>
          // Case 2: simple/actual CORS request

          validateOrigins(origins) match {
            case Nil =>
              mapResponseHeaders { oldHeaders =>
                actualResponseHeaders(origins) ++ oldHeaders.filterNot(h => CorsDirectives.headersToClean.exists(h.is))
              }
            case causes =>
              reject(causes.map(CorsRejection(_)): _*)
          }

        case _ if allowGenericHttpRequests =>
          // Case 3a: not a valid CORS request, but allowed

          pass

        case _ =>
          // Case 3b: not a valid CORS request, forbidden

          reject(CorsRejection(CorsRejection.Malformed))
      }
    }
  }